TOP

Version-Neutral API (OssNas namespace)

Applies to: NAS/C++ LTE/EPC r15.5.0 v7.1.1

The following functions and classes are not dependent on the version of the NAS protocol, so they are placed in the OssNas namespace.

Memory Management

All memory allocations throughout the OSS NAS/C++ runtime are performed using ASN.1/C++ memory management. By default, the standard malloc()/realloc()/free() functions are used, but the user can provide his own memory management. See the OSS ASN.1/C++ Runtime API Reference section for more information.

Error Handling

The following exception class is implemented:

    
class OssNasException
{
public:
    OssNasException(int code, const char *message = NULL, const char *desc = NULL);
    OssNasException(const OssNasException &);
    ~OssNasException();
    int getCode();
    const char *getMessage();
    const char *getDescription();
};

Each exception class contains a numeric error code (see the Error Codes section for possible values), a text description of the error code, and possibly a detailed message.

All error signaling is done by throwing instances of the OssNasException class. No error codes are returned as return values.

Several OSS NAS/C++ API functions can generate multiple error and warning messages during a single invocation of the function. When an encode/decode error or other unexpected event occurs during the execution of an encode/decode operation performed internally by those functions, the operation generates either a severe error condition or a recoverable error condition.

A severe error condition is generated when the unexpected event is such that the encode/decode operation either cannot continue or would produce a meaningless result if it did.

For example

  • An output buffer that is too small to contain the output data
  • An out of range choice index
  • A missing mandatory IE (Information Element)
  • An unknown IE with the "comprehension required" requirement

When a severe error condition occurs, the operation terminates immediately and is considered failed.

A recoverable error condition is generated when the unexpected event is such that the operation can continue safely but will be considered failed when it terminates.

For example

  • A field with a missing fixed value that is required by the specification
  • A field with a value that is forbidden by the specification

Eventually, the operation will terminate either when it reaches completion or because of a severe error condition. In either case, the operation will be considered failed.

In decode operations, many unexpected events will generate a severe or recoverable error condition when they occur in a mandatory part of a message or inside an optional IE with "comprehension required", but will not generate an error when they occur inside an optional IE without "comprehension required". In the latter case, the invalid optional IE is treated as if it was not part of the input (the encoded message), and will be marked as absent in the output (the decoded message). Eventually, the decode operation will be considered successful unless a severe or recoverable error condition occurs.

When an error condition occurs, the OSS NAS/C++ API functions produce an error message. An error message has the following format:

  • A message code, formatted as follows:
    • The letter E (encode) or D (decode), to identify the operation
    • A four-digit number, 0001 to 9999, to identify the condition
    • The letter S= (severe error), W=(warning), or E=(recoverable error) to indicate the severity
    • A colon (:) and a space
  • A text description of the condition (US-ASCII character string), followed by a semicolon (;) and a space
  • The word check
  • The path of the field in or after which the condition occurred, formatted as follows:
    ( field ('ident' | #elem ) (type: basetype) of )* PDU 'pduname'
    where:
    • ident is the ASN.1 identifier of a component of a SEQUENCE or CHOICE type.
    • elem is the ordinal number of an element of a SEQUENCE OF type.
    • basetype is one of SEQUENCE, CHOICE, SEQUENCE OF.
    • pduname is the name of the PDU type (NASMessage).
    with spaces inserted between words.

Examples:

D0065E: An unknown information element was detected in the encoded data; check field 'protocolConfigurationOptions' of field 'activateDefaultEPSBearerContextRequest' (type: SEQUENCE) of field 'body' (type: CHOICE) of field 'esmMessage' (type: SEQUENCE) of PDU 'NASMessage'

D0061W: A forbidden value was detected in the encoded data; check field 'systemIdentification' of field #2 (type: SEQUENCE) of field 'supportedCodecs' (type: SEQUENCE OF) of field 'attachRequest' (type: SEQUENCE) of field 'body' (type: CHOICE) of field 'plain' (type: SEQUENCE) of field 'emmMessage' (type: CHOICE) of PDU 'NASMessage'

The OSS NAS/C++ API functions use a pre-allocated memory buffer to store the messages produced for error conditions that occur during one execution of the operation. In most cases, this buffer is large enough to contain all error messages produced by an operation, however, in rare cases it may be filled. Usually this is not an issue, since a user application is rarely interested in all error messages produced by a single function call that has produced many such messages.

When a call to one of the functions listed above generates at least one severe or recoverable error condition, it signals the error by throwing an OssNasException instance. The thrown object contains the error code of the first severe or recoverable error condition that occurred during the operation. If necessary, consult the message component of the thrown object.

Common Encoder-Decoder Class

OssNasCoderBase is a common ancestor class for encoding-decoding classes.

Definition

class OssNasCoderBase
{
public:
    ~OssNasCoderBase();
    unsigned long getFlags();
    unsigned long getEncodingFlags();
    unsigned long getDecodingFlags();
    void setFlags(unsigned long flags);
    void setEncodingFlags(unsigned long flags);
    void setDecodingFlags(unsigned long flags);
    int getOriginator();
    void setOriginator(int originator);
    void binary2XML(const OssString & in, OssString **out, OSS_UINT32 *encsize);
    void binary2JSON(const OssString & in, OssString **out, OSS_UINT32 *encsize);
};

This class has protected constructors and is not intended for user instantiation. Also, it has some protected methods that are used by its successors. The protected methods are not described here.

Methods

void setEncodingFlags(unsigned long flags);
This method helps control the behavior of encoding functions. It sets the value of the encoding flags word in the OssNasCoderBase object. Currently there are no user-accessible encoding flags defined, so this function is for future use.
void setDecodingFlags(unsigned long flags);
This method helps control the behavior of decoding functions. It sets the value of the decoding flags word in the OssNASCoderBase object. Currently there are no user-accessible decoding flags defined, so this function is for future use.
void setFlags(unsigned long flags);
This method sets both the encoding and decoding flags to the same value. Currently, there are two user-accessible flags:
  • The OSSNAS_OLDXML flag forces the binary2XML() and print() functions to produce XML documents in the format that was used by old releases of the OSS NAS/C++ tools. This format does not fully conform to ITU-T Recommendation X.693 (ISO/IEC 8825-4:2015): Information technology - ASN.1 encoding rules: XML Encoding Rules (XER).
  • The OSSNAS_OLD_MNC_WITH_SPACE flag restores the old decoder behavior to decode a two-digit MNC value into a string of size 3 with a trailing space and forces the encoder to reject MNC strings of size 2 without a trailing space. By default, the decoder decodes a two-digit MNC value into a string of size 2 and the encoder accepts MNC strings of size 2.
unsigned long getEncodingFlags();
This method returns the current value of the encoding flags word. As there are no user-accessible encoding flags defined, this function is for future use.
unsigned long getDecodingFlags();
This method returns the current value of the encoding flags word. As there are no user-accessible decoding flags defined, this function is for future use.
unsigned long getFlags();
This method returns the logical OR of the encoding flags word and the decoding flags word.
void setOriginator(int originator);
The function sets the originator for a NAS message that will be encoded or decoded. This setting affects the behavior of the encoding and decoding functions. In the NAS protocol, certain messages can only be sent by one of the two originators, and the interpretation of other messages depends on the originator of the message. The parameter can be either 1 (UE) or 2 (Network). You can use the OSSNAS_ORIG_UE or OSSNAS_ORIG_NETWORK symbolic names instead of numeric values.
int getOriginator();
The function returns the current originator value set by the setOriginator function.
void binary2XML(const OssString & in, OssString **out, OSS_UINT32 *encsize);
The function converts the encoded NAS message to the textual XML form. The first argument (in) is a buffer that contains the input encoded message. The second argument (out) is a pointer variable. If it is not NULL, it points to the output buffer. If it is NULL, a new buffer long enough to hold the result will be dynamically allocated by the function and assigned to the out pointer. In this case, the output buffer will be owned by the caller. When the buffer is no longer needed, the caller is responsible for deallocating the buffer using the delete operator. The third argument (encsize), if not NULL, points to the integer variable. The function will set it to the length of the resulting XML encoding in bytes. This is especially useful if you call the function using a pre-allocated buffer (*out != NULL). In that case, the size of the output string is different from the size of the buffer, so you need this parameter to obtain the former. If encsize is NULL, this information is lost.
void binary2JSON(const OssString & in, OssString **out, OSS_UINT32 *encsize);
The function converts the encoded NAS message to the textual JSON form. The first argument (in) is a buffer that contains the input encoded message. The second argument (out) is a pointer variable. If it is not NULL, it points to the output buffer. If it is NULL, a new buffer long enough to hold the result will be dynamically allocated by the function and assigned to the out pointer. In this case, the output buffer will be owned by the caller. When the buffer is no longer needed, the caller is responsible for deallocating the buffer using the delete operator. The third argument (encsize), if not NULL, points to the integer variable. The function will set it to the length of the resulting JSON encoding in bytes. This is especially useful if you call the function using a pre-allocated buffer (*out != NULL). In that case, the size of the output string is different from the size of the buffer, so you need this parameter to obtain the former. If encsize is NULL, this information is lost.

Encoder-Decoder Class Template

The application instantiates the OssNasCoder template class to encode/decode NAS messages. The template parameter is the NAS message representation class. Your product version supports version 15.5.0 of NAS, so the classes that can be used as the template parameter are

OssNas::v1550::NASMessage: OssNasCoder<OssNas::v1550::NASMessage> coder1550; /* coder to encode/decode OssNas::v1550::NASMessage */

If you need support for other versions of NAS, contact OSS Nokalva at info@oss.com.

Definition

template <class Message>
class OssNasCoder : public OssNasCoderBase
{
public:
    OssNasCoder();
    void encode(const Message & msg, OssString **buf, OSS_UINT32 *encsize);
    const Message *decode(const OssString & buf);
    void print(const Message & msg);
    void deleteDecoded(const Message *msg);
    int do_getTotalNumberOfWarningConditions( ) ;
    int do_getNumberOfWarningMessagesLogged( ) ;
    const char * const do_getWarningMessage( int n, int &msgLen );
    int do_getTotalNumberOfErrorConditions( ) ;
    int do_getNumberOfErrorMessagesLogged( ) ;
    const char * const do_getErrorMessage( int n, int &msgLen );
    }

Methods

void encode(const Message & msg, OssString **buf, OSS_UINT32 *encsize);
The method encodes a binary structure containing NAS message data into a memory buffer. The first argument (msg) is the binary structure. The second argument (buf) is a pointer variable. If it is not NULL, it points to the output buffer. If it is NULL, a new buffer long enough to hold the encoding will be dynamically allocated by the function and assigned to the buf pointer. In this case, the output buffer will be owned by the caller. When the buffer is no longer needed, the caller is responsible for deallocating the buffer using the delete operator. The third argument (encsize), if not NULL, points to the integer variable. The function will set it to the length of the resulting XML encoding in bytes. This is especially useful if you call the function using a pre-allocated buffer (*buf != NULL). In that case, the size of the output string is different from the size of the buffer, so you need this parameter to obtain the former. If encsize is NULL, this information is lost.
const Message *decode(const OssString & buf);
This function decodes a NAS message from a memory buffer. The buffer is passed as the function parameter and the decoded binary structure is returned as the result. The decoded message is owned by the coder object. The user cannot modify or deallocate it explicitly, which is why it is declared const. If the user needs to modify it, he can make a copy of it using the copy constructor or assignment operator. To instruct the coder object to deallocate a decoded value, the user must use the deleteDecoded function.

As of release 6.1, the decoding of certain variable-length IEs ending with one or more optional octets (UE network capability IE, Mobile station classmark 3 IE, and MS network capability IE) has been modified so any missing optional octets at the end of the IE are treated as zeros. This allows the decoding operation to proceed without error even when an IE is sent that lacks one or more fields at the end, provided that the octets that would have carried the missing fields are marked as optional in the relevant technical specification. This could occur when the sender intentionally omits one or more trailing zero octets from those IEs (e.g., in order to save space) or when the sender uses an older NAS release and the NAS release used by the recipient extends the definition of those IEs by one or more octets.

The parts of the NAS*.h header file that correspond to the three IEs in question have been modified in a non-backward-compatible way. If you have existing code that uses the NAS API, you will have to make minor changes to your code to support the new structures.
void print(const Message & msg);
This function prints a decoded NAS message to the standard output in XML form. The first argument (msg) is the binary structure containing the NAS message data.
void deleteDecoded(const Message *msg);
The function instructs the coder to deallocate a decoded NAS binary structure. As stated in the decode method description, the result of a decoding operation is owned by the coder object and cannot be deallocated by the usual delete operator. The user must use the deleteDecoded function instead.

Note also that this class is derived from the OssNasCoderBase class, so it can use all the methods of the OssNasCoderBase class.

The following functions retrieve information about the error and warning messages generated by the latest call to encode/decode/print APIs.

int getTotalNumberOfWarningConditions( );
This function returns the total number of warning conditions that occurred during the encoding/ decoding/printing of a PDU.
int getNumberOfWarningMessagesLogged( );
This function returns the number of warning conditions which are logged in the internal buffer during the encoding/decoding/printing of a PDU.
const char * const getWarningMessage( int n, int &msgLen );
This function returns the nth of the logged warning messages. The returned message is not Null terminated, and the message length is returned in the output parameter msgLen. The warning message is owned by the coder object. You cannot modify or deallocate it.
int getTotalNumberOfErrorConditions ( );
This function returns the total number of error conditions that occurred during the encoding/decoding/printing of a PDU.
int getNumberOfErrorMessagesLogged ( );
This function returns the total number of error conditions which are logged in the internal buffer during the encoding/decoding/printing of a PDU.
const char * const getWarningMessage( int n, int &msgLen );
This function returns the nth of the logged error messages. The returned message is not Null terminated, and the message length is returned in the output parameter msgLen. The error message is owned by the coder object. You cannot modify or deallocate it.

This documentation applies to the NAS/C++ Encoder Decoder Library for LTE/EPC v7.1.1 for 3GPP Release 15.5.0.

Copyright © 2020 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 NAS/C++ Encoder Decoder Library for LTE/EPC is associated with a specific license and related unique license number. That license determines, among other things, what functions of the NAS/C++ Encoder Decoder Library for LTE/EPC are available to you.