Contents
Here are a few quick steps to get you started:
You can ASN.1-compile using either the command-line ASN.1 compiler or ASN.1 Studio.
The ASN.1 compiler translates your ASN.1 specifications into C data structures that you can use to encode application messages and decode messages. To do this, you have to feed ASCII text files containing your specifications to the ASN.1 compiler (these text files usually have a .asn extension) by passing your text files to the ASN.1 compiler as command-line arguments.
For example, to compile the bcas.asn file located in the samples/basic/decode and samples/basic/encode directories so that both the Basic Encoding Rules (BER) and JavaScript Object Notation Encoding Rules (JER) are supported, execute the following command:
asn1 bcas.asn -ber -json
This generates the following files:
The ASN.1 compiler output consists of two files:
For more information on generating C data structures, see the ASN.1/C Compiler Representation section.
For example, when passing the following ASN.1 syntax to the ASN.1 compiler for C:
-- Baseball Card Abstract Syntax (BCAS) BBCard ::= SEQUENCE { name IA5String (SIZE (1..60)), team IA5String (SIZE (1..60)), age INTEGER (1..100), position IA5String (SIZE (1..60)), handedness ENUMERATED {left-handed(0), right-handed(1), ambidextrous(2)}, batting-average REAL }
a header file containing the following is generated:
#include "ossasn1.h" #define BBCard_PDU 1 /* Baseball Card Abstract Syntax (BCAS) */ typedef struct BBCard { char name[61]; char team[61]; unsigned short age; char position[61]; enum { left_handed = 0, right_handed = 1, ambidextrous = 2 } handedness; double batting_average; struct _seqof1 { struct _seqof1 *next; int value; } *values; } BBCard; extern void * const bcas; /* encoder-decoder control table */
The ossasn1.h file contains public type definitions and manifest constants used by the compiler-generated header file and declares the runtime API functions.
The BBCard_PDU constant can be used to identify the structure (the Protocol Data Unit [PDU] BBCard) intended for encoding/decoding.
Following the #include and #define statements are the actual data structures generated based upon the ASN.1 input.
The variable declaration, extern void * const bcas;, is set to reference the encoder-decoder control table or code file. By default, the name of this variable is derived from the name of the last file specified on the command line (for example, bcas.asn).
To use the ASN.1 compiler output in your application, you need to #include the generated header file in your application code:
#include "bcas.h"
bcas.h is the file location of the generated header file.
Then, you can fill and manipulate the compiler-generated data structures as you do for other C data structures. For example, you can fill the BBCard C struct with application data as follows from within your C application code:
BBCard leaguePlayer; . . . . strcpy(leaguePlayer.name, "John E. Doe"); strcpy(leaguePlayer.team, "Mudville Nine"); leaguePlayer.age = 27; strcpy(leaguePlayer.position, "catcher"); leaguePlayer.handedness = right_handed; leaguePlayer.batting_average = 0.342;
Before calling an API function, you must declare and initialize the OSS global environment variable, OssGlobal. To do so, you can use the ossinit() function for console applications, as follows:
OssGlobal w, *world = &w; . . . . ossinit(world, bcas);
bcas is the pointer to the control-table/code-file declared at the end of the compiler-generated header file.
Then, you can call any of the provided API functions passing the initialized OssGlobal variable as a first argument. For example:
OssBuf encodedData; /* length and address of encoded data */ int returnCode; . . . . encodedData.value = NULL; /* Initialize encoder output buffer to NULL. */ encodedData.length = 0; /* Encoder will allocate needed memory. */ ossSetEncodingRules(world, OSS_EXER); /* Change encoding rules in use to Extended XER */ if (returnCode = ossEncode(world, BBCard_PDU, &leaguePlayer, &encodedData)) { /* An error occurred; so, print error message. */ ossPrint(world, "%s\n", ossGetErrMsg(world)); } else { /* Encode was successful. Print out resultant encoding of data. */ ossPrint(world, "\nData encoded to:\n\n"); ossPrintHex(world, encodedData.value, encodedData.length); }
After finishing all other calls to the OSS API functions, your application should free up the allocated PDUs and encoder buffers using the ossFreePDU() and ossFreeBuf() functions. Then, your application should call the ossterm() (or ossWterm() if you called ossWinit() or used the OSS DLLs) terminating function to free the allocated OssGlobal structures and wrap up the use of the OSS API functions, as follows:
ossterm(world);
The header file, .c file (control table or code file), and the encoder/decoder are connected by the following:
The PDU identification number is declared in the beginning of the header file. One identification number is #defined for each variable or structure that can be encoded/decoded as a separate unit and is passed to the encoder/decoder along with the address of the corresponding variable or structure intended for encoding/decoding. The PDU identification constant can be used by the encoder/decoder to identify the makeup (the type and structure) of the data sent for encoding/decoding.
The pointer to the control table or code file is declared at the end of the header file and initialized at the end of the compiler-generated C file. This pointer is stored in the ossGlobal structure (with the ossinit() function call) and used by the encoder/decoder to access the space-optimized control table or time-optimized encoder/decoder entry points.
OSS provides three types of encoders/decoders:
The application program interface for the three types of encoders/decoders is identical.
You can switch from one type of encoder/decoder to another without having to modify and recompile your application program.
By default, the ASN.1 compiler generates code for use with the time-optimized encoder/decoder. You need to C-compile the generated C file and link your application with the time-optimized encoder/decoder runtime library (toedcode.lib on Windows or libosstoed.a on Unix).
To switch to the space-optimized encoder/decoder, recompile your abstract syntax specifying the -soedFile ASN.1 compiler option, C-compile the generated C file, and then re-link your application with the space-optimized encoder/decoder runtime library (soeddefa.lib or libasn1code.a).
To switch to the Lean encoder/decoder, recompile your abstract syntax with the -soed -lean ASN.1 compiler options, C compile the generated C file, and then re-link your application with the Lean encoder/decoder runtime library ( asn1lean.lib or libasn1lean.a).
To switch back to the time-optimized encoder/decoder, recompile your abstract syntax without the -soedFile compiler option (note that -toedFile is implied by default), C compile the generated C file, and then re-link your application with the time-optimized encoder/decoder runtime library ( toedcode.lib or libosstoed.a).
NOTE: For information about how to cross-compile to a different target platform, see the ASN.1/C Cross-Compiling section.
Compiling using the Microsoft VC++ compiler for linking statically (/MT):
cl -c -MT -IC:\ossasn1\win32\8.x.x\include bcas.c tbcas.c
To use a library that was compiled for dynamic linking (toedcomd.lib or ossapit.lib, for example), replace -MT with -MD.
Compiling using the Microsoft VC++ compiler for linking dynamically (/MD):
cl -c -MD -IC:\ossasn1\win32\8.x.x\include bcas.c tbcas.c
To compile and link your application code with the generated .c and .h files on Unix, use the following command:
$CC -I. -I/usr/local/ossasn1/include $CFLAGS -c bcas.c tbcas.c
$CC is the C compiler used to build the libraries (cc, gcc, c89) and $CFLAGS indicates the required compiler options. Make sure $CFLAGS includes the mandatory options for your platform. The options are listed at the top of the compiler-generated .c and .h files, in the "C compiler options required" comments section.
The above command generates two object files, bcas.o and tbcas.o, which will be linked into the final application executable.
Once you have compiled the generated .c and .h files and your application code into object code, link the code with the provided OSS API Runtime libraries either statically or dynamically.
Linking statically using the Microsoft VC++ linker:
link -release -subsystem:console \ -out:tbcas1.exe bcas.obj tbcas.obj toedcode.lib user32.lib advapi32.lib
For trial versions, use this command:
link -release -subsystem:console \ -out:tbcas1.exe bcas.obj tbcas.obj \ toedcode.lib user32.lib advapi32.lib ossiphlp.lib
Linking with the toedcode.lib library enables your application to call almost all the OSS Runtime API functions while using the time-optimized encoder/decoder. For more information about the other static libraries available for linking, see the doc\FILE-LIST.TXT file.
Linking dynamically using the Microsoft Visual C/C++ linker:
link -release -subsystem:windows / -out:tbcas1.exe tbcas.obj bcas.obj ossapi.lib user32.lib advapi32.lib
Note that to correctly link dynamically with ossapi.lib, you should have C-compiled your application code with the -MD option (and not -MT).
Once you have compiled the generated .c and .h files and your application code into object code, link the code with the provided OSS API Runtime libraries either statically or dynamically.
To link the object code statically with the OSS API Runtime library files on Unix:
$CC -o tbcas1 bcas.o tbcas.o /usr/local/ossasn1/lib/libosstoed.a -lm
$CC is the compiler used to build the libraries (cc, gcc, c89).
Notice how the libosstoed.a static time-optimized library is linked. For more information about other libraries available for linking, see the doc/FILE-LIST.TXT file.
To link dynamically with the OSS libraries, replace:
/usr/local/ossasn1/lib/libosstoed.a
with:
/usr/local/ossasn1/lib/libosstoed.so
For example, the dynamic link command is:
$CC -o tbcas1 bcas.o tbcas.o /usr/local/ossasn1/lib/libosstoed.so -lm
You can run your ASN.1 application in the same way that you run other applications on your system. For example, if the generated executable for your application is called tbcas1, you would issue the following command:
tbcas1
When you include calls to API Runtime functions in your source code, your application should automatically use the OSS Nokalva runtime libraries for encoding, decoding, and performing auxiliary tasks. Note that if you linked your application dynamically with the OSS libraries, you will have to add the bin/ directory which contains the OSS DLLs to your executable search path or copy the OSS DLLs to a directory which is in the executable search path.
You can run your ASN.1 application in the same way that you run other applications on your system. For example, if the generated executable for your application is called tbcas1, you would issue the following command:
tbcas1
If you included calls to the OSS API Runtime functions in your source code, your application should automatically use the OSS Nokalva runtime libraries for encoding, decoding, and performing auxiliary tasks. Note however that if you linked your application dynamically with the OSS libraries, you should set the LD_LIBRARY_PATH environment variable to point to the /lib directory.
For information about the OSS Nokalva makefiles, see the samples\README.TXT and the README.TXT files.
This documentation applies to the OSS® ASN.1 Tools for C release 11.3 and later.
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 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 are available to you.