Acv53CCpp Manual
User Manual: Pdf
Open the PDF directly: View PDF .
Page Count: 319
Download | ![]() |
Open PDF In Browser | View PDF |
ASN1C ASN.1 Compiler Version 5.3 C/C++ User’s Manual Objective Systems, Inc. version 5.3 February 2002 The software described in this document is furnished under a license agreement and may be used only in accordance with the terms of this agreement. Copyright Notice Copyright © 1997-2002 Objective Systems, Inc. All Rights Reserved This document may be distributed in any form, electronic or otherwise, provided that it is distributed in its entirety and that the copyright and this notice are included. Author’s Contact Information: Comments, suggestions, and inquiries regarding ASN1C may be submitted via electronic mail to info@obj-sys.com. CHANGE HISTORY Date 11/06/2001 Author ED Version 5.3 Description Initial version 05/01/2002 ED 5.32 Updated sections on calling C BER/DER encode/decode functions to specify use of rtInitContext. TABLE OF CONTENTS OVERVIEW OF ASN1C ................................................................................................................................................1 USING THE COMPILER ..............................................................................................................................................3 Running the Compiler....................................................................................................................................................3 Compiling and Linking Generated Code .......................................................................................................................6 Porting Run-time Code to Other Platforms....................................................................................................................7 Compiler Configuration File..........................................................................................................................................9 Compiler Error Reporting ............................................................................................................................................13 GENERATED C/C++ SOURCE CODE......................................................................................................................15 Header (.h) File ............................................................................................................................................................15 BOOLEAN ..............................................................................................................................................................17 INTEGER ................................................................................................................................................................17 BIT STRING............................................................................................................................................................18 Named Bits ..............................................................................................................................................................19 ASN1CBitStr Control Class.....................................................................................................................................20 OCTET STRING .....................................................................................................................................................21 ENUMERATED ......................................................................................................................................................22 NULL.......................................................................................................................................................................23 OBJECT IDENTIFIER............................................................................................................................................23 REAL .......................................................................................................................................................................24 SEQUENCE.............................................................................................................................................................24 DEFAULT keyword ................................................................................................................................................28 Extension Elements..................................................................................................................................................28 SET ..........................................................................................................................................................................29 SEQUENCE OF.......................................................................................................................................................29 Static (sized) SEQUENCE OF Type........................................................................................................................30 List-based SEQUENCE OF Type............................................................................................................................30 Generation of Temporary Types for SEQUENCE OF Elements.............................................................................30 SET OF ....................................................................................................................................................................32 CHOICE...................................................................................................................................................................32 Open Type................................................................................................................................................................34 Character String Types.............................................................................................................................................35 Time String Types....................................................................................................................................................36 External Type...........................................................................................................................................................36 Parameterized Types................................................................................................................................................37 Information Objects .................................................................................................................................................38 Value Specifications ................................................................................................................................................39 INTEGER Value Specification ................................................................................................................................39 BOOLEAN Value Specification ..............................................................................................................................40 Binary and Hexadecimal String Value Specification...............................................................................................40 Character String Value Specification.......................................................................................................................40 Object Identifier Value Specification.......................................................................................................................40 Encode/Decode Function Prototypes .......................................................................................................................41 Generated Class Definition ......................................................................................................................................42 Generated Methods ..................................................................................................................................................43 Generated BER Encode Functions...............................................................................................................................44 Generated C Function Format and Calling Parameters............................................................................................44 Generated C++ Encode Method Format and Calling Parameters ............................................................................44 Populating Generated Structure Variables for Encoding .........................................................................................45 Procedure for Calling C Encode Functions..............................................................................................................46 Procedure for Using the C++ Control Class Encode Method ..................................................................................48 Encoding a Series of Messages Using the C++ Control Class Interface..................................................................50 Generated BER Decode Functions ..............................................................................................................................52 Generated C Function Format and Calling Parameters............................................................................................52 ASN1C V5.3 i Generated C++ Decode Method Format and Calling Parameters ............................................................................52 Procedure for Calling C Decode Functions..............................................................................................................53 Procedure for Using the C++ Control Class Decode Method ..................................................................................54 Decoding a Series of Messages Using the C++ Control Class Interface .................................................................55 Performance Considerations: Dynamic Memory Management ...............................................................................57 Generated PER Encode Functions ...............................................................................................................................58 Generated C Function Format and Calling Parameters............................................................................................58 Generated C++ Encode Method Format and Calling Parameters ............................................................................58 Populating Generated Structure Variables for Encoding .........................................................................................59 Procedure for Calling C Encode Functions..............................................................................................................59 Procedure for Using the C++ Control Class Encode Method ..................................................................................60 Encoding a Series of PER Messages using the C++ Interface .................................................................................63 Generated PER Decode Functions...............................................................................................................................64 Generated C Function Format and Calling Parameters............................................................................................64 Generated C++ Decode Method Format and Calling Parameters ............................................................................64 Procedure for Calling C Decode Functions..............................................................................................................65 Procedure for Using the C++ Control Class Encode Method ..................................................................................66 Decoding a Series of Messages Using the C++ Control Class Interface .................................................................67 Performance Considerations: Dynamic Memory Management ...............................................................................68 Generated Print Functions............................................................................................................................................69 Event Handler Interface ...............................................................................................................................................70 How it Works...........................................................................................................................................................70 How to Use It...........................................................................................................................................................71 IMPORT/EXPORT of Types.......................................................................................................................................75 ASN1C90.....................................................................................................................................................................76 ROSE OPERATION and ERROR...........................................................................................................................76 SNMP OBJECT-TYPE............................................................................................................................................78 ASN.1 C++ RUN-TIME CLASSES..............................................................................................................................81 ASN1Context...............................................................................................................................................................81 ASN1Context::ASN1Context ..................................................................................................................................81 ASN1Context::~ASN1Context ................................................................................................................................81 ASN1Context::GetPtr ..............................................................................................................................................81 ASN1Context::PrintErrorInfo..................................................................................................................................82 ASN1MessageBuffer ...................................................................................................................................................83 ASN1MessageBuffer::addEventHandler .................................................................................................................83 ASN1MessageBuffer::CStringToBMPString ..........................................................................................................83 ASN1MessageBuffer::getByteIndex........................................................................................................................84 ASN1MessageBuffer::getContext............................................................................................................................84 ASN1MessageBuffer::GetMsgCopy........................................................................................................................85 ASN1MessageBuffer::GetMsgPtr............................................................................................................................85 ASN1MessageBuffer::Init .......................................................................................................................................86 ASN1MessageBuffer::isA .......................................................................................................................................86 ASN1MessageBuffer::PrintErrorInfo ......................................................................................................................87 ASN1MessageBuffer::setErrorHandler ...................................................................................................................87 ASN1BERMessageBuffer ...........................................................................................................................................89 ASN1BERMessageBuffer::CalcIndefLen ...............................................................................................................89 ASN1BERMessageBuffer::BinDump......................................................................................................................89 ASN1BERMessageBuffer::HexDump.....................................................................................................................90 ASN1BEREncodeBuffer .............................................................................................................................................91 ASN1BEREncodeBuffer::ASN1BEREncodeBuffer ...............................................................................................91 ASN1BEREncodeBuffer::GetMsgCopy..................................................................................................................91 ASN1BEREncodeBuffer::GetMsgPtr......................................................................................................................92 ASN1BEREncodeBuffer::Init..................................................................................................................................92 ASN1BERDecodeBuffer .............................................................................................................................................93 ASN1BERDecodeBuffer::ASN1BERDecodeBuffer...............................................................................................93 ASN1BERDecodeBuffer::FindElement ..................................................................................................................93 ASN1BERDecodeBuffer::ParseTagLen ..................................................................................................................94 ASN1C V5.3 ii ASN1PERMessageBuffer............................................................................................................................................95 ASN1PERMessageBuffer::BinDump ......................................................................................................................95 ASN1PERMessageBuffer::HexDump .....................................................................................................................95 ASN1PERMessageBuffer::GetMsgLen...................................................................................................................95 ASN1PERMessageBuffer::SetTrace........................................................................................................................96 ASN1PEREncodeBuffer..............................................................................................................................................97 ASN1PEREncodeBuffer::ASN1PEREncodeBuffer ................................................................................................97 ASN1PEREncodeBuffer::GetMsgBitCnt ................................................................................................................97 ASN1PEREncodeBuffer::GetMsgCopy ..................................................................................................................98 ASN1PEREncodeBuffer::GetMsgPtr ......................................................................................................................98 ASN1PEREncodeBuffer::Init ..................................................................................................................................98 ASN1PERDecodeBuffer............................................................................................................................................100 ASN1PERDecodeBuffer::ASN1PERDecodeBuffer..............................................................................................100 ASN1CType...............................................................................................................................................................101 ASN1CType::ASN1CType....................................................................................................................................101 ASN1CType::Encode ............................................................................................................................................101 ASN1CType::Decode ............................................................................................................................................101 ASN1CType::memAlloc........................................................................................................................................102 ASN1CType::memFreeAll ....................................................................................................................................102 ASN1CBitStr .............................................................................................................................................................104 ASN1CBitStr::ASN1CBitStr .................................................................................................................................104 ASN1CBitStr::change............................................................................................................................................105 ASN1CBitStr::clear ...............................................................................................................................................106 ASN1CBitStr::set...................................................................................................................................................107 ASN1CBitStr::invert..............................................................................................................................................108 ASN1CBitStr::get ..................................................................................................................................................109 ASN1CBitStr::isSet ...............................................................................................................................................110 ASN1CBitStr::isEmpty..........................................................................................................................................110 ASN1CBitStr::size.................................................................................................................................................111 ASN1CBitStr::length .............................................................................................................................................111 ASN1CBitStr::cardinality ......................................................................................................................................111 ASN1CBitStr::getBytes .........................................................................................................................................112 ASN1CBitStr::doAnd ............................................................................................................................................112 ASN1CBitStr::doOr...............................................................................................................................................114 ASN1CBitStr::doXor.............................................................................................................................................115 ASN1CBitStr::doAndNot ......................................................................................................................................116 ASN1CBitStr::shiftLeft .........................................................................................................................................118 ASN1CBitStr::shiftRight .......................................................................................................................................118 ASN1CBitStr::unusedBitsInLastUnit ....................................................................................................................119 ASN1CBitStr::operator ASN1TDynBitStr ............................................................................................................119 ASN1CSeqOfList ......................................................................................................................................................121 ASN1CSeqOfList:: ASN1CSeqOfList ..................................................................................................................121 ASN1CSeqOfList::append.....................................................................................................................................122 ASN1CSeqOfList::insert .......................................................................................................................................122 ASN1CSeqOfList::remove ....................................................................................................................................122 ASN1CSeqOfList::removeFirst .............................................................................................................................123 ASN1CSeqOfList::removeLast .............................................................................................................................123 ASN1CSeqOfList::indexOf ...................................................................................................................................124 ASN1CSeqOfList::contains ...................................................................................................................................124 ASN1CSeqOfList::getFirst ....................................................................................................................................125 ASN1CSeqOfList::getLast.....................................................................................................................................125 ASN1CSeqOfList::get ...........................................................................................................................................125 ASN1CSeqOfList::operator[] ................................................................................................................................126 ASN1CSeqOfList::set............................................................................................................................................126 ASN1CSeqOfList::clear ........................................................................................................................................126 ASN1CSeqOfList::isEmpty ...................................................................................................................................127 ASN1CSeqOfList::size ..........................................................................................................................................127 ASN1CSeqOfList::iterator.....................................................................................................................................127 ASN1CSeqOfList::iteratorFromLast .....................................................................................................................128 ASN1C V5.3 iii ASN1CSeqOfList::iteratorFrom ............................................................................................................................128 ASN1CSeqOfListIterator...........................................................................................................................................130 ASN1CSeqOfListIterator::hasNext........................................................................................................................130 ASN1CSeqOfListIterator::hasPrev ........................................................................................................................130 ASN1CSeqOfListIterator::next..............................................................................................................................131 ASN1CSeqOfListIterator::prev .............................................................................................................................131 ASN1CSeqOfListIterator::remove.........................................................................................................................131 ASN1CSeqOfListIterator::set ................................................................................................................................132 ASN1CSeqOfListIterator::insert............................................................................................................................132 ASN1CTime ..............................................................................................................................................................134 ASN1CTime::ASN1CTime ...................................................................................................................................134 ASN1CTime::getYear............................................................................................................................................135 ASN1CTime::getMonth.........................................................................................................................................135 ASN1CTime::getDay.............................................................................................................................................135 ASN1CTime::getHour ...........................................................................................................................................136 ASN1CTime::getMinute........................................................................................................................................136 ASN1CTime::getSecond........................................................................................................................................137 ASN1CTime::getFraction ......................................................................................................................................137 ASN1CTime::getDiffHour.....................................................................................................................................138 ASN1CTime::getDiffMinute .................................................................................................................................138 ASN1CTime::getDiff.............................................................................................................................................138 ASN1CTime::getUTC ...........................................................................................................................................139 ASN1CTime::getTime ...........................................................................................................................................139 ASN1CTime::setYear ............................................................................................................................................140 ASN1CTime::setMonth .........................................................................................................................................140 ASN1CTime::setDay .............................................................................................................................................141 ASN1CTime::setHour............................................................................................................................................141 ASN1CTime::setMinute ........................................................................................................................................142 ASN1CTime::setSecond ........................................................................................................................................142 ASN1CTime::setFraction.......................................................................................................................................142 ASN1CTime::setDiffHour .....................................................................................................................................143 ASN1CTime::setDiff .............................................................................................................................................143 ASN1CTime::setDiff .............................................................................................................................................144 ASN1CTime::setUTC............................................................................................................................................144 ASN1CTime::setTime ...........................................................................................................................................145 ASN1CTime::parseString ......................................................................................................................................145 ASN1CTime::clear ................................................................................................................................................146 ASN1CTime::operator =........................................................................................................................................146 ASN1CTime::operator == .....................................................................................................................................147 ASN1CTime::operator >........................................................................................................................................147 ASN1CTime::operator <........................................................................................................................................147 ASN1CTime::operator >= .....................................................................................................................................147 ASN1CTime::operator <= .....................................................................................................................................147 ASN1CGeneralizedTime ...........................................................................................................................................148 ASN1CGeneralizedTime::ASN1CGeneralizedTime.............................................................................................148 ASN1CGeneralizedTime::getCentury ...................................................................................................................149 ASN1CGeneralizedTime::setCentury....................................................................................................................149 ASN1CUTCTime ......................................................................................................................................................150 ASN1CUTCTime::ASN1CUTCTime ...................................................................................................................150 ASN1CUTCTime::setYear ....................................................................................................................................151 Asn1NamedEventHandler .........................................................................................................................................152 Asn1NamedEventHandler::startElement ...............................................................................................................152 Asn1NamedEventHandler::endElement ................................................................................................................152 Asn1NamedEventHandler::boolValue...................................................................................................................153 Asn1NamedEventHandler::intValue......................................................................................................................153 Asn1NamedEventHandler::uIntValue ...................................................................................................................154 Asn1NamedEventHandler::bitStrValue .................................................................................................................154 Asn1NamedEventHandler::octStrValue ................................................................................................................155 Asn1NamedEventHandler::charStrValue ..............................................................................................................155 ASN1C V5.3 iv Asn1NamedEventHandler::charStrValue (16-bit version).....................................................................................156 Asn1NamedEventHandler::nullValue....................................................................................................................156 Asn1NamedEventHandler::oidValue.....................................................................................................................156 Asn1NamedEventHandler::realValue....................................................................................................................157 Asn1NamedEventHandler::enumValue .................................................................................................................157 Asn1NamedEventHandler::octStrValue ................................................................................................................158 Asn1NamedEventHandler::openTypeValue..........................................................................................................158 Asn1ErrorHandler......................................................................................................................................................160 Asn1ErrorHandler::error........................................................................................................................................160 BER RUN-TIME LIBRARY FUNCTIONS..............................................................................................................161 asn1type.h Include File ..............................................................................................................................................161 Error Constants ......................................................................................................................................................161 Tagging Value and Mask Constants ......................................................................................................................161 Sizing Constants.....................................................................................................................................................162 ASN.1 Primitive Type Definitions.........................................................................................................................162 BER/DER C Encode Functions .................................................................................................................................163 xe_setp - Set Encode Buffer Pointer ......................................................................................................................163 xe_getp - Get Encode Buffer Pointer .....................................................................................................................164 xe_tag_len - Encode Tag and Length.....................................................................................................................164 xe_boolean - Encode BOOLEAN..........................................................................................................................165 xe_integer - Encode INTEGER .............................................................................................................................165 xe_unsigned - Encode Unsigned INTEGER..........................................................................................................166 xe_bigint – Encode Big Integer..............................................................................................................................167 xe_bitstr - Encode BIT STRING ...........................................................................................................................167 xe_octstr - Encode OCTET STRING ....................................................................................................................168 xe_charstr – Encode Character String....................................................................................................................169 xe_16BitCharStr – Encode 16-bit Character String ...............................................................................................169 xe_32BitCharStr – Encode 32-bit Character String ...............................................................................................170 xe_enum - Encode ENUMERATED .....................................................................................................................171 xe_null - Encode NULL.........................................................................................................................................171 xe_objid - Encode OBJECT IDENTIFIER............................................................................................................172 xe_real – Encode Real............................................................................................................................................172 xe_OpenType - Encode Open Type.......................................................................................................................173 xe_free – Free Encoder Dynamic Memory ............................................................................................................174 xe_expandBuffer – Expand Dynamic Encode Buffer............................................................................................174 xe_memcpy – Copy Bytes to Encode Buffer .........................................................................................................175 xe_len – Encode a Length Value ...........................................................................................................................175 xe_derCanonicalSort – DER Canonical Sort .........................................................................................................176 xe_TagAndIndefLen – Encode Tag and Indefinite Length....................................................................................177 BER/DER C Decode Functions .................................................................................................................................178 xd_setp - Set Decode Buffer Pointer......................................................................................................................178 xd_tag_len - Decode Tag and Length ....................................................................................................................179 xd_match - Match Tag ...........................................................................................................................................180 xd_boolean - Decode BOOLEAN .........................................................................................................................181 xd_integer - Decode INTEGER .............................................................................................................................181 xd_unsigned - Decode Unsigned INTEGER .........................................................................................................182 xd_bigint – Decode Big Integer .............................................................................................................................183 xd_bitstr - Decode BIT STRING ...........................................................................................................................184 xd_bitstr_s - Decode BIT STRING (static)............................................................................................................184 xd_octstr - Decode OCTET STRING ....................................................................................................................185 xd_octstr_s - Decode OCTET STRING (static) ....................................................................................................186 xd_charstr – Decode Character String ...................................................................................................................187 xd_16BitCharStr – Decode 16-bit Character String...............................................................................................188 xd_32BitCharStr – Decode 32-bit Character String...............................................................................................188 xd_enum - Decode ENUMERATED.....................................................................................................................189 xd_null - Decode NULL ........................................................................................................................................190 xd_objid - Decode OBJECT IDENTIFIER ...........................................................................................................190 ASN1C V5.3 v xd_real - Decode REAL.........................................................................................................................................191 xd_OpenType - Decode Open Type ......................................................................................................................192 xd_OpenTypeExt – Decode Open Type Extension ...............................................................................................193 xd_chkend - Check for End of Context..................................................................................................................193 xd_count - Count Message Components................................................................................................................194 xd_memcpy - Copy Decoded Contents..................................................................................................................194 xd_NextElement – Move to Next Element ............................................................................................................195 xd_indeflen – Calculate Indefinite Length.............................................................................................................196 BER/DER C File Functions .......................................................................................................................................197 xdf_tag – Decode Tag from File ............................................................................................................................197 xdf_len – Decode Length from File .......................................................................................................................197 xdf_TagAndLen – Decode Tag and Length from File...........................................................................................198 xdf_ReadPastEOC – Read Past End-of-Context (EOC) Marker ...........................................................................199 xdf_ReadContents – Read Contents from File.......................................................................................................199 BER/DER C Utility Functions...................................................................................................................................201 Memory Management Functions (xu_malloc and xu_freeall) ...............................................................................201 Output Formatting Functions .................................................................................................................................203 Run-Time Error Reporting Functions ....................................................................................................................205 PER RUN-TIME LIBRARY.......................................................................................................................................209 PER C Encode Functions...........................................................................................................................................209 pe_GetMsgLen – Get Length of Encoded Message...............................................................................................209 pe_GetMsgBitCnt – Get Count of Bits in Encoded Message ................................................................................210 pe_GetMsgPtr – Get Encoded Message Pointer ....................................................................................................210 pe_bit - Encode a Single Bit Value ........................................................................................................................211 pe_bits - Encode Bit Values...................................................................................................................................211 pe_octets - Encode Octets ......................................................................................................................................212 pe_byte_align – Align Encode Buffer on a Byte Boundary...................................................................................212 pe_NonNegBinInt – Encode a Non-negative Binary Integer.................................................................................213 pe_2sCompBinInt – Encode a Two’s Complement Binary Integer.......................................................................213 pe_ConsWholeNumber – Encode a Constrained Whole Number .........................................................................214 pe_SmallNonNegWholeNumber – Encode a Small Non-negative Whole Number ..............................................214 pe_Length – Encode a Length Determinant...........................................................................................................215 pe_ConsInteger – Encode a Constrained Integer ...................................................................................................215 pe_UnconsInteger – Encode an Unconstrained Integer .........................................................................................216 pe_ConsUnsigned – Encode a Constrained Unsigned Integer ...............................................................................217 pe_UnconsUnsigned – Encode an Unconstrained Unsigned Integer .....................................................................217 pe_BigInteger – Encode Big Integer......................................................................................................................218 pe_BitString – Encode a Bit String........................................................................................................................218 pe_OctetString – Encode an Octet String ..............................................................................................................219 pe_Real – Encode Real ..........................................................................................................................................219 pe_ObjectIdentifier – Encode Object Identifier .....................................................................................................220 pe_ConstrainedString – Encode 8-bit Character String .........................................................................................220 ASN.1 8-bit Character String Encode Functions ...................................................................................................221 pe_16BitConstrainedString – Encode 16-bit Character String ..............................................................................222 pe_BMPString – Encode BMP Character String ...................................................................................................223 pe_32BitConstrainedString – Encode 32-bit Character String ..............................................................................223 pe_UniversalString – Encode 32-bit Character String ...........................................................................................224 pe_OpenType – Encode Open Type ......................................................................................................................225 pe_OpenTypeExt – Encode Open Type Extension................................................................................................225 pe_CheckBuffer – Check Encode Buffer Size.......................................................................................................226 pe_ExpandBuffer – Expand Encode Buffer...........................................................................................................226 PER C Decode Functions...........................................................................................................................................228 pd_bit - Decode a Single Bit Value........................................................................................................................228 pd_bits - Decode Bit Values ..................................................................................................................................229 pd_byte_align – Align Buffer on a Byte Boundary ...............................................................................................229 pd_ConsWholeNumber – Decode a Constrained Whole Number .........................................................................230 pd_SmallNonNegWholeNumber – Decode a Small Non-negative Whole Number..............................................230 ASN1C V5.3 vi pd_Length – Decode a Length Determinant ..........................................................................................................231 pd_ConsInteger – Decode a Constrained Integer...................................................................................................231 pd_UnconsInteger – Decode an Unconstrained Integer.........................................................................................232 pd_ConsUnsigned – Decode a Constrained Unsigned Integer...............................................................................232 pd_UnconsUnsigned – Decode an Unconstrained Unsigned Integer.....................................................................233 pd_BigInteger – Decode a Big Integer...................................................................................................................233 pd_BitString – Decode a Bit String .......................................................................................................................234 pd_DynBitString - Decode a Dynamic Bit String..................................................................................................235 pd_OctetString – Decode an Octet String ..............................................................................................................235 pd_DynOctString - Decode a Dynamic Octet String .............................................................................................236 pd_Real – Decode Real..........................................................................................................................................237 pd_ObjectIdentifier – Decode Object Identifier.....................................................................................................237 pd_ConstrainedString – Decode 8-bit Character String.........................................................................................238 ASN.1 8-bit Character String Decode Functions ...................................................................................................238 pd_16BitConstrainedString – Decode 16-bit Character String ..............................................................................239 pd_BMPString – Decode BMP Character String...................................................................................................240 pd_32BitConstrainedString – Decode 32-bit Character String ..............................................................................241 pd_UniversalString – Decode 32-bit Character String...........................................................................................241 pd_OpenType – Decode Open Type......................................................................................................................242 pd_OpenTypeExt – Decode Open Type Extension ...............................................................................................242 PER C Utility Functions ............................................................................................................................................244 Encode/Decode Context Initialization ...................................................................................................................244 Constraint Specification Functions ........................................................................................................................246 Diagnostic Printing Functions................................................................................................................................249 RUN-TIME COMMON LIBRARY ...........................................................................................................................251 Context Initialization Functions.................................................................................................................................251 rtInitContext – Initialize Context Block.................................................................................................................251 rtNewContext – Allocate New Context Block.......................................................................................................251 rtFreeContext – Free Context Block ......................................................................................................................252 Memory Management Functions ...............................................................................................................................252 rtMemAlloc – Allocate Dynamic Memory ............................................................................................................253 rtMemFree – Release Dynamic Memory ...............................................................................................................253 Diagnostic Trace Functions .......................................................................................................................................254 rtdiag – Output Trace Messagesy...........................................................................................................................254 rtSetDiag – Set Diagnostic Tracing........................................................................................................................254 Error Formatting and Print Functions ........................................................................................................................255 rtErrPrint – Print Error Information .......................................................................................................................255 rtErrLogUsingCB – Log Using Callback Function................................................................................................255 rtErrSetData – Set Error Information.....................................................................................................................256 rtErrAddParam – Add Typed Error Parameter to Error Information..........................................................257 rtErrFreeParams – Free Error Parameter Memory .................................................................................................257 Formatted Printing Functions.....................................................................................................................................259 rtBoolToString – Convert ASN.1 Boolean Value to String ...................................................................................259 rtIntToString – Convert ASN.1 Integer Value to String ........................................................................................259 rtUIntToString – Convert ASN.1 Unsigned Integer Value to String .....................................................................260 rtBitStrToString – Convert ASN.1 Bit String Value to String...............................................................................260 rtOctStrToString – Convert ASN.1 Octet String Value to String ..........................................................................261 rtOIDToString – Convert ASN.1 Object Identifier Value to String ......................................................................261 rtTagToString – Convert ASN.1 Tag to String ......................................................................................................262 rtPrint – Print ASN.1 Values to Standard Output .......................................................................................263 Object Identifier Helper Functions ............................................................................................................................264 rtSetOID – Populate Object Identifier Structure ....................................................................................................264 rtPrintOID – Print Object Identifier Structure........................................................................................................264 Linked List and Stack Utility Functions ....................................................................................................................265 rtDListInit – Initialize a Doubly Linked List Structure..........................................................................................265 rtDListAppend – Append an Item to a Doubly Linked List...................................................................................265 rtDListInsert – Insert an Item to a Doubly Linked List..........................................................................................266 ASN1C V5.3 vii rtDListInsertBefore – Insert an Item to a Doubly Linked List before specified node............................................266 rtDListInsertAfter – Insert an Item to a Doubly Linked List after specified node .................................................267 rtDListFindByIndex –Find a node in the Doubly Linked List by index ................................................................268 rtDListFindByData –Find a node in the Doubly Linked List by index..................................................................268 rtDListFindIndexByData –Find an index of node in the Doubly Linked List by data...........................................268 rtDListRemove – Remove a node from a Doubly Linked List ..............................................................................269 rtSListInit – Initialize a Singly Linked List Structure............................................................................................269 rtSListCreate – Create a Singly Linked List Structure...........................................................................................270 rtSListAppend – Append an Item to a Singly Linked List.....................................................................................270 rtStackInit – Initialize a Stack Structure ................................................................................................................271 rtStackCreate – Create a Stack Structure ...............................................................................................................271 rtStackPush – Push an Element onto the Stack ......................................................................................................272 rtStackPop – Pop an Element from the Stack ........................................................................................................272 Character String Conversion Functions .....................................................................................................................273 rtCToBMPString....................................................................................................................................................273 rtBMPToCString....................................................................................................................................................273 rtBMPToNewCString ............................................................................................................................................274 rtCToUCSString ....................................................................................................................................................274 rtUCSToCString ....................................................................................................................................................275 rtUCSToNewCString.............................................................................................................................................276 rtUCSToWCSString ..............................................................................................................................................276 rtWCSToUCSString ..............................................................................................................................................277 rtWCSToUTF8 ......................................................................................................................................................277 rtUTF8ToWCS ......................................................................................................................................................278 rtValidateUTF8 ......................................................................................................................................................278 Big integer helper functions.......................................................................................................................................280 rtBigIntInit – Initialize a big integer Structure.......................................................................................................280 rtSetStrToBigInt – Convert string to a big integer .................................................................................................280 rtSetInt64ToBigInt – Convert ASN1INT64 value to big integer...........................................................................281 rtSetBytesToBigInt – Convert sequence of octets to big integer ...........................................................................281 rtGetBigIntLen– Get big integer length .................................................................................................................282 rtGetBigInt – Copy big integer value into an octet array .......................................................................................282 rtBigIntDigitsNum – Return the approximated number of digits of the big integer ..............................................283 rtBigIntToString – Convert a big integer to a string ..............................................................................................284 rtPrintBigInt – Print big integer value to Standard Output ...................................................................................284 rtCompareBigInt – Compare two big integer values..............................................................................................285 rtBigIntCopy – Copy one big integer structure into another..................................................................................285 rtBigIntFastCopy – Fast copy of one big integer structure into another ................................................................286 APPENDIX A................................................................................................................................................................287 APPENDIX B................................................................................................................................................................289 INDEX ..........................................................................................................................................................................290 ASN1C V5.3 viii Overview of ASN1C The ASN1C code generation tool translates an Abstract Syntax Notation 1 (ASN.1) source file into computer language source files that allow ASN.1 data to be encoded/decoded. This release of the compiler includes options to generate code in three different languages: C, C++, or Java. This manual discusses the C and C++ code generation capabilities. The ASN1C Java User’s Manual discusses the Java code generation capability. Each ASN.1 module that is encountered in an ASN.1 source file results in the generation of the following two types of C/C++ language files: 1. An include (.h) file containing C/C++ typedefs and classes that represent each of the ASN.1 productions listed in the ASN.1 source file, and 2. A C/C++ source (.c or .cpp) file containing C/C++ encode and decode functions. One encode and decode function is generated for each ASN.1 production. These files, when compiled and linked with the ASN.1 low-level encode/decode function library, provide a complete package for working with ASN.1 encoded data. ASN1C works with the version of ASN.1 specified in the ITU standard X.680. It generates code for encoding/decoding data as specified in the Basic Encoding Rules (BER) published in the ITU X.690 standard and the Packed Encoding Rules (PER) published in the ITU X.691 standard. The compiler is capable of parsing all ASN.1 syntax as defined in the standards. Its mission is to get to the base types that are the basis for encoding and decoding the messages that the specification defines. It will skip over all other definitions and related ‘fluff’. This release of the compiler contains a special executable (asn1c90.exe) that backward compatible with deprecated features from the older X.208 and X.209 standards. These include the ANY data type and unnamed fields in SEQUENCE, SET, and CHOICE types. This version can also parse type syntax from common macro definitions such as ROSE. ASN1C V5.3 1 < this page intentionally left blank > ASN1C V5.3 2 Using the Compiler Running the Compiler To test if the compiler was successfully installed, enter asn1c with no parameters as follows (note: if you have not updated your PATH variable, you will need to enter the full pathname): asn1c You should observe the following display (or something similar): ASN1C Compiler, Version 5.3x Copyright (c) 1997-2002 Objective Systems, Inc. All Rights Reserved. Usage: asn1c options options: -hfile -cfile -ber -der -per -trace -c -c++ -java -events -config -nodecode -noencode -noIndefLen -compact -warnings -o -I -pkgpfx -pkgname -list -compat ASN.1 source file name C or C++ header (.h) filename (default is .h) C or C++ source (.c or .cpp) filename (default is .c) Generate print routines and write to filename generate BER encode/decode functions generate DER encode/decode functions generate PER encode/decode functions add trace diag msgs to generated code generate C code generate C++ code generate Java code generate code to invoke event handlers specify configuration file do not generate decode functions do not generate encode functions do not generate indefinite length tests generate compact code Output compiler warning messages Output file directory Import file directory Java package prefix Java package name generate listing generate code compatible with previous compiler version. format is x.x (for example, 5.2) This indicates that to use the compiler, at a minimum, an ASN.1 source file must be provided. The source file specification can be a full pathname or only what is necessary to qualify the file. If directory information is not provided, the user's current default directory is assumed. If a file extension is not provided, the default extension ".asn" is appended to the name. The source file must contain ASN.1 productions that define ASN.1 types and/or value specifications. This file must strictly adhere to the syntax specified in ASN.1 standard ITU X.680.. The asn1c90 executable should be used to parse files based on the 1990 ASN.1 standard (x.208) or that contain references to ROSE macro specifications.. ASN1C V5.3 3 The following table lists all of the command line options and what they are used for: ASN1C V5.3 4 Option -hfile Argument Description This option allows the specification of a header (.h) file to which all of the generated typedefs and function prototypes will be written. If not specified, the default is .h where is the name of the module from the ASN.1 source file. -cfile This option allows the specification of a C or C++ source (.c or .cpp) file to which all of the generated encode/decode functions will be written. If not specified, the default is .c where is the name of the module from the ASN.1 source file. -print This option allows the specification of a C or C++ source (.c or .cpp) file to which generated print functions will be written. Print functions are debug functions that allow the contents of generated type variables to be written to stdout. They are optional: if –print is not specified, no print functions will be generated. The argument to this option is also optional. If not specified, the print functions will be written to Print.c where is the name of the module from the ASN.1 source file. -ber None This option instructs the compiler to generate functions that implement the Basic Encoding Rules (BER) Rulesas specified in the ASN.1 standards. -der None This option instructs the compiler to generate functions that implement the Distinguished Encoding Rules (DER) as specified in the ASN.1 standards. -per None This option instructs the compiler to generate functions that implement the Packed Encoding Rules (PER) as specified in the ASN.1 standards. -trace None This option is used to tell the compiler to add trace diagnostic messages to the generated code. These messages cause printf statements to be added to the generated code to print entry and exit information into the generated functions. This is a debugging option that allows encode/decode problems to be isolated to a given production processing function. Once the code is debugged, this option should not be used as it adversely affects performance. -java None Generate Java source code. -c None Generate C source code. -c++ None Generate C++ source code. -events None Generate extra code to invoke user defined event and error handler callback methods (see the Event Handlers section). -config This option is used to specify the name of a file containing configuration information for the source file being parsed. A full discussion of the contents of a configuration file is provided in a later section. -noencode None This option suppresses the generation of encode functions. . -nodecode None This option suppresses the generation of decode functions. -noIndefLen None This option instructs the compiler to omit indefinite length tests in ASN1C V5.3 5 generated decode functions. These tests result in the generation of a large amount of code. If you know that your application only uses definite length encoding, this option can result in a much smaller code base size. -compact None This option instructs the compiler to generate more compact code at the expense of some constraint and error checking. This is an optimization option that should be used after an application is thoroughly tested. -warnings None Output information on compiler generated warnings. . -o This option is used to specify the name of a directory to which all of the generated files will be written. -I This option is used to specify a directory that the compiler will search for ASN.1 source files for IMPORT items. Multiple –I qualifiers can be used to specify multiple directories to search. -pkgpfx This is a Java option for adding a prefix in front of the assigned Java package name. By default, the Java package name is set to the module name. If the package is embedded within a hierarchy, this option can be used to set the other directory names that must be added to allow Java to find the .class files. -pkgname This is a Java option that allows the entire Java package name to be changed. Instead of the module name, the full name specified using this option will be used. This option cannot be used in conjunction with – pkgpfx option. -list None Generate listing. This will dump the source code to the standard output device as it is parsed. This can be useful for finding parse errors. -compat Generate code compatible with an older version of the compiler. The compiler will attempt to generate code more closely aligned with the given previous release of the compiler. is specified as x.x (for example, -compat 5.2) Several options from the 5.0x release have been decommissioned and replaced with entries in the configuration file. These options include –dynamic, -pdu, and –enum_prefix. See the section on the configuration file to find the equivalent configuration settings for these options. Compiling and Linking Generated Code C/C++ source code generated by the compiler can be compiled using any ANSI standard C or C++ compiler. The only additional option that must be set is the inclusion of the ASN.1 C/C++ header file include directory with the –I option. When linking a program with compiler generated code, it is necessary to include the ASN.1 run-time library. On Windows systems, the name of this file is either asn1ber.lib or asn1per.lib depending on whether BER or PER source-code generation was specified; on UNIX, the library names are libasn1ber.a and libasn1per.a respectively. The library file can be found in the lib subdirectory. For UNIX, the –L switch should be used to point to the subdirectory path and –lasn1ber or –lasn1per used to link with the library. For Windows, the –LIBPATH switch should be used to specify the library path. ASN1C V5.3 6 Windows systems also include dynamic-link library (dll) versions of the library. These are located in the dll subdirectory. To use them, link with the version of the asn1ber.lib or asn1per.lib file that is contained in the dll subdirectory. See the makefile in any of the sample subdirectories of the distribution for an example of what must be included to build a program using generated source code. Porting Run-time Code to Other Platforms The standard version of the compiler includes ANSI-standard source code for the base run-time libraries. This code can be used to build binary versions of the run-time libraries for other operating environments. Included with the source code is a portable makefile that can be used to build the libraries on the target platform with minimal changes. All platform-specific items are isolated in the platform.mk file in the root directory of the installation. The procedure to port the run-time code to a different platform is as follows (note: this assumes common UNIX or GNU compilation utilities are in place on the target platform). ASN1C V5.3 7 1. Create a directory tree containing a root directory (the name does not matter) and lib, src, rtsrc, and rtbuild subdirectories. The tree should be as follows: root lib rtsrc src rtbuild 2. Copy the files ending in extension “.mk” from the root directory of the installation to the root directory of the target platform (note: if going from DOS to UNIX or vice-versa, FTP the files in ASCII mode to ensure lines are terminated properly). 3. Copy all files from the src and rtsrc subdirectories from the installation to the src and rtsrc directories on the target platform (note: if going from DOS to UNIX or vice-versa, FTP the files in ASCII mode to ensure lines are terminated properly). 4. Copy the makefile from the rtbuild subdirectory of the installation to the rtbuild subdirectory on the target platform (note: if going from DOS to UNIX or vice-versa, FTP the files in ASCII mode to ensure lines are terminated properly). 5. Edit the platform.mk file in the root subdirectory and modify the compilation parameters to fit those of the compiler of the target system. In general, the following parameters will need to be adjusted: CC CCC CFLAGS_ C compiler executable name C++ compiler executable name Flags that should be specified on the C or C++ command line The platform.w32 and platform.gnu files in the root directory of the installation are sample files for Windows 32 (Visual C++) and GNU compilers respectively. Either of these can be renamed to platform.mk for building in either of these environments. 6. Invoke the makefile in the rtbuild subdirectory. If all parameters were set up correctly, the result should be binary library files created in the lib subdirectory. ASN1C V5.3 8 Compiler Configuration File In addition to command line options, a configuration file can be used to specify compiler options. These options can be applied not only globally but also to specific modules and productions. A simple form of the Extended Markup Language (XML) is used to format items in the file. This language was chosen because it is fairly well known and provides a natural interface for representing hierarchical data such as the structure of ASN.1 modules and productions. The use of an external configuration file was chosen over embedding directives within the ASN.1 source itself due to the fact that ASN.1 source versions tend to change frequently. An external configuration file can be reused with a new version of an ASN.1 module, but internal directives would have to be reapplied to the new version of the ASN.1 code. At the outer level of the markup is the tag pair. Within this tag pair, the specification of global items and modules can be made. Global items are applied to all items in all modules. An example would be the qualifier. A storage class such as dynamic can be specified and applied to all productions in all modules. This will cause dynamic storage (pointers) to be used to any embedded structures within all of the generated code to reduce memory consumption demands. The specification of a module is done using the tag pair. This tag pair can only be nested within the top-level section. The module is identified by using the required tag pair. Other attributes specified within the section apply only to that module and not to other modules specified within the specification. A complete list of all module attributes is provided in the table at the end of this section. The specification of an individual production is done using the tag pair. This tag pair can only be nested within a section. The production is identified by using the required tag pair. Other attributes within the production section apply only to the referenced production and nothing else. A complete list of attributes that can be applied to individual productions is provided in the table at the end of this section. When an attribute is specified in more than one section, the most specific application is always used. For example, assume a qualifier is used within a module specification to specify a prefix for all generated types in the module and another one is used to a specify a prefix for a single production. The production with the type prefix will be generated with the type prefix assigned to it and all other generated types will contain the type prefix assigned at the module level. Values in the different sections can be specified in one of the following ways: 1. Using the value form. This assigns the given value to the given name. For example, the following would be used to specify the name of the “H323-MESSAGES” module in a module section:H323-MESSAGES 2. Flag variables that turn some attribute on or off would be specified using a singleentry. For example, to specify a given production is a PDU, the following would be specified in a production section: 3. An attribute list can be associated with some items. This is normally used as a shorthand form for specifying lists of names. For example, to specify a list of type names to be included in the generated code for a particular module, the following would be used: The following are some examples of configuration specifications: ASN1C V5.3 9 This specification indicates dynamic storage should be used in all places where its use would result in significant memory usage savings within all modules in the specified source file. dynamic This specification applies to module ‘H323-MESSAGES’ in the source file being processed. For IMPORT statements involving this module, it indicates that the source file ‘h225.asn’ should be searched for specifications. It also indicates that when C or C++ types are generated, they should be prefixed with the ‘H225’. This can help prevent name clashes if one or more modules are involved and they contain productions with common names. The following tables specify the list of attributes that can be applied at all of the different levels: global, module, and individual production: Global Level These attributes can be applied at the global level by including them within the … H323-MESSAGES h225.asn H225 section: Name Values dynamic, static, or list keyword. Description If dynamic, it indicates that dynamic storage (i.e., pointers) should be used everywhere within the generated types where use could result in lower memory consumption. These places include the array element for sized SEQUENCE OF/SET OF types and optional elements within SEQUENCE or SET constructs. If static (the default), it indicates static type should be used in these places. In general, static types are easier to work with. If list, a linked-list type will be used for SEQUENCE OF/SET OF constructs instead of an array type. Module Level These attributes can be applied at the module level by including them within a section: Name Values module name Description This attribute identifies the module to which this section applies. It is required. ASN.1 type or values names are specified as an attribute list This item allows a list of ASN.1 types and/or values to be included in the generated code. By default, the compiler generates code for all types and values within a specification. This allows the user to reduce the size of the generated code base by selecting only a subset of the types/values in a specification for compilation. ASN1C V5.3 10 Note that if a type or value is included that has dependent types or values (for example, the element types in a SEQUENCE, SET, or CHOICE), all of the dependent types will be automatically included as well. ASN.1 module name(s) specified as an attribute list. This form of the include directive tells the compiler to only include types and/or values in the generated code that are imported by the given module(s). ASN.1 type or values names are specified as an attribute list This item allows a list of ASN.1 types and/or values to be excluded in the generated code. By default, the compiler generates code for all types and values within a specification. This is generally not as useful as in include directive because most types in a specification are referenced by other types. If an attempt is made to exclude a type or value referenced by another item, the directive will be ignored. dynamic, static, or list keyword. The definition is the same as for the global case except that the specified storage type will only be applied to generated C and C++ types from the given module. source file name Indicates the given module is contained within the given ASN.1 source file. This is used on IMPORTs to instruct the compiler where to look for imported definitions. This replaces the module.txt file used in previous versions of the compiler to accomplish this function. prefix text This is used to specify a prefix that will be applied to all generated C and C++ typedef names (note: for C++, the prefix is applied after the standard ‘ASN1T_’ prefix). This can be used to prevent name clashes if multiple modules are involved in a compilation and they all contain common names. prefix text This is used to specify a prefix that will be applied to all generated enumerated identifiers within a module. This can be used to prevent name clashes if multiple modules are involved in a compilation. (note: this attribute is normally not needed for C++ enumerated identifiers because they are already wrapped in a structure to allows the type name to be used as an additional identifier). prefix text This is used to specify a prefix that will be applied to all generated value constants within a module. This can be used to prevent name clashes if multiple modules are involved that use a common name for two or more different value declarations. n/a Indicates that this module contains no PDU definitions. This is normally true in modules that are imported to get common type definitions (for example, InformationFramework). This will prevent the C++ version of the compiler from generating any control class definitions for the types in the module. Production Level These attributes can be applied at the production level by including them within a section: ASN1C V5.3 11 Name Values module name Description This attribute identifies the module to which this section applies. It is required. dynamic, static, or list keyword. The definition is the same as for the global case except that the specified storage type will only be applied to the generated C or C++ type for the given production. prefix text This is used to specify a prefix that will be applied to all generated C and C++ typedef names (note: for C++, the prefix is applied after the standard ‘ASN1T_’ prefix). This can be used to prevent name clashes if multiple modules are involved in a compilation and they all contain common names. prefix text This is used to specify a prefix that will be applied to all generated enumerated identifiers within a module. This can be used to prevent name clashes if multiple modules are involved in a compilation. (note: this attribute is normally not needed for C++ enumerated identifiers because they are already wrapped in a structure to allows the type name to be used as an additional identifier). n/a This is a flag variable (an ‘empty element’ in XML terminology) that specifies that this production will be used to store an integer larger than the C or C++ int type on the given system (normally 32 bits). A C string type (char*) will be used to hold a textual representation of the value. This qualifier can be applied to either an integer or constructed type. If constructed, all integer elements within the constructed type are flagged as big integers. ASN1C V5.3 n/a This is a flag variable that specifies that this production represents a Protocol Data Unit (PDU). This is defined as a production that will be encoded or decoded from within the application code. This attribute only makes a difference in the generation of C++ classes. Control classes that are only used in the application code are only generated for types with this attribute set. 12 Compiler Error Reporting Errors that can occur when generating source code from an ASN.1 source specification take two forms: syntax errors and semantics errors. Syntax errors are errors in the ASN.1 source specification itself. These occur when the rules specified in the ASN.1 grammar are not followed. ASN1CPP will flag these types of errors with the error message ‘Syntax Error’ and abort compilation on the source file. The offending line number will be provided. The user can re-run the compilation with the ‘-l’ flag specified to see the lines listed as they are parsed. This can be quite helpful in tracking down a syntax error. The most common types of syntax errors are as follows: • Invalid case on identifiers: module name must begin with an uppercase letter, productions (types) must begin with an uppercase letter, and element names within constructors (SEQUENCE, SET, CHOICE) must begin with lowercase letters. • Elements within constructors not properly delimited with commas: either a comma is omitted at the end of an element declaration, or an extra comma is added at the end of an element declaration before the closing brace. • Invalid special characters: only letters, numbers, and the hyphen (-) character are allowed. C programmers tend to like to use the underscore character (_) in identifiers. This is not allowed in ASN.1. Conversely, C does not allow hyphens in identifiers. To get around this problem, ASN1CPP converts all hyphens in an ASN.1 specification to underscore characters in the generated code. Semantics errors occur on the compiler back-end as the code is being generated. In this case, parsing was successful, but the compiler does not know how to generate the code. These errors are flagged by embedding error messages directly in the generated code. The error messages always begin with an identifier with the prefix ‘%ASN-‘, so a search can be done for this string in order to find the locations of the errors. A single error message is output to stderr after compilation on the unit is complete to indicate error conditions exist. ASN1C V5.3 13 Generated C/C++ Source Code Header (.h) File The generated C or C++ include file contains a section for each ASN.1 production defined in the ASN.1 source file. Different items will be generated depending on whether the selected output code is C or C++. In general, C++ will add some additional items (such as a control class definition) onto what is generated for C. The following items are generated for each ASN.1 production: • • • • • • • • Tag value constant Choice tag constants (CHOICE type only) Named bit index and mask constants (BIT STRING type only) Enumerated type option values (ENUMERATED or INTEGER type only) C type definition Encode function prototype Decode function prototype C++ class definition which ‘wraps’ an instance of the production type variable and associated encode/decode functions. In some cases, the compiler may generate additional methods specific to a particular production type. (C++ only) A sample section from a C header file is as follows: /**************************************************************/ /* */ /* EmployeeNumber */ /* */ /**************************************************************/ #define TV_EmployeeNumber typedef ASN1INT TM_APPL|TM_PRIM|2 EmployeeNumber; int asn1E_EmployeeNumber (ASN1CTXT* ctxt_p, ASN1T_EmployeeNumber *object_p, ASN1TagType tagging); int asn1D_EmployeeNumber (ASN1CTXT* ctxt_p, ASN1T_EmployeeNumber *object_p, ASN1TagType tagging, int length); This corresponds to the following ASN.1 production specification: EmployeeNumber ::= [APPLICATION 2] IMPLICIT INTEGER In this definition, TV_EmployeeNumber is the tag constant. Doing a logical OR on the class, form, and identifier fields forms this constant. This constant can be used in a comparison operation with a tag parsed from a message. The ‘typdef ASN1INT EmployeeNumber’ declares EmployeeNumber to be of an integer type (note: ASN1INT and other primitive type definitions can be found in the asn1type.h header file). asn1E_EmployeeNumber and asn1D_EmployeeNumber are function prototypes for the encode and decode functions respectively. These are BER function prototypes. If the –per switch is used, PER function prototypes are generated. The PER prototypes begin with the prefix ‘asn1PE_’ and ‘asn1PD_’ for encoder and decoder respectively. ASN1C V5.3 15 A sample section from a C++ header file for the same production is as follows: /**************************************************************/ /* */ /* EmployeeNumber */ /* */ /**************************************************************/ #define TV_EmployeeNumber typedef ASN1INT TM_APPL|TM_PRIM|2 ASN1T_EmployeeNumber; class ASN1C_EmployeeNumber : public ASN1CType { public: ASN1T_EmployeeNumber& msgData; ASN1C_EmployeeNumber (ASN1MessageBuffer& msgBuf, ASN1T_EmployeeNumber& data); int Encode (); int Decode (); } ; int asn1E_EmployeeNumber (ASN1CTXT* ctxt_p, ASN1T_EmployeeNumber *object_p, ASN1TagType tagging); int asn1D_EmployeeNumber (ASN1CTXT* ctxt_p, ASN1T_EmployeeNumber *object_p, ASN1TagType tagging, int length); Note the two main differences between this and the C version: 1. The use of the ‘ASN1T_’ prefix on the type definition. The C++ version uses the ‘ASN1T_’ prefix for the typedef and the ‘ASN1C_’ prefix for the control class definition. 2. The inclusion of the ‘ASN1C_EmployeeNumber’ control class. ASN1C_EmployeeNumber is the control class declaration. The purpose of the control class is to provide a linkage between the message buffer object and the ASN.1 typed object containing the message data. The class provides methods such as Encocde and Decode for encoding and decoding the contents to the linked objects. It also provides other utility methods to make populating the typed variable object easier. ASN1C always adds an ASN1C_ prefix to the production name to form the class name. Most generated classes are derived from the standard ASN1CType base class defined in asn1Message.h. The following ASN.1 types cause code to be generated from different base classes: • BIT STRING – The generated control class is derived from the ASN1CBitStr class • SEQUENCE OF or SET OF with linked list storage – The generated control class is derived from the ASN1CSeqOfList base class. These intermediate classes are also derived from the ASN1CType base class. Their purpose is the addition of functionality specific to the given ASN.1 type. For example, the ASN1CBitStr control class provides methods for setting, clearing and testing bits in the referenced bit string variable. In the generated control class, a public msgData variable reference of the generated type is declared. The constructor takes two arguments – an Asn1MessageBuffer object reference and a reference to a variable of the data type to be encoded or decoded. The message buffer object is a work buffer object for encoding or decoding. The data type reference is a reference to the ‘ASN1T_’ variable that was generated for the data type. ASN1C V5.3 16 Encode and Decode methods are declared that wrap the respective compiler generated C encode and decode functions. If the –print function command line argument was used, a Print method is also generated to wrap the corresponding C print function. The equivalent C and C++ type definitions for each of the various ASN.1 types follow. BOOLEAN The ASN.1 BOOLEAN type is converted into a C type named "ASN1BOOL". In the global include file "asn1type.h", ASN1BOOL is defined to be an "unsigned character". ASN.1 production: ::= BOOLEAN Generated C code: typedef ASN1BOOL ; Generated C++ code: typedef ASN1BOOL ASN1T_ ; For example, if “B ::= [PRIVATE 10] BOOLEAN” was defined as an ASN.1 production, the generated C type definition would be “typedef ASN1BOOL B”. Note that the tag information is not represented in the type definition, this is handled within the generated encode/decode functions. Note that the only difference between the C and C++ mapping is the addition of the ‘ASN1T_’ prefix on the C++ type. INTEGER The ASN.1 INTEGER type is converted into a C type named either "ASN1INT" or “ASN1UINT”. In the global include file "asn1type.h", ASN1INT is defined to be an "int”, ASN1UINT is defined to be an “unsigned int”. ASN.1 production: ::= INTEGER Generated C code: typedef ASN1INT ; Generated C++ code: typedef ASN1INT ASN1T_ ; The ASN1INT type represents a signed integer number, ASN1UINT represents an unsigned integer number. ASN1UINT is used if a value range constraint on a production specification exceeds the maximum value that can be stored in a signed integer. An example of this would be the Counter production in the SNMP SMI specification: Counter ::= [APPLICATION 1] IMPLICIT INTEGER (0..4294967295) This would cause the following typedef to be generated: typedef ASN1UINT Counter; Large Integer Support In C and C++, the maximum size for an integer type is normally 32 bits (or 64 bits on some newer, 64-bit machines). ASN.1 has no such limitation on integer sizes and some applications (security key values for example) demand larger sizes. In order to accommodate these types of applications, the ASN1C compiler allows an integer to be declared a “big integer” via a configuration file variable (the setting is used to do this – see the section describing the configuration file for full details). When the compiler detects this setting, it will declare the integer to be a character string variable instead of a C int or unsigned ASN1C V5.3 17 int type. The character string would then be populated with a character string representation of the value to be encoded. Only hexadecimal string representations of the integer value are supported in this release. For example, the following INTEGER type might be declared in the ASN.1 source file: SecurityKeyType ::= [APPLICATION 2] INTEGER Then, in a configuration file used with the ASN.1 definition above, the following declaration can be made: This will cause the compiler to generate the following type declaration: typedef ASN1ConstCharPtr SecurityKeyType The ASN1ConstCharPtr type is declared to be a ‘char*’ type for C and a ‘const char*’ type for C++ in the asn1type.h header file. The SecurityKeyType variable can now be populated with a hexadecimal string for encoding such as the following: SecurityKeyType secKey = “0xfd09874da875cc90240087cd12fd”; Note that in this definition the ‘0x’ prefix is required to identify the string as containing hexadecimal characters. On the decode side, the decoder will populate the variable with the same type of character string after decoding. BIT STRING The ASN.1 BIT STRING type is converted into a C or C++ structured type containing an integer to hold the number of bits and an array of unsigned characters ("OCTETs") to hold the bit string contents. The number of bits integer specifies the actual number of bits used in the bit string and takes into account any unused bits in the last byte. The type definition of the contents field depends on how the bit string is specified in the ASN.1 definition. If a size constraint is used, a static array is generated; otherwise, a pointer variable is generated to hold a dynamically allocated string. The decoder will automatically allocate memory to hold a parsed string based on the received length of the string. In the static case, the length of the character array is determined by adjusting the given size value (which represents the number of bits) into the number of bytes required to hold the bits. Dynamic BIT STRING ASN.1 production: SecurityKeyType ::= BIT STRING Generated C code: typedef ASN1DynBitStr ; Generated C++ code: typedef ASN1TDynBitStr ASN1T_ ; In this case, different base types are used for C and C++. The difference between the two is the C++ version includes constructors that make setting the value a bit easier. The ASN1DynBitStr type (i.e., the type used in the C mapping) is defined in the asn1type.h header file as follows: ASN1C V5.3 18 typedef struct ASN1DynBitStr { ASN1UINT numbits; ASN1OCTET* data; } ASN1TDynBitStr; The ASN1TDynBitStr type is defined in the asn1CppTypes.h header file as follows: typedef struct ASN1TDynBitStr { ASN1UINT numbits; ASN1OCTET* data; // ctors ASN1TDynBitStr () : numbits(0) {} ASN1TDynBitStr (ASN1UINT _numbits, ASN1OCTET* _data); } ASN1TDynBitStr; Static (sized) BIT STRING ASN.1 production: ::= BIT STRING (SIZE ( )) Generated C code: typedef struct { int numbits; ASN1OCTET data[ *]; } ; Generated C++ code: typedef struct { int numbits; ASN1OCTET data[ *]; // ctors ASN1T_ (); ASN1T_ (ASN1UINT _numbits, ASN1OCTET* _data); } ASN1T_ ; * = (( - 1)/8) + 1 For example, the following ASN.1 production: BS ::= [PRIVATE 220] BIT STRING (SIZE (18)) Would translate to the following C typedef: typedef struct ASN1T_BS { ASN1UINT numbits; ASN1OCTET data[3]; } ASN1T_BS; In this case, three octets would be required to hold the 18 bits: eight in the first two bytes, and two in the third. Note that for C++, the compiler generates special constructors and assignment operators to make populating a structure easier. In this case, two constructors were generated: a default constructor and one that takes numbits and data as arguments. Named Bits In the ASN.1 standard, it is possible to define an enumerated bit string that specifies named constants for different bit positions. ASN1C provides support for this type of construct by generating symbolic constants ASN1C V5.3 19 that can be used to set, clear, or test these named bits. These symbolic constants are in the form of a byte index and a bit mask. In addition, generated C++ code contains an enumerated constant added to the control class with an entry for each of the bit numbers. These entries can be used in calls to the methods of the ASN1CBitStr class to set, clear, and test bits. Bits are defined in order from left to right in a bit string. The starting bit number is zero. Therefore, a bit string containing one set bit would result in a single octet value of 0x80 (left most bit set). If this bit were named, the compiler would generate a byte index constant of 0, and a bit mask constant of 0x80. The byte index would be used to access the specific octet in the octet array. The bit mask would then be used to access the bit using a logical bit operator. For example, the following ASN.1 production: NamedBS ::= BIT STRING { bitOne(1), bitTen(10) } Would translate to: /* Named bit constants */ #define #define #define #define BitMbitOne BytXbitOne BitMbitTen BytXbitTen 0x40 0 0x20 1 /* Type definitions */ typedef struct ASN1T_NamedBS { ASN1UINT numbits; ASN1OCTET data[2]; } NamedBS; The named bit constants would be used to access the data array within the ASN1T_NamedBS type. The named bit ‘bitOne’ could be set with the following code: NamedBS bs; memset (&bs, 0, sizeof(bs)); bs.data[BytXbitOne] |= BitMbitOne; The statement to clear the bit would be as follows: bs.data[BytXbitOne] &= ~BitMbitOne; Finally, the bit could be tested using the following statement: bs.data[BytXbitOne] & BitMbitOne Note that the compiler generated a fixed length data array for this specification. It did this because the maximum size of the string is known due to the named bits – it must only be large enough to hold the maximum valued named bit constant. ASN1CBitStr Control Class When C++ code generation is specified, a control class is generated for operating on the target bit string. This class is derived from the ASN1CBitStr class. This class contains methods for operating on bits within the string. Objects of this class can also be declared inline to make operating on bits within other ASN.1 constructs easier. For example, in a SEQUENCE containing a bit string element the generated type will contain a public member variable containing the ‘ASN1T’ type that holds the message data. If one wanted to operate on the bit string contained within that element, they could do so by using the ASN1CBitStr class inline as follows: ASN1C V5.3 20 ASN1CBitStr bs ( . ); bs.set (0); In this example, would represent a generated SEQUENCE variable type and would represent a bit string element within this type. See the ASN1CBitStr in the C++ Run-Time Classes section for details on all of the methods available in this class. OCTET STRING The ASN.1 OCTET STRING type is converted into a C structured type containing an integer to hold the number of octets and an array of unsigned characters ("OCTETs") to hold the octet string contents. The number of octets integer specifies the actual number of octets in the contents field. The allocation for the contents field depends on how the octet string is specified in the ASN.1 definition. If a size constraint is used, a static array of that size is generated; otherwise, a pointer variable is generated to hold a dynamically allocated string. The decoder will automatically allocate memory to hold a parsed string based on the received length of the string. For C++, constructors and assignment operators are generated to make assigning variables to the structures easier. In addition to the default constructor, a constructor is provided for string or binary data. An assignment operator is generated for direct assignment of a null-terminated string to the structure (note: this assignment operator copies the null terminator at the end of the string to the data). Dynamic OCTET STRING ASN.1 production: ::= OCTET STRING Generated C code: typedef ASN1DynOctStr ; Generated C++ code: typedef ASN1TDynOctStr ASN1T_ ; In this case, different base types are used for C and C++. The difference between the two is the C++ version includes constructors and assignment operators that make setting the value a bit easier. The ASN1DynOctStr type (i.e., the type used in the C mapping) is defined in the asn1type.h header file as follows: typedef struct ASN1DynOctStr { ASN1UINT numbits; ASN1OCTET* data; } ASN1TDynBitStr; The ASN1TDynOctStr type is defined in the asn1CppTypes.h header file and has the following definition: typedef struct ASN1TDynOctStr { ASN1UINT numocts; ASN1OCTET* data; // ctors ASN1TDynOctStr (); ASN1TDynOctStr (ASN1UINT _numocts, ASN1OCTET* _data); ASN1TDynOctStr (char* cstring); // assignment operators ASN1TDynOctStr& operator= (char* cstring) } ASN1TDynOctStr; ASN1C V5.3 21 Static (sized) OCTET STRING ASN.1 production: ::= OCTET STRING (SIZE ( )) Generated C code: typedef struct { ASN1UINT numocts; ASN1OCTET data[ ]; } ; Generated C++ code: typedef struct { ASN1UINT numocts; ASN1OCTET data[ ]; // ctors ASN1T_ (); ASN1T_ (ASN1UINT _numocts, ASN1OCTET* _data); ASN1T_ (char* cstring); // assignment operators ASN1T_ & operator= (char* cstring); } ASN1T_ ; ENUMERATED The ASN.1 ENUMERATED type is converted into different types depending on whether C or C++ code is being generated. The C mapping is either a C enum or integer type depending on whether or not the ASN.1 type is extensible or not. The C++ mapping adds a struct wrapper around this type to provide a namespace to aid in making the enumerated values unique across all modules. C Mapping ASN.1 production: ::= ENUMERATED ( ( ), ( ), ...) Generated code: typedef enum { id1 = val1, id2 = val2, ... } The compiler will automatically generate a new identifier value if it detects a duplicate within the source specification. The format of this generated identifier is ‘id_n’ where id is the original identifier and n is a sequential number. The compiler will output an informational message when this is done. A configuration setting is also available to further disambiguate duplicate enumerated item names. This is the “enum prefix” setting that is available at both the module and production levels. For example, the following would cause the prefix “h225” to be added to all enumerated identifiers within the H225 module: C++ Mapping ASN1C V5.3 22 ASN.1 production: H225 h225 ::= ENUMERATED ( ( ), ( ), ...) Generated code: struct { enum Root { id1 = val1, id2 = val2, ... } [ enum Ext { extid1 = extval1, … } ] } ; typedef ::Root ASN1T_ The struct type provides a namespace for the enumerated elements. This allows the same enumerated constant names to be used in different productions within the ASN.1 specification. An enumerated item is specified in the code using the :: form. Every generated definition contains a ‘Root’ enumerated specification and, optionally, an ‘Ext’ specification. The ‘Root’ specification contains the root elements of the type (or all of the elements if it is not an extended type), and the ‘Ext’ specification contains the extension enumerated items. The form of the typedef following the struct specification depends on whether or not the enumerated type contains an extension marker or not. If a marker is present, it means the type can contain values outside the root enumeration. In this case, an ASN1UINT is used in the typedef; otherwise, the Root section of the enumeration is used to define the type. NULL The ASN.1 NULL type does not generate an associated C or C++ type definition. OBJECT IDENTIFIER The ASN.1 OBJECT IDENTIFIER type is converted into a C or C++ structured type to hold the subidentifier values that make up the object identifier. ASN.1 production: ::= OBJECT IDENTIFIER Generated C code: typedef ASN1OBJID ; Generated C++ code: typedef ASN1TObjId ASN1T_ ; In this case, different base types are used for C and C++. The difference between the two is the C++ version includes constructors and assignment operators that make setting the value a bit easier. The ASN1OBJID type (i.e., the type used in the C mapping) is defined in asn1type.h to be the following: typedef struct { ASN1UINT numids; /* number of subidentifiers */ ASN1UINT subid[ASN_K_MAXSUBIDS]; /* subidentifier values */ } ASN1OBJID; ASN1C V5.3 23 The constant "ASN_K_MAXSUBIDS" specifies the maximum number of sub-identifiers that can be assigned to a value of the type. This constant is set to 128 as per the ASN.1 standard. The value of this constant can be changed to a lower number for applications with restricted memory requirements. The ASN1TObjId type used in the C++ mapping is defined in Asn1CppTypes.h as follows: struct EXTERN ASN1TObjId { ASN1UINT numids; ASN1UINT subid[ASN_K_MAXSUBIDS]; ASN1TObjId () : numids(0) {} ASN1TObjId (ASN1OCTET _numids, const ASN1USINT* _subids); ASN1TObjId (const ASN1OBJID& oid); ASN1TObjId (const ASN1TObjId& oid); void operator= (const ASN1OBJID& rhs); void operator= (const ASN1TObjId& rhs); } ; The definition is the same as the C type with the addition of the constructors and assignment operators. Note that a constructor and assignment operator are overloaded to use the C ASN1OBJID type. That is because value assignments are generated using the ASN1OBJID type so these methods allow direct assignment of these generated values to an object of this type. REAL The ASN.1 REAL type is mapped to the C type "ASN1REAL". In the global include file "asn1type.h", ASN1REAL is defined to be a "double”. ASN.1 production: ::= REAL Generated C code: typedef ASN1REAL ; Generated C++ code: typedef ASN1REAL ASN1T_ ; SEQUENCE The mapping for the ASN.1 SEQUENCE type for C and C++ is identical with the exception of: 1. The C++ type having the ‘ASN1T_’ prefix, and 2. The C++ type may have a constructor to initialize an optional bit mask (see the subsection on optional elements). This section shows the C mapping. The C++ mapping is the same with the addition of the ‘ASN1T_’ prefix on each of the type names. An ASN.1 SEQUENCE is a constructed type consisting of a series of element definitions. These elements can be of any ASN.1 type including other constructed types. For example, it is possible to nest a SEQUENCE definition within another SEQUENCE definition as follows: A ::= SEQUENCE { x SEQUENCE { a1 INTEGER, a2 BOOLEAN }, y OCTET STRING SIZE (10) } ASN1C V5.3 24 In this example, the production has two elements – x and y. The nested SEQUENCE x has two additional elements – a1 and a2. The ASN1C compiler first recursively pulls all of the embedded constructed elements out of the SEQUENCE and forms new temporary types. The name of the temporary types are of the form _ _ _ … . For example, in the definition above, two temporary types would be generated: A_x and A_y (A_y is generated because a static OCTET STRING maps to a C++ struct type). The general form is as follows: ASN.1 production: ::= SEQUENCE { , , ... } Generated C code: typedef struct { ; ; ... } ; - or typedef struct { ... } typedef struct { ... } typedef struct { ; ; ... } ; The and placeholders represent the equivalent C types for the ASN.1 types and respectively. This form of the structure will be generated if the internal types are primitive. and are formed using the algorithm described above for pulling structured types out of the definition. This form is used for constructed elements and elements that map to structured C types. The example above would result in the following generated C typedefs: typedef struct _A_x { ASN1INT a1; ASN1BOOL a2; } A_x; typedef struct A_y { ASN1UINT numocts; ASN1OCTET data[10]; } A_y; ASN1C V5.3 25 typedef struct _A { A_x x; A_y y; } A; In this case, elements x and y map to structured C types, so temporary typedefs are generated. In the case of nesting levels greater than two, all of the intermediate element names are used to form the final name. For example, consider the following type definition that contains three nesting levels: X ::= SEQUENCE { a SEQUENCE { aa SEQUENCE { x INTEGER, y BOOLEAN }, bb INTEGER } } In this case, the generation of temporary types results in the following equivalent type definitions: X-a-aa ::= SEQUENCE { x INTEGER, y BOOLEAN } X-a ::= SEQUENCE { aa X-a-aa, bb INTEGER } X ::= SEQUENCE { X-a a } Note that the name for the aa element type is X-a-aa. It contains both the name for a (at level 1) and aa (at level 2). This is a change from v5.1x and lower where only that production name and last element name would be used (i.e., X-aa). The change was made to ensure uniqueness of the generated names when multiple nesting levels are used. Note that although the compiler can handle embedded constructed types within productions, it is generally not considered good style to define productions this way. It is much better to manually define the constructed types for use in the final production definition. For example, the production defined at the start of this section can be rewritten as the following set of productions: X ::= SEQUENCE { a1 INTEGER, a2 BOOLEAN } Y ::= OCTET STRING A ::= SEQUENCE { X x, Y y } This makes the generated code easier to understand for the end user. Unnamed Elements Note: as of X.680, unnamed elements are not allowed – elements must be named. ASN1C still provides backward compatibility support for this syntax however. In an ASN.1 SEQUENCE definition, the tokens at the beginning of element declarations are optional. It is possible to include only a type name without a field identifier to define an element. This is normally done with defined type elements, but can be done with built-in types as well. An example of a SEQUENCE with unnamed elements would be as follows: AnInt ::= [PRIVATE 1] INTEGER ASN1C V5.3 26 Aseq ::= [PRIVATE 2] SEQUENCE { x INTEGER, AnInt } In this case, the first element (x) is named and the second element is unnamed. ASN1C handles this by generating an element name using the type name with the first character set to lower case. For built-in types, a constant element name is used for each type (for example, aInt is used for INTEGER). There is one caveat, however. ASN1C cannot handle multiple unnamed elements in a SEQUENCE or SET with the same type names. Element names must be used in this case to distinguish the elements. So, for the example above, the generated code would be as follows: typedef ASN1INT AnInt; typedef struct Aseq { ASN1INT x; AnInt anInt; } Aseq; OPTIONAL keyword Elements within a sequence can be declared to be optional using the OPTIONAL keyword. This indicates that the element is not required in the encoded message. An additional construct is added to the generated code to indicate whether an optional element is present in the message or not. This construct is a bit structure placed at the beginning of the generated sequence structure. This structure always has variable name ‘m’ and contains single-bit elements of the form ‘ Present’ as follows: struct { unsigned Present : 1, unsigned Present : 1, ... } m; In this case, the elements included in this construct correspond to only those elements marked as OPTIONAL within the production. If a production contains no optional elements, the entire construct is omitted. For example, we will change the production in the previous example to make both elements optional: Aseq ::= [PRIVATE 2] SEQUENCE { x INTEGER OPTIONAL, AnInt OPTIONAL } In this case, the following C typedef is generated: typedef struct Aseq { struct { unsigned xPresent : 1, unsigned anIntPresent : 1 } m; ASN1INT x; AnInt anInt; ASN1C V5.3 27 } Aseq; When this structure is populated for encoding, the developer must set the xPresent and anIntPresent flags accordingly to indicate whether the elements are to be included in the encoded message or not. Conversely, when a message is decoded into this structure, the developer must test the flags to determine if the element was provided in the message or not. The C++ version of the compiler will generate a constructor for the structured type for a SEQUENCE if OPTIONAL elements are present. This constructor will set all optional bits to zero when a variable of the structured type is declared. The programmer therefore does not have to be worried about clearing bits for elements that are not used; only with setting bits for the elements that are to be encoded. DEFAULT keyword The DEFAULT keyword allows a default value to be specified for elements within the SEQUENCE. ASN1C will parse this specification and treat it as it does an optional element. Note that the value specification is only parsed in simple cases for primitive values, so it up to the programmer to provide the value in complex cases. For BER encoding, a value must be specified be it the default or other value. For DER or PER, it is a requirement that no value be present in the encoding for the default value. For integer and boolean default values, the compiler automatically generates code to handle this requirement based on the value in the structure. For other values, an optional present flag bit is generated. The programmer must set this bit to false on the encode side to specify default value selected. If this is done, a value is not encoded into the message. On the decode side, the developer must test for present bit not set. If this is the case, the default value specified in the ASN.1 specification must be used and the value in the structure ignored. Extension Elements If the SEQUENCE type contains an open extension field (i.e., a … at the end of the specification or a …, … in the middle), a special element will be inserted to capture encoded extension elements for inclusion in the final encoded message. This element will be of type ASN1OpenType and have the name extElem1. This field will contain the complete encoding of any extension elements that may have been present in a message when it is decoded. On subsequent encode of the type, the extension fields will be copied into the new message. If the SEQUENCE type contains an extension marker and extension elements, then the open extension type field will not be added. Instead, the actual extension elements will be present. These elements will be treated as optional elements whether they were declared that way or not. The reason is because a version 1 message could be received that does not contain the elements. Additional bits will be generated in the bit mask if version brackets are present. These are groupings of extended elements that typically correspond to a particular version of a protocol. An example would be as follows: TestSequence ::= SEQUENCE { item-code INTEGER (0..254), item-name IA5String (SIZE (3..10)) OPTIONAL, ... ! 1, urgency ENUMERATED { normal, high } DEFAULT normal, [[ alternate-item-code INTEGER (0..254), alternate-item-name IA5String (SIZE (3..10)) OPTIONAL ]] } In this case, a special bit flag will be added to the mask structure to indicate the presence or absence of the entire element block. This will be of the form “_v#ExtPresent” where # would be replaced by the sequential version number. In the example above, this number would be three (two would be the version extension number of the urgency field). Therefore, the generated bit mask would be as follows: ASN1C V5.3 28 struct { unsigned unsigned unsigned unsigned } m; item_namePresent : 1; urgencyPresent : 1; _v3ExtPresent : 1; alternate_item_namePresent : 1; In this case, the setting of the _v3ExtPresent flag would indicate the presence or absence of the entire version block. Note that it is also possible to have optional items within the block (alternate-item-name). SET The ASN.1 SET type is converted into a C or C++ structured type that is identical to that for SEQUENCE as described in the previous section. The only difference between SEQUENCE and SET is that elements may be transmitted in any order in a SET whereas they must be in the defined order in a SEQUENCE. The only impact this has on ASN1C is in the generated decoder for a SET type. The decoder must take into account the possibility of out-of-order elements. This is handled by using a loop to parse each element in the message. Each time an item is parsed, an internal mask bit within the decoder is set to indicate the element was received. The complete set of received elements is then checked after the loop is completed to verify all required elements were received. SEQUENCE OF The ASN.1 SEQUENCE OF type is converted into a C or C++ structured type containing an integer to hold the number of occurrences of the referenced data element and an array or pointer to the referenced type to hold the actual data values. An option is also available to use a doubly-linked structure as the generated type. The allocation for the contents field depends on how the SEQUENCE OF is specified in the ASN.1 definition. If a size constraint is used, a static array of that size is generated; otherwise, a pointer variable is generated to hold a dynamically allocated array of values. The decoder will automatically allocate memory to hold parsed SEQUENCE OF data values. The default behavior of allocating a static array for a sized SEQUENCE OF construct can be modified by the use of a configuration item. The qualifier with the ‘dynamic’ keyword can be used at the global, module, or production level to specify that dynamic memory (i.e., a pointer) is used for the array. The syntax of this qualifier is as follows: dynamic The ‘list’ keyword can also be used in a similar fashion to specify the use of a doubly-linked structure to hold the elements:list See the section entitled Compiler Configuration File for further details on setting up a configuration file. Dynamic SEQUENCE OF Type ASN.1 production:::= SEQUENCE OF Generated C code: typedef struct { int n; * elem; ASN1C V5.3 29 } ; Generated C++ code: typedef struct { int n; * elem; } ASN1T_ ; Note that parsed values can be accessed from the dynamic data variable just as they would be from a static array variable; i.e., an array subscript can be used (ex: elem[0], elem[1]...). Static (sized) SEQUENCE OF Type ASN.1 production: ::= SEQUENCE SIZE OF Generated C code: typedef struct { int n; elem[ ]; } ; Generated C++ code: typedef struct { int n; elem[ ]; } ASN1T_ ; List-based SEQUENCE OF Type A doubly-linked list header type (Asn1RTDList) is used for the typedef if the list storage configuration setting is used (see above). This can be used for either a sized or unsized SEQUENCE OF construct. The generated C or C++ code is as follows: Generated C code: typedef Asn1RTDList ; Generated C++ code: typedef Asn1RTDList ASN1T_ ; The type definition of the Asn1RTDList structure can be found in the asn1type.h header file. The common run-time utility functions rtDListInit and rtDListAppend are available for initializing and adding elements to the list. See the Common Run-time Functions section for a full description of these functions. In addition to the Asn1RTDList C structure and C functions, a C++ class if provided for linked list support. This is the ASN1CSeqOfList class. This class provides methods for adding and deleting elements to and from lists and an iterator interface for traversing lists. See the ASN1CSeqOfList section in the C++ RunTime Classes area for details on all of the methods available in this class. Generation of Temporary Types for SEQUENCE OF Elements As with other constructed types, the variable can reference any ASN.1 type, including other ASN.1 constructed types. Therefore, it is possible to have a SEQUENCE OF SEQUENCE, SEQUENCE OF CHOICE, etc. When a constructed type or type that maps to a C structured type is referenced, a temporary type is generated for use in the final production. The format of this temporary type name is as follows: _element In this definition, refers to the name of the production containing the SEQUENCE OF type. ASN1C V5.3 30 For example, a simple (and very common) single level nested SEQUENCE OF construct might be as follows: A ::= SEQUENCE OF SEQUENCE { INTEGER a, BOOLEAN b } In this case, a temporary type is generated for the element of the SEQUENCE OF construct. This results in the following two equivalent ASN.1 types: A-element ::= SEQUENCE { INTEGER a, BOOLEAN b } A ::= SEQUENCE OF A-element These types are then converted into the equivalent C or C++ typedefs using the standard mapping that was previously described. SEQUENCE OF Type Elements in Other Constructed Types Frequently, a SEQUENCE OF construct is used to define an array of some common type in an element in some other constructed type (for example, a SEQUENCE). An example of this is as follows: SomePDU ::= SEQUENCE { addresses SEQUENCE OF AliasAddress, ... } Normally, this would result in the addresses element being pulled out and used to create a temporary type with a name equal to “SomePDU-addresses” as follows: SomePDU-addresses ::= SEQUENCE OF AliasAddress SomePDU ::= SEQUENCE { addresses SomePDU-addresses, ... } However, when the SEQUENCE OF element references a simple defined type as above with no additional tagging or constraint information, an optimization is done to cut down on the size of the generated code. This optimization is to generate a common name for the new temporary type that can be used for other similar references. The form of this common name is as follows: _SeqOf So instead of this: SomePDU-addresses ::= SEQUENCE OF AliasAddress The following equivalent type would be generated: _SeqOfAliasAddress ::= SEQUENCE OF AliasAddress The advantage is that the new type can now be easily reused if “SEQUENCE OF AliasAddress” is used in any other element declarations. Note the (illegal) use of an underscore in the first position. This is to ensure that no name collisions occur with other ASN.1 productions defined within the specification. An example of the savings of this optimization can be found in H.225. The above element reference is repeated 25 different times in different places. The result is the generation of one new temporary type that is referenced in 25 different places. Without this optimization, 25 unique types with the same definition would have been generated. ASN1C V5.3 31 SET OF The ASN.1 SET OF type is converted into a C or C++ structured type that is identical to that for SEQUENCE OF as described in the previous section. CHOICE The ASN.1 CHOICE type is converted into a C or C++ structured type containing an integer for the choice tag value (t) followed by a union (u) of all of the equivalent types that make up the CHOICE elements. The tag value is simply a sequential number starting at one for each alternative in the CHOICE. A #define constant is generated for each of these values. The format of this constant is "T_ _ " where is the name of the ASN.1 production and is the name of the CHOICE alternative. If a CHOICE alternative is not given an explicit name, then is automatically generated by taking the type name and making the first letter lowercase (this is the same as was done for the ASN.1 SEQUENCE type with unnamed elements). If the generated name is not unique, a sequential number is appended to make it unique. The union of choice alternatives is made of the equivalent C or C++ type definition followed by the element name for each of the elements. The rules for element generation are essentially the same as was described for SEQUENCE above. Constructed types or elements that map to C structured types are pulled out and temporary types are created. Unnamed elements names are automatically generated from the type name by making the first character of the name lowercase. One difference between temporary types used in a SEQUENCE and in a CHOICE is that a pointer variable will generated for use within the CHOICE union construct. ASN.1 production: ::= CHOICE { , , ... } Generated C code: #define T_ _ 1 #define T_ _ 2 ... typedef struct { int t; union { ; ; ... } u; } ; - or typedef struct { ... } ; typedef struct { ... } ; typedef struct { int t; union { ASN1C V5.3 32 * ; * ; ... } u; } ; The C++ mapping is the same with the exception that the ‘ASN1T_’ prefix is added to the generated type name. and are the equivalent C types representing the ASN.1 types and respectively. and represent the names of temporary types that may have been generated as the result of using constructed types within the definition. Choice alternatives may be unnamed, in which case is derived from by making the first letter lowercase. One needs to be careful when nesting CHOICE structures at different levels within other nested ASN.1 structures (SEQUENCEs, SETs, or other CHOICEs). A problem arises when CHOICE element names at different levels are not unique (this is likely when elements are unnamed). The problem is that generated tag constants are not guaranteed to be unique since only the production and end element names are used. The compiler gets around this problem by checking for duplicates. If the generated name is not unique, a sequential number is appended to make it unique. The compiler outputs an informational message when it does this. An example of this can be found in the following production: C ::= CHOICE { [0] INTEGER, [1] CHOICE { [0] INTEGER, [1] BOOLEAN } } This will produce the following C code: #define #define #define #define T_C_aInt T_C_aChoice T_C_aInt_1 T_C_aBool 1 2 1 2 typedef struct { int t; union { ASN1INT aInt; struct { int t; union { ASN1INT aInt; ASN1BOOL aBool; } u; } aChoice; } C; Note that an ‘_1’ was appended to the second instance of ‘T_C_aInt’. Developers must take care to ensure they are using the correct tag constant value when this happens. Populating Generated Choice Structures ASN1C V5.3 33 Populating generated CHOICE structures is more complex then for other generated types due to the use of pointers within the union construct. The recommended way to do it is to declare variables of the embedded type to be used on the stack prior to populating the CHOICE structure. The embedded variable would then be populated with the data to be encoded and then the address of this variable would be plugged into the CHOICE union pointer field. Consider the following definitions: AsciiString ::= [PRIVATE 28] OCTET STRING EBCDICString ::= [PRIVATE 29] OCTET STRING String ::= CHOICE { AsciiString, EBCDICString } This would result in the following type definitions: typedef ASN1DynOctStr AsciiString; typedef ASN1DynOctStr EBCDICString; typedef struct String { int t; union { /* t = 1 */ AsciiString *asciiString; /* t = 2 */ EBCDICString *eBCDICString; } u; } String; To set the AsciiString choice value, one would first declare an AsciiString variable, populate it, and then plug the address into a variable of the String structure as follows: AsciiString asciiString; String string; asciiString = “Hello!”; string.t = T_String_AsciiString; string.u.asciiString = &asciiString; It is also possible to allocate dynamic memory for the CHOICE union option variable; but one must be careful to release this memory when done with the structure. Open Type Note: The X.680 Open Type replaces the X.208 ANY or ANY DEFINED BY constructs. An ANY or ANY DEFINED BY encountered within an ASN.1 module will result in the generation of code corresponding to the Open Type described below. The ASN.1 Open Type is converted into a C or C++ structure used to model a dynamic OCTET STRING type. This structure contains a pointer and length field. The pointer is assumed to point at a string of previously encoded ASN.1 data. When a message containing an open type is decoded, the address of the open type contents field is stored in the pointer field and the length of the component is stored in the length field. ASN.1 production: ::= ANY Generated C code: typedef ASN1OpenType ; Generated C++ code: typedef ASN1TOpenType ; ASN1C V5.3 34 The difference between the two types is the C++ version contains constructors to initialize the value to zero or to a given open type value. The ASN.1 "ANY DEFINED BY Type" construct is treated the same as an ANY. No attempt is made to verify the identified Type. Character String Types As of version 5.0 and above, character string types are now built into the compiler. Previous versions used compiled definitions based on the OCTET STRING base type to model these types. All 8-bit character character-string types now are derived from the C character pointer (char*) base type. This pointer is used to hold a null-terminated C string for encoding/decoding. For encoding, the string can either be static (i.e., a string literal or address of a static buffer) or dynamic. The decoder allocates dynamic memory from within its context to hold the memory for the string. This memory is released when the rtMemFree function is called. The useful character string types in ASN.1 are as follows: UTF8String NumericString PrintableString T61String VideotexString IA5String UTCTime GeneralizedTime GraphicString VisibleString GeneralString UniversalString BMPString ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= [UNIVERSAL [UNIVERSAL [UNIVERSAL [UNIVERSAL [UNIVERSAL [UNIVERSAL [UNIVERSAL [UNIVERSAL [UNIVERSAL [UNIVERSAL [UNIVERSAL [UNIVERSAL [UNIVERSAL 12] 18] 19] 20] 21] 22] 23] 24] 25] 26] 27] 28] 30] IMPLICIT IMPLICIT IMPLICIT IMPLICIT IMPLICIT IMPLICIT IMPLICIT IMPLICIT IMPLICIT IMPLICIT IMPLICIT IMPLICIT IMPLICIT OCTET STRING IA5String IA5String OCTET STRING OCTET STRING OCTET STRING GeneralizedTime IA5String OCTET STRING OCTET STRING OCTET STRING OCTET STRING OCTET STRING ObjectDescriptor ::= [UNIVERSAL 7] IMPLICIT GraphicString Of these, all are represented by char* pointers except for the BMPString and UniversalString types. The BMPString is a 16-bit character string for which the following structure is used: typedef struct { ASN1UINT nchars; ASN116BITCHAR* data; } Asn116BitCharString; The ASN116BITCHAR type used in this definition is defined to be an “unsigned short”. See the rtBMPToCString, rtBMPToNewCString, and the rtCToBMPString run-time function descriptions for information on utilities that can convert standard C strings to and from BMP string format. The UniversalString is a 32-bit character string for which the following structure is used: typedef struct { ASN1UINT nchars; ASN132BITCHAR* data; } Asn132BitCharString; The ASN132BITCHAR type used in this definition is defined to be an “unsigned int”. See the rtUCSToCString, rtUCSToNewCString, and the rtCToUCSString run-time function descriptions for information on utilities that can convert standard C strings to and from Universal Character Set (UCS-4) ASN1C V5.3 35 string format. See also the rtUCSToWCSString and rtWCSToUCSString for information on utilities that can convert standard wide character string to and from UniversalString type. Utilities are also provided for working with UTF-8 string dataThe contents for this string type are assumed to contain the UTF-8 encoding of a character string. The UTF-8 encoding for a standard ASCII string is simply the string itself. For Unicode strings represented in C/C++ using the wide character type (wchar_t), the run-time functions rtUTF8ToWCS and rtWCSToUTF8 can be used for converting to and from Unicode. The function rtValidateUTF8 can be used to ensure that a given UTF-8 encoding is valid. See the RunTime Common Library section for a complete description of these functions. Time String Types The ASN.1 GeneralizedTime and UTCTime types are mapped to standard C/C++ null-terminated character string types. The C++ version of the product contains additional control classes for parsing and formatting time string values. When C++ code generation is specified, a control class is generated for operating on the target time string. This class is derived from the ASN1CGeneralizedTime or ASN1CUTCTime class for GeneralizedTime or UTCTime respectively. These classes contain methods for formatting or parsing time components such as month, day, year etc. from the strings. Objects of these classes can be declared inline to make the task of formatting or parsing time strings easier. For example, in a SEQUENCE containing a time string element the generated type will contain a public member variable containing the ‘ASN1T’ type that holds the message data. If one wanted to operate on the time string contained within that element, they could do so by using one of the time string classes inline as follows: ASN1CGeneralizedTime gtime (msgbuf, . ); gtime.setMonth (ASN1CTime::November); In this example, would represent a generated SEQUENCE variable type and would represent a time string element within this type. See the ASN1CTime, ASN1CGeneralizedTime and ASN1CUTCTIME subsections in the C++ Run-Time Classes section for details on all of the methods available in these classes. External Type The ASN.1 EXTERNAL type is a useful type used to include non-ASN.1 or other data within an ASN.1 encoded message. The type is described using the following ASN.1 SEQUENCE: EXTERNAL ::= [UNIVERSAL 8] IMPLICIT SEQUENCE { direct-reference OBJECT IDENTIFIER OPTIONAL, indirect-reference INTEGER OPTIONAL, data-value-descriptor ObjectDescriptor OPTIONAL, encoding CHOICE { single-ASN1-type [0] ANY, octet-aligned [1] IMPLICIT OCTET STRING, arbitrary [2] IMPLICIT BIT STRING } } The ASN.1 compiler is used to create a meta-definition for this structure. The definition is stored in the file asn1External.h. The resulting C structure is populated just like any other compiler-generated structure for working with ASN.1 data. ASN1C V5.3 36 Parameterized Types The compiler can parse parameterized type definitions and references as specified in the X.683 standard. These types allow dummy parameters to be declared that will be replaced with actual parameters when the type is referenced. This is similar to templates in C++. A simple and common example of the use of parameterized types is for the declaration of an upper bound on a sized type as follows: SizedOctetString{INTEGER:ub} ::= OCTET STRING (SIZE (1..ub)) In this definition, ‘ub’ would be replaced with an actual value when the type is referenced. For example, a sized octet string with an upper bound of 32 would be declared as follows: OctetString32 ::= SizedOctetString{32} The compiler would handle this in the same way as if the original type was declared to be an octet string of size 1 to 32. That is, it will generate a C structure containing a static byte array of size 32 as follows: typedef struct OctetString32 { ASN1UINT numocts; ASN1OCTET data[32]; } OctetString32; Another common example of parameterization is the substitution of a given type inside a common container type. For example, security specifications frequently contain a ‘signed’ parameterized type that allows a digital signature to be applied to other types. An example of this would be as follows: SIGNED { ToBeSigned } ::= SEQUENCE { toBeSigned ToBeSigned, algorithmOID OBJECT IDENTIFIER, paramS Params, signature BIT STRING } An example of a reference to this definition would be as follows: SignedName ::= SIGNED { Name } where ‘Name’ would be another type defined elsewhere within the module. The compiler performs the substitution to create the proper C typedef for SignedName: typedef struct SignedName { Name toBeSigned; ASN1OBJID algorithmOID; Params paramS; ASN1DynBitStr signature; } SignedName; When processing parameterized type definitions, the compiler will first look to see if the parameters are actually used in the final generated code. If not, they will simply be discarded and the parameterized type converted to a normal type reference. For example, when used with information objects, parameterized types are frequently used to pass information object set definitions to impose table constraints on the final type. Since table constraints do not affect the code that is generated by the compiler, the parameterized type definition is reduced to a normal type definition and references to it are handled in the same way as defined type references. This can lead to a significant reduction in generated code in cases where a parameterized type is referenced over and over again. ASN1C V5.3 37 For example, consider the following often-repeated pattern from the UMTS 3GPP specs: ProtocolIE-Field {RANAP-PROTOCOL-IES : IEsSetParam} id RANAP-PROTOCOL-IES.&id criticality RANAP-PROTOCOL-IES.&criticality value RANAP-PROTOCOL-IES.&Value } ::= SEQUENCE { ({IEsSetParam}), ({IEsSetParam}{@id}), ({IEsSetParam}{@id}) In this case, IEsSetParam refers to an information object set specification that constrains the values that are allowed to be passed for any given instance of a type referencing a ProtocolIE-Field. The compiler does not add any extra code to check for these values, so the parameter can be discarded. After processing the Information Object Class references within the construct (refer to the section on “Information Objects” for information on how this is done), the reduced definition for ProtocolIE-Field becomes the following: ProtocolIE-Field ::= SEQUENCE { id ProtocolIE-ID, criticality Criticality, value ASN.1 OPEN TYPE } References to the field are simply replaced with a reference to the ProtocolID-Field typedef. Information Objects Information Objects and Classes are used to define multi-layer protocols in which “holes” are defined within ASN.1 types for passing message components to different layers for processing. These items are also used to define the contents of various messages that are allowed in a particular exchange of messages. The ASN1C compiler extracts the types involved in these message exchanges and generates encoders/decoders for them. The “holes” in the types are accounted for by adding open type holders to the generated structures. These open type holders consist of a byte count and pointer for storing information on an encoded message fragment for processing at the next level. ASN1C compiler support for these types of specifications is limited to the correct application of reference types in places where Information Object Class references are embedded in standard ASN.1 types. Other applications of these constructs are parsed but do not result in the generation of any application code. To better understand the support in this area, the individual components of Information Object specifications are examined. We begin with the “CLASS” specification that provides a schema for Information Object definitions. A sample class specification is as follows: OPERATION ::= CLASS { &operationCode } &ArgumentType, &ResultType, &Errors CHOICE { local INTEGER, global OBJECT IDENTIFIER } ERROR OPTIONAL Users familiar with ASN.1 will recognize this as a simplified definition of the ROSE OPERATION MACRO using the Information Object format. When a class specification such as this is parsed, information on its fields is maintained in memory for later reference. The class definition itself does not result in the generation of any corresponding C or C++ code. It is only an abstract template that will be used to define new items later on in the specification. Fields from within the class can be referenced in standard ASN.1 types. It is these types of references that the compiler is mainly concerned with. These are typically “header” types that are used to add a common header to a variety of other message body types. An example would be the following ASN.1 type definition for a ROSE invoke message header: ASN1C V5.3 38 Invoke ::= SEQUENCE { invokeID INTEGER, opcode OPERATION.&operationCode, argument OPERATION.&ArgumentType } This is a very simple case which purposely omits a lot of additional information such as Information Object Set constraints that are typically a part of definitions such as this. The reason this information is not present is because we are just interested in showing the items that the compiler is concerned with. The opcode field within this definition is an example of a fixed type field reference. It is known as this because if you go back to the original class specification, you will see that operationCode is defined to be of a specific type (namely a choice between a local and global value). The generated typedef for this field will contain a reference to the type from the class definition. The argument field is an example of a variable type field.. In this case, if you refer back to the class definition, you will see that no type is provided. This means that this field can contain an instance of any encoded type (note: in practice, table constraints can be used with Information Object Sets to limit the message types that can be placed in this field). The generated typedef for this field contains an “open type” (ASN1OpenType) reference to hold a previously encoded component to be specified in the final message. The following would be the procedure to add the Invoke header type to an ASN.1 message body: 1. 2. 3. 4. 5. Encode the body type Get the message pointer and length of the encoded body Plug the pointer and length into the “numocts” and “data” items of the argument open type field in the Invoke type variable. Populate the remaining Invoke type fields. Encode the Invoke type to produce the final message. Other constructs can be built using class definitions such as Information Object instances and Information Object Sets. This document will not get into the definition and uses for these items other than to say that the ASN1C compiler will parse and silently ignore them. They provide additional information on how to put messages together, but are not part of the actual types themselves. For this reason, the compiler does not generate any additional code for their use. Value Specifications The compiler can parse any type of ASN.1 value specification, but will only generate code for certain types. In this release of the compiler, the following types of value specifications will result in generated code: • • • • • • • BOOLEAN INTEGER ENUMERATED Binary String Hexadecimal String Character String OBJECT IDENTIFER All value types except INTEGER cause an “extern” statement to be generated in the header file and a global value assignment to be added to the C or C++ source file. INTEGER value specifications cause #define statements to be generated. INTEGER Value Specification ASN1C V5.3 39 The INTEGER type causes a #define statement to be generated in the header file of the form ‘ASN1V_ ’ where would be replaced with the name in the ASN.1 source file. The reason for doing this is the common use of INTEGER values for size and value range constraints in the ASN.1 specifications. By generating #define statements, the symbolic names can be included in the source code making it easier to adjust the boundary values on the fly. For example, the following declaration: ivalue INTEGER ::= 5 will cause the following statement to be added to the generated header file: #define ASN1V_ivalue 5 The reason the ASN1V_ prefix is added is to prevent collisions with INTEGER value declarations and other declarations such as enumeration items with the same name. BOOLEAN Value Specification A BOOLEAN value causes an “extern” statement to be generated in the header file and a global declaration of type ASN1BOOL to be generated in the C or C++ source file. The mapping of ASN.1 declaration to global C or C++ value declaration is as follows: ASN.1 production: BOOLEAN ::= Generated code: ASN1BOOL = ; Binary and Hexadecimal String Value Specification These value specifications cause two global C variables to be generated: a ‘numocts’ variable describing the length of the string and a ‘data’ variable describing the string contents. The mapping for a binary string is as follows (note: BIT STRING can also be used as the type in this type of declaration): ASN.1 production: OCTET STRING ::= ‘ ’B Generated code: ASN1UINT _numocts = ; ASN1OCTET _data[] = ; Hexadecimal string would be the same except the ASN.1 constant would end in a ‘H’. Character String Value Specification A character string declaration would cause a C or C++ char* declaration to be generated: ASN.1 production: ::= Generated code: ASN1ConstCharPtr = ; In this definition, could be any of the standard 8-bit characters string types such as IA5String, PrintableString, etc. (note: this version of the compiler does not contain support for value declarations of larger character string type such as BMPString). The ASN1ConstCharPtr type used in the generated code is a type defined in asn1type.h designed to be a char* type for C or const char* type for C++. Object Identifier Value Specification Object identifier values are somewhat different in that they result in a structure being populated in the C or C++ source file. ASN.1 production: ASN1C V5.3 OBJECT IDENTIFIER ::= 40 Generated code: ASN1OBJID = ; For example, consider the following declaration: oid OBJECT IDENTIFIER ::= { ccitt b(5) 10 } This would result in the following definition in the C or C++ source file: ASN1OBJID oid = { 3, { 0, 5, 10 } } ; To populate a variable in a generated structure with this value, the rtSetOID utility function can be used (see the section in the run-time API guide for a full description of this function). In addition, the C++ base type for this construct (ASN1TObjId) contains constructors and assignment operators that allow direct assignment of values in this from to the target variable. Encode/Decode Function Prototypes If BER or DER encoding is specified, a BER encode and decode function prototype is generated for each production (DER uses the same form – there are only minor differences between the two types of generated functions). These prototypes are of the following general form: int asn1E_ (ASN1CTXT* ctxt_p, * data_p, ASN1TagType tagging); int asn1D_ (ASN1CTXT* ctxt_p, * data_p, ASN1TagType tagging, int length); The prototype with the ‘asn1E_’ prefix is for encoding and the one with ‘asn1D_’ is for decoding. The first parameter is a context variable used for reentrancy. This allows the encoder/decoder to keep track of what it is doing between function invocations. The second parameter is for passing the actual data variable to be encoded or decoded. This is a pointer to a variable of the generated type. The third parameter specifies whether implicit or explicit tagging should be used. In practically all cases, users of the generated function should set this parameter to ASN1EXPL (explicit). This tells the encoder to include an explicit tag around the encoded result. The only time this would not be used is when the encoder or decoder is making internal calls to handle implicit tagging of elements. The final parameter (decode case only), is length. This is ignored when tagging is set to ASN1EXPL (explicit), so users can ignore it for the most part and set it to zero. In the implicit case, this specifies the number of octets to be extracted from the byte stream. This is necessary because implicit indicates no tag/length pair precedes the data; therefore it is up to the user to indicate how many bytes of data are present. If PER encoding is specified, the format of the generated prototypes is different. The PER prototypes are of the following general form: int asn1PE_ (ASN1CTXT* ctxt_p, [*] value); int asn1PD_ (ASN1CTXT* ctxt_p, * pvalue); ASN1C V5.3 41 In these prototypes, the prefixes are different (a ‘P’ character is added to indicate they are PER encoders/decoders), and the tagging argument variables are omitted. In the encode case, the value of the production to be encoded may be passed by value if it is a simple type (for example, BOOLEAN or INTEGER). Structured values will still be passed using a pointer argument. Generated Class Definition A class definition is generated for each defined production in the ASN.1 source file. This class is derived from the ASN1CType base class. This class provides a set of common attributes and methods for encoding/decoding ASN.1 messages. It hides most of the complexity of calling the encode/decode functions directly. The general form of the class definition is as follows: class ASN1C_ : public ASN1CType { public: ASN1T_ & msgData; ASN1C_ (ASN1MessageBuffer& msgBuf, ASN1T_ & data); int Encode (); int Decode (); } ; The name of the generated class is ‘ASN1C_ ’ where ‘ ’ is the name of the production. The only defined attribute is a public variable reference named ‘msgData’ of the generated type. The constructor arguments are a reference to an ‘ASN1MessageBuffer’ type and a reference to an ‘ASN1T_ ’ type. The message buffer argument is a class defined in either the Asn1BerCppTypes.h or Asn1PerCppTypes.h. There are special subclasses for encoding (ASN1BEREncodeBuffer or ASN1PEREncodeBuffer) and decoding (ASN1BERDecodeBuffer and ASN1PERDecodeBuffer). Variables of either of these subclasses can be passed to the constructor depending on whether encoding or decoding is to be performed. The purpose of the buffer objects is to wrap all of the internal values required to manage encode or decode buffers. Examples of using this object can be found in the section on Encoding and Decoding messages. The ‘ASN1T_ ’ argument is used to specify the data variable containing data to be encoded or to receive data on a decode call. The procedure for encoding is to declare a variable of this type, populate it with data, and then instantiate the ASN1C_ object to associate a message buffer object with the data to be encoded. The Encode method can then be called to encode the data. On the decode side, a variable must be declared and passed to the constructor to receive the decoded data. Note that the ASN1C_ class declarations are only required in the application code as an entry point for encoding or decoding a top-level message (or Protocol Data Unit – PDU). Identifying these PDUs and declaring them in a configuration file using the empty element can attain large savings in the amount of code generated for a particular application. For example, in some H.323 applications, the main PDU structure used is H323-UserInformation. The following configuration file entry could be used to only generate the ASN1C_ control class for this PDU: ASN1C V5.3 42 This will cause only a single ASN1C_ class definition to be added to the generated code – that for the H323-UserInformation production. If this information was not included an ASN1C_ class would be generated for all productions and the vast majority of them would never be used. If the module contains no PDUs (i.e,. contains support types only), the H323-MESSAGES H323-UserInformation empty element can be specified at the module level to indicate that no control classes should be generated for the module. Generated Methods For each production, an Encode and Decode method is generated within the generated class structure. These are standard methods that initialize context information and then call the generated C-like encode or decode function. If the generation of print functions was specified (by including –print on the compiler command line), a Print method is also generated that calls the C print function. ASN1C V5.3 43 Generated BER Encode Functions For each ASN.1 production defined in the ASN.1 source file, a C encode function is generated. This function will convert a filled-in C variable of the given type into an encoded ASN.1 message. If C++ code generation is specified, a control class is generated that contains an Encode method that wraps this function. This function is invoked through the class interface to convert a populated msgData attribute variable into an encoded ASN.1 message. Generated C Function Format and Calling Parameters The format of the name of each generated encode function is as follows: asn1E_[ ] where is the name of the ASN.1 production for which the function is being generated and is an optional prefix that can be set via a configuration file setting. The configuration setting used to set the prefix is the element which specifies a prefix that will be applied to all generated typedef names and function names for the production. The calling sequence for each encode function is as follows: len = asn1E_ (ASN1CTXT* ctxt_p, * object, ASN1TagType tagging); In this definition,