blob: bb09d12867d1aa012cd7981ee202c5fca06cfd0e [file] [log] [blame]
Lev Walkin464166c2010-11-09 08:34:38 -08001\documentclass[english,oneside,12pt]{book}
Lev Walkin194b2102013-03-28 01:29:06 -07002\usepackage[no-math]{fontspec}
3\usepackage{MnSymbol}
Lev Walkin464166c2010-11-09 08:34:38 -08004\usepackage{xunicode}
5\usepackage{xltxtra}
6
Lev Walkin11c9a8c2013-03-26 00:46:55 -07007\usepackage[hmargin={1in,1in},vmargin={1.5in,1.5in}]{geometry}
Lev Walkin464166c2010-11-09 08:34:38 -08008
9\defaultfontfeatures{Mapping=tex-text}
Lev Walkin11c9a8c2013-03-26 00:46:55 -070010\setmainfont{PT Sans}
11\setsansfont{PT Sans}
Lev Walkin464166c2010-11-09 08:34:38 -080012\setmonofont{Consolas}
13
Lev Walkined44bf42010-11-08 02:04:55 -080014\usepackage{fancyhdr}
Lev Walkined44bf42010-11-08 02:04:55 -080015\usepackage{longtable}
Lev Walkin464166c2010-11-09 08:34:38 -080016\usepackage{booktabs}
Lev Walkined44bf42010-11-08 02:04:55 -080017\usepackage{varioref}
18\usepackage{url}
Lev Walkin11c9a8c2013-03-26 00:46:55 -070019\usepackage{xcolor}
20\usepackage{listings}
21\usepackage{setspace}
Lev Walkin194b2102013-03-28 01:29:06 -070022\usepackage{unicode-math}
23\usepackage{perpage}
24\MakePerPage{footnote}
Lev Walkin11c9a8c2013-03-26 00:46:55 -070025
26\setstretch{1.1}
27
28% Courier 10 Pitch
29\def\courierFont{Courier10 BT WGL4}
30%\def\courierFont{Consolas}
31\setmonofont[Scale=1.05]{\courierFont}
Lev Walkin194b2102013-03-28 01:29:06 -070032\setmathfont[Scale=1.05]{Cambria Math}
Lev Walkin11c9a8c2013-03-26 00:46:55 -070033
Lev Walkined44bf42010-11-08 02:04:55 -080034
35\makeatletter
36
Lev Walkined44bf42010-11-08 02:04:55 -080037%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Textclass specific LaTeX commands.
Lev Walkin11c9a8c2013-03-26 00:46:55 -070038\lstloadlanguages{C,bash}
39\newfontfamily\listingfont[Scale=1.05]{\courierFont}
40\newfontfamily\inlinelistingfont[Scale=1.05]{\courierFont}
41\definecolor{clrlcomment}{gray}{0.3}
42\definecolor{clrlkeyword}{rgb}{0.588,0.145,0.18}
43\newcommand{\listingkeyword}[1]{\color{clrlkeyword}{#1}}
44\newcommand{\listingstring}[1]{\color{clrlcomment}{#1}}
45\newcommand{\listingcomment}[1]{\color{clrlcomment}{#1}}
46\lstset{tabsize=4,
47 showstringspaces=false,
48 showtabs=false,
49 showspaces=false,
50 keywordstyle=\listingkeyword,
51 stringstyle=\listingstring,
52 commentstyle=\listingcomment,
53 xleftmargin=\parindent,
54 columns=fixed,
55 escapechar=\%,
56 texcl
57}
58\lstdefinestyle{listingStyle}{
59 basicstyle=\small\listingfont,
60 stringstyle=\listingstring,
61 breaklines=true,
62 breakatwhitespace=true,
63 flexiblecolumns=false
64 }
65\lstdefinelanguage{asn1}{
66 morekeywords={DEFINITIONS,BEGIN,END,SEQUENCE,SET,OF,CHOICE,OPTIONAL},
67 morecomment=[l]{--},
68 morecomment=[n]{/*}{*/}
69 }
70
71\lstnewenvironment{codesample}[1][]{\lstset{style=listingStyle,language=C,#1}}{}
Lev Walkin2a744a72013-03-27 01:56:23 -070072\lstnewenvironment{bash}[1][]{\lstset{style=listingStyle,language=bash,#1}}{}
Lev Walkin11c9a8c2013-03-26 00:46:55 -070073\lstnewenvironment{asn}[1][]{\lstset{style=listingStyle,language=asn1,#1}}{}
74\def\code{lstinline}
Lev Walkined44bf42010-11-08 02:04:55 -080075
76%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% User specified LaTeX commands.
77\usepackage{extramarks}
78\lhead{\firstxmark}
79\rfoot{\lastxmark}
Lev Walkin11c9a8c2013-03-26 00:46:55 -070080\definecolor{clrlink}{rgb}{0,0.4,0}
81\definecolor{clrurl}{rgb}{0,0,.6}
Lev Walkined44bf42010-11-08 02:04:55 -080082\usepackage[colorlinks=true,
Lev Walkin11c9a8c2013-03-26 00:46:55 -070083 linkcolor={clrlink},
84 citecolor={clrlink},
85 urlcolor={clrurl},
86 pdfauthor={Lev Walkin},
87 pdftitle={Using the Open Source ASN.1 Compiler},
88 pdfkeywords={ASN.1,asn1c,compiler},
89 bookmarksopen,bookmarksopenlevel=1,
90 pdffitwindow,
91 xetex
Lev Walkined44bf42010-11-08 02:04:55 -080092]{hyperref}
Lev Walkined44bf42010-11-08 02:04:55 -080093
94\makeatother
95
96\usepackage{babel}
97
98\begin{document}
99
Lev Walkin50155de2014-10-26 19:46:16 -0700100\title{Using the Open Source ASN.1 Compiler\\
101\vspace*{1cm}
102\Large Documentation for asn1c version \asnver{}}
Lev Walkined44bf42010-11-08 02:04:55 -0800103\author{Lev Walkin <\href{mailto:vlm@lionet.info?Subject=asn1c}{vlm@lionet.info}>}
104
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700105\pagestyle{fancy}
106\fancyhead[L]{\leftmark}
Lev Walkin50155de2014-10-26 19:46:16 -0700107\fancyhead[R]{\href{http://lionet.info/asn1c}{asn1c-\asnver}}
Lev Walkined44bf42010-11-08 02:04:55 -0800108\maketitle
Lev Walkined44bf42010-11-08 02:04:55 -0800109
110\tableofcontents{}
111
Lev Walkined44bf42010-11-08 02:04:55 -0800112\part{Using the ASN.1 Compiler}
113
114
115\chapter{Introduction to the ASN.1 Compiler}
116
117The purpose of the ASN.1 compiler is to convert the specifications
118in ASN.1 notation into some other language. At this moment, only C
119and C++ target languages are supported, the latter is in upward compatibility
120mode.
121
122The compiler reads the specification and emits a series of target
Lev Walkin464166c2010-11-09 08:34:38 -0800123language structures (C structs, unions, enums) describing the corresponding
Lev Walkined44bf42010-11-08 02:04:55 -0800124ASN.1 types. The compiler also creates the code which allows automatic
125serialization and deserialization of these structures using several
Lev Walkin464166c2010-11-09 08:34:38 -0800126standardized encoding rules (BER, DER, XER, PER).
Lev Walkined44bf42010-11-08 02:04:55 -0800127
128For example, suppose the following ASN.1 module is given%
Lev Walkin194b2102013-03-28 01:29:06 -0700129\footnote{Part \ref{par:ASN.1-Basics} provides a quick reference
Lev Walkin464166c2010-11-09 08:34:38 -0800130on the ASN.1 notation.}:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700131\begin{asn}
132RectangleTest DEFINITIONS ::= BEGIN
Lev Walkined44bf42010-11-08 02:04:55 -0800133
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700134Rectangle ::= SEQUENCE {
135 height INTEGER, -- Height of the rectangle
136 width INTEGER -- Width of the rectangle
137}
Lev Walkined44bf42010-11-08 02:04:55 -0800138
139END
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700140\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -0800141The compiler would read this ASN.1 definition and produce the following
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700142C type:
143\begin{codesample}
144typedef struct Rectangle_s {
145 long height;
146 long width;
147} Rectangle_t;
148\end{codesample}
Lev Walkined44bf42010-11-08 02:04:55 -0800149It would also create the code for converting this structure into platform-independent
150wire representation (a serializer API) and the decoder of such wire
151representation back into local, machine-specific type (a deserializer
152API).
153
154
155\section{Quick start with asn1c}
156
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700157After building and installing the compiler, the \emph{asn1c}
158command may be used to compile the ASN.1 modules%
Lev Walkin194b2102013-03-28 01:29:06 -0700159\footnote{This is probably \textbf{not} what you want to try out right now. Read through the rest of this chapter and check the Section~\ref{sec:Command-line-options}
Lev Walkined44bf42010-11-08 02:04:55 -0800160to find out about \textbf{-P} and \textbf{-R} options.%
161}:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700162\begin{bash}
163asn1c %\emph{<modules.asn1>}%
164\end{bash}
Lev Walkined44bf42010-11-08 02:04:55 -0800165If several ASN.1 modules contain interdependencies, all of the files
166must be specified altogether:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700167\begin{bash}
168asn1c %\emph{<module1.asn1> <module2.asn1> ...}%
169\end{bash}
Lev Walkined44bf42010-11-08 02:04:55 -0800170The compiler \textbf{-E} and \textbf{-EF} options are used for testing
171the parser and the semantic fixer, respectively. These options will
172instruct the compiler to dump out the parsed (and fixed, if \textbf{-F}
Lev Walkin2a744a72013-03-27 01:56:23 -0700173is involved) ASN.1 specification as it was understood
Lev Walkined44bf42010-11-08 02:04:55 -0800174by the compiler. It might be useful to check whether a particular
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700175syntactic construct is properly supported by the compiler.
176\begin{bash}
177asn1c %\textbf{-EF} \emph{<module-to-test.asn1>}%
178\end{bash}
Lev Walkined44bf42010-11-08 02:04:55 -0800179The \textbf{-P} option is used to dump the compiled output on the
180screen instead of creating a bunch of .c and .h files on disk in the
181current directory. You would probably want to start with \textbf{-P}
182option instead of creating a mess in your current directory. Another
183option, \textbf{-R}, asks compiler to only generate the files which
184need to be generated, and supress linking in the numerous support
185files.
186
187Print the compiled output instead of creating multiple source files:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700188\begin{bash}
189asn1c %\textbf{-P} \emph{<module-to-compile-and-print.asn1>}%
190\end{bash}
Lev Walkined44bf42010-11-08 02:04:55 -0800191
Lev Walkin2a744a72013-03-27 01:56:23 -0700192\clearpage{}
Lev Walkined44bf42010-11-08 02:04:55 -0800193\section{Recognizing compiler output}
194
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700195The asn1c compiler produces a number of files:
Lev Walkined44bf42010-11-08 02:04:55 -0800196\begin{itemize}
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700197\item A set of .c and .h files for each type defined
198in the ASN.1 specification. These files will be named similarly to
Lev Walkined44bf42010-11-08 02:04:55 -0800199the ASN.1 types (\emph{Rectangle.c} and \emph{Rectangle.h} for the
200RectangleTest ASN.1 module defined in the beginning of this document).
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700201\item A set of helper .c and .h files which contain the generic encoders,
202decoders and other useful routines. There will be quite a few of them, some
203of them are not even always necessary, but the overall amount of code
Lev Walkined44bf42010-11-08 02:04:55 -0800204after compilation will be rather small anyway.
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700205\item A \emph{converter-sample.c} file containing the \emph{int main()} function with a fully functioning decoder. It can convert a given PDU between BER, XER and possibly PER (if -gen-PER option to asn1c was in effect). At some point you will want to replace this file with your own file containing the \emph{int main()} function.
Lev Walkined44bf42010-11-08 02:04:55 -0800206\item A \emph{Makefile.am.sample} file mentioning all the files created
207at the earlier steps. This file is suitable for either automake suite
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700208or the plain `make` utility. Just rename it into \emph{Makefile}.
Lev Walkined44bf42010-11-08 02:04:55 -0800209\end{itemize}
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700210It is possible to compile everything with just a couple of instructions:
211\begin{bash}
Lev Walkin2a744a72013-03-27 01:56:23 -0700212asn1c -pdu=%\emph{Rectangle}% *.asn1
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700213make -f Makefile.am.sample # If you use `make`
214\end{bash}
215or
216\begin{bash}
Lev Walkin2a744a72013-03-27 01:56:23 -0700217asn1c *.asn1
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700218cc -I. -DPDU=%\emph{Rectangle}% -o rectangle.exe *.c # ... or like this
219\end{bash}
Lev Walkin194b2102013-03-28 01:29:06 -0700220Refer to the Chapter \ref{cha:Step-by-step-examples} for a sample
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700221\emph{int main()} function if you want some custom logic and not satisfied
222with the supplied \emph{converter-sample.c}.
Lev Walkined44bf42010-11-08 02:04:55 -0800223
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700224\clearpage{}
Lev Walkined44bf42010-11-08 02:04:55 -0800225\section{\label{sec:Command-line-options}Command line options}
226
227The following table summarizes the asn1c command line options.
228
Lev Walkin464166c2010-11-09 08:34:38 -0800229\renewcommand{\arraystretch}{1.33}
230\begin{longtable}{lp{4in}}
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700231\textbf{Overall Options} & \textbf{Description}\\
Lev Walkin464166c2010-11-09 08:34:38 -0800232\midrule
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700233{-E} & {\small Stop after the parsing stage and print the reconstructed ASN.1
234specification code to the standard output.}\\
235{-F} & {\small Used together with -E, instructs the compiler to stop after
Lev Walkined44bf42010-11-08 02:04:55 -0800236the ASN.1 syntax tree fixing stage and dump the reconstructed ASN.1
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700237specification to the standard output.}\\
238{-P} & {\small Dump the compiled output to the standard output instead of
239creating the target language files on disk.}\\
240{-R} & {\small Restrict the compiler to generate only the ASN.1 tables, omitting the usual support code.}\\
241{-S}~\emph{<directory>} & {\small Use the specified directory with ASN.1 skeleton files.}\\
242{-X} & {\small Generate the XML DTD for the specified ASN.1 modules.}\\\\
243\textbf{Warning Options} & \textbf{Description}\\
Lev Walkin464166c2010-11-09 08:34:38 -0800244\midrule
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700245{-Werror} & {\small Treat warnings as errors; abort if any warning is produced.}\\
246{-Wdebug-lexer} & {\small Enable lexer debugging during the ASN.1 parsing stage.}\\
247{-Wdebug-fixer} & {\small Enable ASN.1 syntax tree fixer debugging during the
248 fixing stage.}\\
249{-Wdebug-compiler} & {\small Enable debugging during the actual compile time.}\\ \\
250\textbf{Language Options} & \textbf{Description}\\
Lev Walkin464166c2010-11-09 08:34:38 -0800251\midrule
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700252{-fbless-SIZE} & {\small Allow SIZE() constraint for INTEGER, ENUMERATED, and other
Lev Walkined44bf42010-11-08 02:04:55 -0800253types for which this constraint is normally prohibited by the standard.
254This is a violation of an ASN.1 standard and compiler may fail to
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700255produce the meaningful code.}\\
256{-fcompound-names} & {\small Use complex names for C structures. Using complex names prevents
Lev Walkined44bf42010-11-08 02:04:55 -0800257name clashes in case the module reuses the same identifiers in multiple
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700258contexts.}\\
259{-findirect-choice} & {\small When generating code for a CHOICE type, compile the CHOICE
Lev Walkined44bf42010-11-08 02:04:55 -0800260members as indirect pointers instead of declaring them inline. Consider
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700261using this option together with \textbf{-fno-include-deps}
262to prevent circular references. }\\
263{-fknown-extern-type=}\emph{<name>} & {\small Pretend the specified type is known. The compiler will assume
Lev Walkined44bf42010-11-08 02:04:55 -0800264the target language source files for the given type have been provided
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700265manually. }\\
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700266{-fno-constraints} & {\small Do not generate ASN.1 subtype constraint checking code. This
267may produce a shorter executable.}\\
268{-fno-include-deps} & {\small Do not generate courtesy \#include lines for non-critical
269dependencies.}\\
Lev Walkin2a744a72013-03-27 01:56:23 -0700270{-funnamed-unions} & {\small Enable unnamed unions in the definitions of target language's structures.}\\
271{-fwide-types} & {\small Use the wide integer types (INTEGER\_t, REAL\_t) instead of machine's native data types (long, double). }\\\\
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700272\textbf{Codecs Generation Options} & \textbf{Description}\\
Lev Walkin464166c2010-11-09 08:34:38 -0800273\midrule
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700274{-gen-PER} & {\small Generate Packed Encoding Rules (PER) support code.}\\
275{-pdu=}\emph{auto} & {\small Generate PDU tables by discovering Protocol Data Units automatically. Also accepts a special keyword \emph{all} or a particular type to be used as a PDU.}\\ \\
276\textbf{Output Options} & \textbf{Description}\\
Lev Walkin464166c2010-11-09 08:34:38 -0800277\midrule
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700278{-print-constraints} & {\small When -EF are also specified, this option forces the compiler
279to explain its internal understanding of subtype constraints.}\\
280{-print-lines} & {\small Generate ``-{}- \#line'' comments
281in -E output.}\\
Lev Walkined44bf42010-11-08 02:04:55 -0800282\end{longtable}
Lev Walkin464166c2010-11-09 08:34:38 -0800283\renewcommand{\arraystretch}{1}
Lev Walkined44bf42010-11-08 02:04:55 -0800284
285
286\chapter{Using the ASN.1 Compiler}
287
288
289\section[Invoking the helper code]{Invoking the ASN.1 helper code}
290
291First of all, you should include one or more header files into your
292application. Typically, it is enough to include the header file of
293the main PDU type. For our Rectangle module, including the Rectangle.h
294file is sufficient:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700295\begin{codesample}
296#include <Rectangle.h>
297\end{codesample}
Lev Walkined44bf42010-11-08 02:04:55 -0800298The header files defines the C structure corresponding to the ASN.1
299definition of a rectangle and the declaration of the ASN.1 type descriptor,
300which is used as an argument to most of the functions provided by
301the ASN.1 module. For example, here is the code which frees the Rectangle\_t
302structure:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700303\begin{codesample}
304Rectangle_t *rect = ...;
Lev Walkined44bf42010-11-08 02:04:55 -0800305
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700306asn_DEF_Rectangle.free_struct(&asn_DEF_Rectangle, rect, 0);
307\end{codesample}
Lev Walkined44bf42010-11-08 02:04:55 -0800308This code defines a \emph{rect} pointer which points to the Rectangle\_t
309structure which needs to be freed. The second line invokes the generic
310\emph{free\_struct()} routine created specifically for this Rectangle\_t
311structure. The \emph{asn\_DEF\_Rectangle} is the type descriptor,
312which holds a collection of routines to deal with the Rectangle\_t
313structure.
314
315The following member functions of the asn\_DEF\_Rectangle type descriptor
316are of interest:
317\begin{description}
318\item [{ber\_decoder}] This is the generic \emph{restartable}%
319\footnote{Restartable means that if the decoder encounters the end of the buffer,
320it will fail, but may later be invoked again with the rest of the
321buffer to continue decoding.%
322} BER decoder (Basic Encoding Rules). This decoder would create and/or
Lev Walkin194b2102013-03-28 01:29:06 -0700323fill the target structure for you. See Section~\ref{sub:Decoding-BER}.
Lev Walkined44bf42010-11-08 02:04:55 -0800324\item [{der\_encoder}] This is the generic DER encoder (Distinguished Encoding
325Rules). This encoder will take the target structure and encode it
Lev Walkin194b2102013-03-28 01:29:06 -0700326into a series of bytes. See Section~\ref{sub:Encoding-DER}. NOTE:
Lev Walkined44bf42010-11-08 02:04:55 -0800327DER encoding is a subset of BER. Any BER decoder should be able to
328handle DER input.
329\item [{xer\_decoder}] This is the generic XER decoder. It takes both BASIC-XER
330or CANONICAL-XER encodings and deserializes the data into a local,
Lev Walkin194b2102013-03-28 01:29:06 -0700331machine-dependent representation. See Section~\ref{sub:Decoding-XER}.
Lev Walkined44bf42010-11-08 02:04:55 -0800332\item [{xer\_encoder}] This is the XER encoder (XML Encoding Rules). This
333encoder will take the target structure and represent it as an XML
334(text) document using either BASIC-XER or CANONICAL-XER encoding rules.
Lev Walkin194b2102013-03-28 01:29:06 -0700335See Section~\ref{sub:Encoding-XER}.
Lev Walkined44bf42010-11-08 02:04:55 -0800336\item [{uper\_decoder}] This is the Unaligned PER decoder.
337\item [{uper\_encoder}] This is the Unaligned Basic PER encoder. This encoder
338will take the target structure and encode it into a series of bytes.
339\item [{check\_constraints}] Check that the contents of the target structure
340are semantically valid and constrained to appropriate implicit or
Lev Walkin194b2102013-03-28 01:29:06 -0700341explicit subtype constraints. See Section~\ref{sub:Validating-the-target}.
Lev Walkined44bf42010-11-08 02:04:55 -0800342\item [{print\_struct}] This function convert the contents of the passed
343target structure into human readable form. This form is not formal
344and cannot be converted back into the structure, but it may turn out
Lev Walkin194b2102013-03-28 01:29:06 -0700345to be useful for debugging or quick-n-dirty printing. See Section~\ref{sub:Printing-the-target}.
Lev Walkined44bf42010-11-08 02:04:55 -0800346\item [{free\_struct}] This is a generic disposal which frees the target
Lev Walkin194b2102013-03-28 01:29:06 -0700347structure. See Section~\ref{sub:Freeing-the-target}.
Lev Walkined44bf42010-11-08 02:04:55 -0800348\end{description}
349Each of the above function takes the type descriptor (\emph{asn\_DEF\_\ldots{}})
350and the target structure (\emph{rect}, in the above example).
351
352
353\subsection{\label{sub:Decoding-BER}Decoding BER}
354
355The Basic Encoding Rules describe the most widely used (by the ASN.1
356community) way to encode and decode a given structure in a machine-independent
357way. Several other encoding rules (CER, DER) define a more restrictive
358versions of BER, so the generic BER parser is also capable of decoding
359the data encoded by CER and DER encoders. The opposite is not true.
360
361\emph{The ASN.1 compiler provides the generic BER decoder which is
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700362capable of decoding BER, CER and DER encoded data.}
Lev Walkined44bf42010-11-08 02:04:55 -0800363
364The decoder is restartable (stream-oriented), which means that in
365case the buffer has less data than it is expected, the decoder will
366process whatever there is available and ask for more data to be provided.
367Please note that the decoder may actually process less data than it
368was given in the buffer, which means that you must be able to make
369the next buffer contain the unprocessed part of the previous buffer.
370
371Suppose, you have two buffers of encoded data: 100 bytes and 200 bytes.
372\begin{itemize}
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700373\item You can concatenate these buffers and feed the BER decoder with 300
Lev Walkined44bf42010-11-08 02:04:55 -0800374bytes of data, or
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700375\item You can feed it the first buffer of 100 bytes of data, realize that
Lev Walkined44bf42010-11-08 02:04:55 -0800376the ber\_decoder consumed only 95 bytes from it and later feed the
377decoder with 205 bytes buffer which consists of 5 unprocessed bytes
378from the first buffer and the additional 200 bytes from the second
379buffer.
380\end{itemize}
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700381This is not as convenient as it could be (the BER encoder could
Lev Walkined44bf42010-11-08 02:04:55 -0800382consume the whole 100 bytes and keep these 5 bytes in some temporary
383storage), but in case of existing stream based processing it might
384actually fit well into existing algorithm. Suggestions are welcome.
385
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700386Here is the simplest example of BER decoding:
Lev Walkined44bf42010-11-08 02:04:55 -0800387
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700388\begin{codesample}
389Rectangle_t *
390simple_deserializer(const void *buffer, size_t buf_size) {
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700391 asn_dec_rval_t rval;
Lev Walkin194b2102013-03-28 01:29:06 -0700392 Rectangle_t *%$\underbracket{\textrm{\listingfont rect = 0}}$%; /* %\textbf{\color{red}Note this 0\footnote{Forgetting to properly initialize the pointer to a destination structure is a major source of support requests.}!}% */
Lev Walkined44bf42010-11-08 02:04:55 -0800393
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700394 rval = %\textbf{asn\_DEF\_Rectangle.ber\_decoder}%(0,
395 &asn_DEF_Rectangle,
Lev Walkin194b2102013-03-28 01:29:06 -0700396 (void **) %$\underbracket{\textrm{\listingfont \&rect}}$%, /* Decoder %\emph{moves}% the pointer */
397 buffer, buf_size, 0);
Lev Walkined44bf42010-11-08 02:04:55 -0800398
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700399 if(rval%\textbf{.code}% == RC_OK) {
400 return rect; /* Decoding succeeded */
401 } else {
402 /* Free partially decoded rect */
403 asn_DEF_Rectangle.free_struct(&asn_DEF_Rectangle, rect, 0);
404 return 0;
405 }
406}
407\end{codesample}
Lev Walkined44bf42010-11-08 02:04:55 -0800408The code above defines a function, \emph{simple\_deserializer}, which
409takes a buffer and its length and is expected to return a pointer
410to the Rectangle\_t structure. Inside, it tries to convert the bytes
411passed into the target structure (rect) using the BER decoder and
412returns the rect pointer afterwards. If the structure cannot be deserialized,
413it frees the memory which might be left allocated by the unfinished
414\emph{ber\_decoder} routine and returns 0 (no data). (This \textbf{freeing
415is necessary} because the ber\_decoder is a restartable procedure,
416and may fail just because there is more data needs to be provided
417before decoding could be finalized). The code above obviously does
418not take into account the way the \emph{ber\_decoder()} failed, so
419the freeing is necessary because the part of the buffer may already
420be decoded into the structure by the time something goes wrong.
421
422A little less wordy would be to invoke a globally available \emph{ber\_decode()}
423function instead of dereferencing the asn\_DEF\_Rectangle type descriptor:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700424\begin{codesample}
425rval = ber_decode(0, &asn_DEF_Rectangle, (void **)&rect, buffer, buf_size);
426\end{codesample}
Lev Walkined44bf42010-11-08 02:04:55 -0800427Note that the initial (asn\_DEF\_Rectangle.ber\_decoder) reference
428is gone, and also the last argument (0) is no longer necessary.
429
430These two ways of BER decoder invocations are fully equivalent.
431
432The BER de\emph{coder} may fail because of (\emph{the following RC\_\ldots{}
433codes are defined in ber\_decoder.h}):
434\begin{itemize}
435\item RC\_WMORE: There is more data expected than it is provided (stream
436mode continuation feature);
437\item RC\_FAIL: General failure to decode the buffer;
438\item \ldots{} other codes may be defined as well.
439\end{itemize}
440Together with the return code (.code) the asn\_dec\_rval\_t type contains
441the number of bytes which is consumed from the buffer. In the previous
442hypothetical example of two buffers (of 100 and 200 bytes), the first
443call to ber\_decode() would return with .code = RC\_WMORE and .consumed
444= 95. The .consumed field of the BER decoder return value is \textbf{always}
445valid, even if the decoder succeeds or fails with any other return
446code.
447
Lev Walkin464166c2010-11-09 08:34:38 -0800448Look into ber\_decoder.h for the precise definition of ber\_decode()
Lev Walkined44bf42010-11-08 02:04:55 -0800449and related types.
450
451
452\subsection{\label{sub:Encoding-DER}Encoding DER}
453
454The Distinguished Encoding Rules is the \emph{canonical} variant of
455BER encoding rules. The DER is best suited to encode the structures
456where all the lengths are known beforehand. This is probably exactly
457how you want to encode: either after a BER decoding or after a manual
458fill-up, the target structure contains the data which size is implicitly
459known before encoding. Among other uses, the DER encoding is used
460to encode X.509 certificates.
461
462As with BER decoder, the DER encoder may be invoked either directly
463from the ASN.1 type descriptor (asn\_DEF\_Rectangle) or from the stand-alone
464function, which is somewhat simpler:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700465\begin{codesample}
466/*
467 * This is the serializer itself.
468 * It supplies the DER encoder with the
469 * pointer to the custom output function.
470 */
471ssize_t
472simple_serializer(FILE *ostream, Rectangle_t *rect) {
473 asn_enc_rval_t er; /* Encoder return value */
Lev Walkined44bf42010-11-08 02:04:55 -0800474
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700475 er = der_encode(&asn_DEF_Rect, rect, write_stream, ostream);
476 if(er%\textbf{.encoded}% == -1) {
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700477 fprintf(stderr, "Cannot encode %\%%s: %\%%s\n",
478 er%\textbf{.failed\_type}%->name, strerror(errno));
479 return -1;
480 } else {
481 /* Return the number of bytes */
482 return er.encoded;
483 }
484}
485\end{codesample}
Lev Walkined44bf42010-11-08 02:04:55 -0800486As you see, the DER encoder does not write into some sort of buffer
487or something. It just invokes the custom function (possible, multiple
488times) which would save the data into appropriate storage. The optional
489argument \emph{app\_key} is opaque for the DER encoder code and just
490used by \emph{\_write\_stream()} as the pointer to the appropriate
491output stream to be used.
492
493If the custom write function is not given (passed as 0), then the
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700494DER encoder will essentially do the same thing (i.~e., encode the data)
Lev Walkined44bf42010-11-08 02:04:55 -0800495but no callbacks will be invoked (so the data goes nowhere). It may
496prove useful to determine the size of the structure's encoding before
497actually doing the encoding%
498\footnote{It is actually faster too: the encoder might skip over some computations
499which aren't important for the size determination.%
500}.
501
Lev Walkin464166c2010-11-09 08:34:38 -0800502Look into der\_encoder.h for the precise definition of der\_encode()
Lev Walkined44bf42010-11-08 02:04:55 -0800503and related types.
504
505
506\subsection{\label{sub:Encoding-XER}Encoding XER}
507
508The XER stands for XML Encoding Rules, where XML, in turn, is eXtensible
509Markup Language, a text-based format for information exchange. The
510encoder routine API comes in two flavors: stdio-based and callback-based.
511With the callback-based encoder, the encoding process is very similar
Lev Walkin194b2102013-03-28 01:29:06 -0700512to the DER one, described in Section~\ref{sub:Encoding-DER}. The
Lev Walkined44bf42010-11-08 02:04:55 -0800513following example uses the definition of write\_stream() from up there.
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700514\begin{codesample}
515/*
516 * This procedure generates the XML document
517 * by invoking the XER encoder.
518 * NOTE: Do not copy this code verbatim!
519 * If the stdio output is necessary,
520 * use the xer_fprint() procedure instead.
Lev Walkin194b2102013-03-28 01:29:06 -0700521 * See Section~%\ref{sub:Printing-the-target}%.
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700522 */
Lev Walkined44bf42010-11-08 02:04:55 -0800523int
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700524print_as_XML(FILE *ostream, Rectangle_t *rect) {
525 asn_enc_rval_t er; /* Encoder return value */
Lev Walkined44bf42010-11-08 02:04:55 -0800526
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700527 er = xer_encode(&asn_DEF_Rectangle, rect,
528 XER_F_BASIC, /* BASIC-XER or CANONICAL-XER */
529 write_stream, ostream);
Lev Walkined44bf42010-11-08 02:04:55 -0800530
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700531 return (er.encoded == -1) ? -1 : 0;
532}
533\end{codesample}
Lev Walkin464166c2010-11-09 08:34:38 -0800534Look into xer\_encoder.h for the precise definition of xer\_encode()
Lev Walkined44bf42010-11-08 02:04:55 -0800535and related types.
536
Lev Walkin194b2102013-03-28 01:29:06 -0700537See Section~\ref{sub:Printing-the-target} for the example of stdio-based
Lev Walkined44bf42010-11-08 02:04:55 -0800538XML encoder and other pretty-printing suggestions.
539
540
541\subsection{\label{sub:Decoding-XER}Decoding XER}
542
543The data encoded using the XER rules can be subsequently decoded using
544the xer\_decode() API call:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700545\begin{codesample}
546Rectangle_t *
547XML_to_Rectangle(const void *buffer, size_t buf_size) {
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700548 asn_dec_rval_t rval;
Lev Walkin194b2102013-03-28 01:29:06 -0700549 Rectangle_t *%$\underbracket{\textrm{\listingfont rect = 0}}$%; /* %\textbf{\color{red}Note this 0\footnote{Forgetting to properly initialize the pointer to a destination structure is a major source of support requests.}!}% */
Lev Walkined44bf42010-11-08 02:04:55 -0800550
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700551 rval = xer_decode(0, &asn_DEF_Rectangle, (void **)&rect, buffer, buf_size);
Lev Walkined44bf42010-11-08 02:04:55 -0800552
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700553 if(rval%\textbf{.code}% == RC_OK) {
554 return rect; /* Decoding succeeded */
555 } else {
556 /* Free partially decoded rect */
557 asn_DEF_Rectangle.free_struct(&asn_DEF_Rectangle, rect, 0);
558 return 0;
559 }
560}
561\end{codesample}
Lev Walkined44bf42010-11-08 02:04:55 -0800562The decoder takes both BASIC-XER and CANONICAL-XER encodings.
563
564The decoder shares its data consumption properties with BER decoder;
Lev Walkin194b2102013-03-28 01:29:06 -0700565please read the Section~\ref{sub:Decoding-BER} to know more.
Lev Walkined44bf42010-11-08 02:04:55 -0800566
Lev Walkin464166c2010-11-09 08:34:38 -0800567Look into xer\_decoder.h for the precise definition of xer\_decode()
Lev Walkined44bf42010-11-08 02:04:55 -0800568and related types.
569
570
571\subsection{\label{sub:Validating-the-target}Validating the target structure}
572
573Sometimes the target structure needs to be validated. For example,
574if the structure was created by the application (as opposed to being
575decoded from some external source), some important information required
576by the ASN.1 specification might be missing. On the other hand, the
577successful decoding of the data from some external source does not
578necessarily mean that the data is fully valid either. It might well
579be the case that the specification describes some subtype constraints
580that were not taken into account during decoding, and it would actually
581be useful to perform the last check when the data is ready to be encoded
582or when the data has just been decoded to ensure its validity according
583to some stricter rules.
584
585The asn\_check\_constraints() function checks the type for various
586implicit and explicit constraints. It is recommended to use asn\_check\_constraints()
587function after each decoding and before each encoding.
588
Lev Walkin464166c2010-11-09 08:34:38 -0800589Look into constraints.h for the precise definition of asn\_check\_constraints()
Lev Walkined44bf42010-11-08 02:04:55 -0800590and related types.
591
592
593\subsection{\label{sub:Printing-the-target}Printing the target structure}
594
595There are two ways to print the target structure: either invoke the
596print\_struct member of the ASN.1 type descriptor, or using the asn\_fprint()
597function, which is a simpler wrapper of the former:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700598\begin{codesample}
599asn_fprint(stdout, &asn_DEF_Rectangle, rect);
600\end{codesample}
Lev Walkin464166c2010-11-09 08:34:38 -0800601Look into constr\_TYPE.h for the precise definition of asn\_fprint()
Lev Walkined44bf42010-11-08 02:04:55 -0800602and related types.
603
604Another practical alternative to this custom format printing would
605be to invoke XER encoder. The default BASIC-XER encoder performs reasonable
606formatting for the output to be useful and human readable. To invoke
607the XER decoder in a manner similar to asn\_fprint(), use the xer\_fprint()
608call:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700609\begin{codesample}
610xer_fprint(stdout, &asn_DEF_Rectangle, rect);
611\end{codesample}
Lev Walkin194b2102013-03-28 01:29:06 -0700612See Section~\ref{sub:Encoding-XER} for XML-related details.
Lev Walkined44bf42010-11-08 02:04:55 -0800613
614
615\subsection{\label{sub:Freeing-the-target}Freeing the target structure}
616
617Freeing the structure is slightly more complex than it may seem to.
618When the ASN.1 structure is freed, all the members of the structure
619and their submembers are recursively freed as well. But it might not
620be feasible to free the structure itself. Consider the following case:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700621\begin{codesample}
622struct my_figure { /* The custom structure */
623 int flags; /* <some custom member> */
624 /* The type is generated by the ASN.1 compiler */
625 Rectangle_t rect;
626 /* other members of the structure */
627};
628\end{codesample}
Lev Walkined44bf42010-11-08 02:04:55 -0800629In this example, the application programmer defined a custom structure
630with one ASN.1-derived member (rect). This member is not a reference
631to the Rectangle\_t, but an in-place inclusion of the Rectangle\_t
632structure. If the freeing is necessary, the usual procedure of freeing
633everything must not be applied to the \&rect pointer itself, because
634it does not point to the memory block directly allocated by the memory
635allocation routine, but instead lies within a block allocated for
636the my\_figure structure.
637
638To solve this problem, the free\_struct routine has the additional
639argument (besides the obvious type descriptor and target structure
640pointers), which is the flag specifying whether the outer pointer
641itself must be freed (0, default) or it should be left intact (non-zero
642value).
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700643\begin{codesample}
644/* %\textbf{1. Rectangle\_t is defined within my\_figure}% */
645struct my_figure {
646 Rectangle_t rect;
647} *mf = ...;
648/*
649 * Freeing the Rectangle_t
650 * without freeing the mf->rect area.
651 */
652asn_DEF_Rectangle.free_struct(
653 &asn_DEF_Rectangle, &mf->rect, %\textbf{1 /* !free */}%);
654
655/* %\textbf{2. Rectangle\_t is a stand-alone pointer}% */
656Rectangle_t *rect = ...;
657/*
658 * Freeing the Rectangle_t
659 * and freeing the rect pointer.
660 */
661asn_DEF_Rectangle.free_struct(
662 &asn_DEF_Rectangle, rect, %\textbf{0 /* free the pointer too */}%);
663\end{codesample}
Lev Walkined44bf42010-11-08 02:04:55 -0800664It is safe to invoke the \emph{free\_struct} function with the target
665structure pointer set to 0 (NULL), the function will do nothing.
666
667For the programmer's convenience, the following macros are available:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700668\begin{codesample}
669ASN_STRUCT_FREE(asn_DEF, ptr);
670ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF, ptr);
671\end{codesample}
Lev Walkined44bf42010-11-08 02:04:55 -0800672These macros bear the same semantics as the \emph{free\_struct} function
673invocation, discussed above.
674
675
676\chapter{\label{cha:Step-by-step-examples}Step by step examples}
677
678
Lev Walkin464166c2010-11-09 08:34:38 -0800679\section{A ``Rectangle'' Encoder}
Lev Walkined44bf42010-11-08 02:04:55 -0800680
681This example will help you create a simple BER and XER encoder of
Lev Walkin464166c2010-11-09 08:34:38 -0800682a ``Rectangle'' type used throughout this document.
Lev Walkined44bf42010-11-08 02:04:55 -0800683\begin{enumerate}
684\item Create a file named \textbf{rectangle.asn1} with the following contents:
685
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700686\begin{asn}
687RectangleModule1 DEFINITIONS ::= BEGIN
Lev Walkined44bf42010-11-08 02:04:55 -0800688
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700689Rectangle ::= SEQUENCE {
690 height INTEGER,
691 width INTEGER
692}
Lev Walkined44bf42010-11-08 02:04:55 -0800693
694END
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700695\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -0800696\item Compile it into the set of .c and .h files using asn1c compiler \cite{ASN1C}:
697
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700698\begin{bash}
Lev Walkin2a744a72013-03-27 01:56:23 -0700699asn1c %\textbf{rectangle.asn1}%
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700700\end{bash}
Lev Walkined44bf42010-11-08 02:04:55 -0800701\item Alternatively, use the Online ASN.1 compiler \cite{AONL} by uploading
702the \textbf{rectangle.asn1} file into the Web form and unpacking the
703produced archive on your computer.
704\item By this time, you should have gotten multiple files in the current
705directory, including the \textbf{Rectangle.c} and \textbf{Rectangle.h}.
706\item Create a main() routine which creates the Rectangle\_t structure in
707memory and encodes it using BER and XER encoding rules. Let's name
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700708the file \textbf{main.c}:
Lev Walkined44bf42010-11-08 02:04:55 -0800709
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700710\begin{codesample}[basicstyle=\scriptsize\listingfont]
711#include <stdio.h>
712#include <sys/types.h>
713#include <Rectangle.h> /* Rectangle ASN.1 type */
Lev Walkined44bf42010-11-08 02:04:55 -0800714
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700715/* Write the encoded output into some FILE stream. */
716static int write_out(const void *buffer, size_t size, void *app_key) {
717 FILE *out_fp = app_key;
718 size_t wrote = fwrite(buffer, 1, size, out_fp);
719 return (wrote == size) ? 0 : -1;
720}
721
722int main(int ac, char **av) {
723 Rectangle_t *rectangle; /* Type to encode */
724 asn_enc_rval_t ec; /* Encoder return value */
Lev Walkined44bf42010-11-08 02:04:55 -0800725
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700726 /* Allocate the Rectangle_t */
727 rectangle = calloc(1, sizeof(Rectangle_t)); /* not malloc! */
728 if(!rectangle) {
729 perror("calloc() failed");
730 exit(1);
731 }
Lev Walkined44bf42010-11-08 02:04:55 -0800732
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700733 /* Initialize the Rectangle members */
734 rectangle->height = 42; /* any random value */
735 rectangle->width = 23; /* any random value */
Lev Walkined44bf42010-11-08 02:04:55 -0800736
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700737 /* BER encode the data if filename is given */
738 if(ac < 2) {
739 fprintf(stderr, "Specify filename for BER output\n");
740 } else {
741 const char *filename = av[1];
742 FILE *fp = fopen(filename, "wb"); /* for BER output */
743
744 if(!fp) {
745 perror(filename);
746 exit(1);
747 }
Lev Walkined44bf42010-11-08 02:04:55 -0800748
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700749 /* Encode the Rectangle type as BER (DER) */
750 ec = der_encode(&asn_DEF_Rectangle, rectangle, write_out, fp);
751 fclose(fp);
752 if(ec.encoded == -1) {
753 fprintf(stderr, "Could not encode Rectangle (at %\%%s)\n",
754 ec.failed_type ? ec.failed_type->name : "unknown");
755 exit(1);
756 } else {
757 fprintf(stderr, "Created %\%%s with BER encoded Rectangle\n", filename);
758 }
759 }
Lev Walkined44bf42010-11-08 02:04:55 -0800760
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700761 /* Also print the constructed Rectangle XER encoded (XML) */
762 xer_fprint(stdout, &asn_DEF_Rectangle, rectangle);
Lev Walkined44bf42010-11-08 02:04:55 -0800763
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700764 return 0; /* Encoding finished successfully */
765 }
766\end{codesample}
Lev Walkined44bf42010-11-08 02:04:55 -0800767\item Compile all files together using C compiler (varies by platform):
768
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700769\begin{bash}
770cc -I. -o %\textbf{\emph{rencode}} \emph{*.c}%
771\end{bash}
Lev Walkined44bf42010-11-08 02:04:55 -0800772\item Voila! You have just created the BER and XER encoder of a Rectangle
773type, named \textbf{rencode}!
774\end{enumerate}
Lev Walkined44bf42010-11-08 02:04:55 -0800775
Lev Walkin464166c2010-11-09 08:34:38 -0800776\section{\label{sec:A-Rectangle-Decoder}A ``Rectangle'' Decoder}
Lev Walkined44bf42010-11-08 02:04:55 -0800777
778This example will help you to create a simple BER decoder of a simple
Lev Walkin464166c2010-11-09 08:34:38 -0800779``Rectangle'' type used throughout this document.
Lev Walkined44bf42010-11-08 02:04:55 -0800780\begin{enumerate}
781\item Create a file named \textbf{rectangle.asn1} with the following contents:
782
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700783\begin{asn}
784RectangleModule1 DEFINITIONS ::= BEGIN
Lev Walkined44bf42010-11-08 02:04:55 -0800785
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700786Rectangle ::= SEQUENCE {
787 height INTEGER,
788 width INTEGER
789}
Lev Walkined44bf42010-11-08 02:04:55 -0800790
791END
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700792\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -0800793\item Compile it into the set of .c and .h files using asn1c compiler \cite{ASN1C}:
794
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700795\begin{bash}
Lev Walkin2a744a72013-03-27 01:56:23 -0700796asn1c %\textbf{rectangle.asn1}%
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700797\end{bash}
Lev Walkined44bf42010-11-08 02:04:55 -0800798\item Alternatively, use the Online ASN.1 compiler \cite{AONL} by uploading
799the \textbf{rectangle.asn1} file into the Web form and unpacking the
800produced archive on your computer.
801\item By this time, you should have gotten multiple files in the current
802directory, including the \textbf{Rectangle.c} and \textbf{Rectangle.h}.
803\item Create a main() routine which takes the binary input file, decodes
804it as it were a BER-encoded Rectangle type, and prints out the text
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700805(XML) representation of the Rectangle type. Let's name the file \textbf{main.c}:
Lev Walkined44bf42010-11-08 02:04:55 -0800806
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700807\begin{codesample}[basicstyle=\scriptsize\listingfont]
808#include <stdio.h>
809#include <sys/types.h>
810#include <Rectangle.h> /* Rectangle ASN.1 type */
Lev Walkined44bf42010-11-08 02:04:55 -0800811
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700812int main(int ac, char **av) {
813 char buf[1024]; /* Temporary buffer */
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700814 asn_dec_rval_t rval; /* Decoder return value */
Lev Walkin194b2102013-03-28 01:29:06 -0700815 Rectangle_t *%$\underbracket{\textrm{\listingfont rectangle = 0}}$%; /* Type to decode. %\textbf{\color{red}Note this 0\footnote{Forgetting to properly initialize the pointer to a destination structure is a major source of support requests.}!}% */
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700816 FILE *fp; /* Input file handler */
817 size_t size; /* Number of bytes read */
818 char *filename; /* Input file name */
Lev Walkined44bf42010-11-08 02:04:55 -0800819
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700820 /* Require a single filename argument */
821 if(ac != 2) {
822 fprintf(stderr, "Usage: %\%%s <file.ber>\n", av[0]);
823 exit(1);
824 } else {
825 filename = av[1];
826 }
Lev Walkined44bf42010-11-08 02:04:55 -0800827
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700828 /* Open input file as read-only binary */
829 fp = fopen(filename, "rb");
830 if(!fp) {
831 perror(filename);
832 exit(1);
833 }
Lev Walkined44bf42010-11-08 02:04:55 -0800834
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700835 /* Read up to the buffer size */
836 size = fread(buf, 1, sizeof(buf), fp);
837 fclose(fp);
838 if(!size) {
839 fprintf(stderr, "%\%%s: Empty or broken\n", filename);
840 exit(1);
841 }
Lev Walkined44bf42010-11-08 02:04:55 -0800842
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700843 /* Decode the input buffer as Rectangle type */
844 rval = ber_decode(0, &asn_DEF_Rectangle, (void **)&rectangle, buf, size);
845 if(rval.code != RC_OK) {
846 fprintf(stderr, "%\%%s: Broken Rectangle encoding at byte %\%%ld\n", filename, (long)rval.consumed);
847 exit(1);
848 }
Lev Walkined44bf42010-11-08 02:04:55 -0800849
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700850 /* Print the decoded Rectangle type as XML */
851 xer_fprint(stdout, &asn_DEF_Rectangle, rectangle);
Lev Walkined44bf42010-11-08 02:04:55 -0800852
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700853 return 0; /* Decoding finished successfully */
Lev Walkin194b2102013-03-28 01:29:06 -0700854}
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700855\end{codesample}
Lev Walkined44bf42010-11-08 02:04:55 -0800856\item Compile all files together using C compiler (varies by platform):
857
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700858\begin{bash}
859cc -I. -o %\textbf{\emph{rdecode}} \emph{*.c}%
860\end{bash}
Lev Walkined44bf42010-11-08 02:04:55 -0800861\item Voila! You have just created the BER decoder of a Rectangle type,
862named \textbf{rdecode}!
863\end{enumerate}
864
865\chapter{Constraint validation examples}
866
867This chapter shows how to define ASN.1 constraints and use the generated
868validation code.
869
870
Lev Walkin464166c2010-11-09 08:34:38 -0800871\section{Adding constraints into ``Rectangle'' type}
Lev Walkined44bf42010-11-08 02:04:55 -0800872
873This example shows how to add basic constraints to the ASN.1 specification
874and how to invoke the constraints validation code in your application.
875\begin{enumerate}
876\item Create a file named \textbf{rectangle.asn1} with the following contents:
877
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700878\begin{asn}
879RectangleModuleWithConstraints DEFINITIONS ::= BEGIN
Lev Walkined44bf42010-11-08 02:04:55 -0800880
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700881Rectangle ::= SEQUENCE {
882 height INTEGER (0..100), -- Value range constraint
883 width INTEGER (0..MAX) -- Makes width non-negative
884}
Lev Walkined44bf42010-11-08 02:04:55 -0800885
886END
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700887\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -0800888\item Compile the file according to procedures shown in the previous chapter.
889\item Modify the Rectangle type processing routine (you can start with the
Lev Walkin194b2102013-03-28 01:29:06 -0700890main() routine shown in the Section~\ref{sec:A-Rectangle-Decoder})
Lev Walkined44bf42010-11-08 02:04:55 -0800891by placing the following snippet of code \emph{before} encoding and/or
892\emph{after} decoding the Rectangle type%
Lev Walkin2e554fc2014-10-26 19:21:58 -0700893\footnote{Placing the constraint checking code \emph{before encoding} helps
894to make sure the data is correct and within constraints before
Lev Walkined44bf42010-11-08 02:04:55 -0800895sharing the data with anyone else.
Lev Walkin2e554fc2014-10-26 19:21:58 -0700896Placing the constraint checking code \emph{after decoding} helps to make sure
Lev Walkined44bf42010-11-08 02:04:55 -0800897the application got the valid contents before making use of it.%
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700898}:
Lev Walkined44bf42010-11-08 02:04:55 -0800899
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700900\begin{codesample}
901int ret; /* Return value */
902char errbuf[128]; /* Buffer for error message */
903size_t errlen = sizeof(errbuf); /* Size of the buffer */
Lev Walkined44bf42010-11-08 02:04:55 -0800904
Lev Walkin2e554fc2014-10-26 19:21:58 -0700905/* ... here goes the Rectangle %\emph{decoding}% code ... */
Lev Walkined44bf42010-11-08 02:04:55 -0800906
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700907ret = asn_check_constraints(&asn_DEF_Rectangle, rectangle, errbuf, &errlen);
908/* assert(errlen < sizeof(errbuf)); // you may rely on that */
909if(ret) {
910 fprintf(stderr, "Constraint validation failed: %\%%s\n",
911 errbuf /* errbuf is properly nul-terminated */
912 );
913 /* exit(...); // Replace with appropriate action */
914 }
Lev Walkined44bf42010-11-08 02:04:55 -0800915
Lev Walkin2e554fc2014-10-26 19:21:58 -0700916/* ... here goes the Rectangle %\emph{encoding}% code ... */
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700917\end{codesample}
Lev Walkined44bf42010-11-08 02:04:55 -0800918\item Compile the resulting C code as shown in the previous chapters.
919\item Try to test the constraints checking code by assigning integer value
920101 to the \textbf{.height} member of the Rectangle structure, or
921a negative value to the \textbf{.width} member. In either case, the
Lev Walkin464166c2010-11-09 08:34:38 -0800922program should print ``Constraint validation failed'' message, followed
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700923by a short explanation why validation did not succeed.
Lev Walkined44bf42010-11-08 02:04:55 -0800924\item Done.
925\end{enumerate}
926
927\part{\label{par:ASN.1-Basics}ASN.1 Basics}
928
929
930\chapter{\label{cha:Abstract-Syntax-Notation:}Abstract Syntax Notation: ASN.1}
931
932\emph{This chapter defines some basic ASN.1 concepts and describes
933several most widely used types. It is by no means an authoritative
934or complete reference. For more complete ASN.1 description, please
935refer to Olivier Dubuisson's book \cite{Dub00} or the ASN.1 body
936of standards itself \cite{ITU-T/ASN.1}.}
937
938The Abstract Syntax Notation One is used to formally describe the
939semantics of data transmitted across the network. Two communicating
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700940parties may have different formats of their native data types (i.~e.
Lev Walkined44bf42010-11-08 02:04:55 -0800941number of bits in the integer type), thus it is important to have
942a way to describe the data in a manner which is independent from the
943particular machine's representation. The ASN.1 specifications are
944used to achieve the following:
945\begin{itemize}
946\item The specification expressed in the ASN.1 notation is a formal and
947precise way to communicate the data semantics to human readers;
948\item The ASN.1 specifications may be used as input for automatic compilers
949which produce the code for some target language (C, C++, Java, etc)
950to encode and decode the data according to some encoding rules (which
951are also defined by the ASN.1 standard).
952\end{itemize}
953Consider the following example:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700954\begin{asn}
955Rectangle ::= SEQUENCE {
956 height INTEGER,
957 width INTEGER
958}
959\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -0800960This ASN.1 specification describes a constructed type, \emph{Rectangle},
961containing two integer fields. This specification may tell the reader
962that there exists this kind of data structure and that some entity
963may be prepared to send or receive it. The question on \emph{how}
964that entity is going to send or receive the \emph{encoded data} is
965outside the scope of ASN.1. For example, this data structure may be
966encoded according to some encoding rules and sent to the destination
967using the TCP protocol. The ASN.1 specifies several ways of encoding
Lev Walkin464166c2010-11-09 08:34:38 -0800968(or ``serializing'', or ``marshaling'') the data: BER, PER, XER
Lev Walkined44bf42010-11-08 02:04:55 -0800969and others, including CER and DER derivatives from BER.
970
971The complete specification must be wrapped in a module, which looks
972like this:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700973\begin{asn}
Lev Walkined44bf42010-11-08 02:04:55 -0800974RectangleModule1
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700975 { iso org(3) dod(6) internet(1) private(4)
976 enterprise(1) spelio(9363) software(1)
977 asn1c(5) docs(2) rectangle(1) 1 }
978 DEFINITIONS AUTOMATIC TAGS ::=
Lev Walkined44bf42010-11-08 02:04:55 -0800979BEGIN
980
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700981-- This is a comment which describes nothing.
982Rectangle ::= SEQUENCE {
983 height INTEGER, -- Height of the rectangle
984 width INTEGER -- Width of the rectangle
985}
Lev Walkined44bf42010-11-08 02:04:55 -0800986
987END
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700988\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -0800989The module header consists of module name (RectangleModule1), the
Lev Walkin464166c2010-11-09 08:34:38 -0800990module object identifier (\{...\}), a keyword ``DEFINITIONS'', a
991set of module flags (AUTOMATIC TAGS) and ``::= BEGIN''. The module
992ends with an ``END'' statement.
Lev Walkined44bf42010-11-08 02:04:55 -0800993
994
995\section{Some of the ASN.1 Basic Types}
996
997
998\subsection{The BOOLEAN type}
999
1000The BOOLEAN type models the simple binary TRUE/FALSE, YES/NO, ON/OFF
1001or a similar kind of two-way choice.
1002
1003
1004\subsection{The INTEGER type}
1005
1006The INTEGER type is a signed natural number type without any restrictions
1007on its size. If the automatic checking on INTEGER value bounds are
1008necessary, the subtype constraints must be used.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001009\begin{asn}
1010SimpleInteger ::= INTEGER
Lev Walkined44bf42010-11-08 02:04:55 -08001011
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001012-- An integer with a very limited range
1013SmallPositiveInt ::= INTEGER (0..127)
Lev Walkined44bf42010-11-08 02:04:55 -08001014
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001015-- Integer, negative
1016NegativeInt ::= INTEGER (MIN..0)
1017\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001018
1019\subsection{The ENUMERATED type}
1020
1021The ENUMERATED type is semantically equivalent to the INTEGER type
1022with some integer values explicitly named.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001023\begin{asn}
1024FruitId ::= ENUMERATED { apple(1), orange(2) }
Lev Walkined44bf42010-11-08 02:04:55 -08001025
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001026-- The numbers in braces are optional,
1027-- the enumeration can be performed
1028-- automatically by the compiler
1029ComputerOSType ::= ENUMERATED {
1030 FreeBSD, -- acquires value 0
1031 Windows, -- acquires value 1
1032 Solaris(5), -- remains 5
1033 Linux, -- becomes 6
1034 MacOS -- becomes 7
1035}
1036\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001037
1038\subsection{The OCTET STRING type}
1039
1040This type models the sequence of 8-bit bytes. This may be used to
1041transmit some opaque data or data serialized by other types of encoders
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001042(i.~e., video file, photo picture, etc).
Lev Walkined44bf42010-11-08 02:04:55 -08001043
1044\subsection{The OBJECT IDENTIFIER type}
1045
1046The OBJECT IDENTIFIER is used to represent the unique identifier of
1047any object, starting from the very root of the registration tree.
1048If your organization needs to uniquely identify something (a router,
1049a room, a person, a standard, or whatever), you are encouraged to
1050get your own identification subtree at \url{http://www.iana.org/protocols/forms.htm}.
1051
1052For example, the very first ASN.1 module in this Chapter (RectangleModule1)
1053has the following OBJECT IDENTIFIER: 1 3 6 1 4 1 9363 1 5 2 1 1.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001054\begin{asn}
1055ExampleOID ::= OBJECT IDENTIFIER
Lev Walkined44bf42010-11-08 02:04:55 -08001056
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001057rectangleModule1-oid ExampleOID
1058 ::= { 1 3 6 1 4 1 9363 1 5 2 1 1 }
Lev Walkined44bf42010-11-08 02:04:55 -08001059
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001060-- An identifier of the Internet.
1061internet-id OBJECT IDENTIFIER
1062 ::= { iso(1) identified-organization(3)
1063 dod(6) internet(1) }
1064\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001065As you see, names are optional.
1066
1067
1068\subsection{The RELATIVE-OID type}
1069
1070The RELATIVE-OID type has the semantics of a subtree of an OBJECT
1071IDENTIFIER. There may be no need to repeat the whole sequence of numbers
1072from the root of the registration tree where the only thing of interest
1073is some of the tree's subsequence.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001074\begin{asn}
1075this-document RELATIVE-OID ::= { docs(2) usage(1) }
Lev Walkined44bf42010-11-08 02:04:55 -08001076
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001077this-example RELATIVE-OID ::= {
1078 this-document assorted-examples(0) this-example(1) }
1079\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001080
1081\section{Some of the ASN.1 String Types}
1082
1083
1084\subsection{The IA5String type}
1085
1086This is essentially the ASCII, with 128 character codes available
1087(7 lower bits of an 8-bit byte).
1088
1089
1090\subsection{The UTF8String type}
1091
1092This is the character string which encodes the full Unicode range
1093(4 bytes) using multibyte character sequences.
1094
1095
1096\subsection{The NumericString type}
1097
1098This type represents the character string with the alphabet consisting
Lev Walkin464166c2010-11-09 08:34:38 -08001099of numbers (``0'' to ``9'') and a space.
Lev Walkined44bf42010-11-08 02:04:55 -08001100
1101
1102\subsection{The PrintableString type}
1103
Lev Walkin464166c2010-11-09 08:34:38 -08001104The character string with the following alphabet: space, ``\textbf{'}''
1105(single quote), ``\textbf{(}'', ``\textbf{)}'', ``\textbf{+}'',
1106``\textbf{,}'' (comma), ``\textbf{-}'', ``\textbf{.}'', ``\textbf{/}'',
1107digits (``0'' to ``9''), ``\textbf{:}'', ``\textbf{=}'', ``\textbf{?}'',
1108upper-case and lower-case letters (``A'' to ``Z'' and ``a''
1109to ``z'').
Lev Walkined44bf42010-11-08 02:04:55 -08001110
1111
1112\subsection{The VisibleString type}
1113
1114The character string with the alphabet which is more or less a subset
Lev Walkin464166c2010-11-09 08:34:38 -08001115of ASCII between the space and the ``\textbf{\textasciitilde{}}''
Lev Walkined44bf42010-11-08 02:04:55 -08001116symbol (tilde).
1117
1118Alternatively, the alphabet may be described as the PrintableString
Lev Walkin464166c2010-11-09 08:34:38 -08001119alphabet presented earlier, plus the following characters: ``\textbf{!}'',
1120``\textbf{``}'', ``\textbf{\#}'', ``\textbf{\$}'', ``\textbf{\%}'',
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001121``\textbf{\&}'', ``\textbf{*}'', ``\textbf{;}'', ``\textbf{<}'',
Lev Walkin464166c2010-11-09 08:34:38 -08001122``\textbf{>}'', ``\textbf{{[}}'', ``\textbf{\textbackslash{}}'',
1123``\textbf{{]}}'', ``\textbf{\textasciicircum{}}'', ``\textbf{\_}'',
1124``\textbf{`}`` (single left quote), ``\textbf{\{}'', ``\textbf{|}'',
1125``\textbf{\}}'', ``\textbf{\textasciitilde{}}''.
Lev Walkined44bf42010-11-08 02:04:55 -08001126
1127
1128\section{ASN.1 Constructed Types}
1129
1130
1131\subsection{The SEQUENCE type}
1132
1133This is an ordered collection of other simple or constructed types.
Lev Walkin464166c2010-11-09 08:34:38 -08001134The SEQUENCE constructed type resembles the C ``struct'' statement.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001135\begin{asn}
1136Address ::= SEQUENCE {
1137 -- The apartment number may be omitted
1138 apartmentNumber NumericString OPTIONAL,
1139 streetName PrintableString,
1140 cityName PrintableString,
1141 stateName PrintableString,
1142 -- This one may be omitted too
1143 zipNo NumericString OPTIONAL
1144}
1145\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001146
1147\subsection{The SET type}
1148
1149This is a collection of other simple or constructed types. Ordering
1150is not important. The data may arrive in the order which is different
1151from the order of specification. Data is encoded in the order not
1152necessarily corresponding to the order of specification.
1153
1154
1155\subsection{The CHOICE type}
1156
1157This type is just a choice between the subtypes specified in it. The
1158CHOICE type contains at most one of the subtypes specified, and it
1159is always implicitly known which choice is being decoded or encoded.
Lev Walkin464166c2010-11-09 08:34:38 -08001160This one resembles the C ``union'' statement.
Lev Walkined44bf42010-11-08 02:04:55 -08001161
1162The following type defines a response code, which may be either an
Lev Walkin464166c2010-11-09 08:34:38 -08001163integer code or a boolean ``true''/``false'' code.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001164\begin{asn}
1165ResponseCode ::= CHOICE {
1166 intCode INTEGER,
1167 boolCode BOOLEAN
1168}
1169\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001170
1171\subsection{The SEQUENCE OF type}
1172
1173This one is the list (array) of simple or constructed types:
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001174\begin{asn}
1175-- Example 1
1176ManyIntegers ::= SEQUENCE OF INTEGER
Lev Walkined44bf42010-11-08 02:04:55 -08001177
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001178-- Example 2
1179ManyRectangles ::= SEQUENCE OF Rectangle
Lev Walkined44bf42010-11-08 02:04:55 -08001180
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001181-- More complex example:
1182-- an array of structures defined in place.
1183ManyCircles ::= SEQUENCE OF SEQUENCE {
1184 radius INTEGER
1185 }
1186\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001187
1188\subsection{The SET OF type}
1189
1190The SET OF type models the bag of structures. It resembles the SEQUENCE
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001191OF type, but the order is not important: i.~e. the elements may arrive
Lev Walkined44bf42010-11-08 02:04:55 -08001192in the order which is not necessarily the same as the in-memory order
1193on the remote machines.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001194\begin{asn}
1195-- A set of structures defined elsewhere
1196SetOfApples :: SET OF Apple
Lev Walkined44bf42010-11-08 02:04:55 -08001197
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001198-- Set of integers encoding the kind of a fruit
1199FruitBag ::= SET OF ENUMERATED { apple, orange }
1200\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001201\begin{thebibliography}{ITU-T/ASN.1}
1202\bibitem[ASN1C]{ASN1C}The Open Source ASN.1 Compiler. \url{http://lionet.info/asn1c}
1203
1204\bibitem[AONL]{AONL}Online ASN.1 Compiler. \url{http://lionet.info/asn1c/asn1c.cgi}
1205
1206\bibitem[Dub00]{Dub00}Olivier Dubuisson --- \emph{ASN.1 Communication
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001207between heterogeneous systems} --- Morgan Kaufmann Publishers, 2000.
Lev Walkined44bf42010-11-08 02:04:55 -08001208\url{http://asn1.elibel.tm.fr/en/book/}. ISBN:0-12-6333361-0.
1209
Lev Walkin464166c2010-11-09 08:34:38 -08001210\bibitem[ITU-T/ASN.1]{ITU-T/ASN.1}ITU-T Study Group 17 --- Languages
Lev Walkined44bf42010-11-08 02:04:55 -08001211for Telecommunication Systems \url{http://www.itu.int/ITU-T/studygroups/com17/languages/}
1212\end{thebibliography}
1213
1214\end{document}