Generated Information Object Table Structures
When the -tables command line option is used, additional code is generated to support the additional processing required to verify table constraints. This code varies depending on whether C or C++ code generation is selected. The C++ code is designed to take advantage of the object-oriented capabilities of C++. These capabilities are well suited for modeling the behavior of information objects in practice. The following subsections describe the code generated for each of these languages.
The code generated to support these constraints is intended for use only in compiler-generated code. Therefore, it is not necessary for the average user to understand the mappings in order to use the product. The information presented here is informative only to provide a better understanding of how the compiler handles table constraints.
For C, code is generated for the Information Object Sets defined within a specification in the form of a global array of structures. Each structure in the array is an equivalent C structure representing the corresponding ASN.1 information object.
Additional encode and decode functions are also generated for each type that contains table constraints. These functions have the following prototypes:
int asn1ETC_<ProdName> (ASN1CTXT* pctxt, <ProdName>* pvalue); int asn1DTC_<ProdName> (ASN1CTXT* pctxt, <ProdName>* pvalue);int asn1PETC_<ProdName> (ASN1CTXT* pctxt, <ProdName>* pvalue); int asn1PDTC_<ProdName> (ASN1CTXT* pctxt, <ProdName>* pvalue);The purpose of these functions is to verify the fixed values within the table constraints are what they should be and to encode or decode the open type fields using the encoder or decoder assigned to the given table row. Calls to these functions are automatically built into the standard encode or decode functions for the given type. They should be considered hidden functions not for use within an application that uses the API.
For C++, code is generated for ASN.1 classes, information objects, and information object sets. This code is then referenced when table constraint processing must be performed.
Each of the generated C++ classes builds on each other. First, the classes generated that correspond to ASN.1 classes form the base class foundation. Then C++ classes derived from these base classes corresponding to the information objects are generated. Finally, C++ singleton classes corresponding to the information object sets are generated. Each of these classes provides a container for a collection of C++ objects that make up the object set.
The C++ class generated to model an ASN.1 class contains member variables for each of the fixed-type fields within the class. Derived information object classes are required to populate these variables with the values defined in the ASN.1 information object specification. The C++ class also contains virtual methods representing each of the type fields within the ASN.1 class specification. If the field is not defined to be optional in the ASN.1 specification, then it is declared to be abstract in the generated class definition. A class generated for an ASN.1 information object that references this base class is required to implement these abstract virtual methods.
As an example, consider the following ASN.1 class definition (this was derived from the NBAP 3GPP ASN.1 specification):
NBAP-ELEMENTARY-PROCEDURE ::= CLASS { &InitiatingMessage , &SuccessfulOutcome OPTIONAL, &UnsuccessfulOutcome OPTIONAL, &Outcome OPTIONAL, &message DiscriminatorMessageDiscriminator, &procedureID Procedure IDUNIQUE, &criticality Criticality DEFAULT ignore } WITH SYNTAX { INITIATING MESSAGE &InitiatingMessage [SUCCESSFULOUTCOME &SuccessfulOutcome] [UNSUCCESSFUL OUTCOME &UnsuccessfulOutcome] [OUTCOME &Outcome] MESSAGE DISCRIMINATOR &messageDiscriminator PROCEDURE ID &procedureID [CRITICALITY &criticality] }This results in the generation of the following C++ class definition (note: some auxiliary details have been removed to illustrate the points made above):
class EXTERN NBAP_ELEMENTARY_PROCEDURE { protected: ASN1T_MessageDiscriminator messageDiscriminator; ASN1T_ProcedureID procedureID; ASN1T_Criticality criticality; NBAP_ELEMENTARY_PROCEDURE (); public: virtual int encodePERInitiatingMessage (ASN1CTXT* pctxt, ASN1TObject& object) = 0; virtual int decodePERInitiatingMessage (ASN1CTXT* pctxt, ASN1TObject& object) = 0; virtual int encodePERSuccessfulOutcome (ASN1CTXT* pctxt, ASN1TObject& object) { return 0; } virtual int decodePERSuccessfulOutcome (ASN1CTXT* pctxt, ASN1TObject& object) { return 0; }virtual int encodePERUnsuccessfulOutcome (ASN1CTXT* pctxt, ASN1TObject& object) { return 0; } virtual int decodePERUnsuccessfulOutcome (ASN1CTXT* pctxt, ASN1TObject& object) { return 0; } virtual int encodePEROutcome (ASN1CTXT* pctxt, ASN1TObject& object) { return 0; } virtual int decodePEROutcome (ASN1CTXT* pctxt, ASN1TObject& object) { return 0; } inline ASN1BOOL messageDiscriminatorEquals (ASN1T_MessageDiscriminator value) { return (messageDiscriminator == value); } inline ASN1BOOL procedureIDEquals (ASN1T_ProcedureID* pvalue) { return (0 == asn1CmpTC_ProcedureID (&procedureID, pvalue)); } inline ASN1BOOL criticalityEquals (ASN1T_Criticality value) { return (criticality == value); } } ;First notice that member variables have been generated for the fixed-type fields in the definition. These include the messageDiscriminator, procedureID, and criticality fields. Information object classes derived from this definition are expected to populate these fields in their constructors.
Also, virtual methods have been generated for each of the type fields in the class. These include the InitiatingMessage, SuccessfulOutcome, UnsuccessfulOutcome, and Outcome fields. The method generated for InitiatingMessage is abstract and must be implemented in a derived information object class. The other fields are optional and therefore have default implementations that do nothing.
Also generated are Equals methods for the fixed-type fields. These are used by the generated code to verify that data in a generated structure to be encoded (or data that has just been decoded) matches the table constraint values.
The C++ classes generated for ASN.1 information objects are derived from the ASN.1 class objects. The constructors in these classes populate the fixed-type field member variables with the values specified in the information object. The classes also implement the virtual methods generated for the information object type fields. All non-optional methods are required to be implemented. The optional methods are only implemented if they are defined in the information object definition.
An example of an information object definition that is derived from the ASN.1 class above is as follows:
radioLinkSetupFDD NBAP-ELEMENTARY-PROCEDURE ::= { INITIATING MESSAGE RadioLinkSetupRequestFDD SUCCESSFUL OUTCOME RadioLinkSetupResponseFDD UNSUCCESSFUL OUTCOME RadioLinkSetupFailureFDD MESSAGE DISCRIMINATOR common PROCEDURE ID { procedureCode id-radioLinkSetup, ddMode fdd } CRITICALITY reject }class EXTERN radioLinkSetupFDD : public NBAP_ELEMENTARY_PROCEDURE { public: radioLinkSetupFDD(); virtual int encodePERInitiatingMessage (ASN1CTXT* pctxt, ASN1TObject& object); virtual int decodePERInitiatingMessage (ASN1CTXT* pctxt, ASN1TObject& object); virtual void printInitiatingMessage (ASN1ConstCharPtr name, ASN1TObject& object); virtual int encodePERSuccessfulOutcome (ASN1CTXT* pctxt, ASN1TObject& object); virtual int decodePERSuccessfulOutcome (ASN1CTXT* pctxt, ASN1TObject& object);virtual void printSuccessfulOutcome (ASN1ConstCharPtr name, ASN1TObject& object); virtual int encodePERUnsuccessfulOutcome (ASN1CTXT* pctxt, ASN1TObject& object); virtual int decodePERUnsuccessfulOutcome (ASN1CTXT* pctxt, ASN1TObject& object); virtual void printUnsuccessfulOutcome (ASN1ConstCharPtr name, ASN1TObject& object); } ;The constructor implementation for this class (not shown) sets the fixed type fields (messageDiscriminator, procedureID, and criticality) to the assigned values (common, {id-radioLinkSetup, fdd}, and reject respectively). The class also implements the virtual methods for the type field virtual methods defined in the base class. These methods simply call the PER encode or decode method for the assigned type (this example assumes -per was specified for code generation - other encode rules could have been used as well). Note that the base class methods for the Outcome field are not implemented. This is because this is an optional type field and it is not defined in the information object definition.
The final item in this model is the mapping of ASN.1 information object sets to C++ classes. In this case, a C++ singleton class is generated. This class contains a container to hold an instance of each of the ASN.1 information object C++ objects. As of this writing, a static array is used to hold the objects, but this could be changed to something like a linked list or hash without affecting the public interface to the class. The class also contains an object lookup method for each of the key fields. Key fields are identified in the class as either a) fields that are marked unique, or b) fields that are referenced in table constraints with the `@' notation.
An example of an information object set that uses the information object class defined above is as follows:
NBAP-ELEMENTARY-PROCEDURES NBAP-ELEMENTARY-PROCEDURE ::= { radioLinkSetupFDD | radioLinkSetupTDD , ... }class EXTERN NBAP_ELEMENTARY_PROCEDURES { protected: NBAP_ELEMENTARY_PROCEDURE* mObjectSet[2]; const size_t mNumObjects; static NBAP_ELEMENTARY_PROCEDURES* mpInstance; NBAP_ELEMENTARY_PROCEDURES (); public: NBAP_ELEMENTARY_PROCEDURE* lookupObject (ASN1T_ProcedureID _procedureID); static NBAP_ELEMENTARY_PROCEDURES* instance(); } ;The mObjectSet array is the container for the information object classes. These objects are created and this array populated in the class constructor. Note that this is a singleton class (as evidenced by the protected constructor and instance methos). Therefore, the object set array is only initialized once the first time the instance method is invoked.
The other method of interest is the lookupObject method. This was generated for the procedureID field because it was identified as a key field. This determination was made because procedureID was declared to be UNIQUE in the class definition above. A field can also be determined to be a key field if it is referenced via the `@' notation in a table constraint in a standard type definition. For example, in the following element assignment:
Additional encode and decode functions are also generated as they were in the C code generation case for interfacing with the object definitions above. These functions have the following prototypes:
int asn1ETC_<ProdName> (ASN1CTXT* pctxt, <ProdName>* pvalue, <ClassName>* pobject); int asn1DTC_<ProdName> (ASN1CTXT* pctxt, <ProdName>* pvalue, <ClassName>* pobject);int asn1PETC_<ProdName> (ASN1CTXT* pctxt, <ProdName>* pvalue, <ClassName>* pobject); int asn1PDTC_<ProdName> (ASN1CTXT* pctxt, <ProdName>* pvalue, <ClassName>* pobject);These prototypes are identical to the C code generation case except for the addition of the pobject argument. This argument is for a pointer to the information object that matches the key field value for a given encoding. The logic to invoke one of these functions on the encode side is as follows:
- The lookupObject method is invoked on the object set instance to find the class object for the data in the populated type variable to be encoded.
- If a match is found, the table constraint encode function as defined above is invoked. This function will verify all fixed type values match what is defined in the information object definition and will encode all type fields and store the resulting encoded data in the ASN1Tobject.encoded fields.
- The normal encode logic is then performed to encode all of the standard and open type fields in the message.
- The normal decode logic is performed to populate the standard and open type fields in the generated structure.
- The lookupObject method is invoked on the decoded key field value to find an object match.
- If a match is found, the table constraint decode function as defined above is invoked. This function will verify all fixed type values match what is defined in the information object definition and will fully decode all type fields and store pointers to the decoded type variables in the ASN1TObject.decoded fields.
Objective Systems, Inc.102 Pickering Way, Suite #506Exton, 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 |