TOP

ASN.1/C++ Runtime API Overview

Applies to: ASN.1/C++ 6.5

Introduction

The ASN.1/C++ Runtime API is a set of runtime libraries your application can use to encode, decode, and otherwise modify application messages, that is, Protocol Data Units (PDUs). The API offers C++ classes and methods that allow common programming operations and are independent from the encoding rules being used.

The ASN.1/C++ Runtime API enables you to

  • Encode to and decode from the following encoding rules:
    • Basic Encoding Rules (BER)
    • Packed Encoding Rules (Aligned: PER, Unaligned: UPER)
    • Distinguished Encoding Rules (DER)
    • Canonical Encoding Rules (CER)
    • XML Encoding Rules (Basic: XER, Canonical: CXER, Extended: E-XER)
    • Octet Encoding Rules (Basic: OER, Canonical: C-OER)
    • JavaScript Object Notation Encoding Rules (JSON)
  • Check an unencoded PDU to see if the schema constraints are satisfied.
  • Print PDUs in encoded and unencoded/decoded forms.
  • Copy PDUs to different destinations.
  • Compare unencoded or decoded PDUs.
  • Free encoder/decoder output memory.
  • Set and retrieve attribute values of classes that represent ASN.1 types.

Encoder and Decoder Types

The encoder transforms data stored in C structures into encoded data. The decoder, on the other hand, transforms encodings into C data structures. The encoder/decoder relies on the C++ code generated by the OSS ASN.1 compiler.

NOTE: Starting with version 5.0, by default, the OSS ASN.1 compiler generates TOED files instead of SOED files.

OSS Nokalva offers three types of encoders/decoders:

Time-Optimized Encoder/Decoder (TOED)
The TOED is optimized to minimize CPU utilization. The OSS ASN.1 Tools for C++ uses it by default.
Space-Optimized Encoder/Decoder (SOED)
The SOED is Optimized to minimize the use of memory. It has the same API as the TOED.
Lean Encoder/Decoder (LED)
The LED is optimized for embedded systems with limited available memory running applications that require fast processing times. Its speed is comparable to the TOED and it uses less memory than the SOED. The LED is provided separately.

Since the TOED and SOED have identical interfaces, you can easily switch from one encoder/decoder to the other without modifying your application program. Simply re-compile your ASN.1 schema with the -soed or -toed compiler option, and re-build your application by linking to the corresponding encoder/decoder runtime library.

If your schema is small to medium in size, the code generated by the TOED is smaller and faster than the SOED. So the TOED is probably a better choice, unless you need the external memory manager that the SOED uses.

If your schema is very large or complex, the SOED (and its compiled control table) requires less memory than the TOED.

Encoder/Decoder Flags

Along with compiler options and directives, you can use the encoder/decoder flags to configure the OSS ASN.1 Tools for C++ to meet your application-specific requirements. See OssControl for information about the encoder/decoder flags and their use.

Linking Options

To use the API classes and methods, link your application with the OSS API libraries and the generated .cpp files. Generally, you will link with one OSS C++ library and one encoder/decoder library, unless Windows DLLs are used[1]. Multiple static and dynamic libraries are provided for use with specific encoders/decoders and C++ compiler options.

Libraries for Microsoft Windows Platforms

Library Type Encoder/Decoder Type DLL Import Library Static Library[2]
ASN.1/C++ Runtime Space-Optimized lib\cppsoed.lib lib\osscppmd.lib
lib\osscppmt.lib
Time-Optimized lib\cpptoed.lib
Lean lib\cppled.lib
Encoder/Decoder Space-Optimized lib\cppsoed.lib lib\cppsoedmd.lib
lib\cppsoedmt.lib
Time-Optimized lib\cpptoed.lib lib\cpptoedmd.lib
lib\cpptoedmt.lib
Lean lib\cppled.lib lib\cppledmd.lib
lib\cppledmt.lib

[1]When using dynamic libraries (DLLs), link with only one library: cppsoed.lib, cpptoed.lib, or cppled.lib. These DLL import libraries include both the C++ Runtime and the encoder/decoder libraries.

[2]Use the *mt.lib libraries when your application is compiled with the Visual C++ /MT (multi-threaded) compiler option. Use the *md.lib libraries with the Visual C++ /MD (multi-threaded DLL) compiler option.

Remarks

  • If you use the /MD C++ compiler option and link with osscppmd.lib and cppsoedmd.lib, cpptoedmd.lib, or cppledmd.lib, be sure to define the USE_MD_LIB constant on the C++ compiler command line (e.g., DUSE_MD_LIB).
  • To create a DLL from the compiler-generated .cpp file, use this option
    -DOSS_PUBLIC=__declspec(dllexport)

    when you C++ compile the file, creating the base for the DLL. Then use

    -DOSS_PUBLIC=__declspec(dllimport)
    

    to C++ compile the application that uses the DLL you created.


Libraries for UNIX Platforms

Library Type Encoder/Decoder Type Shared Library Static Library Shared Archive
ASN.1/C++ Runtime All lib/libosscpp.so lib/libosscpp.a lib/libosscpp.sa
Encoder/Decoder Space-Optimized lib/libcppsoed.so lib/libcppsoed.a lib/libcppsoed.sa
Time-Optimized lib/libcpptoed.so lib/libcpptoed.a lib/libcpptoed.sa
Lean lib/libcppled.so lib/libcppled.a lib/libcppled.sa

NOTE: Dynamic shared libraries (*.so) and shared archives (*.sa) are available only on common platforms like Linux and Solaris, and may not be available for your embedded system port. If you are interested in these libraries for your platform, contact OSS Nokalva Sales at info@oss.com.

To avoid having multiple incompatible copies of runtime code in memory, make sure you are consistent in the way you are using your C/C++ compiler options. For example, if you compile your DLLs or executables to link statically with the C++ runtime libraries (/MT for Microsoft VC++), use the static OSS library soeddefa.lib (also compiled with /MT).

Similarly, if you compile your code to link dynamically with the C runtime libraries (/MD for Microsoft VC++), either use ossapi.lib or soeddemd.lib (the latter is built using /MD option for C++ runtime libraries).

OSS encoder/decoder DLLs are located in the bin/ directory of the OSS ASN.1/C++ Tools. Make sure these libraries are available at runtime. For example, include the bin/ directory in the environment path of the operating system or move these DLLs to another location in your environment path.

Using Multiple Threads

To avoid potential synchronization problems in multithreaded applications, follow these rules when using the OSS ASN.1 Tools for C++:

  • Do not use the same object in different threads simultaneously, unless you implement your own synchronization for it. Specifically, create one OssControl object for each thread; do not use the same OssControl object in different threads.
  • The legacy error handling mode is not thread-safe, because it uses a static variable to store the last error code.
  • The asn1_set_error_handling function is also, strictly speaking, not thread-safe, because it stores information in static memory. This function is called only once, in the beginning of the application, to set the desired error handling for the entire application.
  • Do not set the OSS_TRAPPING flag. The OSS ASN.1 Tools for C++ cannot trap memory violations in a thread-safe manner.
  • Do not change the current memory system when multiple threads are running.
  • If you are using memory pools, deallocate an object within the same thread that allocated it.

Runtime Restrictions

Restrictions: Time-Optimized Encoder/Decoder (TOED)

The Time-Optimized Encoder/Decoder does not support

  • Pattern constraints
  • Compression
  • User defined constraints (CONSTRAINED BY)

Length Forms of BER Encodings

The Time-Optimized encoder supports only the definite length form of BER encodings. On the other hand, the Time-Optimized decoder supports all valid BER encodings, including those in the indefinite length form.

Canonical Encoding Rules

The Time-Optimized encoder does not support the Canonical Encoding Rules (CER). However, the Time-Optimized decoder supports decoding of a CER encoding, since CER is a valid subset of BER.

EncodedSocket and EncodedFile Classes

The Time-Optimized Encoder/Decoder does not support encoding to or decoding from sockets or files without using intermediate memory buffers, so the EncodedSocket and EncodedFile classes cannot be used with the TOED.

ASN.1 Value Notation Conversion

The Time-Optimized Encoder/Decoder does not support conversion to/from ASN.1 value notation using the ASN1Handle::asValueNotation or ASN1Handle::setFromValueNotation function. However, the ASN1Handle::print function is supported, provided the generated code is compiled with the OSSPRINT preprocessor defined.

Automatically Encode/Decode Open Types

Use the following procedure to automatically encode/decode open types using the TOED:

  1. ASN.1 compile your input specification with both the -autoEncDec and -toed options specified.
  2. Set the AUTOMATIC_ENCDEC flag during runtime using the OssControl setEncodingFlags() and setDecodingFlags() methods.

Currently, in the TOED implementation of automatic encoding/decoding of open types, a SET OF or SEQUENCE OF type cannot be referenced by a component relation constraint that is used to determine the base type of the open type.

Rare Invalid Encodings

For improved speed, some rare forms of invalid encodings are silently ignored by the decoder. However, the encoder will encode (or re-encode) such values on request, in a format that conforms to the official encoding rules standard.

See Also

Compiler Restrictions: Time-Optimized Encoder/Decoder

↩Runtime Restrictions

Restrictions: Space-Optimized Encoder/Decoder (SOED)

The Space-Optimized Encoder/Decoder does not support partial decoding.

↩Runtime Restrictions

Restrictions: Lean Encoder/Decoder (LED)

The Lean Encoder/Decoder does not support

  • Constraint-checking routines
  • The OSS_TRAPPING/NOTRAPPING runtime flags
  • Partial decoding

Length Forms of BER Encodings

The Lean encoder supports only the DEFINITE length form of BER encodings. On the other hand, the Lean decoder supports all valid BER encodings, including those that are in the INDEFINITE form.

Tag-Controlled Decoding

The Lean Encoder/Decoder does not support tag-controlled BER or XER decoding, so you should always know the exact ASN.1 type being decoded.

Canonical Encoding Rules

The Lean encoder does not support the Canonical Encoding Rules (CER). However, the Lean decoder supports decoding of a CER encoding, since CER is a valid subset of BER.

INTEGER Types

INTEGER types can have only a 32-bit, 64-bit, or OssHugeInt representation. Use the OSS.HUGE directive to obtain the OssHugeInt representation.

EncodedSocket and EncodedFile Classes

The Lean Encoder/Decoder does not support encoding to or decoding from sockets or files without using intermediate memory buffers, so the EncodedSocket and EncodedFile classes cannot be used with the LED.

See Also

Compiler Restrictions: Lean Encoder/Decoder

↩Runtime Restrictions

Restrictions: Distinguished Encoding Rules (DER)

SET OF Value Matches DEFAULT Value

When the value of a SET OF type is the same as its DEFAULT value, the DER encoder will not see the match if the order of the elements in the value differs from the DEFAULT value. For example, a component defined as

numbers  SET OF INTEGER DEFAULT {3, 2, 1},

is presented the following value for encoding:

{1, 2, 3}

Technically, the encoder should not encode the value since it is the same as the default. Instead, the value is encoded as if the two were unequal. This approach simplifies the comparison algorithm, which reduces its size and increases its speed. In practice, this restriction does not pose a problem with X.509 or any known ASN.1 DER specification, since such defaults are not defined.

GMT (Greenwich Mean Time)

The DER encoder cannot determine whether a time is GMT (Greenwich Mean Time, also referred to as UTC - Coordinating Universal Time), therefore you must ensure that any OssGeneralizedTime value is GMT. To do so, set the utc component of the OssGeneralizedTime class to TRUE by calling the set_utc() method or by passing a utc value in the class constructor, indicating that the time is GMT.

↩Runtime Restrictions

Restrictions: Octet Encoding Rules / Canonical Octet Encoding Rules (OER/C-OER)

Automatic Coding of BIT STRING and OCTET STRING Types

Automatic coding of a BIT STRING or OCTET STRING with a contents constraint is supported only when the contents constraint does not contain the ENCODED BY clause.

ASN1.DeferDecoding Directive

When OER/C-OER is in use, the ASN1.DeferDecoding compiler directive is not supported.

↩Runtime Restrictions

Restrictions: XML Encoding Rules (XER)

Runtime Flags

XER does not support the DEBUGPDU, IGNORE_DEFER_DECODING, DONT_FREE_ENCODED, and IGNORE_PDU_TAG runtime flags.

Maximum Node Values

Node values for an OBJECT IDENTIFIER type with an ENCODED representation or for a RELATIVE-OID type should not exceed the maximum value of a 64-bit unsigned integer (18446744073709551615). This applies to all encoder/decoder libraries (SOED/TOED/LED), XER, CXER, and E-XER.

↩Runtime Restrictions

Restrictions: Extended XML Encoding Rules (E-XER)

Automatic Decoding

The E-XER decoder will not automatically decode types with component relation constraints that reference

  • SEQUENCE OF fields in EMBED-VALUES or USE-ORDER encoding instructions
  • Fields with ANY-ELEMENT or ANY-ATTRIBUTES encoding instructions

Decoding CHOICE Types

When a control table is produced with the -noConstraints option, some CHOICE types with the USE-UNION instruction might be decoded incorrectly. This could happen when the constraint information is needed to identify the union alternative.

Example

For the following ASN.1 type

C ::= [USE-UNION] CHOICE {
   t1 IA5String (FROM ("a".."z")),
   t2 INTEGER (1..MAX),
   t3 BOOLEAN }

this instance

<C>0</C> 

will be decoded as

v C ::= t1 : "0"

instead of

v C ::= t3 : FALSE

↩Runtime Restrictions

Other Restrictions

DEFAULT Values in BER and PER

When BER is used according to the ASN.1 standard, the sender can choose to encode or ignore a DEFAULT value. The same is true for non-primitive types in PER. However, this option can result in encodings with different bit-patterns that equal the same value, which can cause problems when error-detection schemes, such as checksum, are involved.

In the OSS ASN.1 Tools, the decoder assumes the DEFAULT value was intended when it is missing from an encoding. When a value is present for a DEFAULT field in a BER/PER encoding, you must ensure that the transmitted value differs from the DEFAULT value. The decoder will not do so for the sake of performance.

Note that in PER, DEFAULT values are not encoded according to the standard. The OSS encoder assumes that you will omit the encoding of DEFAULT values.

↩Runtime Restrictions

Windows DLLs

A <project_name>_Control class object will not function correctly when both of these (unlikely) conditions are true:

  • The OSS ASN.1/C++ runtime DLLs are used; the application is linked with cpptoed.lib, cppsoed.lob, or cppled.lib.
  • The object is a copy of a copy, that is, it is created using the copy constructor from another control class object, which was also created with the copy constructor.

Example

<project_name>_Control ct1;
<project_name>_Control ct2 = ct1;

In the following definition, ct3 will not function correctly because ct2 is copied into ct3 by assignment.

<project_name>_Control ct3 = ct2;

In this definition, function(ct2) will not function correctly because the control object is passed by value on the stack where additional copying occurs.

int function(<project_name>_Control);
......
function(ct2);

To avoid this problem, always copy from the original object:

<project_name>_Control ct3 = ct1;

function(ct1); // A function call can copy the original, too.

Remember that you can also pass by reference, which can help avoid extra copying:

int function(<project_name>_Control &);
......
function(ct2);

↩Runtime Restrictions

Compressor Classes

The encoder/decoder libraries ignore the ASN1.DeferDecoding directive when compressor classes are used.

Compression is supported by the Space-Optimized Encoder/Decoder and the Lean Encoder/Decoder, but not by the Time-Optimized Encoder/Decoder.

↩Runtime Restrictions

Constraint Checker

For all encoding rules, the encoder/decoder ignores single value or value range constraint violations for SET OF values.

In the following example, value v is successfully encoded and decoded to avoid a potential performance hit that might occur during verification of such constraints:

Test DEFINITIONS ::= BEGIN
   Setof ::= SET ({1, 2}) OF INTEGER
   v Setof ::= {1}
END

↩Runtime Restrictions


This documentation applies to release 6.5 and later of the OSS® ASN.1 Tools for C++.

Copyright © 2017 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.