Example: Building an XER Application

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 runtime APIs to invoke the Basic-XER (here after called XER) encoder/decoder.

The C application program in this example is tperson.c and the associated ASN.1 source file is person.asn . The ASN.1 file contains two Personnel records, john and mary . The application program encodes these Personnel records using XER, and then decodes the encoded XER encoded data into structures.

The following outline shows how you can produce and run a sample executable program that encodes and then decodes a message using XER (XML Encoding Rules).

Step 1: Invoking the ASN.1 Compiler

1.1 Input ASN.1 Syntax (person.asn)
1.2 Command to compile person.asn
1.3 Output files generated by the ASN.1 Compiler

Step 2: Compiling and Linking the sample application

2.1 Input application program tperson.c
2.2 Commands to compile and link the sample program

Step 3: Running the sample program

3.1 Command to run the executable
3.2 Output of sample program

 

Step 1: Invoking the ASN.1 Compiler

The following describes how to compile abstract syntax defined in the person.asn file.

1.1 Input ASN.1 Syntax (person.asn)

Personnel
DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
   
    PersonnelRecord ::= SET {
    name         [0] Name,
    title        [1] VisibleString,
    number       [2] EmployeeNumber,
    dateOfHire   [3] Date,
    nameOfSpouse [4] Name,
    children     [5] SEQUENCE OF ChildInformation
    }
   
    ChildInformation ::= SET {
    name        [0] Name,
    dateOfBirth [1] Date,
    sex         [2] ENUMERATED {
        male(1),
        female(2),
        unknown(3)
    } OPTIONAL
    }
   
    Name ::= SEQUENCE {
    givenName  [0] NameString,
    initial    [1] NameString,
    familyName [2] NameString
    }
   
    EmployeeNumber ::= INTEGER (0..9999)
   
    Date ::= VisibleString (FROM ("0".."9") INTERSECTION SIZE (8..20))
   
    NameString ::= VisibleString (FROM ("a".."z" | "A".."Z" |
    "-.") INTERSECTION SIZE (1..64))
   
    john ::=
    <PersonnelRecord>
    <name>
        <givenName>John</givenName>
        <initial>P</initial>
        <familyName>Smith</familyName>
    </name>
    <title>Director</title>
    <number>51</number>
    <dateOfHire>19710917</dateOfHire>
    <nameOfSpouse>
        <givenName>Mary</givenName>
        <initial>T</initial>
        <familyName>Smith</familyName>
    </nameOfSpouse>
    <children>
        <ChildInformation>
        <name>
            <givenName>Ralph</givenName>
            <initial>J</initial>
            <familyName>Smith</familyName>
        </name>
        <dateOfBirth>19791111</dateOfBirth>
        </ChildInformation>
        <ChildInformation>
        <name>
            <givenName>Susan</givenName>
            <initial>J</initial>
            <familyName>Smith</familyName>
        </name>
        <dateOfBirth>19820715</dateOfBirth>
        <sex><female/></sex>
        </ChildInformation>
    </children>
    </PersonnelRecord>

    mary PersonnelRecord ::= {
    name         {
        givenName  "Mary",
        initial    "T",
        familyName "Smith"
    },
    title        "Housewife",
    number       1281,
    dateOfHire   "19790422",
    nameOfSpouse {
        givenName  "John",
        initial    "P",
        familyName "Smith"
    },
    children     {
        {
        name        {
            givenName  "Ralph",
            initial    "J",
            familyName "Smith"
        },
        dateOfBirth "19791111"
        },
        {
        name        {
            givenName  "Susan",
            initial    "J",
            familyName "Smith"
        },
        dateOfBirth "19820715",
        sex         female
        }
    }
    }
   
END

Go back to top

1.2 Command to compile person.asn

The following command compiles person.asn, and generates person.h and person.c files. The person.h file contains the structures corresponding to the components of ASN.1 file. The person.c file contains information needed by the encoder and the decoder at runtime. The file, person.c,  must be compiled and linked with the sample application.

asn1 -xer person.asn

or

asn1 -xer person

The -xer compiler option notifies compiler that XER (XML Encoding Rules) will be used at runtime. A detailed description of all the compiler options supported by the OSS ASN.1/C Compiler can be found in the OSS ASN.1 Compiler for C Reference Manual.

Go back to top

1.3 Output files generated by the ASN.1 Compiler

person.h

     #ifndef OSS_person
     #define OSS_person

     #include "asn1hdr.h"
     #include "asn1code.h"

     #define          PersonnelRecord_PDU 1

     typedef char            NameString[65];

     typedef struct Name {
         NameString      givenName;
         NameString      initial;
         NameString      familyName;
     } Name;

     typedef unsigned short  EmployeeNumber;

     typedef char            Date[21];

     typedef struct ChildInformation {
         unsigned char   bit_mask;
     #       define      sex_present 0x80
         Name            name;
         Date            dateOfBirth;
         enum {
             male = 1,
             female = 2,
             unknown = 3
         } sex;  /* optional; set in bit_mask sex_present if present */
     } ChildInformation;

     typedef struct PersonnelRecord {
         Name            name;
         char            *title;
         EmployeeNumber  number;
         Date            dateOfHire;
         Name            nameOfSpouse;
         struct _seqof1 {
             struct _seqof1  *next;
             ChildInformation value;
         } *children;
     } PersonnelRecord;

     extern PersonnelRecord john;

     extern PersonnelRecord mary;


     extern void * const person;    /* encoder-decoder control table */
     #endif /* OSS_person */


Go back to top

person.c

The person.c file contains the information needed by the runtime APIs to encode and decode PDUs. Since this file contains internal information, it is not shown here. This file must be compiled and linked with the sample application.

Step 2:  Compiling and Linking the sample application

The following C program, tperson.c, encodes the PDU described by the person.asn abstract syntax using XER (XML Encoding Rules), and then decodes it. Note that person.h (generated by the compiler) has been #included in the application program. This 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 runtime library must be linked into the resulting executable file.

2.1 Input application program tperson.c

/* Application Program: tperson.c                                     */
/* Encodes and decodes sample personnel records using XER.           */

#include "person.h"  /* compiler-generated header file */

static int encodeAndDecode(OssGlobal *world, PersonnelRecord* ptrRecord)
{

    OssBuf        encodedData;   /* length and address of encoded data */
    PersonnelRecord    *myRecordPtr = NULL;    /* address of decoded data */
    int            pdu_num = 0;   /* PDU number */
    int            retcode = 0;   /* return code */
   
    /*
     * Print the input to the encoder
     */
    ossPrint(world, "\nThe input to the encoder ...\n\n");
    ossPrintPDU(world, PersonnelRecord_PDU, ptrRecord);

    ossPrint(world, "\nEncoding Personnel Record ...\n");

    encodedData.length = 0;
    encodedData.value = NULL;

    /*
     * Encode a record.  Return non-zero for failure.
     */
    if (ossEncode(world, PersonnelRecord_PDU, ptrRecord, &encodedData)) {
    ossPrint(world, "%s\n", ossGetErrMsg(world));  /* an error occurred, print errmsg */
    return 1;
    }
    else {
    ossPrint(world, "Record encoded successfully.\n");

    /*
     * Print XER encoded data.
     */
    ossPrint(world, "\nEncoded Data: %.*s\n\n", encodedData.length, encodedData.value);

    /*
     * Decode a record.  Return non-zero for failure.
     */
    ossPrint(world, "\nDecoding XER encoded Personnel Record ...\n");
    if (ossDecode(world, &pdu_num, &encodedData, (void **)&myRecordPtr)) {
        ossPrint(world, "%s\n", ossGetErrMsg(world));  /* an error occurred, print errmsg */
        retcode = 1;
        } else {

        ossPrint(world, "Record decoded successfully.\n");
        /*
         * Print the decoder's output
         */
        ossPrint(world, "\nOutput from the decoder ...\n\n");
        ossPrintPDU(world, pdu_num, myRecordPtr);
        ossFreePDU(world, pdu_num, myRecordPtr);
    }
    }
    return retcode;
}
 
int main(void)
{
    OssGlobal w, *world = &w;   /* structure ossGlobal */
    int          retcode;          /* return code */

    /*
     * Call ossinit() first to initialize OSS's global structure
     */
    if (retcode = ossinit(world, person)) {
    ossPrint(NULL, "Ossinit() returned %d\n", retcode);
    return retcode;
    }


    /*
     * Set OSS_XER encoding rules.
     */
    ossSier new;">     */
    if (retcode = encodeAndDecode(world, &john))
    return retcode;
    if (retcode = encodeAndDecode(world, &mary))
    return retcode;

    /*
     * Call ossterm() to free all resources
     */
    ossterm(world);

    return retcode;
}


2.2 Command to compile and link sample program

The sample program can be compiled and linked using makefiles asn1cpl.mak and tperson.mak. The asn1cp.mak file compiles the ASN.1 syntax and generates .h and .c files. Another makefile, tperson.mak, compiles application code with the generated .c file, and links the object file with the OSS runtime libraries to generate a sample executable. These files are located under the samples/xml directory. For example, if you have installed OSS ASN.1/C tools under the /ossasn1/win32/6.1.0 directory, these makefiles can be found under the /ossasn1/win32/6.1.0/samples/xml directory. An executable for the sample program can be created by using the following commands on Windows and UNIX:

For Windows:

nmake -f asn1cpl.mak
nmake -f tperson.mak

For Unix:

make -f asn1cpl.mak
make -f tperson.mak

Step 3: Running the sample program

3.1 Command to run  the executable

An executable tperson (tperson.exe for Windows) will be generated after step 2.2. This executable can be run on the command line by the following command:

tperson

3.2 Output of the sample program

Running tperson will generate the following output:

The input to the encoder ...

value PersonnelRecord ::=
{
  name
  {
    givenName "John",
    initial "P",
    familyName "Smith"
  },
  title "Director",
  number 51,
  dateOfHire "19710917",
  nameOfSpouse
  {
    givenName "Mary",
    initial "T",
    familyName "Smith"
  },
  children
  {
    {
      name
      {
        givenName "Ralph",
        initial "J",
        familyName "Smith"
      },
      dateOfBirth "19791111"
    },
    {
      name
      {
        givenName "Susan",
        initial "J",
        familyName "Smith"
      },
      dateOfBirth "19820715",
      sex female
    }
  }
}

Encoding Personnel Record ...
Record encoded successfully.

Encoded Data: <?xml version="1.0" encoding="UTF-8"?>
<PersonnelRecord>
  <name>
    <givenName>John</givenName>
    <initial>P</initial>
    <familyName>Smith</familyName>
  </name>
  <title>Director</title>
  <number>51</number>
  <dateOfHire>19710917</dateOfHire>
  <nameOfSpouse>
    <givenName>Mary</givenName>
    <initial>T</initial>
    <familyName>Smith</familyName>
  </nameOfSpouse>
  <children>
    <ChildInformation>
      <name>
        <givenName>Ralph</givenName>
        <initial>J</initial>
        <familyName>Smith</familyName>
      </name>
      <dateOfBirth>19791111</dateOfBirth>
    </ChildInformation>
    <ChildInformation>
      <name>
        <givenName>Susan</givenName>
        <initial>J</initial>
        <familyName>Smith</familyName>
      </name>
      <dateOfBirth>19820715</dateOfBirth>
      <sex><female/></sex>
    </ChildInformation>
  </children>
</PersonnelRecord>


Decoding XER encoded Personnel Record ...
Record decoded successfully.

Output from the decoder ...

value PersonnelRecord ::=
{
  name
  {
    givenName "John",
    initial "P",
    familyName "Smith"
  },
  title "Director",
  number 51,
  dateOfHire "19710917",
  nameOfSpouse
  {
    givenName "Mary",
    initial "T",
    familyName "Smith"
  },
  children
  {
    {
      name
      {
        givenName "Ralph",
        initial "J",
        familyName "Smith"
      },
      dateOfBirth "19791111"
    },
    {
      name
      {
        givenName "Susan",
        initial "J",
        familyName "Smith"
      },
      dateOfBirth "19820715",
      sex female
    }
  }
}

The input to the encoder ...

value PersonnelRecord ::=
{
  name
  {
    givenName "Mary",
    initial "T",
    familyName "Smith"
  },
  title "Housewife",
  number 1281,
  dateOfHire "19790422",
  nameOfSpouse
  {
    givenName "John",
    initial "Pr new;">   {
    {
      name
      {
        givenName "Ralph",
        initial "J",
        familyName "Smith"
      },
      dateOfBirth "19791111"
    },
    {
      name
      {
        givenName "Susan",
        initial "J",
        familyName "Smith"
      },
      dateOfBirth "19820715",
      sex female
    }
  }
}

Encoding Personnel Record ...
Record encoded successfully.

Encoded Data: <?xml version="1.0" encoding="UTF-8"?>
<PersonnelRecord>
  <name>
    <givenName>Mary</givenName>
    <initial>T</initial>
    <familyName>Smith</familyName>
  </name>
  <title>Housewife</title>
  <number>1281</number>
  <dateOfHire>19790422</dateOfHire>
  <nameOfSpouse>
    <givenName>John</givenName>
    <initial>P</initial>
    <familyName>Smith</familyName>
  </nameOfSpouse>
  <children>
    <ChildInformation>
      <name>
        <givenName>Ralph</givenName>
        <initial>J</initial>
        <familyName>Smith</familyName>
      </name>
      <dateOfBirth>19791111</dateOfBirth>
    </ChildInformation>
    <ChildInformation>
      <name>
        <givenName>Susan</givenName>
        <initial>J</initial>
        <familyName>Smith</familyName>
      </name>
      <dateOfBirth>19820715</dateOfBirth>
      <sex><female/></sex>
    </ChildInformation>
  </children>
</PersonnelRecord>


Decoding XER encoded Personnel Record ...
Record decoded successfully.

Output from the decoder ...

value PersonnelRecord ::=
{
  name
  {
    givenName "Mary",
    initial "T",
    familyName "Smith"
  },
  title "Housewife",
  number 1281,
  dateOfHire "19790422",
  nameOfSpouse
  {
    givenName "John",
    initial "P",
    familyName "Smith"
  },
  children
  {
    {
      name
      {
        givenName "Ralph",
        initial "J",
        familyName "Smith"
      },
      dateOfBirth "19791111"
    },
     {
      name
      {
        givenName "Susan",
        initial "J",
        familyName "Smith"
      },
      dateOfBirth "19820715",
      sex female
    }
  }
}

Copyright © 2008 OSS Nokalva, Inc.   All Rights Reserved.

ASN.1 Protocols

Platform Information

E-XER

FAQs

Purchase

Free Trial Download