#LyX 1.3 created this file. For more info see http://www.lyx.org/ \lyxformat 221 \textclass book \begin_preamble \usepackage{extramarks} \lhead{\firstxmark} \rfoot{\lastxmark} \usepackage{color} \definecolor{gray40}{gray}{.4} \definecolor{urlblue}{rgb}{0,0,.6} \usepackage[colorlinks=true, linkcolor={gray40}, urlcolor={urlblue}, pdfauthor={Lev Walkin}, pdftitle={Using the Open Source ASN.1 Compiler}, pdfkeywords={ASN.1,asn1c,compiler} ]{hyperref} %\fancyhf{} %\fancyhead[LE,RO]{\thepage} %\fancyhead[LO]{\rightmark} %\fancyhead[RE]{\leftmark} %\fancyfoot[R]{\lastxmark} \end_preamble \language english \inputencoding latin1 \fontscheme times \graphics default \paperfontsize default \spacing single \papersize Default \paperpackage a4 \use_geometry 0 \use_amsmath 0 \use_natbib 0 \use_numerical_citations 0 \paperorientation portrait \secnumdepth 2 \tocdepth 2 \paragraph_separation indent \defskip medskip \quotes_language swedish \quotes_times 2 \papercolumns 1 \papersides 2 \paperpagestyle fancy \layout Title Using the Open Source ASN.1 Compiler \layout Author Lev Walkin < \begin_inset ERT status Collapsed \layout Standard \backslash href{mailto:vlm@lionet.info?Subject=asn1c}{vlm@lionet.info} \end_inset > \layout Standard \begin_inset ERT status Open \layout Standard \backslash lhead{This document describes \backslash href{http://lionet.info/asn1c}{asn1c-0.9.21}} \layout Standard \backslash rhead{$Revision$} \end_inset \layout Standard \begin_inset LatexCommand \tableofcontents{} \end_inset \layout Standard \begin_inset ERT status Open \layout Standard \backslash pagestyle{headings} \end_inset \layout Part Using the ASN.1 Compiler \layout Chapter Introduction to the ASN.1 Compiler \layout Standard The purpose of the ASN.1 compiler is to convert the specifications in ASN.1 notation into some other language. At this moment, only C and C++ target languages are supported, the latter is in upward compatibility mode. \layout Standard The compiler reads the specification and emits a series of target language structures (C's structs, unions, enums) describing the corresponding ASN.1 types. The compiler also creates the code which allows automatic serialization and deserialization of these structures using several standardized encoding rules (BER, DER, XER). \layout Standard For example, suppose the following ASN.1 module is given \begin_inset Foot collapsed true \layout Standard Please look into Part \begin_inset LatexCommand \vref{par:ASN.1-Basics} \end_inset for a quick reference on how to understand the ASN.1 notation. \end_inset : \layout LyX-Code RectangleTest DEFINITIONS ::= \layout LyX-Code BEGIN \layout LyX-Code \layout LyX-Code Rectangle ::= SEQUENCE { \layout LyX-Code height INTEGER, -- Height of the rectangle \layout LyX-Code width INTEGER -- Width of the rectangle \layout LyX-Code } \layout LyX-Code \layout LyX-Code END \layout Standard The compiler would read this ASN.1 definition and produce the following C type \begin_inset Foot collapsed false \layout Standard \emph on -fnative-types \emph default compiler option is used to produce basic C \emph on int \emph default types instead of infinite width INTEGER_t structures. See Section \begin_inset LatexCommand \vref{sec:Command-line-options} \end_inset . \end_inset : \layout LyX-Code typedef struct Rectangle_s { \layout LyX-Code int height; \layout LyX-Code int width; \layout LyX-Code } Rectangle_t; \layout Standard It would also create the code for converting this structure into platform-indepe ndent wire representation (a serializer API) and the decoder of such wire representation back into local, machine-specific type (a deserializer API). \layout Section Quick start with asn1c \layout Standard After building and installing the compiler, the \emph on asn1c \begin_inset Foot collapsed false \layout Standard The 1 symbol in asn \series bold 1 \series default c is a digit, not an \begin_inset Quotes sld \end_inset ell \begin_inset Quotes srd \end_inset letter. \end_inset \emph default command may be used to compile the ASN.1 module \begin_inset Foot collapsed false \layout Standard This is probably \series bold not \series default what you want to try out right now -- read through the rest of this chapter and check the Section \begin_inset LatexCommand \vref{sec:Command-line-options} \end_inset to find out about \series bold -P \series default and \series bold -R \series default options. \end_inset : \layout LyX-Code asn1c \emph on \layout Standard If several ASN.1 modules contain interdependencies, all of the files must be specified altogether: \layout LyX-Code asn1c \emph on ... \layout Standard The compiler \series bold -E \series default and \series bold -EF \series default options are used for testing the parser and the semantic fixer, respectively. These options will instruct the compiler to dump out the parsed (and fixed, if \series bold -F \series default is involved) ASN.1 specification as it was "understood" by the compiler. It might be useful to check whether a particular syntactic construction is properly supported by the compiler. \layout LyX-Code asn1c \series bold -EF \series default \emph on \layout Standard The \series bold -P \series default option is used to dump the compiled output on the screen instead of creating a bunch of .c and .h files on disk in the current directory. You would probably want to start with \series bold -P \series default option instead of creating a mess in your current directory. Another option, \series bold -R \series default , asks compiler to only generate the files which need to be generated, and supress linking in the numerous support files. \layout Standard Print the compiled output instead of creating multiple source files: \layout LyX-Code asn1c \series bold -P \series default \emph on \layout Section Recognizing compiler output \layout Standard After compiling, the following entities will be created in your current directory: \layout Itemize A set of .c and .h files, generally a single pair for each type defined in the ASN.1 specifications. These files will be named similarly to the ASN.1 types ( \emph on Rectangle.c \emph default and \emph on Rectangle.h \emph default for the RectangleTest ASN.1 module defined in the beginning of this document). \layout Itemize A set of helper .c and .h files which contain generic encoders, decoders and other useful routines. There will be quite a few of them, some of them even are not always necessary, but the overall amount of code after compilation will be rather small anyway. \layout Itemize A \emph on Makefile.am.sample \emph default file mentioning all the files created at the earlier steps. This file is suitable for either automake suite or the plain `make` utility. \layout Standard It is your responsibility to create .c file with the \emph on int main() \emph default routine. \layout Standard In other words, after compiling the Rectangle module, you have the following set of files: { Makefile.am.sample, Rectangle.c, Rectangle.h, \series bold \SpecialChar \ldots{} \series default }, where \series bold \begin_inset Quotes sld \end_inset \SpecialChar \ldots{} \begin_inset Quotes srd \end_inset \series default stands for the set of additional \begin_inset Quotes sld \end_inset helper \begin_inset Quotes srd \end_inset files created by the compiler. If you add a simple file with the \emph on int main() \emph default routine, it would even be possible to compile everything with the single instruction: \layout LyX-Code cc -I. -o rectangle.exe *.c # It could be \emph on that \emph default simple \layout Standard Refer to the Chapter \begin_inset LatexCommand \vref{cha:Step-by-step-examples} \end_inset for a sample \emph on int main() \emph default routine. \layout Section \begin_inset LatexCommand \label{sec:Command-line-options} \end_inset Command line options \layout Standard The following table summarizes the asn1c command line options. \layout Standard \begin_inset Tabular \begin_inset Text \layout Standard \series bold \size small Overall Options \end_inset \begin_inset Text \layout Standard \series bold \size small Description \end_inset \begin_inset Text \layout Standard \size small -E \end_inset \begin_inset Text \layout Standard \size small Stop after the parsing stage and print the reconstructed ASN.1 specification code to the standard output. \end_inset \begin_inset Text \layout Standard \size small -F \end_inset \begin_inset Text \layout Standard \size small Used together with -E, instructs the compiler to stop after the ASN.1 syntax tree fixing stage and dump the reconstructed ASN.1 specification to the standard output. \end_inset \begin_inset Text \layout Standard \size small -P \end_inset \begin_inset Text \layout Standard \size small Dump the compiled output to the standard output instead of cre- ating the target language files on disk. \end_inset \begin_inset Text \layout Standard \size small -R \end_inset \begin_inset Text \layout Standard \size small Restrict the compiler to generate only the ASN.1 tables, omit- ting the usual support code. \end_inset \begin_inset Text \layout Standard \size small -S \emph on \end_inset \begin_inset Text \layout Standard \size small Use the specified directory with ASN.1 skeleton files. \end_inset \begin_inset Text \layout Standard \size small -X \end_inset \begin_inset Text \layout Standard \size small Generate the XML DTD for the specified ASN.1 modules. \end_inset \begin_inset Text \layout Standard \series bold \size small Warning Options \end_inset \begin_inset Text \layout Standard \series bold \size small Description \end_inset \begin_inset Text \layout Standard \size small -Werror \end_inset \begin_inset Text \layout Standard \size small Treat warnings as errors; abort if any warning is produced. \end_inset \begin_inset Text \layout Standard \size small -Wdebug-lexer \end_inset \begin_inset Text \layout Standard \size small Enable lexer debugging during the ASN.1 parsing stage. \end_inset \begin_inset Text \layout Standard \size small -Wdebug-fixer \end_inset \begin_inset Text \layout Standard \size small Enable ASN.1 syntax tree fixer debugging during the fixing stage. \end_inset \begin_inset Text \layout Standard \size small -Wdebug-compiler \end_inset \begin_inset Text \layout Standard \size small Enable debugging during the actual compile time. \end_inset \begin_inset Text \layout Standard \series bold \size small Language Options \end_inset \begin_inset Text \layout Standard \series bold \size small Description \end_inset \begin_inset Text \layout Standard \size small -fbless-SIZE \end_inset \begin_inset Text \layout Standard \size small Allow SIZE() constraint for INTEGER, ENUMERATED, and other types for which this constraint is normally prohibited by the standard. This is a violation of an ASN.1 standard and compiler may fail to produce the meaningful code. \end_inset \begin_inset Text \layout Standard \size small -fcompound-names \end_inset \begin_inset Text \layout Standard \size small Use complex names for C structures. Using complex names prevents name clashes in case the module reuses the same identifiers in multiple contexts. \end_inset \begin_inset Text \layout Standard \size small -findirect-choice \end_inset \begin_inset Text \layout Standard \size small When generating code for a CHOICE type, compile the CHOICE members as indirect pointers instead of declaring them inline. Consider using this option together with \series bold -fno-include-deps \series default to prevent circular references. \end_inset \begin_inset Text \layout Standard \size small -fknown-extern-type= \emph on \end_inset \begin_inset Text \layout Standard \size small Pretend the specified type is known. The compiler will assume the target language source files for the given type have been provided manually. \end_inset \begin_inset Text \layout Standard \size small -fnative-types \end_inset \begin_inset Text \layout Standard \size small Use the native machine's data types (int, double) whenever possible, instead of the compound INTEGER_t, ENUMERATED_t and REAL_t types. \end_inset \begin_inset Text \layout Standard \size small -fno-constraints \end_inset \begin_inset Text \layout Standard \size small Do not generate ASN.1 subtype constraint checking code. This may produce a shorter executable. \end_inset \begin_inset Text \layout Standard \size small -fno-include-deps \end_inset \begin_inset Text \layout Standard \size small Do not generate courtesy #include lines for non-critical dependencies. \end_inset \begin_inset Text \layout Standard \size small -funnamed-unions \end_inset \begin_inset Text \layout Standard \size small Enable unnamed unions in the definitions of target language's structures. \end_inset \begin_inset Text \layout Standard \size small -fskeletons-copy \end_inset \begin_inset Text \layout Standard \size small Copy support files rather than symlink them. \end_inset \begin_inset Text \layout Standard \series bold \size small Codecs Generation Options \end_inset \begin_inset Text \layout Standard \series bold \size small Description \end_inset \begin_inset Text \layout Standard \size small -gen-PER \end_inset \begin_inset Text \layout Standard \size small Generate Packed Encoding Rules (PER) support code. \end_inset \begin_inset Text \layout Standard \size small -pdu= \emph on auto \end_inset \begin_inset Text \layout Standard \size small Generate PDU tables by discovering Protocol Data Units automatically. \end_inset \begin_inset Text \layout Standard \series bold \size small Output Options \end_inset \begin_inset Text \layout Standard \series bold \size small Description \end_inset \begin_inset Text \layout Standard \size small -print-constraints \end_inset \begin_inset Text \layout Standard \size small When -EF are also specified, this option forces the compiler to explain its internal understanding of subtype constraints. \end_inset \begin_inset Text \layout Standard \size small -print-lines \end_inset \begin_inset Text \layout Standard \size small Generate "-- #line" comments in -E output. \end_inset \end_inset \layout Chapter Using the ASN.1 Compiler \layout Section Invoking the ASN.1 helper code \begin_inset OptArg collapsed true \layout Standard Invoking the helper code \end_inset \layout Standard First of all, you should include one or more header files into your application. Typically, it is enough to include the header file of the main PDU type. For our Rectangle module, including the Rectangle.h file is sufficient: \layout LyX-Code #include \layout Standard The header files defines the C structure corresponding to the ASN.1 definition of a rectangle and the declaration of the ASN.1 type descriptor, which is used as an argument to most of the functions provided by the ASN.1 module. For example, here is the code which frees the Rectangle_t structure: \layout LyX-Code Rectangle_t *rect = ...; \layout LyX-Code \layout LyX-Code asn_DEF_Rectangle.free_struct(&asn_DEF_Rectangle, \layout LyX-Code rect, 0); \layout Standard This code defines a \emph on rect \emph default pointer which points to the Rectangle_t structure which needs to be freed. The second line invokes the generic \emph on free_struct() \emph default routine created specifically for this Rectangle_t structure. The \emph on asn_DEF_Rectangle \emph default is the type descriptor, which holds a collection of routines to deal with the Rectangle_t structure. \layout Standard The following member functions of the asn_DEF_Rectangle type descriptor are of interest: \layout Description ber_decoder This is the generic \emph on restartable \begin_inset Foot collapsed false \layout Standard Restartable means that if the decoder encounters the end of the buffer, it will fail, but may later be invoked again with the rest of the buffer to continue decoding. \end_inset \emph default BER decoder (Basic Encoding Rules). This decoder would create and/or fill the target structure for you. See Section \begin_inset LatexCommand \vref{sub:Decoding-BER} \end_inset . \layout Description der_encoder This is the generic DER encoder (Distinguished Encoding Rules). This encoder will take the target structure and encode it into a series of bytes. See Section \begin_inset LatexCommand \vref{sub:Encoding-DER} \end_inset . NOTE: DER encoding is a subset of BER. Any BER decoder should be able to handle DER input. \layout Description xer_decoder This is the generic XER decoder. It takes both BASIC-XER or CANONICAL-XER encodings and deserializes the data into a local, machine-dependent representation. See Section \begin_inset LatexCommand \vref{sub:Decoding-XER} \end_inset . \layout Description xer_encoder This is the XER encoder (XML Encoding Rules). This encoder will take the target structure and represent it as an XML (text) document using either BASIC-XER or CANONICAL-XER encoding rules. See Section \begin_inset LatexCommand \vref{sub:Encoding-XER} \end_inset . \layout Description uper_decoder This is the Unaligned PER decoder. \layout Description uper_encoder This is the Unaligned Basic PER encoder. This encoder will take the target structure and encode it into a series of bytes. \layout Description check_constraints Check that the contents of the target structure are semantical ly valid and constrained to appropriate implicit or explicit subtype constraints. See Section \begin_inset LatexCommand \vref{sub:Validating-the-target} \end_inset . \layout Description print_struct This function convert the contents of the passed target structure into human readable form. This form is not formal and cannot be converted back into the structure, but it may turn out to be useful for debugging or quick-n-dirty printing. See Section \begin_inset LatexCommand \vref{sub:Printing-the-target} \end_inset . \layout Description free_struct This is a generic disposal which frees the target structure. See Section \begin_inset LatexCommand \vref{sub:Freeing-the-target} \end_inset . \layout Standard Each of the above function takes the type descriptor ( \emph on asn_DEF_\SpecialChar \ldots{} \emph default ) and the target structure ( \emph on rect \emph default , in the above example). \layout Subsection \begin_inset LatexCommand \label{sub:Decoding-BER} \end_inset Decoding BER \layout Standard The Basic Encoding Rules describe the most widely used (by the ASN.1 community) way to encode and decode a given structure in a machine-independent way. Several other encoding rules (CER, DER) define a more restrictive versions of BER, so the generic BER parser is also capable of decoding the data encoded by CER and DER encoders. The opposite is not true. \layout Standard \emph on The ASN.1 compiler provides the generic BER decoder which is implicitly capable of decoding BER, CER and DER encoded data. \layout Standard The decoder is restartable (stream-oriented), which means that in case the buffer has less data than it is expected, the decoder will process whatever there is available and ask for more data to be provided. Please note that the decoder may actually process less data than it was given in the buffer, which means that you must be able to make the next buffer contain the unprocessed part of the previous buffer. \layout Standard Suppose, you have two buffers of encoded data: 100 bytes and 200 bytes. \layout Itemize You may concatenate these buffers and feed the BER decoder with 300 bytes of data, or \layout Itemize You may feed it the first buffer of 100 bytes of data, realize that the ber_decoder consumed only 95 bytes from it and later feed the decoder with 205 bytes buffer which consists of 5 unprocessed bytes from the first buffer and the additional 200 bytes from the second buffer. \layout Standard This is not as convenient as it could be (like, the BER encoder could consume the whole 100 bytes and keep these 5 bytes in some temporary storage), but in case of existing stream based processing it might actually fit well into existing algorithm. Suggestions are welcome. \layout Standard Here is the simplest example of BER decoding. \layout LyX-Code Rectangle_t * \layout LyX-Code simple_deserializer(const void *buffer, size_t buf_size) { \layout LyX-Code Rectangle_t *rect = 0; /* Note this 0! */ \layout LyX-Code asn_dec_rval_t rval; \layout LyX-Code \layout LyX-Code rval = \series bold asn_DEF_Rectangle.ber_decoder \series default (0, \layout LyX-Code &asn_DEF_Rectangle, \layout LyX-Code (void **)&rect, \layout LyX-Code buffer, buf_size, \layout LyX-Code 0); \layout LyX-Code \layout LyX-Code if(rval \series bold .code \series default == RC_OK) { \layout LyX-Code return rect; /* Decoding succeeded */ \layout LyX-Code } else { \layout LyX-Code /* Free partially decoded rect */ \layout LyX-Code asn_DEF_Rectangle.free_struct( \layout LyX-Code &asn_DEF_Rectangle, rect, 0); \layout LyX-Code return 0; \layout LyX-Code } \layout LyX-Code } \layout Standard The code above defines a function, \emph on simple_deserializer \emph default , which takes a buffer and its length and is expected to return a pointer to the Rectangle_t structure. Inside, it tries to convert the bytes passed into the target structure (rect) using the BER decoder and returns the rect pointer afterwards. If the structure cannot be deserialized, it frees the memory which might be left allocated by the unfinished \emph on ber_decoder \emph default routine and returns 0 (no data). (This \series bold freeing is necessary \series default because the ber_decoder is a restartable procedure, and may fail just because there is more data needs to be provided before decoding could be finalized). The code above obviously does not take into account the way the \emph on ber_decoder() \emph default failed, so the freeing is necessary because the part of the buffer may already be decoded into the structure by the time something goes wrong. \layout Standard A little less wordy would be to invoke a globally available \emph on ber_decode() \emph default function instead of dereferencing the asn_DEF_Rectangle type descriptor: \layout LyX-Code rval = ber_decode(0, &asn_DEF_Rectangle, (void **)&rect, \layout LyX-Code buffer, buf_size); \layout Standard Note that the initial (asn_DEF_Rectangle.ber_decoder) reference is gone, and also the last argument (0) is no longer necessary. \layout Standard These two ways of BER decoder invocations are fully equivalent. \layout Standard The BER de \emph on coder \emph default may fail because of ( \emph on the following RC_\SpecialChar \ldots{} codes are defined in ber_decoder.h \emph default ): \layout Itemize RC_WMORE: There is more data expected than it is provided (stream mode continuat ion feature); \layout Itemize RC_FAIL: General failure to decode the buffer; \layout Itemize \SpecialChar \ldots{} other codes may be defined as well. \layout Standard Together with the return code (.code) the asn_dec_rval_t type contains the number of bytes which is consumed from the buffer. In the previous hypothetical example of two buffers (of 100 and 200 bytes), the first call to ber_decode() would return with .code = RC_WMORE and .consumed = 95. The .consumed field of the BER decoder return value is \series bold always \series default valid, even if the decoder succeeds or fails with any other return code. \layout Standard Please look into ber_decoder.h for the precise definition of ber_decode() and related types. \layout Subsection \begin_inset LatexCommand \label{sub:Encoding-DER} \end_inset Encoding DER \layout Standard The Distinguished Encoding Rules is the \emph on canonical \emph default variant of BER encoding rules. The DER is best suited to encode the structures where all the lengths are known beforehand. This is probably exactly how you want to encode: either after a BER decoding or after a manual fill-up, the target structure contains the data which size is implicitly known before encoding. Among other uses, the DER encoding is used to encode X.509 certificates. \layout Standard As with BER decoder, the DER encoder may be invoked either directly from the ASN.1 type descriptor (asn_DEF_Rectangle) or from the stand-alone function, which is somewhat simpler: \layout LyX-Code \layout LyX-Code /* \layout LyX-Code * This is the serializer itself, \layout LyX-Code * it supplies the DER encoder with the \layout LyX-Code * pointer to the custom output function. \layout LyX-Code */ \layout LyX-Code ssize_t \layout LyX-Code simple_serializer(FILE *ostream, Rectangle_t *rect) { \layout LyX-Code asn_enc_rval_t er; /* Encoder return value */ \layout LyX-Code \layout LyX-Code er = der_encode(&asn_DEF_Rect, rect, \layout LyX-Code write_stream, ostream); \layout LyX-Code if(er. \series bold encoded \series default == -1) { \layout LyX-Code /* \layout LyX-Code * Failed to encode the rectangle data. \layout LyX-Code */ \layout LyX-Code fprintf(stderr, \begin_inset Quotes sld \end_inset Cannot encode %s: %s \backslash n \begin_inset Quotes srd \end_inset , \layout LyX-Code er. \series bold failed_type \series default ->name, \layout LyX-Code strerror(errno)); \layout LyX-Code return -1; \layout LyX-Code } else { \layout LyX-Code /* Return the number of bytes */ \layout LyX-Code return er.encoded; \layout LyX-Code } \layout LyX-Code } \layout Standard As you see, the DER encoder does not write into some sort of buffer or something. It just invokes the custom function (possible, multiple times) which would save the data into appropriate storage. The optional argument \emph on app_key \emph default is opaque for the DER encoder code and just used by \emph on _write_stream() \emph default as the pointer to the appropriate output stream to be used. \layout Standard If the custom write function is not given (passed as 0), then the DER encoder will essentially do the same thing (i.e., encode the data) but no callbacks will be invoked (so the data goes nowhere). It may prove useful to determine the size of the structure's encoding before actually doing the encoding \begin_inset Foot collapsed false \layout Standard It is actually faster too: the encoder might skip over some computations which aren't important for the size determination. \end_inset . \layout Standard Please look into der_encoder.h for the precise definition of der_encode() and related types. \layout Subsection \begin_inset LatexCommand \label{sub:Encoding-XER} \end_inset Encoding XER \layout Standard The XER stands for XML Encoding Rules, where XML, in turn, is eXtensible Markup Language, a text-based format for information exchange. The encoder routine API comes in two flavors: stdio-based and callback-based. With the callback-based encoder, the encoding process is very similar to the DER one, described in Section \begin_inset LatexCommand \vref{sub:Encoding-DER} \end_inset . The following example uses the definition of write_stream() from up there. \layout LyX-Code /* \layout LyX-Code * This procedure generates the XML document \layout LyX-Code * by invoking the XER encoder. \layout LyX-Code * NOTE: Do not copy this code verbatim! \layout LyX-Code * If the stdio output is necessary, \layout LyX-Code * use the xer_fprint() procedure instead. \layout LyX-Code * See Section \begin_inset LatexCommand \vref{sub:Printing-the-target} \end_inset . \layout LyX-Code */ \layout LyX-Code int \layout LyX-Code print_as_XML(FILE *ostream, Rectangle_t *rect) { \layout LyX-Code asn_enc_rval_t er; /* Encoder return value */ \layout LyX-Code \layout LyX-Code er = xer_encode(&asn_DEF_Rectangle, rect, \layout LyX-Code XER_F_BASIC, /* BASIC-XER or CANONICAL-XER */ \layout LyX-Code write_stream, ostream); \layout LyX-Code \layout LyX-Code return (er.encoded == -1) ? -1 : 0; \layout LyX-Code } \layout Standard Please look into xer_encoder.h for the precise definition of xer_encode() and related types. \layout Standard See Section \begin_inset LatexCommand \ref{sub:Printing-the-target} \end_inset for the example of stdio-based XML encoder and other pretty-printing suggestion s. \layout Subsection \begin_inset LatexCommand \label{sub:Decoding-XER} \end_inset Decoding XER \layout Standard The data encoded using the XER rules can be subsequently decoded using the xer_decode() API call: \layout LyX-Code Rectangle_t * \layout LyX-Code XML_to_Rectangle(const void *buffer, size_t buf_size) { \layout LyX-Code Rectangle_t *rect = 0; /* Note this 0! */ \layout LyX-Code asn_dec_rval_t rval; \layout LyX-Code \layout LyX-Code rval = xer_decode(0, &asn_DEF_Rectangle, (void **)&rect, \layout LyX-Code buffer, buf_size); \layout LyX-Code if(rval \series bold .code \series default == RC_OK) { \layout LyX-Code return rect; /* Decoding succeeded */ \layout LyX-Code } else { \layout LyX-Code /* Free partially decoded rect */ \layout LyX-Code asn_DEF_Rectangle.free_struct( \layout LyX-Code &asn_DEF_Rectangle, rect, 0); \layout LyX-Code return 0; \layout LyX-Code } \layout LyX-Code } \layout Standard The decoder takes both BASIC-XER and CANONICAL-XER encodings. \layout Standard The decoder shares its data consumption properties with BER decoder; please read the Section \begin_inset LatexCommand \vref{sub:Decoding-BER} \end_inset to know more. \layout Standard Please look into xer_decoder.h for the precise definition of xer_decode() and related types. \layout Subsection \begin_inset LatexCommand \label{sub:Validating-the-target} \end_inset Validating the target structure \layout Standard Sometimes the target structure needs to be validated. For example, if the structure was created by the application (as opposed to being decoded from some external source), some important information required by the ASN.1 specification might be missing. On the other hand, the successful decoding of the data from some external source does not necessarily mean that the data is fully valid either. It might well be the case that the specification describes some subtype constraints that were not taken into account during decoding, and it would actually be useful to perform the last check when the data is ready to be encoded or when the data has just been decoded to ensure its validity according to some stricter rules. \layout Standard The asn_check_constraints() function checks the type for various implicit and explicit constraints. It is recommended to use asn_check_constraints() function after each decoding and before each encoding. \layout Standard Please look into constraints.h for the precise definition of asn_check_constraint s() and related types. \layout Subsection \begin_inset LatexCommand \label{sub:Printing-the-target} \end_inset Printing the target structure \layout Standard There are two ways to print the target structure: either invoke the print_struct member of the ASN.1 type descriptor, or using the asn_fprint() function, which is a simpler wrapper of the former: \layout LyX-Code asn_fprint(stdout, &asn_DEF_Rectangle, rect); \layout Standard Please look into constr_TYPE.h for the precise definition of asn_fprint() and related types. \layout Standard Another practical alternative to this custom format printing would be to invoke XER encoder. The default BASIC-XER encoder performs reasonable formatting for the output to be useful and human readable. To invoke the XER decoder in a manner similar to asn_fprint(), use the xer_fprint() call: \layout LyX-Code xer_fprint(stdout, &asn_DEF_Rectangle, rect); \layout Standard See Section \begin_inset LatexCommand \vref{sub:Encoding-XER} \end_inset for XML-related details. \layout Subsection \begin_inset LatexCommand \label{sub:Freeing-the-target} \end_inset Freeing the target structure \layout Standard Freeing the structure is slightly more complex than it may seem to. When the ASN.1 structure is freed, all the members of the structure and their submembers are recursively freed as well. But it might not be feasible to free the structure itself. Consider the following case: \layout LyX-Code struct my_figure { /* The custom structure */ \layout LyX-Code int flags; /* */ \layout LyX-Code /* The type is generated by the ASN.1 compiler */ \layout LyX-Code \emph on Rectangle_t rect; \layout LyX-Code /* other members of the structure */ \layout LyX-Code }; \layout Standard In this example, the application programmer defined a custom structure with one ASN.1-derived member (rect). This member is not a reference to the Rectangle_t, but an in-place inclusion of the Rectangle_t structure. If the freeing is necessary, the usual procedure of freeing everything must not be applied to the &rect pointer itself, because it does not point to the memory block directly allocated by the memory allocation routine, but instead lies within a block allocated for the my_figure structure. \layout Standard To solve this problem, the free_struct routine has the additional argument (besides the obvious type descriptor and target structure pointers), which is the flag specifying whether the outer pointer itself must be freed (0, default) or it should be left intact (non-zero value). \layout LyX-Code \series bold /* 1. Rectangle_t is defined within my_figure */ \layout LyX-Code struct my_figure { \layout LyX-Code Rectangle_t rect; \layout LyX-Code } *mf = \series bold ... \series default ; \layout LyX-Code /* \layout LyX-Code * Freeing the Rectangle_t \layout LyX-Code * without freeing the mf->rect area \layout LyX-Code */ \layout LyX-Code asn_DEF_Rectangle.free_struct( \layout LyX-Code &asn_DEF_Rectangle, &mf->rect, \series bold 1 \emph on \emph default /* !free */ \series default ); \layout LyX-Code \layout LyX-Code \layout LyX-Code \series bold /* 2. Rectangle_t is a stand-alone pointer */ \layout LyX-Code Rectangle_t *rect = \series bold ... \series default ; \layout LyX-Code /* \layout LyX-Code * Freeing the Rectangle_t \layout LyX-Code * and freeing the rect pointer \layout LyX-Code */ \layout LyX-Code asn_DEF_Rectangle.free_struct( \layout LyX-Code &asn_DEF_Rectangle, rect, \series bold 0 \emph on \emph default /* free the pointer too */ \series default ); \layout Standard It is safe to invoke the \emph on free_struct \emph default function with the target structure pointer set to 0 (NULL), the function will do nothing. \layout Standard For the programmer's convenience, the following macros are available: \layout LyX-Code ASN_STRUCT_FREE(asn_DEF, ptr); \layout LyX-Code ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF, ptr); \layout Standard These macros bear the same semantics as the \emph on free_struct \emph default function invocation, discussed above. \layout Chapter \begin_inset LatexCommand \label{cha:Step-by-step-examples} \end_inset Step by step examples \layout Section A \begin_inset Quotes sld \end_inset Rectangle \begin_inset Quotes srd \end_inset Encoder \layout Standard This example will help you create a simple BER and XER encoder of a \begin_inset Quotes sld \end_inset Rectangle \begin_inset Quotes srd \end_inset type used throughout this document. \layout Enumerate Create a file named \series bold rectangle.asn1 \series default with the following contents: \begin_deeper \layout LyX-Code RectangleModule1 DEFINITIONS ::= \layout LyX-Code BEGIN \layout LyX-Code \layout LyX-Code Rectangle ::= SEQUENCE { \layout LyX-Code height INTEGER, \layout LyX-Code width INTEGER \layout LyX-Code } \layout LyX-Code \layout LyX-Code END \end_deeper \layout Enumerate Compile it into the set of .c and .h files using asn1c compiler \begin_inset LatexCommand \cite{ASN1C} \end_inset : \begin_deeper \layout LyX-Code \emph on asn1c -fnative-types \series bold \emph default rectangle.asn1 \end_deeper \layout Enumerate Alternatively, use the Online ASN.1 compiler \begin_inset LatexCommand \cite{AONL} \end_inset by uploading the \series bold rectangle.asn1 \series default file into the Web form and unpacking the produced archive on your computer. \layout Enumerate By this time, you should have gotten multiple files in the current directory, including the \series bold Rectangle.c \series default and \series bold Rectangle.h \series default . \layout Enumerate Create a main() routine which creates the Rectangle_t structure in memory and encodes it using BER and XER encoding rules. Let's name the file \series bold main.c \series default : \begin_inset ERT status Open \layout Standard \backslash clearpage{} \end_inset \begin_deeper \layout LyX-Code \size small #include \layout LyX-Code \size small #include \layout LyX-Code \size small #include /* Rectangle ASN.1 type */ \layout LyX-Code \layout LyX-Code \size small /* \layout LyX-Code \size small * This is a custom function which writes the \layout LyX-Code \size small * encoded output into some FILE stream. \layout LyX-Code \size small */ \layout LyX-Code \size small static int \layout LyX-Code \size small write_out(const void *buffer, size_t size, void *app_key) { \layout LyX-Code \size small FILE *out_fp = app_key; \layout LyX-Code \size small size_t wrote; \layout LyX-Code \size small \layout LyX-Code \size small wrote = fwrite(buffer, 1, size, out_fp); \layout LyX-Code \size small \layout LyX-Code \size small return (wrote == size) ? 0 : -1; \layout LyX-Code \size small } \layout LyX-Code \layout LyX-Code \size small int main(int ac, char **av) { \layout LyX-Code \size small Rectangle_t *rectangle; /* Type to encode */ \layout LyX-Code \size small asn_enc_rval_t ec; /* Encoder return value */ \layout LyX-Code \size small \layout LyX-Code \size small /* Allocate the Rectangle_t */ \layout LyX-Code \size small rectangle = calloc(1, sizeof(Rectangle_t)); /* not malloc! */ \layout LyX-Code \size small if(!rectangle) { \layout LyX-Code \size small perror( \begin_inset Quotes sld \end_inset calloc() failed \begin_inset Quotes srd \end_inset ); \layout LyX-Code \size small exit(71); /* better, EX_OSERR */ \layout LyX-Code \size small } \layout LyX-Code \size small \layout LyX-Code \size small /* Initialize the Rectangle members */ \layout LyX-Code \size small rectangle->height = 42; /* any random value */ \layout LyX-Code \size small rectangle->width = 23; /* any random value */ \layout LyX-Code \size small \layout LyX-Code \size small /* BER encode the data if filename is given */ \layout LyX-Code \size small if(ac < 2) { \layout LyX-Code \size small fprintf(stderr, \begin_inset Quotes sld \end_inset Specify filename for BER output \backslash n \begin_inset Quotes srd \end_inset ); \layout LyX-Code \size small } else { \layout LyX-Code \size small const char *filename = av[1]; \layout LyX-Code \size small FILE *fp = fopen(filename, \begin_inset Quotes sld \end_inset wb \begin_inset Quotes srd \end_inset ); /* for BER output */ \layout LyX-Code \layout LyX-Code \size small if(!fp) { \layout LyX-Code \size small perror(filename); \layout LyX-Code \size small exit(71); /* better, EX_OSERR */ \layout LyX-Code \size small } \layout LyX-Code \size small \layout LyX-Code \size small /* Encode the Rectangle type as BER (DER) */ \layout LyX-Code \size small ec = der_encode(&asn_DEF_Rectangle, \layout LyX-Code \size small rectangle, write_out, fp); \layout LyX-Code \size small fclose(fp); \layout LyX-Code \size small if(ec.encoded == -1) { \layout LyX-Code \size small fprintf(stderr, \layout LyX-Code \size small \begin_inset Quotes sld \end_inset Could not encode Rectangle (at %s) \backslash n \begin_inset Quotes srd \end_inset , \layout LyX-Code \size small ec.failed_type ? ec.failed_type->name : \begin_inset Quotes sld \end_inset unknown \begin_inset Quotes srd \end_inset ); \layout LyX-Code \size small exit(65); /* better, EX_DATAERR */ \layout LyX-Code \size small } else { \layout LyX-Code \size small fprintf(stderr, \begin_inset Quotes sld \end_inset Created %s with BER encoded Rectangle \backslash n \begin_inset Quotes srd \end_inset , \layout LyX-Code \size small filename); \layout LyX-Code \size small } \layout LyX-Code \size small } \layout LyX-Code \size small \layout LyX-Code \size small /* Also print the constructed Rectangle XER encoded (XML) */ \layout LyX-Code \size small xer_fprint(stdout, &asn_DEF_Rectangle, rectangle); \layout LyX-Code \size small \layout LyX-Code \size small return 0; /* Encoding finished successfully */ \layout LyX-Code \size small } \end_deeper \layout Enumerate Compile all files together using C compiler (varies by platform): \begin_deeper \layout LyX-Code \emph on cc -I. -o \series bold rencode \series default *.c \end_deeper \layout Enumerate Voila! You have just created the BER and XER encoder of a Rectangle type, named \series bold rencode \series default ! \layout Standard \begin_inset ERT status Collapsed \layout Standard \backslash clearpage{} \end_inset \layout Section \begin_inset LatexCommand \label{sec:A-Rectangle-Decoder} \end_inset A \begin_inset Quotes sld \end_inset Rectangle \begin_inset Quotes srd \end_inset Decoder \layout Standard This example will help you to create a simple BER decoder of a simple \begin_inset Quotes sld \end_inset Rectangle \begin_inset Quotes srd \end_inset type used throughout this document. \layout Enumerate Create a file named \series bold rectangle.asn1 \series default with the following contents: \begin_deeper \layout LyX-Code RectangleModule1 DEFINITIONS ::= \layout LyX-Code BEGIN \layout LyX-Code \layout LyX-Code Rectangle ::= SEQUENCE { \layout LyX-Code height INTEGER, \layout LyX-Code width INTEGER \layout LyX-Code } \layout LyX-Code \layout LyX-Code END \end_deeper \layout Enumerate Compile it into the set of .c and .h files using asn1c compiler \begin_inset LatexCommand \cite{ASN1C} \end_inset : \begin_deeper \layout LyX-Code \emph on asn1c -fnative-types \series bold \emph default rectangle.asn1 \end_deeper \layout Enumerate Alternatively, use the Online ASN.1 compiler \begin_inset LatexCommand \cite{AONL} \end_inset by uploading the \series bold rectangle.asn1 \series default file into the Web form and unpacking the produced archive on your computer. \layout Enumerate By this time, you should have gotten multiple files in the current directory, including the \series bold Rectangle.c \series default and \series bold Rectangle.h \series default . \layout Enumerate Create a main() routine which takes the binary input file, decodes it as it were a BER-encoded Rectangle type, and prints out the text (XML) representat ion of the Rectangle type. Let's name the file \series bold main.c \series default : \begin_inset ERT status Collapsed \layout Standard \backslash clearpage{} \end_inset \begin_deeper \layout LyX-Code \size small #include \layout LyX-Code \size small #include \layout LyX-Code \size small #include /* Rectangle ASN.1 type */ \layout LyX-Code \size small \layout LyX-Code \size small int main(int ac, char **av) { \layout LyX-Code \size small char buf[1024]; /* Temporary buffer */ \layout LyX-Code \size small Rectangle_t *rectangle = 0; /* Type to decode */ \layout LyX-Code \size small asn_dec_rval_t rval; /* Decoder return value */ \layout LyX-Code \size small FILE *fp; /* Input file handler */ \layout LyX-Code \size small size_t size; /* Number of bytes read */ \layout LyX-Code \size small char *filename; /* Input file name */ \layout LyX-Code \size small \layout LyX-Code \size small /* Require a single filename argument */ \layout LyX-Code \size small if(ac != 2) { \layout LyX-Code \size small fprintf(stderr, \begin_inset Quotes sld \end_inset Usage: %s \backslash n \begin_inset Quotes srd \end_inset , av[0]); \layout LyX-Code \size small exit(64); /* better, EX_USAGE */ \layout LyX-Code \size small } else { \layout LyX-Code \size small filename = av[1]; \layout LyX-Code \size small } \layout LyX-Code \size small \layout LyX-Code \size small /* Open input file as read-only binary */ \layout LyX-Code \size small fp = fopen(filename, \begin_inset Quotes sld \end_inset rb \begin_inset Quotes srd \end_inset ); \layout LyX-Code \size small if(!fp) { \layout LyX-Code \size small perror(filename); \layout LyX-Code \size small exit(66); /* better, EX_NOINPUT */ \layout LyX-Code \size small } \layout LyX-Code \size small \layout LyX-Code \size small /* Read up to the buffer size */ \layout LyX-Code \size small size = fread(buf, 1, sizeof(buf), fp); \layout LyX-Code \size small fclose(fp); \layout LyX-Code \size small if(!size) { \layout LyX-Code \size small fprintf(stderr, \begin_inset Quotes sld \end_inset %s: Empty or broken \backslash n \begin_inset Quotes srd \end_inset , filename); \layout LyX-Code \size small exit(65); /* better, EX_DATAERR */ \layout LyX-Code \size small } \layout LyX-Code \size small \layout LyX-Code \size small /* Decode the input buffer as Rectangle type */ \layout LyX-Code \size small rval = ber_decode(0, &asn_DEF_Rectangle, \layout LyX-Code \size small (void **)&rectangle, buf, size); \layout LyX-Code \size small if(rval.code != RC_OK) { \layout LyX-Code \size small fprintf(stderr, \layout LyX-Code \size small \begin_inset Quotes sld \end_inset %s: Broken Rectangle encoding at byte %ld \backslash n \begin_inset Quotes srd \end_inset , \layout LyX-Code \size small filename, (long)rval.consumed); \layout LyX-Code \size small exit(65); /* better, EX_DATAERR */ \layout LyX-Code \size small } \layout LyX-Code \size small \layout LyX-Code \size small /* Print the decoded Rectangle type as XML */ \layout LyX-Code \size small xer_fprint(stdout, &asn_DEF_Rectangle, rectangle); \layout LyX-Code \size small \layout LyX-Code \size small return 0; /* Decoding finished successfully */ \layout LyX-Code \size small } \end_deeper \layout Enumerate Compile all files together using C compiler (varies by platform): \begin_deeper \layout LyX-Code \emph on cc -I. -o \series bold rdecode \series default *.c \end_deeper \layout Enumerate Voila! You have just created the BER decoder of a Rectangle type, named \series bold rdecode \series default ! \layout Chapter Constraint validation examples \layout Standard This chapter shows how to define ASN.1 constraints and use the generated validation code. \layout Section Adding constraints into \begin_inset Quotes sld \end_inset Rectangle \begin_inset Quotes srd \end_inset type \layout Standard This example shows how to add basic constraints to the ASN.1 specification and how to invoke the constraints validation code in your application. \layout Enumerate Create a file named \series bold rectangle.asn1 \series default with the following contents: \begin_deeper \layout LyX-Code RectangleModuleWithConstraints DEFINITIONS ::= \layout LyX-Code BEGIN \layout LyX-Code \layout LyX-Code Rectangle ::= SEQUENCE { \layout LyX-Code height INTEGER (0..100), -- Value range constraint \layout LyX-Code width INTEGER (0..MAX) -- Makes width non-negative \layout LyX-Code } \layout LyX-Code \layout LyX-Code END \end_deeper \layout Enumerate Compile the file according to procedures shown in the previous chapter. \layout Enumerate Modify the Rectangle type processing routine (you can start with the main() routine shown in the Section \begin_inset LatexCommand \vref{sec:A-Rectangle-Decoder} \end_inset ) by placing the following snippet of code \emph on before \emph default encoding and/or \emph on after \emph default decoding the Rectangle type \begin_inset Foot collapsed true \layout Standard Placing the constraint checking code \emph on before \emph default encoding helps to make sure you know the data is correct and within constraints before sharing the data with anyone else. \layout Standard Placing the constraint checking code \emph on after \emph default decoding, but before any further action depending on the decoded data, helps to make sure the application got the valid contents before making use of it. \end_inset : \begin_inset ERT status Collapsed \layout Standard \backslash clearpage{} \end_inset \begin_deeper \layout LyX-Code \size small int ret; /* Return value */ \layout LyX-Code \size small char errbuf[128]; /* Buffer for error message */ \layout LyX-Code \size small size_t errlen = sizeof(errbuf); /* Size of the buffer */ \layout LyX-Code \size small \layout LyX-Code \size small /* ... here may go Rectangle decoding code ... */ \layout LyX-Code \size small \layout LyX-Code \size small ret = asn_check_constraints(&asn_DEF_Rectangle, \layout LyX-Code \size small rectangle, errbuf, &errlen); \layout LyX-Code \size small /* assert(errlen < sizeof(errbuf)); // you may rely on that */ \layout LyX-Code \size small if(ret) { \layout LyX-Code \size small fprintf(stderr, \begin_inset Quotes sld \end_inset Constraint validation failed: %s \backslash n \begin_inset Quotes srd \end_inset , \layout LyX-Code \size small errbuf /* errbuf is properly nul-terminated */ \layout LyX-Code \size small ); \layout LyX-Code \size small /* exit(...); // Replace with appropriate action */ \layout LyX-Code \size small } \layout LyX-Code \size small \layout LyX-Code \size small /* ... here may go Rectangle encoding code ... */ \end_deeper \layout Enumerate Compile the resulting C code as shown in the previous chapters. \layout Enumerate Try to test the constraints checking code by assigning integer value 101 to the \series bold .height \series default member of the Rectangle structure, or a negative value to the \series bold .width \series default member. In either case, the program should print \begin_inset Quotes sld \end_inset Constraint validation failed \begin_inset Quotes srd \end_inset message, followed by the short explanation why validation did not succeed. \layout Enumerate Done. \layout Part \begin_inset LatexCommand \label{par:ASN.1-Basics} \end_inset ASN.1 Basics \layout Chapter \begin_inset LatexCommand \label{cha:Abstract-Syntax-Notation:} \end_inset Abstract Syntax Notation: ASN.1 \layout Standard \emph on This chapter defines some basic ASN.1 concepts and describes several most widely used types. It is by no means an authoritative or complete reference. For more complete ASN.1 description, please refer to Olivier Dubuisson's book \begin_inset LatexCommand \cite{Dub00} \end_inset or the ASN.1 body of standards itself \begin_inset LatexCommand \cite{ITU-T/ASN.1} \end_inset . \layout Standard The Abstract Syntax Notation One is used to formally describe the semantics of data transmitted across the network. Two communicating parties may have different formats of their native data types (i.e. number of bits in the integer type), thus it is important to have a way to describe the data in a manner which is independent from the particular machine's representation. The ASN.1 specifications are used to achieve the following: \layout Itemize The specification expressed in the ASN.1 notation is a formal and precise way to communicate the data semantics to human readers; \layout Itemize The ASN.1 specifications may be used as input for automatic compilers which produce the code for some target language (C, C++, Java, etc) to encode and decode the data according to some encoding rules (which are also defined by the ASN.1 standard). \layout Standard Consider the following example: \layout LyX-Code Rectangle ::= SEQUENCE { \layout LyX-Code height INTEGER, \layout LyX-Code width INTEGER \layout LyX-Code } \layout Standard This ASN.1 specification describes a constructed type, \emph on Rectangle \emph default , containing two integer fields. This specification may tell the reader that there exists this kind of data structure and that some entity may be prepared to send or receive it. The question on \emph on how \emph default that entity is going to send or receive the \emph on encoded data \emph default is outside the scope of ASN.1. For example, this data structure may be encoded according to some encoding rules and sent to the destination using the TCP protocol. The ASN.1 specifies several ways of encoding (or \begin_inset Quotes sld \end_inset serializing \begin_inset Quotes srd \end_inset , or \begin_inset Quotes sld \end_inset marshaling \begin_inset Quotes srd \end_inset ) the data: BER, PER, XER and others, including CER and DER derivatives from BER. \layout Standard The complete specification must be wrapped in a module, which looks like this: \layout LyX-Code RectangleModule1 \layout LyX-Code { iso org(3) dod(6) internet(1) private(4) \layout LyX-Code enterprise(1) spelio(9363) software(1) \layout LyX-Code asn1c(5) docs(2) rectangle(1) 1 } \layout LyX-Code DEFINITIONS AUTOMATIC TAGS ::= \layout LyX-Code BEGIN \layout LyX-Code \layout LyX-Code -- This is a comment which describes nothing. \layout LyX-Code Rectangle ::= SEQUENCE { \layout LyX-Code height INTEGER, -- Height of the rectangle \layout LyX-Code width INTEGER -- Width of the rectangle \layout LyX-Code } \layout LyX-Code \layout LyX-Code END \layout Standard The module header consists of module name (RectangleModule1), the module object identifier ({...}), a keyword \begin_inset Quotes sld \end_inset DEFINITIONS \begin_inset Quotes srd \end_inset , a set of module flags (AUTOMATIC TAGS) and \begin_inset Quotes sld \end_inset ::= BEGIN \begin_inset Quotes srd \end_inset . The module ends with an \begin_inset Quotes sld \end_inset END \begin_inset Quotes srd \end_inset statement. \layout Section Some of the ASN.1 Basic Types \layout Subsection The BOOLEAN type \layout Standard The BOOLEAN type models the simple binary TRUE/FALSE, YES/NO, ON/OFF or a similar kind of two-way choice. \layout Subsection The INTEGER type \layout Standard The INTEGER type is a signed natural number type without any restrictions on its size. If the automatic checking on INTEGER value bounds are necessary, the subtype constraints must be used. \layout LyX-Code SimpleInteger ::= INTEGER \layout LyX-Code \layout LyX-Code -- An integer with a very limited range \layout LyX-Code SmallPositiveInt ::= INTEGER (0..127) \layout LyX-Code \layout LyX-Code -- Integer, negative \layout LyX-Code NegativeInt ::= INTEGER (MIN..0) \layout Subsection The ENUMERATED type \layout Standard The ENUMERATED type is semantically equivalent to the INTEGER type with some integer values explicitly named. \layout LyX-Code FruitId ::= ENUMERATED { apple(1), orange(2) } \layout LyX-Code \layout LyX-Code -- The numbers in braces are optional, \layout LyX-Code -- the enumeration can be performed \layout LyX-Code -- automatically by the compiler \layout LyX-Code ComputerOSType ::= ENUMERATED { \layout LyX-Code FreeBSD, -- acquires value 0 \layout LyX-Code Windows, -- acquires value 1 \layout LyX-Code Solaris(5), -- remains 5 \layout LyX-Code Linux, -- becomes 6 \layout LyX-Code MacOS -- becomes 7 \layout LyX-Code } \layout Subsection The OCTET STRING type \layout Standard This type models the sequence of 8-bit bytes. This may be used to transmit some opaque data or data serialized by other types of encoders (i.e. video file, photo picture, etc). \layout Subsection The OBJECT IDENTIFIER type \layout Standard The OBJECT IDENTIFIER is used to represent the unique identifier of any object, starting from the very root of the registration tree. If your organization needs to uniquely identify something (a router, a room, a person, a standard, or whatever), you are encouraged to get your own identification subtree at \begin_inset LatexCommand \htmlurl{http://www.iana.org/protocols/forms.htm} \end_inset . \layout Standard For example, the very first ASN.1 module in this Chapter (RectangleModule1) has the following OBJECT IDENTIFIER: 1 3 6 1 4 1 9363 1 5 2 1 1. \layout LyX-Code ExampleOID ::= OBJECT IDENTIFIER \layout LyX-Code \layout LyX-Code rectangleModule1-oid ExampleOID \layout LyX-Code ::= { 1 3 6 1 4 1 9363 1 5 2 1 1 } \layout LyX-Code \layout LyX-Code -- An identifier of the Internet. \layout LyX-Code internet-id OBJECT IDENTIFIER \layout LyX-Code ::= { iso(1) identified-organization(3) \layout LyX-Code dod(6) internet(1) } \layout Standard As you see, names are optional. \layout Subsection The RELATIVE-OID type \layout Standard The RELATIVE-OID type has the semantics of a subtree of an OBJECT IDENTIFIER. There may be no need to repeat the whole sequence of numbers from the root of the registration tree where the only thing of interest is some of the tree's subsequence. \layout LyX-Code this-document RELATIVE-OID ::= { docs(2) usage(1) } \layout LyX-Code \layout LyX-Code this-example RELATIVE-OID ::= { \layout LyX-Code this-document assorted-examples(0) this-example(1) } \layout Section Some of the ASN.1 String Types \layout Subsection The IA5String type \layout Standard This is essentially the ASCII, with 128 character codes available (7 lower bits of an 8-bit byte). \layout Subsection The UTF8String type \layout Standard This is the character string which encodes the full Unicode range (4 bytes) using multibyte character sequences. \layout Subsection The NumericString type \layout Standard This type represents the character string with the alphabet consisting of numbers ( \begin_inset Quotes sld \end_inset 0 \begin_inset Quotes srd \end_inset to \begin_inset Quotes sld \end_inset 9 \begin_inset Quotes srd \end_inset ) and a space. \layout Subsection The PrintableString type \layout Standard The character string with the following alphabet: space, \begin_inset Quotes sld \end_inset \series bold ' \series default \begin_inset Quotes srd \end_inset (single quote), \begin_inset Quotes sld \end_inset \series bold ( \series default \begin_inset Quotes sld \end_inset , \begin_inset Quotes sld \end_inset \series bold ) \series default \begin_inset Quotes srd \end_inset , \begin_inset Quotes sld \end_inset \series bold + \series default \begin_inset Quotes srd \end_inset , \begin_inset Quotes sld \end_inset \series bold , \series default \begin_inset Quotes srd \end_inset (comma), \begin_inset Quotes sld \end_inset \series bold - \series default \begin_inset Quotes srd \end_inset , \begin_inset Quotes sld \end_inset \series bold . \series default \begin_inset Quotes srd \end_inset , \begin_inset Quotes sld \end_inset \series bold / \series default \begin_inset Quotes srd \end_inset , digits ( \begin_inset Quotes sld \end_inset 0 \begin_inset Quotes srd \end_inset to \begin_inset Quotes sld \end_inset 9 \begin_inset Quotes srd \end_inset ), \begin_inset Quotes sld \end_inset \series bold : \series default \begin_inset Quotes srd \end_inset , \begin_inset Quotes sld \end_inset \series bold = \series default \begin_inset Quotes srd \end_inset , \begin_inset Quotes sld \end_inset \series bold ? \series default \begin_inset Quotes srd \end_inset , upper-case and lower-case letters ( \begin_inset Quotes sld \end_inset A \begin_inset Quotes srd \end_inset to \begin_inset Quotes sld \end_inset Z \begin_inset Quotes srd \end_inset and \begin_inset Quotes sld \end_inset a \begin_inset Quotes srd \end_inset to \begin_inset Quotes sld \end_inset z \begin_inset Quotes srd \end_inset ). \layout Subsection The VisibleString type \layout Standard The character string with the alphabet which is more or less a subset of ASCII between the space and the \begin_inset Quotes sld \end_inset \series bold ~ \series default \begin_inset Quotes srd \end_inset symbol (tilde). \layout Standard Alternatively, the alphabet may be described as the PrintableString alphabet presented earlier, plus the following characters: \begin_inset Quotes sld \end_inset \series bold ! \series default \begin_inset Quotes srd \end_inset , \begin_inset Quotes sld \end_inset \series bold \begin_inset Quotes srd \end_inset \series default \begin_inset Quotes srd \end_inset , \begin_inset Quotes sld \end_inset \series bold # \series default \begin_inset Quotes srd \end_inset , \begin_inset Quotes sld \end_inset \series bold $ \series default \begin_inset Quotes srd \end_inset , \begin_inset Quotes sld \end_inset \series bold % \series default \begin_inset Quotes srd \end_inset , \begin_inset Quotes sld \end_inset \series bold & \series default \begin_inset Quotes srd \end_inset , \begin_inset Quotes sld \end_inset \series bold * \series default \begin_inset Quotes srd \end_inset , \begin_inset Quotes sld \end_inset \series bold ; \series default \begin_inset Quotes srd \end_inset , \begin_inset Quotes sld \end_inset \series bold < \series default \begin_inset Quotes srd \end_inset , \begin_inset Quotes sld \end_inset \series bold > \series default \begin_inset Quotes srd \end_inset , \begin_inset Quotes sld \end_inset \series bold [ \series default \begin_inset Quotes srd \end_inset , \begin_inset Quotes sld \end_inset \series bold \backslash \series default \begin_inset Quotes srd \end_inset , \begin_inset Quotes sld \end_inset \series bold ] \series default \begin_inset Quotes srd \end_inset , \begin_inset Quotes sld \end_inset \series bold ^ \series default \begin_inset Quotes srd \end_inset , \begin_inset Quotes sld \end_inset \series bold _ \series default \begin_inset Quotes srd \end_inset , \begin_inset Quotes sld \end_inset \series bold ` \series default \begin_inset Quotes srd \end_inset (single left quote), \begin_inset Quotes sld \end_inset \series bold { \series default \begin_inset Quotes srd \end_inset , \begin_inset Quotes sld \end_inset \series bold | \series default \begin_inset Quotes srd \end_inset , \begin_inset Quotes sld \end_inset \series bold } \series default \begin_inset Quotes srd \end_inset , \begin_inset Quotes sld \end_inset \series bold ~ \series default \begin_inset Quotes srd \end_inset . \layout Section ASN.1 Constructed Types \layout Subsection The SEQUENCE type \layout Standard This is an ordered collection of other simple or constructed types. The SEQUENCE constructed type resembles the C \begin_inset Quotes sld \end_inset struct \begin_inset Quotes srd \end_inset statement. \layout LyX-Code Address ::= SEQUENCE { \layout LyX-Code -- The apartment number may be omitted \layout LyX-Code apartmentNumber NumericString OPTIONAL, \layout LyX-Code streetName PrintableString, \layout LyX-Code cityName PrintableString, \layout LyX-Code stateName PrintableString, \layout LyX-Code -- This one may be omitted too \layout LyX-Code zipNo NumericString OPTIONAL \layout LyX-Code } \layout Subsection The SET type \layout Standard This is a collection of other simple or constructed types. Ordering is not important. The data may arrive in the order which is different from the order of specifica tion. Data is encoded in the order not necessarily corresponding to the order of specification. \layout Subsection The CHOICE type \layout Standard This type is just a choice between the subtypes specified in it. The CHOICE type contains at most one of the subtypes specified, and it is always implicitly known which choice is being decoded or encoded. This one resembles the C \begin_inset Quotes sld \end_inset union \begin_inset Quotes srd \end_inset statement. \layout Standard The following type defines a response code, which may be either an integer code or a boolean \begin_inset Quotes sld \end_inset true \begin_inset Quotes srd \end_inset / \begin_inset Quotes srd \end_inset false \begin_inset Quotes srd \end_inset code. \layout LyX-Code ResponseCode ::= CHOICE { \layout LyX-Code intCode INTEGER, \layout LyX-Code boolCode BOOLEAN \layout LyX-Code } \layout LyX-Code \layout Subsection The SEQUENCE OF type \layout Standard This one is the list (array) of simple or constructed types: \layout LyX-Code -- Example 1 \layout LyX-Code ManyIntegers ::= SEQUENCE OF INTEGER \layout LyX-Code \layout LyX-Code -- Example 2 \layout LyX-Code ManyRectangles ::= SEQUENCE OF Rectangle \layout LyX-Code \layout LyX-Code -- More complex example: \layout LyX-Code -- an array of structures defined in place. \layout LyX-Code ManyCircles ::= SEQUENCE OF SEQUENCE { \layout LyX-Code radius INTEGER \layout LyX-Code } \layout Subsection The SET OF type \layout Standard The SET OF type models the bag of structures. It resembles the SEQUENCE OF type, but the order is not important: i.e. the elements may arrive in the order which is not necessarily the same as the in-memory order on the remote machines. \layout LyX-Code -- A set of structures defined elsewhere \layout LyX-Code SetOfApples :: SET OF Apple \layout LyX-Code \layout LyX-Code -- Set of integers encoding the kind of a fruit \layout LyX-Code FruitBag ::= SET OF ENUMERATED { apple, orange } \layout Bibliography \bibitem [ASN1C]{ASN1C} The Open Source ASN.1 Compiler. \begin_inset LatexCommand \htmlurl{http://lionet.info/asn1c} \end_inset \layout Bibliography \bibitem [AONL]{AONL} Online ASN.1 Compiler. \begin_inset LatexCommand \htmlurl{http://lionet.info/asn1c/asn1c.cgi} \end_inset \layout Bibliography \bibitem [Dub00]{Dub00} Olivier Dubuisson --- \emph on ASN.1 Communication between heterogeneous systems \emph default --- Morgan Kaufmann Publishers, 2000. \begin_inset LatexCommand \htmlurl{http://asn1.elibel.tm.fr/en/book/} \end_inset . ISBN:0-12-6333361-0. \layout Bibliography \bibitem [ITU-T/ASN.1]{ITU-T/ASN.1} ITU-T Study Group 17 -- Languages for Telecommunication Systems \begin_inset LatexCommand \url{http://www.itu.int/ITU-T/studygroups/com17/languages/} \end_inset \the_end