1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2012-2017. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20
21-module(asn1rtt_jer).
22%% encoding / decoding of BER
23-ifdef(DEBUG).
24-compile(export_all).
25-endif.
26%% For typeinfo JER
27-export([encode_jer/3, decode_jer/3]).
28
29
30%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31%% Common code for all JER encoding/decoding
32%%
33%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34encode_jer(Module,InfoFunc,Val) ->
35    Info = Module:InfoFunc(),
36    encode_jer(Info,Val).
37
38%% {sequence,
39%%    Name::atom() % The record name used for the sequence
40%%    Arity::integer() % number of components
41%%    CompInfos::[CompInfo()] % list of components with name, type etc
42%%    Value::record matching name and arity
43
44encode_jer({sequence_tab,Simple,Sname,Arity,CompInfos},Value)
45  when tuple_size(Value) == Arity+1 ->
46    [Sname|Clist] = tuple_to_list(Value),
47    encode_jer_component_tab(CompInfos,Clist,Simple,#{});
48%% {sequence,
49%%    Name::atom() % The record name used for the sequence
50%%    Arity::integer() % number of components
51%%    CompInfos::[CompInfo()] % list of components with name, type etc
52%%    Value::record matching name and arity
53encode_jer({sequence,Sname,Arity,CompInfos},Value)
54  when tuple_size(Value) == Arity+1 ->
55    [Sname|Clist] = tuple_to_list(Value),
56    encode_jer_component(CompInfos,Clist,[]);
57encode_jer(string,Str) when is_list(Str) ->
58    list_to_binary(Str);
59encode_jer({string,_Prop},Str) when is_list(Str) ->
60    list_to_binary(Str);
61encode_jer(string,Str) when is_binary(Str) ->
62    Str;
63encode_jer({string,_Prop},Str) when is_binary(Str) ->
64    Str;
65encode_jer('INTEGER',Int) when is_integer(Int) ->
66    Int;
67encode_jer({'INTEGER',{Min,Max}},Int) when is_integer(Int),Max >=Int, Int >= Min ->
68    Int;
69encode_jer({'INTEGER_NNL',_NNL},Int) when is_integer(Int) ->
70    Int;
71encode_jer(Type = {'INTEGER_NNL',NNList},Int) when is_atom(Int) ->
72    case lists:keyfind(Int, 1, NNList) of
73        {_, NewVal} ->
74            NewVal;
75        _ ->
76            exit({error, {asn1, {Type,Int}}})
77    end;
78encode_jer({Type = {'INTEGER_NNL',_NNList},_Constraint},Int) when is_atom(Int) ->
79    encode_jer(Type,Int);
80encode_jer({{'INTEGER_NNL',_NNList},Constraint},Int) when is_integer(Int) ->
81    encode_jer({'INTEGER',Constraint},Int);
82encode_jer('BOOLEAN',Bool) when is_boolean(Bool) ->
83    Bool;
84encode_jer({'BOOLEAN',_Prop},Bool) when is_boolean(Bool) ->
85    Bool;
86encode_jer('NULL',_) ->
87    null;
88encode_jer(legacy_octet_string, Value) when is_list(Value) ->
89    bitstring2json(list_to_binary(Value));
90encode_jer({legacy_octet_string,_Prop}, Value) when is_list(Value) ->
91    bitstring2json(list_to_binary(Value));
92encode_jer(octet_string,Value) when is_binary(Value) ->
93    encode_jer({octet_string,[]}, Value);
94encode_jer({octet_string,_Prop}, Value) when is_binary(Value) ->
95    bitstring2json(Value);
96
97encode_jer({'ENUMERATED',EnumMap},Val) when is_map_key(Val,EnumMap) ->
98    Val;
99encode_jer({Type = {'ENUMERATED',_EnumList},_Constr}, Val) ->
100    encode_jer(Type,Val);
101
102encode_jer({'ENUMERATED_EXT',_EnumMap},Val) when is_atom(Val) ->
103    Val;
104encode_jer({Type = {'ENUMERATED_EXT',_EnumList},_Constr}, Val) ->
105    encode_jer(Type,Val);
106
107encode_jer({typeinfo,{Module,Func}},Val) ->
108    TypeInfo = Module:Func(),
109    encode_jer(TypeInfo,Val);
110
111encode_jer({sof,Type},Vals) when is_list(Vals) ->
112    [encode_jer(Type,Val)||Val <- Vals];
113encode_jer({choice,Choices},{Alt,Value}) ->
114    case is_map_key(AltBin = atom_to_binary(Alt,utf8),Choices) of
115        true ->
116            EncodedVal = encode_jer(maps:get(AltBin,Choices),Value),
117            #{AltBin => EncodedVal};
118        false ->
119            exit({error,{asn1,{invalid_choice,Alt,Choices}}})
120    end;
121
122encode_jer(bit_string,Value) ->
123    Str = bitstring2json(Value),
124    #{value => Str, length => bit_size(Value)};
125encode_jer({bit_string,FixedLength},Value) when is_bitstring(Value), is_integer(FixedLength) ->
126    Value2 = jer_padbitstr(Value,FixedLength),
127    bitstring2json(Value2);
128encode_jer(compact_bit_string,Compact) ->
129    BitStr = jer_compact2bitstr(Compact),
130    encode_jer(bit_string,BitStr);
131encode_jer({compact_bit_string,FixedLength},Compact = {_Unused,Binary}) when is_binary(Binary) ->
132    BitStr = jer_compact2bitstr(Compact),
133    encode_jer({bit_string,FixedLength},BitStr);
134encode_jer({bit_string_nnl,NNL},Value) ->
135    Value1 = jer_bit_str2bitstr(Value,NNL),
136    encode_jer(bit_string,Value1);
137encode_jer({{bit_string_nnl,NNL},FixedLength},Value) ->
138    Value1 = jer_bit_str2bitstr(Value,NNL),
139    encode_jer({bit_string,FixedLength},Value1);
140encode_jer({compact_bit_string_nnl,NNL},Value) ->
141    Value1 = jer_bit_str2bitstr(Value,NNL),
142    encode_jer(bit_string,Value1);
143encode_jer({{compact_bit_string_nnl,NNL},FixedLength},Value) ->
144    Value1 = jer_bit_str2bitstr(Value,NNL),
145    encode_jer({bit_string,FixedLength},Value1);
146%%encode_jer({legacy_bit_string_nnl,NNL},Value) ->
147%%encode_jer({{legacy_bit_string_nnl,NNL},FixedLength},Value) ->
148encode_jer('OBJECT IDENTIFIER',Oid) when is_tuple(Oid) ->
149    oid2json(Oid);
150encode_jer('RELATIVE-OID',Oid) when is_tuple(Oid) ->
151    oid2json(Oid);
152encode_jer({'ObjClassFieldType',_,_},Val) when is_binary(Val)->
153    Val;
154encode_jer('ASN1_OPEN_TYPE',Val) when is_binary(Val) ->
155    Val;
156
157encode_jer(Type,Val) ->
158    exit({error,{asn1,{{encode,Type},Val}}}).
159
160
161encode_jer_component_tab([{_Name, _Type, 'OPTIONAL'} | CompInfos], [asn1_NOVALUE | Rest], Simple, MapAcc) ->
162    encode_jer_component_tab(CompInfos, Rest, Simple, MapAcc);
163encode_jer_component_tab([{_Name, _Type, {'DEFAULT',_}} | CompInfos], [asn1_DEFAULT | Rest], Simple, MapAcc) ->
164    encode_jer_component_tab(CompInfos, Rest, Simple, MapAcc);
165encode_jer_component_tab([{Name, Type, _OptOrDefault} | CompInfos], [Value | Rest], Simple, MapAcc) ->
166    Enc = encode_jer(Type, Value),
167    encode_jer_component_tab(CompInfos, Rest, Simple, MapAcc#{Name => Enc});
168encode_jer_component_tab([], _, _Simple, MapAcc) ->
169    MapAcc.
170
171encode_jer_component([{_Name, _Type, 'OPTIONAL'} | CompInfos], [asn1_NOVALUE | Rest], Acc) ->
172    encode_jer_component(CompInfos, Rest, Acc);
173encode_jer_component([{_Name, _Type, {'DEFAULT',_}} | CompInfos], [asn1_DEFAULT | Rest], Acc) ->
174    encode_jer_component(CompInfos, Rest, Acc);
175encode_jer_component([{Name, Type, _OptOrDefault} | CompInfos], [Value | Rest], Acc) ->
176    Enc = encode_jer(Type, Value),
177    encode_jer_component(CompInfos, Rest, [{Name,Enc}|Acc]);
178encode_jer_component([], _, []) ->
179    #{}; % ensure that it is encoded as an empty object in JSON
180encode_jer_component([], _, Acc) ->
181    lists:reverse(Acc).
182
183decode_jer(Module,InfoFunc,Val) ->
184    Info = Module:InfoFunc(),
185    decode_jer(Info,Val).
186%% FIXME probably generate EnumList as a map with binaries as keys
187%% and check if the Value is in the map. Also take the extensionmarker into
188%% account and in that case allow any value but return as binary since it
189%% is a potential atom leak to convert unknown values to atoms
190%% maybe convert to existing atom
191%% FIXME this is a discrepancy compare with other backends which return {asn1_enum,Val}
192%% for unknown enum values when the type is extensible
193decode_jer({'ENUMERATED',_EnumList}, Val) when is_binary(Val) ->
194    binary_to_existing_atom(Val,utf8);
195decode_jer({'ENUMERATED',_EnumList}, Val) when is_boolean(Val) ->
196    Val;
197decode_jer({'ENUMERATED',_EnumList}, null) ->
198    null;
199decode_jer({Type = {'ENUMERATED',_EnumList},_Constr}, Val) ->
200    decode_jer(Type,Val);
201decode_jer({'ENUMERATED_EXT',EnumList}, Val) ->
202    decode_jer({'ENUMERATED',EnumList}, Val);
203decode_jer({Type = {'ENUMERATED_EXT',_EnumList},_Constr}, Val) ->
204    decode_jer(Type,Val);
205
206decode_jer({typeinfo,{Module,Func}},Val) ->
207    TypeInfo = Module:Func(),
208    decode_jer(TypeInfo,Val);
209decode_jer({sequence,Sname,_Arity,CompInfos},Value)
210  when is_map(Value) ->
211    DecodedComps = decode_jer_component(CompInfos,Value,[]),
212    list_to_tuple([Sname|DecodedComps]);
213
214%% Unfortunately we have to represent strings as lists to be compatible
215%% with the other backends. Should add an option to the compiler in the future
216%% which makes it possible to represent all strings as erlang binaries
217decode_jer(string,Str) when is_binary(Str) ->
218    binary_to_list(Str);
219decode_jer({string,_Prop},Str) when is_binary(Str) ->
220    binary_to_list(Str);
221decode_jer('INTEGER',Int) when is_integer(Int) ->
222    Int;
223decode_jer({'INTEGER',{Min,Max}},Int) when is_integer(Int),Max >=Int, Int >= Min ->
224    Int;
225decode_jer({Type = {'INTEGER_NNL',_NNList},_},Int) ->
226    decode_jer(Type,Int);
227decode_jer({'INTEGER_NNL',NNList},Int) ->
228    case lists:keyfind(Int, 2, NNList) of
229        {NewName, _} ->
230            NewName;
231        _ ->
232            Int
233    end;
234decode_jer('BOOLEAN',Bool) when is_boolean(Bool) ->
235    Bool;
236decode_jer({'BOOLEAN',_Prop},Bool) when is_boolean(Bool) ->
237    Bool;
238decode_jer('NULL',null) ->
239    'NULL';
240decode_jer(legacy_octet_string,Str) when is_binary(Str) ->
241    json2octetstring2string(binary_to_list(Str));
242decode_jer(octet_string,Str) when is_binary(Str) ->
243    json2octetstring2binary(binary_to_list(Str));
244decode_jer({sof,Type},Vals) when is_list(Vals) ->
245    [decode_jer(Type,Val)||Val <- Vals];
246decode_jer({choice,ChoiceTypes},ChoiceVal) ->
247    [{Alt,Val}] = maps:to_list(ChoiceVal),
248    case ChoiceTypes of
249        #{Alt := Type} ->
250            Type = maps:get(Alt,ChoiceTypes),
251            {binary_to_atom(Alt,utf8),decode_jer(Type,Val)};
252        _ ->
253            exit({error,{asn1,{invalid_choice,Alt,maps:keys(ChoiceTypes)}}})
254    end;
255decode_jer(bit_string,#{<<"value">> := Str, <<"length">> := Length}) ->
256    json2bitstring(binary_to_list(Str),Length);
257decode_jer({bit_string,FixedLength},Str) when is_binary(Str) ->
258    json2bitstring(binary_to_list(Str),FixedLength);
259decode_jer({bit_string_nnl,NNL},#{<<"value">> := Str, <<"length">> := Length}) ->
260    BitStr = json2bitstring(binary_to_list(Str),Length),
261    jer_bitstr2names(BitStr,NNL);
262decode_jer({{bit_string_nnl,NNL},FixedLength},Str) when is_binary(Str)->
263    BitStr = json2bitstring(binary_to_list(Str),FixedLength),
264    jer_bitstr2names(BitStr,NNL);
265decode_jer({compact_bit_string_nnl,NNL},Value) ->
266    decode_jer({bit_string_nnl,NNL},Value);
267decode_jer({{compact_bit_string_nnl,NNL},FixedLength},Value) ->
268    decode_jer({{bit_string_nnl,NNL},FixedLength},Value);
269decode_jer(compact_bit_string,#{<<"value">> := Str, <<"length">> := Length}) ->
270    BitStr = json2bitstring(binary_to_list(Str),Length),
271    jer_bitstr2compact(BitStr);
272decode_jer({compact_bit_string,FixedLength},Str) ->
273    BitStr = json2bitstring(binary_to_list(Str),FixedLength),
274    Unused = (8 - (FixedLength rem 8)) band 7,
275    {Unused,<<BitStr/bitstring,0:Unused>>};
276decode_jer('OBJECT IDENTIFIER',OidBin) when is_binary(OidBin) ->
277    json2oid(OidBin);
278decode_jer('RELATIVE-OID',OidBin) when is_binary(OidBin) ->
279    json2oid(OidBin);
280decode_jer({'ObjClassFieldType',_,_},Bin) when is_binary(Bin) ->
281    Bin;
282decode_jer('ASN1_OPEN_TYPE',Bin) when is_binary(Bin) ->
283    Bin;
284decode_jer(Type,Val) ->
285    exit({error,{asn1,{{decode,Type},Val}}}).
286
287decode_jer_component([{Name, Type, _OptOrDefault} | CompInfos], VMap, Acc)
288    when is_map_key(Name, VMap) ->
289    Value = maps:get(Name, VMap),
290    Dec = decode_jer(Type, Value),
291    decode_jer_component(CompInfos, VMap, [Dec | Acc]);
292decode_jer_component([{_Name, _Type, 'OPTIONAL'} | CompInfos], VMap, Acc) ->
293    decode_jer_component(CompInfos, VMap, [asn1_NOVALUE | Acc]);
294decode_jer_component([{_Name, _Type, {'DEFAULT',Dvalue}} | CompInfos], VMap, Acc) ->
295    decode_jer_component(CompInfos, VMap, [Dvalue | Acc]);
296decode_jer_component([{Name, _Type, _OptOrDefault} | _CompInfos], VMap, _Acc) ->
297    exit({error,{asn1,{{decode,{mandatory_component_missing,Name}},VMap}}});
298decode_jer_component([], _, Acc) ->
299    lists:reverse(Acc).
300
301%% This is the default representation of octet string i.e binary
302json2octetstring2binary(Value) ->
303    list_to_binary(json2octetstring(Value,[])).
304
305%% This is the legacy_types representation of octet string i.e as a list
306json2octetstring2string(Value) ->
307    json2octetstring(Value,[]).
308
309json2octetstring([A1,A2|Rest],Acc) ->
310    Int = list_to_integer([A1,A2],16),
311    json2octetstring(Rest,[Int|Acc]);
312json2octetstring([], Acc) ->
313    lists:reverse(Acc).
314
315json2bitstring(Value,Length) ->
316    json2bitstring(Value,Length,[]).
317
318json2bitstring([A1,A2],Length,Acc) ->
319    Int = list_to_integer([A1,A2],16) bsr (8-Length),
320    Bin = list_to_binary(lists:reverse(Acc)),
321    << Bin/binary,Int:Length>>;
322json2bitstring([A1,A2|Rest],Length,Acc) ->
323    Int = list_to_integer([A1,A2],16),
324    json2bitstring(Rest,Length-8,[Int|Acc]);
325json2bitstring([],0,Acc) ->
326    Bin = list_to_binary(lists:reverse(Acc)),
327    Bin.
328
329bitstring2json(BitStr) when is_binary(BitStr) ->
330    octetstring2json(binary_to_list(BitStr));
331bitstring2json(BitStr) ->
332    Pad = 8 - bit_size(BitStr) rem 8,
333    NewStr = <<BitStr/bitstring,0:Pad>>,
334    octetstring2json(binary_to_list(NewStr)).
335
336octetstring2json(List) when is_list(List) ->
337    list_to_binary([begin Num = integer_to_list(X,16),
338           if length(Num) == 1 -> "0"++Num;
339              true -> Num
340           end
341     end|| X<-List]).
342
343oid2json(Oid) when is_tuple(Oid) ->
344    OidList = tuple_to_list(Oid),
345    OidNumberStr = [integer_to_list(V)|| V <- OidList],
346    oid2json(OidNumberStr,[]).
347
348oid2json([Num|T],[]) ->
349    oid2json(T,[Num]);
350oid2json([Num|T],Acc) ->
351    oid2json(T,[Num,$.|Acc]);
352oid2json([],Acc) ->
353    list_to_binary(lists:reverse(Acc)).
354
355json2oid(OidStr) when is_binary(OidStr) ->
356    OidList = binary:split(OidStr,[<<".">>],[global]),
357    OidNumList = [binary_to_integer(Num)||Num <- OidList],
358    list_to_tuple(OidNumList).
359
360jer_bit_str2bitstr(Compact = {_Unused,_Binary}, _NamedBitList) ->
361    jer_compact2bitstr(Compact);
362jer_bit_str2bitstr(Int, _NamedBitList) when is_integer(Int) ->
363    jer_compact2bitstr(Int);
364jer_bit_str2bitstr(BitList = [Bit|_], _NamedBitList) when Bit == 1; Bit == 0 ->
365    Int = list_to_integer([case B of 0 -> $0; 1 -> $1 end || B <- BitList],2),
366    Len = length(BitList),
367    <<Int:Len>>;
368jer_bit_str2bitstr([H | _] = Bits, NamedBitList)
369    when is_atom(H) ->
370    jer_do_encode_named_bit_string(Bits, NamedBitList);
371jer_bit_str2bitstr([{bit, _} | _] = Bits, NamedBitList) ->
372    jer_do_encode_named_bit_string(Bits, NamedBitList);
373jer_bit_str2bitstr([], _NamedBitList) ->
374    <<>>;
375jer_bit_str2bitstr(BitStr,_NamedBitList) when is_bitstring(BitStr) ->
376    BitStr.
377
378jer_compact2bitstr({Unused,Binary}) ->
379    Size = bit_size(Binary) - Unused,
380    <<BitStr:Size/bitstring,_/bitstring >> = Binary,
381    BitStr;
382jer_compact2bitstr(Int) when is_integer(Int) ->
383    jer_int2bitstr(Int);
384jer_compact2bitstr(BitList = [Bit|_]) when Bit == 1; Bit == 0 ->
385    IntStr = jer_skip_trailing_zeroes(BitList,[]),
386    Int = list_to_integer(IntStr,2),
387    Len = length(IntStr),
388    <<Int:Len>>.
389
390jer_skip_trailing_zeroes([1|Rest],Acc) ->
391    jer_skip_trailing_zeroes(Rest,[$1|Acc]);
392jer_skip_trailing_zeroes([0|Rest],Acc) ->
393    jer_skip_trailing_zeroes(Rest,[$0|Acc]);
394jer_skip_trailing_zeroes([],[$0|Acc]) ->
395    jer_skip_trailing_zeroes([],Acc);
396jer_skip_trailing_zeroes([],Acc) ->
397    lists:reverse(Acc).
398
399
400
401
402jer_padbitstr(BitStr,FixedLength) when bit_size(BitStr) == FixedLength ->
403    BitStr;
404jer_padbitstr(BitStr,FixedLength) when bit_size(BitStr) < FixedLength ->
405    Len = bit_size(BitStr),
406    PadLen = FixedLength - Len,
407    <<BitStr/bitstring,0:PadLen>>.
408
409jer_int2bitstr(Int) when is_integer(Int), Int >= 0 ->
410    jer_int2bitstr(Int,<<>>).
411
412jer_int2bitstr(0,Acc) ->
413    Acc;
414jer_int2bitstr(Int,Acc) ->
415    Bit = Int band 1,
416    jer_int2bitstr(Int bsr 1,<<Acc/bitstring,Bit:1>>).
417
418jer_bitstr2compact(BitStr) ->
419    Size = bit_size(BitStr),
420    Unused = (8 - Size rem 8) band 7,
421    {Unused,<<BitStr/bitstring,0:Unused>>}.
422
423jer_do_encode_named_bit_string([FirstVal | RestVal], NamedBitList) ->
424    ToSetPos = jer_get_all_bitposes([FirstVal | RestVal], NamedBitList, []),
425    Size = lists:max(ToSetPos) + 1,
426    BitList = jer_make_and_set_list(Size, ToSetPos, 0),
427    encode_bitstring(BitList).
428
429jer_get_all_bitposes([{bit, ValPos} | Rest], NamedBitList, Ack) ->
430    jer_get_all_bitposes(Rest, NamedBitList, [ValPos | Ack]);
431jer_get_all_bitposes([Val | Rest], NamedBitList, Ack) when is_atom(Val) ->
432    case lists:keyfind(Val, 1, NamedBitList) of
433        {_ValName, ValPos} ->
434            jer_get_all_bitposes(Rest, NamedBitList, [ValPos | Ack]);
435        _ ->
436            exit({error, {asn1, {bitstring_namedbit, Val}}})
437    end;
438jer_get_all_bitposes([], _NamedBitList, Ack) ->
439    lists:sort(Ack).
440
441jer_make_and_set_list(0, [], _) ->
442    [];
443jer_make_and_set_list(0, _, _) ->
444    exit({error, {asn1, bitstring_sizeconstraint}});
445jer_make_and_set_list(Len, [XPos | SetPos], XPos) ->
446    [1 | jer_make_and_set_list(Len - 1, SetPos, XPos + 1)];
447jer_make_and_set_list(Len, [Pos | SetPos], XPos) ->
448    [0 | jer_make_and_set_list(Len - 1, [Pos | SetPos], XPos + 1)];
449jer_make_and_set_list(Len, [], XPos) ->
450    [0 | jer_make_and_set_list(Len - 1, [], XPos + 1)].
451
452%%=================================================================
453%% Do the actual encoding
454%%     ([bitlist]) -> {ListLen, UnusedBits, OctetList}
455%%=================================================================
456
457encode_bitstring([B8, B7, B6, B5, B4, B3, B2, B1 | Rest]) ->
458    Val = (B8 bsl 7) bor (B7 bsl 6) bor (B6 bsl 5) bor (B5 bsl 4) bor
459	(B4 bsl 3) bor (B3 bsl 2) bor (B2 bsl 1) bor B1,
460    encode_bitstring(Rest, <<Val>>);
461encode_bitstring(Val) ->
462    unused_bitlist(Val, <<>>).
463
464encode_bitstring([B8, B7, B6, B5, B4, B3, B2, B1 | Rest], Ack) ->
465    Val = (B8 bsl 7) bor (B7 bsl 6) bor (B6 bsl 5) bor (B5 bsl 4) bor
466	(B4 bsl 3) bor (B3 bsl 2) bor (B2 bsl 1) bor B1,
467    encode_bitstring(Rest, [Ack | [Val]]);
468%%even multiple of 8 bits..
469encode_bitstring([], Ack) ->
470    Ack;
471%% unused bits in last octet
472encode_bitstring(Rest, Ack) ->
473    unused_bitlist(Rest,Ack).
474
475%%%%%%%%%%%%%%%%%%
476%% unused_bitlist([list of ones and zeros <= 7], 7, []) ->
477%%  {Unused bits, Last octet with bits moved to right}
478unused_bitlist([], Ack) ->
479    Ack;
480unused_bitlist([Bit | Rest], Ack) ->
481    unused_bitlist(Rest, <<Ack/bitstring,Bit:1>>).
482
483jer_bitstr2names(BitStr,[]) ->
484    BitStr;
485jer_bitstr2names(BitStr,NNL) ->
486    %% Fixme, the sorting should be done in compile time, maybe it already is
487    SortedList  = lists:keysort(2,NNL), %% Should be from bit 0 to bit N
488    jer_bitstr2names(BitStr,SortedList,0,[]).
489
490jer_bitstr2names(<<1:1,BitStr/bitstring>>,[{Name,Pos}|Rest],Pos,Acc) ->
491    jer_bitstr2names(BitStr,Rest,Pos+1,[Name|Acc]);
492jer_bitstr2names(<<1:1,BitStr/bitstring>>,NNL,Num,Acc) ->
493    jer_bitstr2names(BitStr,NNL,Num+1,[{bit,Num}|Acc]);
494jer_bitstr2names(<<0:1,BitStr/bitstring>>,[{_,Num}|Rest],Num,Acc) ->
495    jer_bitstr2names(BitStr,Rest,Num+1,Acc);
496jer_bitstr2names(<<0:1,BitStr/bitstring>>,NNL,Num,Acc) ->
497    jer_bitstr2names(BitStr,NNL,Num+1,Acc);
498jer_bitstr2names(<<>>,_,_,Acc) ->
499    lists:reverse(Acc).
500
501
502
503
504
505
506