The following are the basic steps to decode with a PDU decode function:
Prepare a context variable for decoding
Initialize the data structure to receive the decoded data
Call the desired PDU decode function to decode the message
Free the context after use of the decoded data is complete to free allocated memory structures
Before a NAS decode function can be called, the user must first initialize a context block structure. The context block is initialized by calling the rtInitContext
function.
Only memory-buffer based encoding is supported for 3GPP layer 3 because the message sizes are generally small (normally less than 256 bytes).
To do memory-based decoding, the rtxInitContextBuffer
function would be called. The message to be decoded must reside in memory. The arguments to this function would then specify the message buffer in which the data to be decoded exists.
The PDU variable that is to receive the decoded data must then be initialized. This can be done by either initializing the variable to zero using memset, or by calling the ASN1C generated initialization function.
The PDU decode function can then be called to decode the message. If the return status indicates success (0), then the message will have been decoded into the PDU type variable. The decode function may automatically allocate dynamic memory to hold variable length variables during the course of decoding. This memory will be tracked in the context structure, so the programmer does not need to worry about freeing it. It will be released when the either the context is freed or explicitly when the rtxMemFree
or rtxMemReset
function is called.
The final step of the procedure is to free the context block. This must be done regardless of whether the block is static (declared on the stack and initialized using rtInitContext
), or dynamic (created using rtNewContext
). The function to free the context is rtFreeContext
.
A program fragment that could be used to decode a 3G NAS PDU is as follows:
#include "rt3gppsrc/TS24008Msgs.h" /* include file generated by ASN1C */ main () { TS24008Msg_PDU data; OSCTXT ctxt; OSOCTET* msgbuf; const char* filename = "message.dat"; int stat; OSSIZE len; /* step 1: initialize context */ stat = rtInitContext (&ctxt); if (stat != 0) { printf (“rtInitContext failed (check license)\n“); rtErrPrint (&ctxt); return stat; } /* step 2: read input file into a memory buffer */ stat = rtxFileReadBinary (&ctxt, filename, &pMsgBuf, &len); if (0 == stat) { stat = rtxInitContextBuffer (&ctxt, pMsgBuf, len); } if (0 != stat) { rtxErrPrint (&ctxt); rtFreeContext (&ctxt); return stat; } /* step 3: set protocol version number */ rtxCtxtSetProtocolVersion (&ctxt, 8); /* step 4: call the decode function */ stat = NASDec_TS24008Msg_PDU (&ctxt, &data); if (stat == 0) { process received data.. } else { /* error processing... */ rtxErrPrint (&ctxt); } /* step 5: free the context */ rtFreeContext (&ctxt); }