Encode and Decode S1AP-PDU using ASNSDK TCE-C++

This section describes how to create, encode and decode a 3GPP S1AP-PDU (3GPP TS 36.413 v.10.6.0) using ASNSDK TCE-C++.

Let's create and encode the following value:

<S1AP-PDU> 
<initiatingMessage>
<procedureCode>1</procedureCode>
<criticality>
<reject/>
</criticality>
<value>
<HandoverRequest>
<protocolIEs>
<SEQUENCE>
<id>1</id>
<criticality>
<reject/>
</criticality>
<value>
<HandoverType>
<intralte/>
</HandoverType>
</value>
</SEQUENCE>
</protocolIEs>
</HandoverRequest>
</value>
</initiatingMessage>
</S1AP-PDU>

The corresponding S1AP-PDU definition starts with:

S1AP-PDU ::= CHOICE { 
initiatingMessage InitiatingMessage,
successfulOutcome SuccessfulOutcome,
unsuccessfulOutcome UnsuccessfulOutcome,
...
}
InitiatingMessage ::= SEQUENCE {
procedureCode S1AP-ELEMENTARY-PROCEDURE.&procedureCode ({S1AP-ELEMENTARY-PROCEDURES}),
criticality S1AP-ELEMENTARY-PROCEDURE.&criticality ({S1AP-ELEMENTARY-PROCEDURES}{@procedureCode}),
value S1AP-ELEMENTARY-PROCEDURE.&InitiatingMessage ({S1AP-ELEMENTARY-PROCEDURES}{@procedureCode})
}

S1AP-PDU is a CHOICE type for which the TCE-C++ ASN.1 Compiler generates a class S1AP_PDU with a pointer to all alternatives of this CHOICE type:

class S1AP_PDU : public asntype 
{
public:
S1AP_PDU__C * value;
...

One of the alternatives is InitiatingMessage for which the ASN.1 Compiler generates:

class asncinitiatingMessage: public S1AP_PDU__C 
{
public:
asnMAXSINT procedureCode;
asnMAXSINT criticality;
asntype * value;
...

procedureCode and criticality are easy to set but the value field is an open type which can be set in either encoded form or decoded form.

Create the open type value in encoded form (i.e. with binary data) using ASNSDK TCE-C++

To create the field value in encoded form, an object of class asnOpenType taking the binary data as parameter must be created:

  asnbyte encodedForm[] = {0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00};
  initMsg->value = new asnOpenType(8, (asnbyte*)encodedForm, asnPER);

This results in the following code for the complete sample for creating, encoding and decoding using the encoded form for open types:

  // instanciate the S1AP PDU to encode 
S1AP_PDU s1ap_pdu;
asncinitiatingMessage* initMsg = new asncinitiatingMessage();
s1ap_pdu.value = initMsg;
initMsg->procedureCode = 1;
initMsg->criticality = reject;
// Set the open type in encoded form
asnbyte encodedForm[] = {0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00};
initMsg->value = new asnOpenType(8, (asnbyte*)encodedForm, asnPER);
/* ENCODING PROCESS */
// encode s1ap_pdu into the encoding stream
asnMAXUINT len = s1ap_pdu.PERencode(&context, &encoding);
// get the buffer from encoding stream
asnbytep buffer = encoding.detach();
/* DECODING PROCESS */
// a buffer contains the message to decode
// build a decoding stream over the buffer
asnMemoryStream decoding(buffer, // memory area
len, // area length
asnFSTREAM_READ); // read binary stream
// decode the decoding stream into myDecodedValue
S1AP_PDU myDecodedValue;
myDecodedValue.PERdecode(&context, &decoding);

Executing the sample returns the following value trace:

  
<S1AP-PDU>
<initiatingMessage>
<procedureCode>1</procedureCode>
<criticality>
<reject/>
</criticality>
<value>0000010001000100</value>
</initiatingMessage>
</S1AP-PDU>

... and the encoding:

  
<encoding>
00010008 00000100 01000100
</encoding>

Create the open type value in decoded form (i.e. C++ objects) using ASNSDK TCE-C++


To create the field value in decoded form, an object of class HandoverRequest taking the binary data as parameter must be created.

Replace in the above sample code:

 
  // Set the open type in encoded form 
asnbyte encodedForm[] = {0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00};
initMsg->value = new asnOpenType(8, (asnbyte*)encodedForm, asnPER);

by

 
  // Set the open type in decoded form 
HandoverRequest* handoverRequest = new HandoverRequest();
initMsg->value = handoverRequest;
asncHandoverRequest__protocolIEss* ie = new asncHandoverRequest__protocolIEss();
handoverRequest->protocolIEs.addElement(ie);
HandoverType* handoverType = new HandoverType();
handoverType->value = intralte;
ie->id = 1;
ie->criticality = reject;
ie->value = handoverType;

in order to get the same value and encoding.