Two-phase decoding is the reverse operation of two-phase encoding. In this scenario, a message is received and decoded. The header and payload are contained in the message, and the payload type and content must be decoded after the message is received.
This example shows how to decode the message encoded in the previous section. As before, some setup is required to perform the decode:
ApduType data; OSCTXT ctxt; OSBOOL trace = TRUE, verbose = FALSE; const char* filename = "message.dat"; int i, stat; /* Initialize context structure */ stat = rtInitContext (&ctxt); if (stat != 0) { rtxErrPrint (&ctxt); return stat; } rtxSetDiag (&ctxt, verbose);
In this case, the content is read from an input file, so a
file stream is created using rtxStreamFileCreateReader
.
Thereafter, the PDU data type is initialized using its initialization
function and the message is decoded with the generated
MDERDec
function:
/* Create file input stream */ stat = rtxStreamFileCreateReader (&ctxt, filename); if (0 != stat) { rtxErrPrint (&ctxt); rtFreeContext (&ctxt); return stat; } asn1Init_ApduType (&data); /* Call compiler generated decode function */ stat = MDERDec_ApduType (&ctxt, &data); if (stat != 0) { printf ("decode of ApduType failed\n"); rtxErrPrint (&ctxt); rtFreeContext (&ctxt); return -1; } rtxStreamClose (&ctxt);
The second phase of the decode can now proceed. Because the open
type data can appear in a list, a while
loop is used to
cycle through the data:
/* Decode APDU open type data */ if (data.t == T_ApduType_aarq) { OSRTDListNode* pnode = data.u.aarq->data_proto_list.head; while (0 != pnode) { PhdAssociationInformation phdAssocInfo; DataProto* pDataProto = (DataProto*) pnode->data; /* Create memory input stream */ stat = rtxStreamMemoryCreateReader (&ctxt, (OSOCTET*)pDataProto->data_proto_info.data, pDataProto->data_proto_info.numocts);
Note here that the rtxStreamMemoryCreateReader
function is used to stream data from the previously decoded message.
It points to the octets held inside of the open type. After
initializing the stream reader, the data can be decoded into the
appropriate structure using the corresponding MDERDec
function:
/* Decode PhdAssociationInformation */ asn1Init_PhdAssociationInformation (&phdAssocInfo); stat = MDERDec_PhdAssociationInformation (&ctxt, &phdAssocInfo); if (stat != 0) { printf ("decode of ApduType failed\n"); rtxErrPrint (&ctxt); rtFreeContext (&ctxt); return -1; } rtxStreamClose (&ctxt); pnode = pnode->next; } }