The following sample application illustrates the use of the OSS ASN.1 Compiler to compile a simple ASN.1 module, and the use of the OSS API to invoke the encoder/decoder. By following these steps you can produce and run an executable program that encodes and then decodes a message.
The C application program in this example is tbcas.c and the associated ASN.1 source file is bcas.asn. Both of these files can be found in the SAMPLES subdirectory of the OSS ASN.1 Tools shipment.
The following describes how to compile the abstract syntax defined in bcas.asn:
INPUT:
-- Baseball Card Abstract Syntax (BCAS) BCAS DEFINITIONS ::= BEGIN 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 } myCard BBCard ::= { name "Casey", team "Mudville Nine", age 32, position "left field", handedness ambidextrous, batting-average {mantissa 250, base 10, exponent -3} } END
COMMAND:
You enter the following command:
asn1 bcas.asn
or equivalently:
asn1 bcas
The OSS command line syntax allows the compiler-generated filenames to be selectively overridden. In this example, we let the names default, yielding file names bcas.c, and bcas.h.
OUTPUT
Header file, bcas.h:
#ifndef OSS_bcas #define OSS_bcas /* Baseball Card Abstract Syntax (BCAS) */ #include "asn1hdr.h" #include "asn1code.h" #define BBCard_PDU 1 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; } BBCard; extern BBCard myCard; extern void * const bcas; /* encoder-decoder control table */ #endif /* OSS_bcas */
When compiling the ASN.1 specifications for use with the SOED (Space Optimized Encoder Decoder), the .c file contains OSS internals information and is not shown here.
The following is a copy of the C program in tbcas.c. This program encodes the PDU described by the bcas.asn abstract syntax, then decodes it. Note that bcas.h (generated by the compiler) has been #included into the application program. The header file contains the generated declarations for the application. (The function calls to the OSS Encoder/Decoder functions are in bold font.)
After the application program is compiled, the OSS Encoder/Decoder object library must be linked into the resulting executable file.
INPUT
C File, tbcas.c:
/* Application Program: tbcas.c */ /* Encodes a sample baseball card */ /* using BCAS (Baseball Card Abstract Syntax) */ #include <stdio.h> #include "bcas.h" /* compiler-generated header file */ /* Encodes a card. If the card is successfully encoded, decodes it. */ int main() { OssBuf encodedData; /* length and address of encoded data */ BBCard *myCardPtr = NULL; /* address of decoded data */ int pdu_num = 0; struct ossGlobal w, *world = &w; unsigned char *buf; /* saves address of encoded data */ int retcode; /* return code */ if ((retcode = ossinit(world, bcas))) return retcode; ossSetFlags(world, DEBUGPDU); /* Print the input to the encoder */ ossPrint(world, "\nThe input to the encoder ...\n\n"); ossPrintPDU(world, BBCard_PDU, &myCard); /* Encode a card, Return non-zero for failure. */ encodedData.value = NULL; encodedData.length = 0; ossPrint(world, "\nThe encoder's trace messages...\n\n"); if (ossEncode(world, BBCard_PDU, &myCard, &encodedData)) { /* an error occurred, print errmsg */ ossPrint(world, "%s\n", ossGetErrMsg(world)); retcode = 1; } else { /* card was successfully encoded; print encoded data */ ossPrint(world, "\nEncoded message...\n\n"); ossPrintHex(world, (char *)encodedData.value, encodedData.length); /* Save the address of the buffer with the encoded data. */ buf = encodedData.value; /* Decode the card whose encoding is in encodedData. */ ossPrint(world, "\nThe decoder's trace messages...\n\n"); if (ossDecode(world, &pdu_num,&encodedData,(void **)&myCardPtr)){ /* an error occurred, print errmsg */ ossPrint(world, "%s\n", ossGetErrMsg(world)); retcode = 1; } else { /* Successfully decoded. Print decoder's output, then free it */ ossPrint(world, "\nCasey of the Mudville Nine has a batting average of %0.3f\n\n", myCardPtr->batting_average); // where x should print as 0.250 ossPrint(world, "\nOutput from the decoder...\n\n"); ossPrintPDU(world, pdu_num, myCardPtr); ossFreePDU(world, pdu_num, myCardPtr); retcode = 0; } /* Free the encoder's output buffer */ ossFreeBuf(world, buf); /* Free all globally allocated resources */ ossterm(world); return retcode; } }
COMMAND
Next, compile and link the sample application program as follows:
gcc -c bcas.c tbcas.c gcc -o tbcas bcas.o tbcas.o -lasn1code -lm
OUTPUT
The above command C-compiles the compiler-generated .cfile (bcas.c) and the sample application program (tbcas.c), and links them with the space-optimized encoder/decoder and the default memory manager (all contained in libasn1code.a). The resulting executable file is tbcas.exe.
INPUT
(None. For this example, the encoder input is generated by the ASN.1 compiler as C initialized variables that are set from the ASN.1 value notation.)
COMMAND
tbcas
This command simply runs tbcas. Note that debugging output is generated because the DEBUGPDU encoder/decoder flag was set before the encoder/decoder was called.
OUTPUT
Encoder/decoder debugging output, and completion message.
The input to the encoder ... value BBCard ::= { name "Casey", team "Mudville Nine", age 32, position "left field", handedness ambidextrous, batting-average {mantissa 2.500, base 10, exponent -1} } The encoder's trace messages... BBCard SEQUENCE: tag = [UNIVERSAL 16] constructed; length = 45 name IA5String: tag = [UNIVERSAL 22] primitive; length = 5 "Casey" team IA5String: tag = [UNIVERSAL 22] primitive; length = 13 "Mudville Nine" age INTEGER: tag = [UNIVERSAL 2] primitive; length = 1 32 position IA5String: tag = [UNIVERSAL 22] primitive; length = 10 "left field" handedness ENUMERATED: tag = [UNIVERSAL 10] primitive; length = 1 2 batting-average REAL: tag = [UNIVERSAL 9] primitive; length = 3 1 * 2^-2 Encoded message... 302D1605 43617365 79160D4D 75647669 6C6C6520 4E696E65 02012016 0A6C6566 74206669 656C640A 01020903 80FE01 The decoder's trace messages... BBCard SEQUENCE: tag = [UNIVERSAL 16] constructed; length = 45 name IA5String: tag = [UNIVERSAL 22] primitive; length = 5 "Casey" team IA5String: tag = [UNIVERSAL 22] primitive; length = 13 "Mudville Nine" age INTEGER: tag = [UNIVERSAL 2] primitive; length = 1 32 position IA5String: tag = [UNIVERSAL 22] primitive; length = 10 "left field" handedness ENUMERATED: tag = [UNIVERSAL 10] primitive; length = 1 2 batting-average REAL: tag = [UNIVERSAL 9] primitive; length = 3 1 * 2^-2 Card decoded Casey of the Mudville Nine has a batting average of 0.250 Output from the decoder... value BBCard ::= { name "Casey", team "Mudville Nine", age 32 position "left field", handedness ambidextrous, batting-average {mantissa 1, base 2, exponent -2} }
The samples included with some of the Knowledge Center answers are meant for your general understanding of the OSS products. Different versions of the products might produce slightly different outputs. Consult the products documentation and samples for the most up-to-date products information and code examples.
Test drive the OSS Nokalva ASN.1, LTE, and XML Tools now! Your trial includes complete software, documentation, sample programs, free 24x7 technical support and more.
Our expert personnel can help you learn ASN.1!
We offer 4-day ASN.1 courses at our headquarters or your premises.