TOP

IAAPI Restrictions

Applies to: ASN.1/C v11.3-11.3.1

General Restrictions

If the input ASN.1 syntax contains PDU types with the same type reference name, the ossGetComponentByAbsRef(), ossPutComponentByAbsRef(), and ossPduTypeHandleByName() functions might encounter name resolution problems (for example, if the input syntax contains several modules and the -root option is specified).

The ossIntervalPropertySettingsForPER(), ossDatePropertySettingsForPER(), and ossTimeOfDayIntervalPropertySettingsForPER() functions retrieve PER-visible property settings information only for time types that are constrained so that all their abstract values have PER encodings that are not encodings of the MIXED-ENCODING type, as defined in ITU-T Rec. X.691:2021 | ISO/IEC 8825-2:2021. In some cases, it is not possible to reproduce the original PropertySettingsConstraint based on this information.

Example 1

T ::= TIME ((SETTINGS "Basic=Rec-Interval Interval-type=SE SE-point=Date") ^
            ((SETTINGS "Date=C Year=Negative Recurrence=R10") |
             (SETTINGS "Date=C Year=L5 Recurrence=Unlimited")))

The ossPrintASN1DescriptionOfType() function prints the PropertySettingsConstraint using a minimum permitted value for recurrence digits R10 and a minimum number of digits in large years L5, which is different from the actual constraint applied to the time type.

T ::= TIME ( (SETTINGS "Basic=Rec-Interval Recurrence=R10 
					Interval-type=SE SE-point=Date Date=C Year=Negative") | 
		    (SETTINGS "Basic=Rec-Interval Recurrence=R10
					Interval-type=SE SE-point=Date Date=C Year=L5"))

Example 2

Time-date ::= TIME ("1234-12-12".."1450-10-01")

Time-interval ::= TIME ("R/-12345C/P12Y123M0D")

The ossPrintASN1DescriptionOfType() function prints the PropertySettingsConstraint corresponding to the property settings of the values specified in TimePointRange and SingleValue, not the actual range or single value constraint.

Time-date ::= TIME (SETTINGS "Basic=Date Date=YMD Year=Proleptic")

Time-interval ::= TIME (SETTINGS "Basic=Interval Interval-type=SD
										 SE-point=Date Date=C Year=L7")

The Lean Encoder/Decoder

Each ASN.1 type has a single C representation regardless of the applied constraints or directives. Only REAL, INTEGER, SET OF, and SEQUENCE OF can have two or more representations.

REAL

REAL types can have BINARY (double) as the default representation or DECIMAL (char *) if the OSS.DECIMAL directive is applied.

Example

DefaultReal ::= REAL
typedef ossReal DefaultReal;

DecimalReal ::= REAL --<DECIMAL>--
typedef char *DecimalReal;

SET OF and SEQUENCE OF

SET OF and SEQUENCE OF can have LINKED as the default representation or UNBOUNDED if the OSS.UNBOUNDED directive is applied.

Example

Sof ::= SEQUENCE OF INTEGER

typedef struct Sof {
    struct Sof *next;
    OSS_INT32  value;
} *Sof;


Sof ::= SEQUENCE --<UNBOUNDED>-- OF INTEGER

typedef struct Sof {
    OSS_UINT32 count;
    OSS_INT32  *value;
} *Sof;

INTEGER

By default, INTEGER types have the OSS_INT32 representation.

Example

I ::= INTEGER

typedef OSS_INT32       I;

If the type is constrained to have only positive values, the OSS_UINT32 representation is used.

I ::= INTEGER (0..20)

typedef OSS_UINT32       I;
I ::= INTEGER (-1..1234567890123)

typedef OSS_INT64	I;

If the type is constrained to have only positive values with a 64-bit integer range, the OSS_UINT64 representation is used.

I ::= INTEGER (0..4294967295) 

typedef OSS_UINT64       I;

If the OSS.HUGE directive is applied to INTEGER types, the following C structure is generated:

I ::= INTEGER --<HUGE>--

typedef ossHugeInt I;
typedef struct ossHugeInt {
    OSS_UINT32     length;
    unsigned char  *value;
} ossHugeInt;

BIT STRING, OCTET STRING, CharacterString

All string types have the UNBOUNDED representation with OSS_UINT32.

Example

typedef struct ossOctetString {
    OSS_UINT32    length;
    unsigned char *value;
} ossOctetString;

BMPString

typedef struct ossBMPString {
    OSS_UINT32 length;
    OSS_UINT16 *value;
} ossBMPString;

For more details, see leandef.h.

UniversalString

typedef struct ossUniversalString {
    OSS_UINT32 length;
    OSS_INT32 *value;
} ossUniversalString;

OBJECT IDENTIFIER, RELATIVE-OID

RELATIVE-OID and OBJECT IDENTIFIER have the UNBOUNDED ENCODED representation.

Example

typedef struct ossObjectID {
    OSS_UINT32     length;
    unsigned char  *value;
} ossObjectID;

GeneralizedTime, UTCTime

GeneralizedTime and UTCTime have the char * representation.

Example

Generaltime ::= GeneralizedTime

typedef char *Generaltime;

CHOICE

For CHOICE types, the structure consists of the choice selector and a union of alternatives. For each alternative, a #define is generated to identify which alternative is selected.

Example

Personal ::= CHOICE {
    married BOOLEAN,
    age INTEGER
}

typedef struct Personal {
    OSS_UINT32 choice;
# define married_chosen 1
# define age_chosen 2
    union {
	ossBoolean married; /* to choose, set choice to married_chosen */
	OSS_INT32 age; /* to choose, set choice to age_chosen */
    } u;
} Personal;

SET, SEQUENCE

SET and SEQUENCE types with OPTIONAL or DEFAULT or with extension additions have the bit mask field (OSS_UINT32) generated to indicate their presence or absence. If the number (N) of OPTIONAL fields is greater than 32, the bit mask is defined as char [].

unsigned char bit_mask[N];

Example

Personal ::= SEQUENCE {
    married BOOLEAN,
    age INTEGER,
    weight INTEGER OPTIONAL,
    name IA5String OPTIONAL
}

typedef struct Personal {
    OSS_UINT32 bit_mask;
# define weight_present 0x80000000
# define name_present 0x40000000
    ossBoolean married;
    OSS_INT32 age;
    OSS_INT32 weight; /* optional; set in bit_mask weight_present if present */
    ossCharString name; /* optional; set in bit_mask name_present if present */
} Personal;

ENUMERATED

ENUMERATED has the enum C representation. By default, it corresponds to OSS_INT32 or OSS_UINT32 integer C types.

In some cases, on a platform that requires a C compiler option like -short-enum, an enum type is represented by a minimum integer that is sufficient to keep any value of this type, which is char, short, or int.

Recursive ASN.1 Types

Recursive ASN.1 types are generated with an extra pointer.

Example

TreeNode ::= SEQUENCE {
    text VisibleString (SIZE(1..255)),
    left [1] TreeNode OPTIONAL,
    right [2] TreeNode OPTIONAL
}

typedef struct TreeNode {
    ossCharString text;
    struct TreeNode *left; /* NULL for not present */
    struct TreeNode *right; /* NULL for not present */
} TreeNode;

SOED versus LED

The following tables summarize the differences between SOED and LED.

ASN.1 definitions, directives and generated C-structures
Feature SOED LED
OSS ASN.1 compiler directives All OSS directives are allowed. When -lean is specified, the ASN.1 compiler ignores the following compiler directives and issues a warning:
OSS.ARRAY 
OSS.DLINKED
OSS.DLINKED-PLUS
OSS.DOUBLE
OSS.FLOAT
OSS.INT 
OSS.LINKED 
OSS.LLONG
OSS.LONG
OSS.MIXED
OSS.NULLTERM
OSS.OBJECTID
OSS.ONECHAR
OSS.PADDED
OSS.POINTER (will be supported)
OSS.SHORT  
OSS.VARYING
C Representations
Feature SOED LED
ANY/ANY DEFINED BY
OSS.DLINKED
OSS.LINKED
OSS.POINTER
OSS.UNBOUNDED
ossAny
(similar to OSS.UNBOUNDED)
BIT STRING
OSS.DLINKED
OSS.LINKED
OSS.PADDED
OSS.POINTER
OSS.UNBOUNDED
OSS.VARYING
ossBitString
(similar to OSS.UNBOUNDED)
BMPString
OSS.POINTER
typedef 
{
   unsigned int length;
   unsigned short  *value;
};
ossBMPString
(similar to OSS.UNBOUNDED)
BOOLEAN
typedef char ossBoolean;
OSS.POINTER
ossBoolean
CHOICE default, OSS.POINTER similar to default (choice index has OSS_UINT32 type)
EMBEDDED PDV default, OSS.POINTER similar to default
ENUMERATED default, OSS.POINTER similar to default
EXTERNAL default, OSS.POINTER similar to default
GeneralizedTime
typedef GeneralizedTime;
        OSS.POINTER
char *
INSTANCE OF default similar to default
INTEGER
int
ASN1.HugeInteger | OSS.HUGE
OSS.INT
OSS.LONG
OSS.LONGLONG
OSS.POINTER
OSS.SHORT
OSS_INT32
OSS_UINT32
ossHugeInt
OSS_INT64
OSS_UNIT64 (available in next release)
(OSS.LONGLONG is supported if runtime compiled with
OSS_LONGLONG_SUPPORTED)
NULL
typedef char Nulltype;
OSS.POINTER
typedef char Nulltype
OBJECT IDENTIFIER
OSS.ARRAY
OSS.LINKED
OSS.OBJECTID length
OSS.OBJECTID ENCODED / ENCODED
OSS.POINTER
OSS.SHORT / OSS.INT / OSS.LONG (when applied locally)
OSS.UNBOUNDED
ossObjectID (similar to ENCODED)
ObjectDescriptor <GraphicString> ossCharString (similar to OSS.UNBOUNDED)
OCTET STRING
OSS.DLINKED
OSS.LINKED
OSS.POINTER
OSS.UNBOUNDED
OSS.VARYING
ossOctetString (similar to OSS.UNBOUNDED)
OID-IRI
RELATIVE-OID-IRI	
OSS.NULLTERM
OSS.POINTER
OSS.UNBOUNDED
OSS.VARYING	
ossCharString (similar to OSS.UNBOUNDED)
Open type
OSS.POINTER
The OSS.OBJHANDLE | OSS.NOCOPY directives are allowed on this type, but have no effect on the representation in the header file.
The OSS.OBJHANDLE | OSS.NOCOPY directives are allowed on this type but have no effect on the representation in the header file.
REAL
OSS.FLOAT
OSS.DECIMAL
OSS.DOUBLE
OSS.MIXED
OSS.POINTER
ossReal char * (for decimal representation)
RELATIVE-OID type
OSS.OBJECTID length
OSS.OBJECTID ENCODED | ENCODED
OSS.POINTER
(similar to ENCODED)
Recursive types extra pointer extra pointer
(restricted) Character string types
OSS.DLINKED
OSS.LINKED
OSS.NULLTERM
OSS.PADDED
OSS.POINTER
OSS.UNBOUNDED
OSS.VARYING
ossCharString (all similar to OSS.UNBOUNDED)
CHARACTER STRING default similar to default
Selection default similar to default
SEQUENCE default, OSS.POINTER similar to default Bit mask for OPTIONAL field has OSS_UINT32 or char * representation
SEQUENCE OF
OSS.ARRAY
OSS.DLINKED
OSS.LINKED
OSS.POINTER
OSS.UNBOUNDED
OSS.LINKED - by default OSS.UNBOUNDED - with ASN.1 directive
SET default, OSS.POINTER similar to default Bit mask for OPTIONAL field has OSS_UINT32 or char * representation
SET OF
OSS.ARRAY
OSS.DLINKED
OSS.DLINKED-PLUS
OSS.LINKED
OSS.POINTER
OSS.UNBOUNDED
OSS.LINKED - by default OSS.UNBOUNDED - with ASN.1 directive
Tagged default similar to default
UniversalString
OSS.POINTER
        typedef 
{
   unsigned int length;
   unsigned int  *value;
};	
ossUniversalString (similar to OSS.UNBOUNDED)
UTCTime
typedef UTCTime;,
        OSS.POINTER
char *
Compile / Link Aspects
Feature SOED LED
Works on both aCC and cfront Yes aCC - Yes cfront - memory problems ?
Availability in 64-bit version Yes OSS_LONGLONG_SUPPORTED
Mixed SOED/LED encoding / decoding No No
Runtime Aspects
Feature SOED LED
Runtime constraints checking Yes The LED runtime library does not have any constraint-checking routines. But SOED constraint-checking can be used by linking with both the SOED and LED libraries. Additionally, the LED does not currently identify the exact field in which an error occurs.
Runtime copy and comparison of decoded PDUs Yes No SOED copy and comparison can be used.
Support functions for working with information object sets (e.g., ossAddInfoObject(), ossGetInfoObject(), ossGetInfoObjectSet(), and ossRemoveInfoObject()) Yes No SOED functions for working with information object sets can be used.
Function ossSetUser MallocFreeRealloc() Yes No (will be supported in the next release)
Support for automatic checking default values in encoding (for DER encoding) Yes Limited support for the following types:
1) NULL, ENUMERATED, BOOLEAN, INTEGER, REAL EMBEDDED PDV, CHARACTER STRING
2) OBJECT IDENTIFIER, RELATIVE-OID, OCTET STRING, IA5String, VisibleString, PrintableString, TeletexString if NOCOPY is not applied.
3) SET, SEQUENCE, CHOICE with the fields of the listed above ASN.1 types.
The SOED can be used for full checking of default values.
Support for indefinite length encoding / decoding Yes The Lean encoder supports only definite length encoding. However, the Lean decoder supports any valid BER encoding. OSS can add this feature, if necessary.
Performance (encode / decode time) 1 ~ 0.5 * SOED

Comma-Separated Value (CSV) Conversion

Starting with version 10.3, the IAAPI includes functions to convert decoded values to and from CSV format. To represent a structured decoded value in CSV format, the IAAPI flattens it into a fixed number of columns by recursively expanding complex SET, SEQUENCE, and CHOICE types, up to the innermost fields, with simple ASN.1 types. The resulting record includes a place for each simple type value, which can be empty for optional fields with absent values. Note that, like all IAAPI functions, the CSV conversion functions are not supported in the Time-Optimized Encoder/Decoder library (TOED), which is the runtime library used by default.

IAAPI supports two CSV formats, as follows:

  • Row format, where each row is a record containing values separated by a comma or some other separator.
  • Column format, where each value is placed on a separate line, possibly after an optional CSV header name and a column separator.

The CSV format can include an optional CSV header created by parsing the input PDU type definition. The header record consists of complete absolute references or single ASN.1 names that match the values in the rows or columns. The column values are generated by parsing encoded messages or value notation.

Example

ASN.1 CSV row format
PersonnelRecord ::= SEQUENCE {
         name     PrintableString,
         number   INTEGER OPTIONAL,
         children SEQUENCE OF ChildInformation
}
ChildInformation ::= SET {
         name    PrintableString,
         date    GeneralizedTime OPTIONAL
}

PersonnelRecord value:

{
        name "Nancy",
        number 20,
        children {
                {name "James", date "20020312000000"},
                {name "Martha", date "20100820000000"}
        }
}
name,number,children_name,children_date
"Nancy",20,"James",03/12/02 00:00:00
"Nancy",20,"Martha",08/20/10 00:00:00

CSV Conversion Restrictions

There are some restrictions imposed on CSV conversion because

  • ASN.1 PDU types are usually structured and can be nested to an arbitrary depth.
  • Some ASN.1 types can be defined recursively.
  • Open types or types with contents constraints can include other type values, known or unknown.

These restrictions are as follows:

  • The values for nested recursions are supported only in full CSV header format, which includes absolute references for all fields. Multiple CSV records of recursive types must have the same number of initialized nesting levels, so all records will have the same number of columns.
  • Values of SET OF and SEQUENCE OF types with multiple components are mapped into several CSV records where only one component differs and the rest are repeated. SET OF and SEQUENCE OF types can be nested inside these types. By default, to avoid significant performance degradation, the IAAPI supports an additional CSV for up to 50 components inside each type. To set the maximum number of components, call ossSetCsvSetting() with the OSS_CSV_MAX_SET_OF_SEQ_OF_COMPONENTS identifier. The total number of additional CSVs for all SET OF and SEQUENCE OF types is limited to the maximum between the user-specified number set by the OSS_CSV_ALL_MAX setting and 50, multiplied by 50.
  • Automatic decoding of open types is supported only in full CSV header format, which includes nested PDU names or numbers inside parentheses. When open types are included, at any nesting level and within SET OF or SEQUENCE OF types, their containing PDUs must be the same for all components, so that the CSV structure does not change.

Example

ASN.1 CSV
ErrorEntry ::=  SEQUENCE {
              errorCode ERROR-CLASS.&code ({ErrorSet}),
              errorInfo ERROR-CLASS.&Type ({ErrorSet}{@.errorCode})
}
e ErrorEntry ::= { errorCode 10, errorInfo Int : 20}
errorCode,errorInfo(Int)
10,20
  • The values of types with contents constraints and known containing types are always automatically decoded. If the CSV record includes values of such types in the form of xmlbstring (0101...) or xmlhstring (AB09...), an error is issued.
  • By default, CSVs with string type values containing Unicode characters are written to the output file in binary format with UTF-8 character encoding. These CSVs are displayed using \x##, a special C-style character escape sequence. To create CSVs in this format, call the following function:
ossSetCsvSetting(world, OSS_CSV_FLAGS, 
ossGetCsvFlags(world, OSS_CSV_FLAGS) | OSS_CSV_TEXT_FORMAT);

Example

ASN.1 CSV
myLabelUtf8 LabelUtf8 ::= "Umlaute: äÄöÖüÜ"
LabelUtf8
"Umlaute: \xc3\xa4\xc3\x84\xc3\xb6\xc3\x96\xc3\xbc\xc3\x9c"
  • When the input ASN.1 syntax includes SET or CHOICE types with fields whose tags are not in PER-required ascending order, encoding and decoding in CSV format should be consistent with any field sorting for PER. When ASN.1 compiling the input ASN.1 syntax, if a CSV is created while sorting fields by tag because -per is specified (implicitly or explicitly), then -per should also be specified when decoding that CSV. This ensures that the order of the field names in the CSV header is the same as in the related SET or CHOICE internal structure, whether or not sorting occurs.

Type Mapping and Data Conversion

CSVs are in human-readable format similar to ASN.1 value notation. The following table shows the differences sorted by ASN.1 type. Additional CSV representations are available by passing special flags to the -csv option.

ASN.1 Type ASN.1 Value CSV Value
BIT STRING bstring
'0101011'B
xmlbstring
010101
BOOLEAN
TRUE or FALSE
XML boolean extended items
TRUE or FALSE 
1 or 0
Restricted Character String types Quoted cstring or list notation Quoted strings UTF-8 encoding is used for Unicode characters; a special C-style character escape sequence \x## is used in the CSV text format.
CHOICE The selected alternative name is included as chosen : <value> All alternatives are present, the ones that are not chosen have empty values with extra separators for all their nested components.
ENUMERATED identifier identifier number
GeneralizedTime
"20120808131347+0500"
Same non-quoted value One of time stamp formats:
06/01/00 00:00:00 
2007-11-07 11:36:49
NULL NULL NULL
OBJECT IDENTIFIER, RELATIVE-OID {arc1(num1) arc2 ... } or encoded format Dot notation:
1.3.6.1.4.1.1900
OCTET STRINGS hstring
'6B646F726C793031'H
xmlhstring
6B646F726C793031
ASCII format: kdorly01
OpenType Either encoded or automatically decoded Automatically decoded only if the full CSV header is present XML format Hexadecimal format
Types with ContentsConstraint bstring automatically decoded Automatically decoded if the containing PDU is known.
REAL Different representations, including {mantissa, base, exponent} notation Decimal format
SET, SEQUENCE Values for fields with OPTIONAL/DEFAULT can be absent Columns for all fields with all their nested components are present. Missing values for optional fields are marked with extra separators.
SET OF, SEQUENCE OF Component values are included in
{val1, val2,  ...}
One column is present for only one component. The row for the complete PDU is repeated for each extra component.
TIME, DATE, and other time types
"2010-04-15T17:18:18-07:00"
The same quoted value
UTCTime
"200808131347Z"
The same non-quoted value
Circularly defined types Values for nested types are printed. CSVs for nested recursions are created only if the full CSV header is present
Fields marked with the ASN1.Remove directive Ignored Ignored without extra column separators

Use the ossSetCsvSetting() function to instruct the CSV conversion functions to perform extra conversions when OCTET STRING values are converted to or from ASCII, BCD, TBCD, IP address, and time stamp format. Alternatively, use the OSS.PrintFunctionName directive with an OSS-specific function name for that conversion, for example "ossPrintOctetAsBCDString" for a BCD conversion. Applying the OSS.PrintFunctionName directive to OCTET STRING types converts their values to or from the specified format. For example, you can mark OCTET STRING types for conversion to TBCD, BCD, ASCII, IP address, or a special time stamp format using the following directives:

--<OSS.PrintFunctionName MOD.Seq.*.soctVarBcd  "ossPrintOctetAsBCDString">--
--<OSS.PrintFunctionName MOD.Seq.*.soctVarTbcd "ossPrintOctetAsTBCDString">--
--<OSS.PrintFunctionName MOD.Seq.*.soctVarIp   "ossPrintOctetAsIPAddress">--
--<OSS.PrintFunctionName MOD.Seq.*.soctVarAsc  "ossPrintOctetAsASCII">--
--<OSS.PrintFunctionName MOD.Seq.*.soctVarTime "ossPrintOctetAsTimeStamp">--

When you include the following call in your application the type values to which the directives are applied will not be affected. However, other OCTET STRING type values will be converted to the ASCII format.

ossSetCsvSetting(world, OSS_CSV_OCTET_STRING, OSS_COS_ASCII);
ossConvertPduValueToCsv(...);

When using ASCII to convert an OCTET STRING hstring value that begins with one or more space characters (0x20), the resulting CSV value is enclosed in quotation marks, indicating that the spaces are part of the value. The CSV decoder ignores quotation marks that follow space characters.

Example

ASN.1 CSV
Oct ::= OCTET STRING
oct Oct ::= '20206C65616469616720737061636573'H
Oct
"  leading spaces"

When conversion into one of the OSS.PrintFunctionName directive's formats fails, the original OCTET STRING value is printed in hexadecimal format and is prefixed with the ??? string. The CSV decoder ignores the prefix and uses the hstring value while omitting conversion.

Example

ASN.1 CSV
--<OSS.PrintFunctionName Mod.Oct "ossPrintOctetAsBCDString">--

Oct ::= OCTET STRING
oct Oct ::= '12191D'H
Oct
???12191D

This documentation applies to the OSS® ASN.1 Tools for C release 10.7 and later. If you are using an earlier version, consult the documentation that was shipped with your product.

Copyright © 2024 OSS Nokalva, Inc. All rights reserved.
No part of this publication may be reproduced, stored in a retrieval system, or transmitted in any form or by any means electronic, mechanical, photocopying, recording or otherwise, without the prior permission of OSS Nokalva, Inc.
Every distributed copy of the OSS® ASN.1 Tools for C is associated with a specific license and related unique license number. That license determines, among other things, what functions of the OSS ASN.1 Tools for C are available to you.