Ultra provides support for parsing a subset of ASN.1 definitions, which can be used to decode from and encode to the corresponding BER or PER encoded data. ASN.1 parsing is requested in UFDL via the asn_block
construct. The syntax of the ASN.1 blocks is declared as follows:
asn_block { -- ASN.1 definitions here };
All ASN.1 constructed types declared either SEQUENCE, SET, or CHOICE, are treated as external format declarations. The name of the resulting external format will be the name of the ASN.1 definition. Any ASN.1 module name is added to the name space. That is, the total name space for the ASN.1 definition is <folder>.<configuration name>.<ASN.1 module name>
.
All occurrences of the dash character (-
) in identifiers are converted to underscores since dashes are not valid in Ultra type naming.
Any in-map or out-map using an external ASN.1 type will by default specify BER encoding. PER encoding can be selected by specifying one of the map options to PER_aligned
or PER_unaligned
.
Notes on ASN.1
Inter Module References
It is currently not possible to refer to non-constructed types or list types (that is, SEQUENCE OF and SET OF) declared in other modules. These must be contained within the asn_block
to where they are referred. Any constructed ASN.1 types referred to must be specified in an ASN.1 IMPORT statement to be available. For instance,
MyType ::= SET(field1 TAC, field2 MobileOriginatedCall)
If TAC
and MobileOriginated
are declared in another asn_block
in the same module,
TAC ::= OCTET STRING; MobileOriginatedCall ::= SET ( .... )
The following applies:
The
TAC
declaration must be duplicated in theasn_block
ofMyType
.MobileOriginatedCall
must be imported within theasn_block
containingMyType
.
ASN.1 Primitive Type Mapping
ASN.1 types are automatically mapped by Ultra as follows (this applies when there are automatic
statements in the in-maps):
ASN.1 Type: | Ultra Type mapped to: |
---|---|
|
|
|
|
|
|
All ASN.1 string types except |
|
|
|
|
|
|
|
|
By default, the float ultra type is automatically mapped to the REAL ASN.1 type. Substituting ASN.1 type REAL with bigdec casts the field as BigDecimal type. Mapping to bigdecimalAnother method of mapping a REAL type to BigDecimal, is to use internal. //Create a flat internal that will be used to populate with integer and bigdecimal values. internal flatInternal { int calledNumber; bigdec duration; }; |
|
For BER BIT STRING encoding: '0410'H is the correct encoding of the bit string '0001'B ("{3}" in APL debug, length of 4 bits. Note!The string representation here does not actually give complete information since the length is not included. It can be inconvenient to have the same string representation for '0001'B and '000100'B, but the reason is that the same string representation as the Java BitSet class is used. In BER, these values are handled differently. For example, '0001'B is encoded as 0x0410, while '000100'B is encoded as 0x0210. For further information about how BIT STRING is encoded/decoded in BER, see ITU-T specification X.690 (the first byte is not part of the bitstring itself - instead it encodes the number of unused trailing bits in the last byte in the bitstring encoding, which starts after the first byte). |
|
|
Ultra Extensions
Within a UFDL asn_block
it is possible to use some extensions which are not part of the ASN.1 standard. These are added to provide better automatic
decoding support for some formats.
Direct BCD Support
A bcd
type is introduced. The ASN.1 formats encoded in BER
frequently use the OCTET STRING
to describe BCD data, leading to complicated processing. By replacing these entries with the bcd
type, Ultra automatically converts such entries. The syntax for the bcd type declaration is declared as follows:
bcd(lsn_fd) bcd(msn_fd) bcd(lsn_fd) terminated_by(<expr>) bcd(msn_fd) terminated_by(<expr>)
Note!
There is a limitation when using terminated_by
with bcd for specfying field sizes. A detailed explanation of the limitation can be found in the Field Declarations section.
Data Support
Many ASN.1 formats declare date and time information as OCTET STRING
. The date type converter is introduced to manage an automatic conversion to date instances. A possible syntax of date declaration is declared as follows:
Time ::= OCTET STRING date({HH,mm,ss}) (SIZE(3)) Date ::= OCTET STRING date({yy,MM,dd})(SIZE(3)) Date ::= OCTET STRING date({cc,yy,MM,dd} , {yy,MM,dd}) DateTime ::= OCTET STRING date({cc,yy,MM,dd,HH,mm,ss})
Note!
These are applicable to OCTET STRINGS
only.
Using Sequential Record Types
Some ASN.1 definitions contain data with an OCTET STRING
declaration that contains additional structures. In order to manage this, it is possible to split such declarations into sequential record types.
It is also possible to use sequential formats to describe constructed ASN.1 types. In this case the tag must be declared as constructed
(a specific keyword) to allow Ultra to correctly encode the type.
Example - Simple sequential record type
An example of a simple type is the definition within an asn_block
(module GSM):
AddressString ::= OCTET STRING (SIZE(1..20))
It can be brought outside the asn_block
and redefined as:
external GSM.AddressString { bit_block : static_size(1) { int npi : msb(3), lsb(0); int ton : msb(7), lsb(4); }; bcd(msn_fd) msisdn : dynamic_size(udr_size-1), terminated_by(0xF); };
Example - Complex sequential record type
An example of a complex type occurs when a field - fieldB
- is to be decoded differently depending on the value of another field - fieldA
. This ASN.1 definition:
ComplexType ::= [APPLICATION 1] SEQUENCE { fieldA INTEGER, fieldB OCTET STRING }
Can be replaced with the sequential format:
external ComplexType_Seq { int tagA: static_size(1); int lengthA: static_size(1); int fieldA: dynamic_size(lengthA); // Definitions of SubType1 and SubType2 not included // in this example. SubType1 fieldB1: present if( fieldA == 1 ); SubType2 fieldB2: present if( fieldA == 2 ); };
And the extended ASN.1:
ComplexType ::= [APPLICATION 1 constructed] ComplexType_Seq
Mapping of ASN.1 INTEGER type and bigint Support
Since INTEGER
types are automatically mapped to int
, which is a 32-bit integer type, INTEGER
s longer than 4 bytes cause decoding errors. This can be avoided by using the bigint
type in place of INTEGER
. The only difference between bigint
and INTEGER
is that bigint
is automatically mapped to the bigint
type, which can support INTEGER
s of any size.
Options for in and out maps
By default, ASN.1 external formats are decoded and encoded as BER. However, the decoding and encoding behavior can be modified by options on the in_map
and out_map
declarations. The available options are:
Option | Effect |
---|---|
| When encoding to BER, use the indefinite length encoding instead of definite length encoding (which is default) |
| When decoding BER data, the presence of unknown tags are no longer considered decoding errors. Instead they are simply ignored |
| Instead of BER, use PER ALIGNED encoding |
| Instead of BER, use PER UNALIGNED encoding |
ASN Language Limitations
The ASN.1 compiler is mostly concerned with the type notation of ASN.1. Elements of type notation not supported are:
COMPONENTS OF
WITH COMPONENT
WITH COMPONENTS
ABSENT/PRESENT
ANY, ANY DEFINED BY
ObjectDescriptor
DEFAULT
DEFINITIONS
EXPLICIT, EXPLICIT TAGS
INCLUDES
MACRO
PRIVATE
UTCTime
EXTERNAL
GeneralizedTime
OPERATIONS
There are also limitations regarding the support of value notation or macro notation. It is only supported to declare INTEGER
constants and use them in constraint specifications.
There is also limited support for information object classes and OBJECT IDENTIFIER types. Object identifiers are decoded to bytearrays and the information object content is only decoded according to the class definition.
BER Limitations
In addition to the general ASN.1 limitations there are also some limitations regarding BER that must be taken in consideration:
Explicit tags are not supported - All tags are by default implicit (except for tags of
CHOICE
types, which are always assumed to be explicit according to the ASN.1 standard). Any attempt to specify explicit tagging will result in a compilation error.All string fields are encoded/decoded according to
ISO8859-1
except forUTF8String
.No validation to ensure that mandatory fields are actually present is performed for
SEQUENCE
andSET
types.Not all character types are supported. However,
GraphicalString, IA5String, VisibleString, NumericString
, andUTF8String
are supported.
PER Limitations
In addition to the general ASN.1 limitations there are also some limitations regarding PER that must be taken in consideration:
For string types, constraints on the permitted alphabet are not handled.
Fragmented encoding (encoding for large-size fields) is not supported.
Not all character types are supported. However,
GraphicalString, IA5String, VisibleString, NumericString
, andUTF8String
are supported.