Skip to content
Snippets Groups Projects
Forked from oai / asn1c
893 commits behind the upstream repository.
asn1c-usage.lyx 69.04 KiB
#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{Document describes 
\backslash 
href{http://lionet.info/asn1c}{asn1c-0.9.8}}
\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

ASN.1 Basics
\layout Chapter

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, CER, DER and XER, some of them which will be outlined later.
\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 document 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 Part

Using the ASN.1 Compiler
\layout Chapter

Introduction to the ASN.1 Compiler
\layout Standard

The purpose of the ASN.1 compiler, of which this document is part, is to
 convert the ASN.1 specifications to some other target language (currently,
 only C is supported
\begin_inset Foot
collapsed false

\layout Standard

C++ is 
\begin_inset Quotes sld
\end_inset 

supported
\begin_inset Quotes srd
\end_inset 

 too, as long as an class-based approach is not a definitive factor.
\end_inset 

).
 The compiler reads the specification and emits a series of target language
 structures and surrounding maintenance code.
 For example, the C structure which may be created by compiler to represent
 the simple 
\emph on 
Rectangle
\emph default 
 specification defined earlier in this document, may look like this
\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 Table 
\begin_inset LatexCommand \vref{cap:asn1c-cmdopts}

\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

This would not be of much value for such a simple specification, so the
 compiler goes further and actually produces the code which fills in this
 structure by parsing the opaque binary
\begin_inset Foot
collapsed true

\layout Standard

BER, CER and DER encodings are binary.
 However, the XER encoding is text (XML) based.
\end_inset 

 data provided in some buffer.
 It also produces the code that takes this structure as an argument and
 performs structure serialization by emitting a series of bytes.
\layout Chapter

Quick start
\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 specification
\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
 to find out about 
\series bold 
-P
\series default 
 and 
\series bold 
-R
\series default 
 options.
\end_inset 

:
\layout LyX-Code

asn1c 
\emph on 
<spec.asn1>
\layout Standard

If several specifications contain interdependencies, all of the files must
 be specified altogether:
\layout LyX-Code

asn1c 
\emph on 
<spec1.asn1> <spec2.asn1> ...
\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 
<spec-to-test.asn1>
\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 
<spec-to-compile-and-print.asn1>
\layout LyX-Code

\layout Chapter

Using the ASN.1 Compiler
\layout Section

Command-line options
\layout Standard

The Table 
\begin_inset LatexCommand \vref{cap:asn1c-cmdopts}

\end_inset 
 summarizes various options affecting the compiler's behavior.
\layout Standard


\begin_inset Float table
wide false
collapsed false

\layout Standard


\begin_inset  Tabular
<lyxtabular version="3" rows="22" columns="2">
<features islongtable="true">
<column alignment="left" valignment="top" leftline="true" width="0">
<column alignment="block" valignment="top" leftline="true" rightline="true" width="3in">
<row topline="true" bottomline="true">
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\layout Standard


\series bold 
Overall Options
\end_inset 
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\layout Standard


\series bold 
Description
\end_inset 
</cell>
</row>
<row topline="true">
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\layout Standard

-E
\end_inset 
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\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 
</cell>
</row>
<row topline="true">
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\layout Standard

-F
\end_inset 
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\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 
</cell>
</row>
<row topline="true">
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\layout Standard

-P
\end_inset 
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\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 
</cell>
</row>
<row topline="true">
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\layout Standard

-R
\end_inset 
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\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 
</cell>
</row>
<row topline="true">
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\layout Standard

-S 
\emph on 
<directory>
\end_inset 
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\layout Standard

\size small 
Use the specified directory with ASN.1 skeleton files.
\end_inset 
</cell>
</row>
<row topline="true" bottomline="true">
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\layout Standard

-X
\end_inset 
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\layout Standard

Generate the XML DTD for the specified ASN.1 modules.
\end_inset 
</cell>
</row>
<row topline="true">
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\layout Standard


\series bold 
Warning Options
\end_inset 
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\layout Standard


\series bold 
Description
\end_inset 
</cell>
</row>
<row topline="true">
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\layout Standard

-Werror
\end_inset 
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\layout Standard


\size small 
Treat warnings as errors; abort if any warning is produced.
\end_inset 
</cell>
</row>
<row topline="true">
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\layout Standard

-Wdebug-lexer
\end_inset 
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\layout Standard


\size small 
Enable lexer debugging during the ASN.1 parsing stage.
\end_inset 
</cell>
</row>
<row topline="true">
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\layout Standard

-Wdebug-fixer
\end_inset 
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\layout Standard


\size small 
 Enable ASN.1 syntax  tree  fixer  debugging  during  the  fixing stage.
\end_inset 
</cell>
</row>
<row topline="true" bottomline="true">
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\layout Standard

-Wdebug-compiler
\end_inset 
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\layout Standard


\size small 
Enable debugging during the actual compile time.
\end_inset 
</cell>
</row>
<row topline="true">
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\layout Standard


\series bold 
Language Options
\end_inset 
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\layout Standard


\series bold 
Description
\end_inset 
</cell>
</row>
<row topline="true">
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\layout Standard

-fall-defs-global
\end_inset 
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\layout Standard

Normally the compiler hides the definitions (asn_DEF_xxx) of the inner structure
 elements (members of SEQUENCE, SET and other types).
 This option makes all such definitions global.
 Enabling this option may pollute the namespace by making lots of asn_DEF_xxx
 structures globally visible, but will allow you to manipulate (encode and
 decode) the individual members of any complex ASN.1 structure.
\end_inset 
</cell>
</row>
<row topline="true">
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\layout Standard

-fbless-SIZE
\end_inset 
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\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 
</cell>
</row>
<row topline="true">
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\layout Standard

-fnative-types
\end_inset 
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\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 
</cell>
</row>
<row topline="true">
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\layout Standard

-fno-constraints
\end_inset 
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\layout Standard

Do not generate ASN.1 subtype constraint checking code.
 This may make a shorter executable.
\end_inset 
</cell>
</row>
<row topline="true">
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\layout Standard

-funnamed-unions
\end_inset 
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\layout Standard


\size small 
Enable  unnamed  unions  in the definitions of target language's structures.
\end_inset 
</cell>
</row>
<row topline="true" bottomline="true">
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\layout Standard

-ftypes88
\end_inset 
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\layout Standard


\size small 
Pretend to support only ASN.1:1988 embedded types.
 Certain reserved words, such as UniversalString and BMPString, become ordinary
 type references and may be redefined by the specification.
\end_inset 
</cell>
</row>
<row topline="true" newpage="true">
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text
\layout Standard


\series bold 
Output Options
\end_inset 
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\layout Standard


\series bold 
Description
\end_inset 
</cell>
</row>
<row topline="true">
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\layout Standard

-print-constraints
\end_inset 
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\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 
</cell>
</row>
<row topline="true" bottomline="true">
<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
\begin_inset Text

\layout Standard

-print-lines
\end_inset 
</cell>
<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
\begin_inset Text

\layout Standard


\size small 
Generate "-- #line" comments in -E output.
\end_inset 
</cell>
</row>
</lyxtabular>

\end_inset 


\layout Caption


\begin_inset LatexCommand \label{cap:asn1c-cmdopts}

\end_inset 

The list of asn1c command line options
\end_inset 


\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 specification 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 compiling will be rather small anyway.
\layout Standard

It is your responsibility to create .c file with the
\emph on 
 int main()
\emph default 
 routine and the Makefile (if needed).
 Compiler helps you with the latter by creating the Makefile.am.sample, containing
 the skeleton definition for the automake, should you want to use autotools.
\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 the 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 -o rectangle *.c   # It could be 
\emph on 
that
\emph default 
 simple
\begin_inset Foot
collapsed false

\layout Standard

Provided that you've also created a .c file with the 
\emph on 
int main()
\emph default 
 routine.
\end_inset 


\layout Section

Invoking the ASN.1 helper code from an application
\begin_inset OptArg
collapsed true

\layout Standard

Invoking the helper code
\end_inset 


\layout Standard

First of all, you should to include one or more header files into your applicati
on.
 For our Rectangle module, including the Rectangle.h file is enough:
\layout LyX-Code

#include <Rectangle.h>
\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 free_struct 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 generic routines to
 deal with the Rectangle_t structure.
\layout Standard

There are several generic functions available:
\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.
 Please refer to Section 
\begin_inset LatexCommand \ref{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.
 Please refer to Section 
\begin_inset LatexCommand \ref{sub:Encoding-DER}

\end_inset 

.
\layout Description

xer_encoder This is the generic XER encoder (XML Encoding Rules).
 This encoder will take the target structure and represent it as an XML
 (text) document.
 Please refer to Section 
\begin_inset LatexCommand \ref{sub:Encoding-XER}

\end_inset 

.
\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.
 Please refer to 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.
 Please refer to Section 
\begin_inset LatexCommand \ref{sub:Printing-the-target}

\end_inset 

.
\layout Description

free_struct This is a generic disposal which frees the target structure.
 Please refer to Section 
\begin_inset LatexCommand \ref{sub:Freeing-the-target}

\end_inset 

.
\layout Standard

check_constraints Check that the contents of the target structure are semantical
ly valid and constrained to appropriate implicit or explicit subtype constraints.
 Please refer to Section 
\begin_inset LatexCommand \vref{sub:Validating-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).
 The target structure is typically created by the generic BER decoder or
 by the application itself.
\layout Standard

Here is how the buffer can be deserialized into the structure:
\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 = asn_DEF_Rectangle->ber_decoder(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 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 generic 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 NULL.
 
\series bold 
This 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

Restartable decoding is a little bit trickier: you need to provide the old
 target structure pointer (which might be already half-decoded) and react
 on RC_WMORE return code.
 This will be explained later in Section 
\begin_inset LatexCommand \vref{sub:Decoding-BER}

\end_inset 


\layout Subsection


\begin_inset LatexCommand \label{sub:Decoding-BER}

\end_inset 

Decoding BER
\layout Standard

The Basic Encoding Rules describe the basic way how the structure can be
 encoded and decoded.
 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

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
 it is available and ask for more data to be provided.
 Please note that the decoder may actually process less data than it is
 given in the buffer, which means that you should 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 latter 200 bytes from the second buffer.
\layout Standard

This is not as convenient as it could be (like, the BER encoder would consume
 the whole 100 bytes and keep these 5 bytes in some temporary storage),
 but in case of stream-based processing it might actually be OK.
 Suggestions are welcome.
\layout Standard

There are two ways to invoke a BER decoder.
 The first one is a direct reference of the type-specific decoder.
 This way was shown in the previous example of 
\emph on 
simple_deserializer
\emph default 
 function.
 The second way is to invoke a 
\emph on 
ber_decode
\emph default 
 function, which is just a simple wrapper of the former approach into a
 less wordy notation:
\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 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.
 The DER encoding is used, for example, 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_Rect, 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: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 etc etc are recursively freed too.
 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;           /* <some custom member> */
\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 memory allocation routine, but
 instead lies within such a block allocated for my_figure structure.
\layout Standard

To solve this problem, the free_struct routine has the additional argument
 (besides the intuitive 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

/* Rectangle_t is defined within my_figure */
\layout LyX-Code

struct my_figure *mf = 
\series bold 
...
\series default 
;
\layout LyX-Code

/*
\layout LyX-Code

 * Freeing the Rectangle_td
\layout LyX-Code

 * without freeing the mf->rect pointer
\layout LyX-Code

 */
\layout LyX-Code

asn_DEF_Rectangle->free_struct(
\layout LyX-Code

    &asn_DEF_Rectangle, &mf->rect, 
\emph on 
1
\emph default 
 /* !free */);
\layout LyX-Code

 
\layout LyX-Code

/* 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, 
\emph on 
0
\emph default 
 /* free the pointer too */);
\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 Part

Examples
\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 to 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 <stdio.h>
\layout LyX-Code


\size small 
#include <sys/types.h>
\layout LyX-Code


\size small 
#include <Rectangle.h>   /* 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 
w
\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 <stdio.h>
\layout LyX-Code


\size small 
#include <sys/types.h>
\layout LyX-Code


\size small 
#include <Rectangle.h>   /* 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 <file.ber>
\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 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