TOC PREV NEXT INDEX


Procedure for Calling C Encode Functions



This section describes the step-by-step procedure for calling a C BER or DER encode function. This method must be used if C code generation was done. This method can also be used as an alternative to using the control class interface if C++ code generation was done.

Before any encode function can be called; the user must first initialize an encoding context. This is a variable of type ASN1CTXT. This variable holds all of the working data used during the encoding of a message. The context variable is declared as a normal automatic variable within the top-level calling function. It must be initialized before use. This can be accomplished by using the rtInitContext function as follows:

 
        ASN1CTXT ctxt;			// context variable 
 

 
        if (rtInitContext (&ctxt) != ASN_OK) {
 
           /* initialization failed, could be a license problem */
 
           printf ("context initialization failed (check license)\n");
 
           return -1;
 
        }
 


The next step is to specify an encode buffer into which the message will be encoded. This is accomplished by calling the xe_setp run-time function. The user can either pass the address of a buffer and size allocated in his or her program (referred to as a static buffer), or set these parameters to zero and let the encode function manage the buffer memory allocation (referred to as a dynamic buffer). Better performance can normally be attained by using a static buffer because this eliminates the high-overhead operation of allocating and reallocating memory.

After initializing the context and populating a variable of the structure to be encoded, an encode function can be called to encode the message. If the return status indicates success (positive length value), the run-time library function xe_getp can be called to obtain the start address of the encoded message. Note that the returned address is not the start address of the target buffer. BER encoded messages are constructed from back to front (i.e., starting at the end of the buffer and working backwards) so the start point will fall somewhere in the middle of the buffer after encoding is complete. This illustrated in the following diagram:



In this example, a 1K encode buffer is declared which happens to start at address 0x100. When the context is initialized with a pointer to this buffer and size equal to 1K, it positions the internal encode pointer to the end of the buffer (address 0x500). Encoding then proceeds from back-to-front until encoding of the message is complete. In this case, the encoded message turned out to be 0x300 (768) bytes in length and the start address fell at 0x200. This is the value that would be returned by the xe_getp function.

A program fragment that could be used to encode an employee record is as follows:

    #include employee.h         /* include file generated by ASN1C */
 

 
    int main ()
 
    {
 
        ASN1OCTET msgbuf[1024], *msgptr;
 
        int       msglen;
 
        ASN1CTXT  ctxt;
 
        Employee  employee;	/* typedef generated by ASN1C */
 

 
        /* Step 1: Initialize the context and set the buffer pointer */
 

 
        if (rtInitContext (&ctxt) != ASN_OK) {
 
           /* initialization failed, could be a license problem */
 
           printf ("context initialization failed (check license)\n");
 
           return -1;
 
        }
 

 
        xe_setp (&ctxt, msgbuf, sizeof(msgbuf));
 

 
        /* Step 2: Populate the structure to be encoded */
 

 
        employee.name.numocts = 5;
 
        employee.name.data = "SMITH";
 
        ...
 

 
        /* Step 3: Call the generated encode function */
 

 
        msglen = asn1E_Employee (&ctxt, &employee, ASN1EXPL);
 

 
        /* Step 4: Check the return status (note: the test is 	*/
 
        /* > 0 because the returned value is the length of the 	*/
 
        /* encoded message component)..					*/
 

 
        if (msglen > 0) {
 

 
          /* Step 5: If encoding is successful, call xe_getp to 	*/
 
          /* fetch a pointer to the start of the encoded message.	*/
 

 
          msgptr = xe_getp (&ctxt);
 
          ...
 
        }
 
        else
 
          error processing...
 
    }
 

In general, static buffers should be used for encoding messages where possible as they offer a substantial performance benefit over dynamic buffer allocation. The problem with static buffers, however, is that you are required to estimate in advance the approximate size of the messages you will be encoding. There is no built-in formula to do this, the size of an ASN.1 message can vary widely based on data types and the number of tags required.

If performance is not a significant an issue, then dynamic buffer allocation is a good alternative. Setting the buffer pointer argument to NULL in the call to xe_setp specifies dynamic allocation. This tells the encoding functions to allocate a buffer dynamically. The address of the start of the message is obtained as before by calling xe_getp. Note that this is not the start of the allocated memory; that is maintained within the context structure. To free the memory, the rtMemFree run-time function or ASN1MEMFREE macro must be called.

The following code fragment illustrates encoding using a dynamic buffer:

    #include employee.h         /* include file generated by ASN1C */
 

 
    main ()
 
    {
 
        ASN1OCTET *msgptr;
 
        int       msglen;
 
        ASN1CTXT  ctxt;
 
        Employee  employee;	/* typedef generated by ASN1C */
 

 
        if (rtInitContext (&ctxt) != ASN_OK) {
 
           /* initialization failed, could be a license problem */
 
           printf ("context initialization failed (check license)\n");
 
           return -1;
 
        }
 

 
        xe_setp (&ctxt, NULL, 0);
 

 
        employee.name.numocts = 5;
 
        employee.name.data = "SMITH";
 
        ...
 

 
        msglen = asn1E_Employee (&ctxt, &employee, ASN1EXPL);
 

 
        if (msglen > 0) {
 
          msgptr = xe_getp (&ctxt);
 
          ...
 

 
          ASN1MEMFREE (&ctxt);   /* don't call free (msgptr); !!! */
 
        }
 
        else
 
          error processing...
 
    }
 



Objective Systems, Inc.

102 Pickering Way, Suite #506
Exton, Pennsylvania 19341
http://www.obj-sys.com
Phone: (484) 875-9841
Toll-free: (877) 307-6855 (US only)
Fax: (484) 875-9830
info@obj-sys.com
TOC PREV NEXT INDEX