aboutsummaryrefslogtreecommitdiffstats
path: root/lib/asn1
diff options
context:
space:
mode:
Diffstat (limited to 'lib/asn1')
-rw-r--r--lib/asn1/c_src/asn1_erl_driver.c3
-rw-r--r--lib/asn1/doc/src/asn1_ug.xml113
-rw-r--r--lib/asn1/src/asn1ct.erl2
-rw-r--r--lib/asn1/src/asn1ct_check.erl6
-rw-r--r--lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl31
-rw-r--r--lib/asn1/src/asn1ct_gen.erl27
-rw-r--r--lib/asn1/src/asn1ct_gen_ber.erl13
-rw-r--r--lib/asn1/src/asn1ct_gen_ber_bin_v2.erl14
-rw-r--r--lib/asn1/src/asn1ct_gen_per.erl23
-rw-r--r--lib/asn1/src/asn1ct_gen_per_rt2ct.erl23
-rw-r--r--lib/asn1/src/asn1rt_uper_bin.erl29
-rw-r--r--lib/asn1/test/asn1_SUITE.erl.src7
-rw-r--r--lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn18
-rw-r--r--lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl13
-rw-r--r--lib/asn1/test/test_compile_options.erl2
15 files changed, 214 insertions, 110 deletions
diff --git a/lib/asn1/c_src/asn1_erl_driver.c b/lib/asn1/c_src/asn1_erl_driver.c
index fd284e5800..9dd3a0fd7d 100644
--- a/lib/asn1/c_src/asn1_erl_driver.c
+++ b/lib/asn1/c_src/asn1_erl_driver.c
@@ -1407,7 +1407,6 @@ int decode_partial(ErlDrvBinary **drv_binary,unsigned char *in_buf, int in_buf_l
int msg_index_val;
int *msg_index, *tag_index, tmp_index;
int tag_seq_length;
- char tag_code; /* one of ASN1_SKIPPED, ASN1_OPTIONAL, ASN1_CHOOSEN */
int wanted_tag, next_tag;
int buf_end_index = in_buf_len;
int ret = 0, length, old_index;
@@ -1600,7 +1599,7 @@ int get_value(char *out_buf,
{
int len, lenoflen, indef=0, skip_len;
int ret=0;
- int start_index, out_index = 0;
+ int start_index;
/* printf("get_value 1\n\r"); */
if (in_buf[*msg_index] < 0x80){ /* short definite length */
diff --git a/lib/asn1/doc/src/asn1_ug.xml b/lib/asn1/doc/src/asn1_ug.xml
index f2cd073ec8..12d986308f 100644
--- a/lib/asn1/doc/src/asn1_ug.xml
+++ b/lib/asn1/doc/src/asn1_ug.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -22,7 +22,7 @@
</legalnotice>
<title>Asn1</title>
- <prepared>ETX/DN/SP Kenneth. Lundin</prepared>
+ <prepared>Kenneth Lundin</prepared>
<docno></docno>
<date>1999-03-25</date>
<rev>D</rev>
@@ -41,17 +41,28 @@
decode functions to be used by Erlang programs sending and
receiving ASN.1 specified data.</item>
<item>Run-time functions used by the generated code.</item>
- <item>Encoding rules supported are <em>BER</em>, the
- specialized BER version <em>DER</em> and the basic form of
- aligned and unaligned variants of <em>PER</em>.</item>
+ <item>The supported encoding rules are:
+ <list>
+ <item>
+ Basic Encoding Rules (<em>BER</em>)
+ </item>
+ <item>
+ Distinguished Encoding Rules (<em>DER</em>), a specialized form of BER that is used in security-conscious applications.
+ </item>
+ <item>
+ Packed Encoding Rules (<em>PER</em>) both the aligned and unaligned variant.
+ </item>
+ </list>
+ </item>
</list>
</section>
<section>
<title>Overview</title>
- <p>ASN.1 (Abstract Syntax Notation 1) defines the abstract
- syntax of information. The purpose of ASN.1 is to have
- a platform independent language to express types using a
+ <p>ASN.1 (Abstract Syntax Notation 1) is a formal language for describing data structures to be exchanged between distributed computer systems.
+ The purpose of ASN.1 is to have
+ a platform and programming language independent notation to express
+ types using a
standardized set of rules for the transformation of values of
a defined type, into a stream of bytes. This stream of bytes
can then be sent on a communication channel set up by the
@@ -102,20 +113,16 @@
[<cite id="DUBUISSON"></cite>], free to download at
<url href="http://www.oss.com/asn1/dubuisson.html">http://www.oss.com/asn1/dubuisson.html </url>.
</p>
- <p>Knowledge of Erlang programming is also essential and reading the book
- <em>Concurrent Programming in ERLANG</em>,
- [<cite id="erlbook2"></cite>], is recommended. Part 1 of this is available on the web in
- <url href="http://www.erlang.org/download/erlang-book-part1.pdf">PDF</url> format.
- </p>
</section>
<section>
<title>Capability</title>
<p>This application covers all features of ASN.1 up to the 1997
- edition of the specification. In the 2002 edition some new
- extensions came up of which there are support only for some of
- them. ECN (Cncoding Control Notation) and XML notation are still
- unsupported. Though, the other features of 2002 edition are
+ edition of the specification. In the 2002 edition of ASN.1 a number of
+ new features where introduced of which some are supported while
+ others are not. For example the
+ ECN (Encoding Control Notation) and XML notation are still
+ unsupported. Though, the other features of the 2002 edition are
fully or partly supported as shown below:</p>
<list type="bulleted">
<item>
@@ -308,7 +315,7 @@ erlc -o ../asnfiles -I ../asnfiles -I /usr/local/standards/asn1 Person.asn
<p>Choice of encoding rules, if omitted <c>ber</c> is the
default. The <c>ber_bin</c> and <c>per_bin</c> options
allows for optimizations and are therefore recommended
- instaed of the <c>ber</c> and <c>per</c> options.</p>
+ instead of the <c>ber</c> and <c>per</c> options.</p>
</item>
<tag><c>-o OutDirectory</c></tag>
<item>
@@ -629,7 +636,7 @@ asn1ct:decode('H323-MESSAGES','SomeChoiceType',Bytes). </pre>
<c>driver</c> options does not affect the encode or decode
result, just the time spent in run-time. When <c>ber_bin</c> and
<c>driver</c> or <c>per_bin, optimize</c> and <c>driver</c> is
- combined the C-code driver is used in choosen parts of encode /
+ combined the C-code driver is used in chosen parts of encode /
decode procedure.
</p>
<table>
@@ -749,11 +756,11 @@ asn1rt:decode('H323-MESSAGES','SomeChoiceType',Bytes). </pre>
you may want to continue running the old asn1 run-time
functionality.</item>
<item>Performance issues: If you have an asn1 system with a lot
- of cross references you may gain in performance. Meassurements
+ of cross references you may gain in performance. Measurements
must be done for each case.</item>
</list>
<p>You may choose either the plain multi file compilation that just
- merges the choosen asn1 specs or the <c>{inline,OutputModule}</c>
+ merges the chosen asn1 specs or the <c>{inline,OutputModule}</c>
that also includes the used asn1 run-time functionality.</p>
<p>For both cases you need to specify which asn1 specs you will
compile in a module that must have the extension
@@ -919,7 +926,7 @@ T5 ::= INTEGER (MIN&lt;..-99)
T6 ::= INTEGER {red(0),blue(1),white(2)}
</pre>
<p>The Erlang representation of an ASN.1 INTEGER is an integer or
- an atom if a so called \011<c>Named NumberList</c> (see T6 above)
+ an atom if a so called <c>Named Number List</c> (see T6 above)
is specified.</p>
<p>Below is an example of Erlang code which assigns values for the
above types: </p>
@@ -934,7 +941,7 @@ T6value3 = white
ASN.1 defined types. This style of value can be passed directly
to the encoder for transformation into a series of bytes.</p>
<p>The decoder will return an atom if the value corresponds to a
- symbol in the Named NumberList.</p>
+ symbol in the Named Number List.</p>
</section>
<section>
@@ -978,8 +985,9 @@ N1 = 'NULL',
<p>The enumerated type can be used, when the value we wish to
describe, may only take one of a set of predefined values.</p>
<pre>
-DaysOfTheWeek ::= ENUMERATED { sunday(1),monday(2),tuesday(3),
-\011wednesday(4),thursday(5),friday(6),saturday(7) }
+DaysOfTheWeek ::= ENUMERATED {
+ sunday(1),monday(2),tuesday(3),
+ wednesday(4),thursday(5),friday(6),saturday(7) }
</pre>
<p>For example to assign a weekday value in Erlang use the same atom
as in the <c>Enumerations</c> of the type definition:</p>
@@ -1273,11 +1281,14 @@ Pdu ::= SEQUENCE {
<p>Values can be assigned in Erlang as shown below:</p>
<pre>
MyPdu = #'Pdu'{a=22,b=77.99,c={0,1,2,3,4},d='NULL'}. </pre>
- <p>It is also possible to specify the value for each component in
- a SEQUENCE or a SET as <c>{ComponentName,Value}</c>. It is not
- recommended and is not supported if the flags <c>per_bin</c> or
- <c>ber_bin</c> and <c>optimize</c> were used when the module was
- compiled.</p>
+<note>
+ <p>
+ In very early versions of the asn1 compiler it was also possible to
+ specify the values of the components in
+ a SEQUENCE or a SET as a list of tuples <c>{ComponentName,Value}</c>.
+ This is no longer supported.
+ </p>
+</note>
<p>The decode functions will return a record as result when decoding
a <c>SEQUENCE</c> or a <c>SET</c>.
<marker id="DEFAULT"></marker>
@@ -1293,13 +1304,13 @@ MyPdu = #'Pdu'{a=22,b=77.99,c={0,1,2,3,4},d='NULL'}. </pre>
<p>For instance, if the following types exists in a file "File.asn":</p>
<pre>
Seq1 ::= SEQUENCE {
-\011a INTEGER DEFAULT 1,
-\011b Seq2 DEFAULT {aa TRUE, bb 15}
+ a INTEGER DEFAULT 1,
+ b Seq2 DEFAULT {aa TRUE, bb 15}
}
Seq2 ::= SEQUENCE {
-\011aa BOOLEAN,
-\011bb INTEGER
+ aa BOOLEAN,
+ bb INTEGER
}
</pre>
<p>Some values and the corresponding encoding in an Erlang terminal
@@ -1331,7 +1342,7 @@ ok
<marker id="DEFAULT DER"></marker>
</p>
<p>But, the DER encoding format has stronger requirements regarding
- default\011values both for SET and SEQUENCE. A more elaborate and time
+ default values both for SET and SEQUENCE. A more elaborate and time
expensive check of default values will take place. The following is
an example with the same types and values as above but with der
encoding format.</p>
@@ -1409,7 +1420,7 @@ Bad ::= SET {i INTEGER,
values is the same for SET as for SEQUENCE, and is supported by
the compiler, <seealso marker="#DEFAULT DER">see above</seealso>.</p>
<p>Moreover, in DER the elements of a SET will be sorted. If a
- component is an untagged choice the sorting have to take place
+ component is an un-tagged choice the sorting have to take place
in run-time. This fact emphasizes the following recommendation
if DER encoding format is used.</p>
<p>The concept of SET is an unusual
@@ -1425,7 +1436,7 @@ Bad ::= SET {i INTEGER,
</section>
<section>
- <title>Notes about Extendability for SEQUENCE and SET</title>
+ <title>Notes about Extend-ability for SEQUENCE and SET</title>
<p>When a SEQUENCE or SET contains an extension marker and
extension components like this:</p>
<pre>
@@ -1498,9 +1509,9 @@ C2 ::= CHOICE {
<section>
<title>Extendable CHOICE</title>
<p>When a CHOICE contains an extension marker and the decoder detects
- an unknown alternative of the CHIOCE the value is represented as:</p>
+ an unknown alternative of the CHOICE the value is represented as:</p>
<pre>
-\011 {asn1_ExtAlt, BytesForOpenType}
+{asn1_ExtAlt, BytesForOpenType}
</pre>
<p>Where <c>BytesForOpenType</c> is a list of bytes constituting the
encoding of the "unknown" CHOICE alternative. </p>
@@ -1630,15 +1641,15 @@ V = #'Emb'{a=["qqqq",[1,2,255]],
the record name is extended with an underscore and the component
name. If the embedded structure is deeper with SEQUENCE, SET or
CHOICE types in the line, each component-/alternative-name will
- be added to the recordname.</p>
+ be added to the record-name.</p>
<p>For example:</p>
<pre>
Seq ::= SEQUENCE{
- a\011CHOICE{
-\011b SEQUENCE {
-\011 c INTEGER
-\011 }
-\011}
+ a CHOICE{
+ b SEQUENCE {
+ c INTEGER
+ }
+ }
} </pre>
<p>will result in the following record:</p>
<pre>
@@ -1650,10 +1661,10 @@ Seq ::= SEQUENCE{
<pre>
Seq ::= SEQUENCE {
a SEQUENCE OF SEQUENCE {
-\011 b
+ b
}
c SET OF SEQUENCE {
-\011 d
+ d
}
} </pre>
<p>This results in the records:</p>
@@ -1802,16 +1813,16 @@ GENERAL-PROCEDURES GENERAL-PROCEDURE ::= {
<pre>
StartMessage ::= SEQUENCE {
msgId GENERAL-PROCEDURE.&amp;id ({GENERAL-PROCEDURES}),
- content GENERAL-PROCEDURE.&amp;Message\011({GENERAL-PROCEDURES}{@msgId}),
+ content GENERAL-PROCEDURE.&amp;Message ({GENERAL-PROCEDURES}{@msgId}),
} </pre>
<p>In the type <c>StartMessage</c> the constraint following the
<c>content</c> field tells that in a value of type
<c>StartMessage</c> the value in the <c>content</c> field must
- come from the same object that is choosen by the <c>msgId</c>
+ come from the same object that is chosen by the <c>msgId</c>
field.</p>
<p>So, the value <c>#'StartMessage'{msgId="home",content="Any Printable String"}</c> is legal to encode as a StartMessage
value, while the value <c>#'StartMessage'{msgId="remote", content="Some String"}</c> is illegal since the constraint
- in StartMessage tells that when you have choosen a value from a
+ in StartMessage tells that when you have chosen a value from a
specific object in the object set GENERAL-PROCEDURES in the
msgId field you have to choose a value from that same object in
the content field too. In this second case it should have been
@@ -1831,7 +1842,7 @@ StartMessage ::= SEQUENCE {
information object sets.
A part of a definition can be supplied as a parameter. For
instance, if a Type is used in a definition with certain
- purpose, one want the typename to express the intention. This
+ purpose, one want the type-name to express the intention. This
can be done with parameterization.</p>
<p>When many types (or an other ASN.1 entity) only differs in some
minor cases, but the structure of the types are similar, only
diff --git a/lib/asn1/src/asn1ct.erl b/lib/asn1/src/asn1ct.erl
index ae681a4a78..968468cb7f 100644
--- a/lib/asn1/src/asn1ct.erl
+++ b/lib/asn1/src/asn1ct.erl
@@ -1674,7 +1674,7 @@ create_pdec_inc_command(ModName,
% [concat_sequential(lists:reverse(Comms),
% [LastComm,CompAcc])|Acc]
case lists:reverse(TagCommand) of
- [Atom|Comms]�when is_atom(Atom) ->
+ [Atom|Comms] when is_atom(Atom) ->
[concat_sequential(lists:reverse(Comms),
[Atom,CompAcc])|Acc];
[[Command2,Tag2]|Comms] ->
diff --git a/lib/asn1/src/asn1ct_check.erl b/lib/asn1/src/asn1ct_check.erl
index 1c9f2c759a..7cd29623c1 100644
--- a/lib/asn1/src/asn1ct_check.erl
+++ b/lib/asn1/src/asn1ct_check.erl
@@ -6408,6 +6408,12 @@ any_component_relation(S,Type,CNames,NamePath,Acc) when is_record(Type,type) ->
[]
end,
InnerAcc ++ CRelPath ++ Acc;
+%% Just skip the markers for ExtensionAdditionGroup start and end
+%% in this function
+any_component_relation(S,[#'ExtensionAdditionGroup'{}|Cs],CNames,NamePath,Acc) ->
+ any_component_relation(S,Cs,CNames,NamePath,Acc);
+any_component_relation(S,['ExtensionAdditionGroupEnd'|Cs],CNames,NamePath,Acc) ->
+ any_component_relation(S,Cs,CNames,NamePath,Acc);
any_component_relation(_,[],_,_,Acc) ->
Acc.
diff --git a/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl b/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl
index a55ac9db8e..e3be914af4 100644
--- a/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl
+++ b/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -75,13 +75,15 @@ gen_encode_sequence(Erules,Typename,D) when is_record(D,type) ->
"Val"
end,
- {SeqOrSet,TableConsInfo,CompList} =
+ {SeqOrSet,TableConsInfo,CompList0} =
case D#type.def of
#'SEQUENCE'{tablecinf=TCI,components=CL} ->
{'SEQUENCE',TCI,CL};
#'SET'{tablecinf=TCI,components=CL} ->
{'SET',TCI,CL}
end,
+ %% filter away extensionAdditiongroup markers
+ CompList = filter_complist(CompList0),
Ext = extensible(CompList),
CompList1 = case CompList of
{Rl1,El,Rl2} -> Rl1 ++ El ++ Rl2;
@@ -183,7 +185,10 @@ gen_decode_sequence(Erules,Typename,D) when is_record(D,type) ->
asn1ct_name:start(),
asn1ct_name:clear(),
asn1ct_name:new(tag),
- #'SEQUENCE'{tablecinf=TableConsInfo,components=CList} = D#type.def,
+ #'SEQUENCE'{tablecinf=TableConsInfo,components=CList0} = D#type.def,
+
+ %% filter away extensionAdditiongroup markers
+ CList = filter_complist(CList0),
Ext = extensible(CList),
{CompList,CompList2} =
case CList of
@@ -345,7 +350,9 @@ gen_decode_set(Erules,Typename,D) when is_record(D,type) ->
asn1ct_name:clear(),
%% asn1ct_name:new(term),
asn1ct_name:new(tag),
- #'SET'{tablecinf=TableConsInfo,components=TCompList} = D#type.def,
+ #'SET'{tablecinf=TableConsInfo,components=TCompList0} = D#type.def,
+ %% filter away extensionAdditiongroup markers
+ TCompList = filter_complist(TCompList0),
Ext = extensible(TCompList),
ToOptional = fun(mandatory) ->
'OPTIONAL';
@@ -1426,6 +1433,22 @@ extensible({RootList,ExtList}) ->
{ext,length(RootList)+1,length(ExtList)};
extensible({_Rl1,_Ext,_Rl2}) ->
extensible.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% filter away ExtensionAdditionGroup start and end marks since these
+%% have no significance for the BER encoding
+%%
+filter_complist(CompList) when is_list(CompList) ->
+ lists:filter(fun(#'ExtensionAdditionGroup'{}) ->
+ false;
+ ('ExtensionAdditionGroupEnd') ->
+ false;
+ (_) ->
+ true
+ end, CompList);
+filter_complist({Root,Ext}) ->
+ {Root,filter_complist(Ext)};
+filter_complist({Root1,Ext,Root2}) ->
+ {Root1,filter_complist(Ext),Root2}.
print_attribute_comment(InnerType,Pos,Cname,Prop) ->
diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl
index 6b511a66da..0bb0b65e5d 100644
--- a/lib/asn1/src/asn1ct_gen.erl
+++ b/lib/asn1/src/asn1ct_gen.erl
@@ -537,33 +537,18 @@ gen_part_decode_funcs(WhatKind,_TypeName,{_,Directive,_,_}) ->
throw({error,{asn1,{"Not implemented yet",WhatKind," partial incomplete directive:",Directive}}}).
-extaddgroup2sequence(ExtList) ->
- extaddgroup2sequence(ExtList,[]).
-
-extaddgroup2sequence([{'ExtensionAdditionGroup',Number0}|T],Acc) ->
- Number = case Number0 of undefined -> 1; _ -> Number0 end,
- {ExtGroupComps,['ExtensionAdditionGroupEnd'|T2]} =
- lists:splitwith(fun(Elem) -> is_record(Elem,'ComponentType') end,T),
- extaddgroup2sequence(T2,[#'ComponentType'{
- name='ExtAddGroup',
- typespec=#type{def=#'SEQUENCE'{
- extaddgroup=Number,
- components=ExtGroupComps}},
- prop='OPTIONAL'}|Acc]);
-extaddgroup2sequence([C|T],Acc) ->
- extaddgroup2sequence(T,[C|Acc]);
-extaddgroup2sequence([],Acc) ->
- lists:reverse(Acc).
-
-
gen_types(Erules,Tname,{RootL1,ExtList,RootL2})
when is_list(RootL1), is_list(RootL2) ->
gen_types(Erules,Tname,RootL1),
- gen_types(Erules,Tname,extaddgroup2sequence(ExtList)),
+ Rtmod = list_to_atom(lists:concat(["asn1ct_gen_",erule(Erules),
+ rt2ct_suffix(Erules)])),
+ gen_types(Erules,Tname,Rtmod:extaddgroup2sequence(ExtList)),
gen_types(Erules,Tname,RootL2);
gen_types(Erules,Tname,{RootList,ExtList}) when is_list(RootList) ->
gen_types(Erules,Tname,RootList),
- gen_types(Erules,Tname,extaddgroup2sequence(ExtList));
+ Rtmod = list_to_atom(lists:concat(["asn1ct_gen_",erule(Erules),
+ rt2ct_suffix(Erules)])),
+ gen_types(Erules,Tname,Rtmod:extaddgroup2sequence(ExtList));
gen_types(Erules,Tname,[{'EXTENSIONMARK',_,_}|Rest]) ->
gen_types(Erules,Tname,Rest);
gen_types(Erules,Tname,[ComponentType|Rest]) ->
diff --git a/lib/asn1/src/asn1ct_gen_ber.erl b/lib/asn1/src/asn1ct_gen_ber.erl
index d70586c75c..491ebcb8fd 100644
--- a/lib/asn1/src/asn1ct_gen_ber.erl
+++ b/lib/asn1/src/asn1ct_gen_ber.erl
@@ -33,6 +33,7 @@
-export([gen_objectset_code/2, gen_obj_code/3]).
-export([re_wrap_erule/1]).
-export([unused_var/2]).
+-export([extaddgroup2sequence/1]).
-import(asn1ct_gen, [emit/1,demit/1]).
@@ -1734,3 +1735,15 @@ get_object_field(Name,ObjectFields) ->
{value,Field} -> Field;
false -> false
end.
+
+%% For BER the ExtensionAdditionGroup notation has no impact on the encoding/decoding
+%% and therefore we only filter away the ExtensionAdditionGroup start and end markers
+%%
+extaddgroup2sequence(ExtList) when is_list(ExtList) ->
+ lists:filter(fun(#'ExtensionAdditionGroup'{}) ->
+ false;
+ ('ExtensionAdditionGroupEnd') ->
+ false;
+ (_) ->
+ true
+ end, ExtList).
diff --git a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
index a146e92d64..9ec458e351 100644
--- a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
+++ b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
@@ -33,6 +33,7 @@
-export([gen_objectset_code/2, gen_obj_code/3]).
-export([encode_tag_val/3]).
-export([gen_inc_decode/2,gen_decode_selected/3]).
+-export([extaddgroup2sequence/1]).
-import(asn1ct_gen, [emit/1,demit/1]).
@@ -1826,8 +1827,15 @@ mk_object_val(Val, Ack, Len) ->
add_func(F={_Func,_Arity}) ->
ets:insert(asn1_functab,{F}).
-
-
-
+%% For BER the ExtensionAdditionGroup notation has no impact on the encoding/decoding
+%% and therefore we only filter away the ExtensionAdditionGroup start and end markers
+extaddgroup2sequence(ExtList) when is_list(ExtList) ->
+ lists:filter(fun(#'ExtensionAdditionGroup'{}) ->
+ false;
+ ('ExtensionAdditionGroupEnd') ->
+ false;
+ (_) ->
+ true
+ end, ExtList).
diff --git a/lib/asn1/src/asn1ct_gen_per.erl b/lib/asn1/src/asn1ct_gen_per.erl
index 23fb392d60..8313cf1b60 100644
--- a/lib/asn1/src/asn1ct_gen_per.erl
+++ b/lib/asn1/src/asn1ct_gen_per.erl
@@ -31,6 +31,7 @@
-export([gen_encode/2, gen_encode/3]).
-export([is_already_generated/2,more_genfields/1,get_class_fields/1,
get_object_field/2]).
+-export([extaddgroup2sequence/1]).
-import(asn1ct_gen, [emit/1,demit/1]).
@@ -1393,3 +1394,25 @@ get_object_field(Name,ObjectFields) ->
false -> false
end.
+
+%% For PER the ExtensionAdditionGroup notation has significance for the encoding and decoding
+%% the components within the ExtensionAdditionGroup is treated in a similar way as if they
+%% have been specified within a SEQUENCE, therefore we construct a fake sequence type here
+%% so that we can generate code for it
+extaddgroup2sequence(ExtList) ->
+ extaddgroup2sequence(ExtList,[]).
+
+extaddgroup2sequence([{'ExtensionAdditionGroup',Number0}|T],Acc) ->
+ Number = case Number0 of undefined -> 1; _ -> Number0 end,
+ {ExtGroupComps,['ExtensionAdditionGroupEnd'|T2]} =
+ lists:splitwith(fun(Elem) -> is_record(Elem,'ComponentType') end,T),
+ extaddgroup2sequence(T2,[#'ComponentType'{
+ name='ExtAddGroup',
+ typespec=#type{def=#'SEQUENCE'{
+ extaddgroup=Number,
+ components=ExtGroupComps}},
+ prop='OPTIONAL'}|Acc]);
+extaddgroup2sequence([C|T],Acc) ->
+ extaddgroup2sequence(T,[C|Acc]);
+extaddgroup2sequence([],Acc) ->
+ lists:reverse(Acc).
diff --git a/lib/asn1/src/asn1ct_gen_per_rt2ct.erl b/lib/asn1/src/asn1ct_gen_per_rt2ct.erl
index e1feb42a59..4f4fcfafc3 100644
--- a/lib/asn1/src/asn1ct_gen_per_rt2ct.erl
+++ b/lib/asn1/src/asn1ct_gen_per_rt2ct.erl
@@ -29,6 +29,7 @@
-export([gen_obj_code/3,gen_objectset_code/2]).
-export([gen_decode/2, gen_decode/3]).
-export([gen_encode/2, gen_encode/3]).
+-export([extaddgroup2sequence/1]).
-import(asn1ct_gen, [emit/1,demit/1]).
-import(asn1ct_gen_per, [is_already_generated/2,more_genfields/1,
@@ -1796,3 +1797,25 @@ dec_enumerated_cases([Name|Rest],Tmpremain,No) ->
dec_enumerated_cases(Rest,Tmpremain,No+1);
dec_enumerated_cases([],_,_) ->
"".
+
+%% For PER the ExtensionAdditionGroup notation has significance for the encoding and decoding
+%% the components within the ExtensionAdditionGroup is treated in a similar way as if they
+%% have been specified within a SEQUENCE, therefore we construct a fake sequence type here
+%% so that we can generate code for it
+extaddgroup2sequence(ExtList) ->
+ extaddgroup2sequence(ExtList,[]).
+
+extaddgroup2sequence([{'ExtensionAdditionGroup',Number0}|T],Acc) ->
+ Number = case Number0 of undefined -> 1; _ -> Number0 end,
+ {ExtGroupComps,['ExtensionAdditionGroupEnd'|T2]} =
+ lists:splitwith(fun(Elem) -> is_record(Elem,'ComponentType') end,T),
+ extaddgroup2sequence(T2,[#'ComponentType'{
+ name='ExtAddGroup',
+ typespec=#type{def=#'SEQUENCE'{
+ extaddgroup=Number,
+ components=ExtGroupComps}},
+ prop='OPTIONAL'}|Acc]);
+extaddgroup2sequence([C|T],Acc) ->
+ extaddgroup2sequence(T,[C|Acc]);
+extaddgroup2sequence([],Acc) ->
+ lists:reverse(Acc).
diff --git a/lib/asn1/src/asn1rt_uper_bin.erl b/lib/asn1/src/asn1rt_uper_bin.erl
index a964b835ae..abe178a69e 100644
--- a/lib/asn1/src/asn1rt_uper_bin.erl
+++ b/lib/asn1/src/asn1rt_uper_bin.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -1611,25 +1611,8 @@ complete_NFP(InList) when is_bitstring(InList) ->
%% 10.5.6 NOTE: If "range" satisfies the inequality 2^m < "range" =<
%% 2^(m+1) then the number of bits = m + 1
-num_bits(1) -> 0;
-num_bits(2) -> 1;
-num_bits(R) when R =< 4 ->
- 2;
-num_bits(R) when R =< 8 ->
- 3;
-num_bits(R) when R =< 16 ->
- 4;
-num_bits(R) when R =< 32 ->
- 5;
-num_bits(R) when R =< 64 ->
- 6;
-num_bits(R) when R =< 128 ->
- 7;
-num_bits(R) when R =< 256 ->
- 8;
-num_bits(R) when R =< 512 ->
- 9;
-num_bits(R) when R =< 1024 ->
- 10;
-num_bits(R) ->
- 1+num_bits(R bsr 1).
+
+num_bits(N) ->
+ num_bits(N,1,0).
+num_bits(N,T,B) when N=<T->B;
+num_bits(N,T,B) ->num_bits(N,T bsl 1, B+1).
diff --git a/lib/asn1/test/asn1_SUITE.erl.src b/lib/asn1/test/asn1_SUITE.erl.src
index f0228546a5..fad094c988 100644
--- a/lib/asn1/test/asn1_SUITE.erl.src
+++ b/lib/asn1/test/asn1_SUITE.erl.src
@@ -2299,11 +2299,12 @@ testExtensionAdditionGroup(Config) ->
?line Path = code:get_path(),
?line code:add_patha(PrivDir),
DoIt = fun(Erule) ->
- ?line ok = asn1ct:compile(filename:join(DataDir,"Extension-Addition-Group"),[Erule,{outdir,PrivDir}]),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Extension-Addition-Group"),Erule ++ [{outdir,PrivDir}]),
?line {ok,_M} = compile:file(filename:join(DataDir,"extensionAdditionGroup"),[{i,PrivDir},{outdir,PrivDir},debug_info]),
- ?line ok = extensionAdditionGroup:run(Erule)
+ ?line ok = extensionAdditionGroup:run(Erule),
+ ?line ok = extensionAdditionGroup:run2(Erule)
end,
- ?line [DoIt(Rule)|| Rule <- [per_bin,uper_bin,ber_bin]],
+ ?line [DoIt(Rule)|| Rule <- [[per_bin],[per_bin,optimize],[uper_bin],[ber_bin],[ber_bin,optimize]]],
?line code:set_path(Path).
diff --git a/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn b/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn
index b985c970ac..fc244c30a2 100644
--- a/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn
+++ b/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn
@@ -48,6 +48,7 @@ Ax ::= SEQUENCE {
}
-- valAx Ax ::= { a 253, b TRUE, c e: TRUE, g "123", h TRUE }
+
Ax2 ::= SEQUENCE {
a INTEGER (250..253),
b BOOLEAN,
@@ -55,7 +56,6 @@ Ax2 ::= SEQUENCE {
ug NumericString
}
-END
-- The value { a 253, b TRUE, c e: TRUE, g "123", h TRUE }
-- is encoded in PER as
@@ -64,3 +64,19 @@ END
-- is encoded in Unaligned PER as
-- 9E000600 040A4690
+
+Ax3 ::= SEQUENCE {
+ a INTEGER (250..253),
+ b BOOLEAN,
+ s SEQUENCE {
+ sa INTEGER,
+ sb BOOLEAN,
+ ...,
+ [[
+ sextaddgroup INTEGER OPTIONAL
+ ]]
+ }
+}
+
+-- { a 253, b TRUE, s {sa 17, sb TRUE, sextaddgroup 11}}
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl b/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl
index 79e200f561..c86c787610 100644
--- a/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl
+++ b/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl
@@ -41,3 +41,16 @@ run(Erule) ->
Val -> ok;
_ -> exit({expected,Val, got, Val2})
end.
+
+run2(Erule) ->
+ Val = #'Ax3'{a=253, b = true, s = #'Ax3_s'{sa = 11, sb = true, sextaddgroup = 17}},
+ io:format("~p:~p~n",[Erule,Val]),
+ {ok,List}= asn1rt:encode('Extension-Addition-Group','Ax3',Val),
+ Enc = iolist_to_binary(List),
+ io:format("~p~n",[Enc]),
+ {ok,Val2} = asn1rt:decode('Extension-Addition-Group','Ax3',Enc),
+ io:format("~p~n",[Val2]),
+ case Val2 of
+ Val -> ok;
+ _ -> exit({expected,Val, got, Val2})
+ end.
diff --git a/lib/asn1/test/test_compile_options.erl b/lib/asn1/test/test_compile_options.erl
index 83f38c5e6d..5e027cdedb 100644
--- a/lib/asn1/test/test_compile_options.erl
+++ b/lib/asn1/test/test_compile_options.erl
@@ -132,7 +132,7 @@ verbose(Config) when is_list(Config) ->
?line ok = asn1ct:compile(Asn1File, [{i,DataDir},{outdir,OutDir},noobj,verbose]),
?line test_server:capture_stop(),
?line [Line0|_] = test_server:capture_get(),
- ?line lists:prefix("Erlang ASN.1 version", Line0),
+ ?line true = lists:prefix("Erlang ASN.1 version", Line0),
%% Test non-verbose compile
?line test_server:capture_start(),