blob: c1d5b7324932ed724b6f82c0e2421aac245d1050 [file] [log] [blame]
Lev Walkin288527b2014-10-26 20:12:53 -07001\batchmode
Lev Walkin464166c2010-11-09 08:34:38 -08002\documentclass[english,oneside,12pt]{book}
Lev Walkin194b2102013-03-28 01:29:06 -07003\usepackage[no-math]{fontspec}
4\usepackage{MnSymbol}
Lev Walkin464166c2010-11-09 08:34:38 -08005\usepackage{xunicode}
6\usepackage{xltxtra}
7
Lev Walkin11c9a8c2013-03-26 00:46:55 -07008\usepackage[hmargin={1in,1in},vmargin={1.5in,1.5in}]{geometry}
Lev Walkin464166c2010-11-09 08:34:38 -08009
10\defaultfontfeatures{Mapping=tex-text}
Lev Walkin11c9a8c2013-03-26 00:46:55 -070011\setmainfont{PT Sans}
12\setsansfont{PT Sans}
Lev Walkin464166c2010-11-09 08:34:38 -080013\setmonofont{Consolas}
14
Lev Walkined44bf42010-11-08 02:04:55 -080015\usepackage{fancyhdr}
Lev Walkined44bf42010-11-08 02:04:55 -080016\usepackage{longtable}
Lev Walkin464166c2010-11-09 08:34:38 -080017\usepackage{booktabs}
Lev Walkined44bf42010-11-08 02:04:55 -080018\usepackage{varioref}
19\usepackage{url}
Lev Walkin11c9a8c2013-03-26 00:46:55 -070020\usepackage{xcolor}
21\usepackage{listings}
22\usepackage{setspace}
Lev Walkin194b2102013-03-28 01:29:06 -070023\usepackage{unicode-math}
24\usepackage{perpage}
25\MakePerPage{footnote}
Lev Walkin11c9a8c2013-03-26 00:46:55 -070026
27\setstretch{1.1}
28
29% Courier 10 Pitch
30\def\courierFont{Courier10 BT WGL4}
31%\def\courierFont{Consolas}
32\setmonofont[Scale=1.05]{\courierFont}
Lev Walkin194b2102013-03-28 01:29:06 -070033\setmathfont[Scale=1.05]{Cambria Math}
Lev Walkin11c9a8c2013-03-26 00:46:55 -070034
Lev Walkined44bf42010-11-08 02:04:55 -080035
36\makeatletter
37
Lev Walkined44bf42010-11-08 02:04:55 -080038%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Textclass specific LaTeX commands.
Lev Walkin11c9a8c2013-03-26 00:46:55 -070039\lstloadlanguages{C,bash}
40\newfontfamily\listingfont[Scale=1.05]{\courierFont}
41\newfontfamily\inlinelistingfont[Scale=1.05]{\courierFont}
42\definecolor{clrlcomment}{gray}{0.3}
43\definecolor{clrlkeyword}{rgb}{0.588,0.145,0.18}
44\newcommand{\listingkeyword}[1]{\color{clrlkeyword}{#1}}
45\newcommand{\listingstring}[1]{\color{clrlcomment}{#1}}
46\newcommand{\listingcomment}[1]{\color{clrlcomment}{#1}}
47\lstset{tabsize=4,
48 showstringspaces=false,
49 showtabs=false,
50 showspaces=false,
51 keywordstyle=\listingkeyword,
52 stringstyle=\listingstring,
53 commentstyle=\listingcomment,
54 xleftmargin=\parindent,
55 columns=fixed,
56 escapechar=\%,
57 texcl
58}
59\lstdefinestyle{listingStyle}{
60 basicstyle=\small\listingfont,
61 stringstyle=\listingstring,
62 breaklines=true,
63 breakatwhitespace=true,
64 flexiblecolumns=false
65 }
66\lstdefinelanguage{asn1}{
67 morekeywords={DEFINITIONS,BEGIN,END,SEQUENCE,SET,OF,CHOICE,OPTIONAL},
68 morecomment=[l]{--},
69 morecomment=[n]{/*}{*/}
70 }
71
72\lstnewenvironment{codesample}[1][]{\lstset{style=listingStyle,language=C,#1}}{}
Lev Walkin2a744a72013-03-27 01:56:23 -070073\lstnewenvironment{bash}[1][]{\lstset{style=listingStyle,language=bash,#1}}{}
Lev Walkin11c9a8c2013-03-26 00:46:55 -070074\lstnewenvironment{asn}[1][]{\lstset{style=listingStyle,language=asn1,#1}}{}
75\def\code{lstinline}
Lev Walkined44bf42010-11-08 02:04:55 -080076
77%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% User specified LaTeX commands.
78\usepackage{extramarks}
79\lhead{\firstxmark}
80\rfoot{\lastxmark}
Lev Walkin11c9a8c2013-03-26 00:46:55 -070081\definecolor{clrlink}{rgb}{0,0.4,0}
82\definecolor{clrurl}{rgb}{0,0,.6}
Lev Walkined44bf42010-11-08 02:04:55 -080083\usepackage[colorlinks=true,
Lev Walkin11c9a8c2013-03-26 00:46:55 -070084 linkcolor={clrlink},
85 citecolor={clrlink},
86 urlcolor={clrurl},
87 pdfauthor={Lev Walkin},
88 pdftitle={Using the Open Source ASN.1 Compiler},
89 pdfkeywords={ASN.1,asn1c,compiler},
90 bookmarksopen,bookmarksopenlevel=1,
91 pdffitwindow,
92 xetex
Lev Walkined44bf42010-11-08 02:04:55 -080093]{hyperref}
Lev Walkined44bf42010-11-08 02:04:55 -080094
95\makeatother
96
97\usepackage{babel}
98
99\begin{document}
100
Lev Walkin50155de2014-10-26 19:46:16 -0700101\title{Using the Open Source ASN.1 Compiler\\
Lev Walkin288527b2014-10-26 20:12:53 -0700102\vspace*{0.4cm}
Lev Walkin50155de2014-10-26 19:46:16 -0700103\Large Documentation for asn1c version \asnver{}}
Lev Walkined44bf42010-11-08 02:04:55 -0800104\author{Lev Walkin <\href{mailto:vlm@lionet.info?Subject=asn1c}{vlm@lionet.info}>}
105
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700106\pagestyle{fancy}
107\fancyhead[L]{\leftmark}
Lev Walkin50155de2014-10-26 19:46:16 -0700108\fancyhead[R]{\href{http://lionet.info/asn1c}{asn1c-\asnver}}
Lev Walkined44bf42010-11-08 02:04:55 -0800109\maketitle
Lev Walkined44bf42010-11-08 02:04:55 -0800110
111\tableofcontents{}
112
Lev Walkined44bf42010-11-08 02:04:55 -0800113\part{Using the ASN.1 Compiler}
114
115
116\chapter{Introduction to the ASN.1 Compiler}
117
118The purpose of the ASN.1 compiler is to convert the specifications
119in ASN.1 notation into some other language. At this moment, only C
120and C++ target languages are supported, the latter is in upward compatibility
121mode.
122
123The compiler reads the specification and emits a series of target
Lev Walkin464166c2010-11-09 08:34:38 -0800124language structures (C structs, unions, enums) describing the corresponding
Lev Walkined44bf42010-11-08 02:04:55 -0800125ASN.1 types. The compiler also creates the code which allows automatic
126serialization and deserialization of these structures using several
Lev Walkin464166c2010-11-09 08:34:38 -0800127standardized encoding rules (BER, DER, XER, PER).
Lev Walkined44bf42010-11-08 02:04:55 -0800128
129For example, suppose the following ASN.1 module is given%
Lev Walkin194b2102013-03-28 01:29:06 -0700130\footnote{Part \ref{par:ASN.1-Basics} provides a quick reference
Lev Walkin464166c2010-11-09 08:34:38 -0800131on the ASN.1 notation.}:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700132\begin{asn}
133RectangleTest DEFINITIONS ::= BEGIN
Lev Walkined44bf42010-11-08 02:04:55 -0800134
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700135Rectangle ::= SEQUENCE {
136 height INTEGER, -- Height of the rectangle
137 width INTEGER -- Width of the rectangle
138}
Lev Walkined44bf42010-11-08 02:04:55 -0800139
140END
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700141\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -0800142The compiler would read this ASN.1 definition and produce the following
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700143C type:
144\begin{codesample}
145typedef struct Rectangle_s {
146 long height;
147 long width;
148} Rectangle_t;
149\end{codesample}
Lev Walkined44bf42010-11-08 02:04:55 -0800150It would also create the code for converting this structure into platform-independent
151wire representation (a serializer API) and the decoder of such wire
152representation back into local, machine-specific type (a deserializer
153API).
154
155
156\section{Quick start with asn1c}
157
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700158After building and installing the compiler, the \emph{asn1c}
159command may be used to compile the ASN.1 modules%
Lev Walkin194b2102013-03-28 01:29:06 -0700160\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 -0800161to find out about \textbf{-P} and \textbf{-R} options.%
162}:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700163\begin{bash}
164asn1c %\emph{<modules.asn1>}%
165\end{bash}
Lev Walkined44bf42010-11-08 02:04:55 -0800166If several ASN.1 modules contain interdependencies, all of the files
167must be specified altogether:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700168\begin{bash}
169asn1c %\emph{<module1.asn1> <module2.asn1> ...}%
170\end{bash}
Lev Walkined44bf42010-11-08 02:04:55 -0800171The compiler \textbf{-E} and \textbf{-EF} options are used for testing
172the parser and the semantic fixer, respectively. These options will
173instruct the compiler to dump out the parsed (and fixed, if \textbf{-F}
Lev Walkin2a744a72013-03-27 01:56:23 -0700174is involved) ASN.1 specification as it was understood
Lev Walkined44bf42010-11-08 02:04:55 -0800175by the compiler. It might be useful to check whether a particular
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700176syntactic construct is properly supported by the compiler.
177\begin{bash}
178asn1c %\textbf{-EF} \emph{<module-to-test.asn1>}%
179\end{bash}
Lev Walkined44bf42010-11-08 02:04:55 -0800180The \textbf{-P} option is used to dump the compiled output on the
181screen instead of creating a bunch of .c and .h files on disk in the
182current directory. You would probably want to start with \textbf{-P}
183option instead of creating a mess in your current directory. Another
184option, \textbf{-R}, asks compiler to only generate the files which
185need to be generated, and supress linking in the numerous support
186files.
187
188Print the compiled output instead of creating multiple source files:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700189\begin{bash}
190asn1c %\textbf{-P} \emph{<module-to-compile-and-print.asn1>}%
191\end{bash}
Lev Walkined44bf42010-11-08 02:04:55 -0800192
Lev Walkin2a744a72013-03-27 01:56:23 -0700193\clearpage{}
Lev Walkined44bf42010-11-08 02:04:55 -0800194\section{Recognizing compiler output}
195
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700196The asn1c compiler produces a number of files:
Lev Walkined44bf42010-11-08 02:04:55 -0800197\begin{itemize}
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700198\item A set of .c and .h files for each type defined
199in the ASN.1 specification. These files will be named similarly to
Lev Walkined44bf42010-11-08 02:04:55 -0800200the ASN.1 types (\emph{Rectangle.c} and \emph{Rectangle.h} for the
201RectangleTest ASN.1 module defined in the beginning of this document).
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700202\item A set of helper .c and .h files which contain the generic encoders,
203decoders and other useful routines. There will be quite a few of them, some
204of them are not even always necessary, but the overall amount of code
Lev Walkined44bf42010-11-08 02:04:55 -0800205after compilation will be rather small anyway.
Lev Walkin15b26e62017-09-26 23:04:57 -0700206\item A \emph{converter-example.c} file containing the \emph{int main()} function with a fully functioning decoder. It can convert a given PDU between BER, XER and possibly OER and PER (if -gen-OER or -gen-PER options to asn1c were in effect). At some point you will want to replace this file with your own file containing the \emph{int main()} function.
207\item A \emph{Makefile.am.libasncodecs} file mentioning all the files created
208at the earlier steps. The accompanying \emph{Makefile.am.example} file is
209suitable for either automake suite or the plain `make` utility.
210Just rename it into \emph{Makefile}.
Lev Walkined44bf42010-11-08 02:04:55 -0800211\end{itemize}
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700212It is possible to compile everything with just a couple of instructions:
213\begin{bash}
Lev Walkin2a744a72013-03-27 01:56:23 -0700214asn1c -pdu=%\emph{Rectangle}% *.asn1
Lev Walkin15b26e62017-09-26 23:04:57 -0700215make -f Makefile.am.example # If you use `make`
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700216\end{bash}
217or
218\begin{bash}
Lev Walkin2a744a72013-03-27 01:56:23 -0700219asn1c *.asn1
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700220cc -I. -DPDU=%\emph{Rectangle}% -o rectangle.exe *.c # ... or like this
221\end{bash}
Lev Walkin194b2102013-03-28 01:29:06 -0700222Refer to the Chapter \ref{cha:Step-by-step-examples} for a sample
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700223\emph{int main()} function if you want some custom logic and not satisfied
Lev Walkin15b26e62017-09-26 23:04:57 -0700224with the supplied \emph{converter-example.c}.
Lev Walkined44bf42010-11-08 02:04:55 -0800225
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700226\clearpage{}
Lev Walkined44bf42010-11-08 02:04:55 -0800227\section{\label{sec:Command-line-options}Command line options}
228
229The following table summarizes the asn1c command line options.
230
Lev Walkin464166c2010-11-09 08:34:38 -0800231\renewcommand{\arraystretch}{1.33}
232\begin{longtable}{lp{4in}}
Lev Walkin288527b2014-10-26 20:12:53 -0700233\textbf{Stage Selection Options} & \textbf{Description}\\
Lev Walkin464166c2010-11-09 08:34:38 -0800234\midrule
Lev Walkin288527b2014-10-26 20:12:53 -0700235{\ttfamily -E} & {\small Stop after the parsing stage and print the reconstructed ASN.1
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700236specification code to the standard output.}\\
Lev Walkin288527b2014-10-26 20:12:53 -0700237{\ttfamily -F} & {\small Used together with \texttt{-E}, instructs the compiler to stop after
Lev Walkined44bf42010-11-08 02:04:55 -0800238the ASN.1 syntax tree fixing stage and dump the reconstructed ASN.1
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700239specification to the standard output.}\\
Lev Walkin288527b2014-10-26 20:12:53 -0700240{\ttfamily -P} & {\small Dump the compiled output to the standard output instead of
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700241creating the target language files on disk.}\\
Lev Walkin288527b2014-10-26 20:12:53 -0700242{\ttfamily -R} & {\small Restrict the compiler to generate only the ASN.1 tables, omitting the usual support code.}\\
243{\ttfamily -S~\emph{<directory>}} & {\small Use the specified directory with ASN.1 skeleton files.}\\
244{\ttfamily -X} & {\small Generate the XML DTD for the specified ASN.1 modules.}\\\\
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700245\textbf{Warning Options} & \textbf{Description}\\
Lev Walkin464166c2010-11-09 08:34:38 -0800246\midrule
Lev Walkin288527b2014-10-26 20:12:53 -0700247{\ttfamily -Werror} & {\small Treat warnings as errors; abort if any warning is produced.}\\
Lev Walkin6a0b3632017-09-13 01:36:47 -0700248{\ttfamily -Wdebug-parser} & {\small Enable the parser debugging during the ASN.1 parsing stage.}\\
249{\ttfamily -Wdebug-lexer} & {\small Enable the lexer debugging during the ASN.1 parsing stage.}\\
250{\ttfamily -Wdebug-fixer} & {\small Enable the ASN.1 syntax tree fixer debugging during the fixing stage.}\\
Lev Walkin288527b2014-10-26 20:12:53 -0700251{\ttfamily -Wdebug-compiler} & {\small Enable debugging during the actual compile time.}\\ \\
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700252\textbf{Language Options} & \textbf{Description}\\
Lev Walkin464166c2010-11-09 08:34:38 -0800253\midrule
Lev Walkin288527b2014-10-26 20:12:53 -0700254{\ttfamily -fbless-SIZE} & {\small Allow SIZE() constraint for INTEGER, ENUMERATED, and other types for which this constraint is normally prohibited by the standard.
255This is a violation of an ASN.1 standard and compiler may fail to produce the meaningful code.}\\
256{\ttfamily -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.}\\
Lev Walkin288527b2014-10-26 20:12:53 -0700259{\ttfamily -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 Walkin288527b2014-10-26 20:12:53 -0700261using this option together with \texttt{-fno-include-deps}
262to prevent circular references.}\\
263{\ttfamily -fincludes-quoted} & {\small Generate \#include lines in "double" instead of <angle> quotes.}\\
264{\ttfamily -fknown-extern-type=\emph{<name>}} & {\small Pretend the specified type is known. The compiler will assume
Lev Walkined44bf42010-11-08 02:04:55 -0800265the target language source files for the given type have been provided
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700266manually. }\\
Lev Walkin288527b2014-10-26 20:12:53 -0700267{\ttfamily -fline-refs} & {\small Include ASN.1 module's line numbers in generated code comments.}\\
268{\ttfamily -fno-constraints} & {\small Do not generate ASN.1 subtype constraint checking code. This
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700269may produce a shorter executable.}\\
Lev Walkin288527b2014-10-26 20:12:53 -0700270{\ttfamily -fno-include-deps} & {\small Do not generate courtesy \#include lines for non-critical dependencies.}\\
271{\ttfamily -funnamed-unions} & {\small Enable unnamed unions in the definitions of target language's structures.}\\
272{\ttfamily -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 -0700273\textbf{Codecs Generation Options} & \textbf{Description}\\
Lev Walkin464166c2010-11-09 08:34:38 -0800274\midrule
Lev Walkinba68c912017-07-06 07:52:39 -0700275{\ttfamily -gen-OER} & {\small Generate the Octet Encoding Rules (OER) support code.}\\
Lev Walkin288527b2014-10-26 20:12:53 -0700276{\ttfamily -gen-PER} & {\small Generate the Packed Encoding Rules (PER) support code.}\\
277{\ttfamily -pdu=\{\textbf{all}|\textbf{auto}|\emph{Type}\}} & {\small Create a PDU table for specified types, or discover the Protocol Data Units automatically.
278In case of \texttt{-pdu=\textbf{all}}, all ASN.1 types defined in all modules wil form a PDU table. In case of \texttt{-pdu=\textbf{auto}}, all types not referenced by any other type will form a PDU table. If \texttt{\emph{Type}} is an ASN.1 type identifier, it is added to a PDU table. The last form may be specified multiple times.}\\ \\
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700279\textbf{Output Options} & \textbf{Description}\\
Lev Walkin464166c2010-11-09 08:34:38 -0800280\midrule
Lev Walkin288527b2014-10-26 20:12:53 -0700281{\ttfamily -print-constraints} & {\small When \texttt{-EF} are also specified, this option forces the compiler
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700282to explain its internal understanding of subtype constraints.}\\
Lev Walkin288527b2014-10-26 20:12:53 -0700283{\ttfamily -print-lines} & {\small Generate \texttt{``-{}- \#line''} comments
284in \texttt{-E} output.}\\
Lev Walkined44bf42010-11-08 02:04:55 -0800285\end{longtable}
Lev Walkin464166c2010-11-09 08:34:38 -0800286\renewcommand{\arraystretch}{1}
Lev Walkined44bf42010-11-08 02:04:55 -0800287
288
289\chapter{Using the ASN.1 Compiler}
290
291
292\section[Invoking the helper code]{Invoking the ASN.1 helper code}
293
294First of all, you should include one or more header files into your
295application. Typically, it is enough to include the header file of
296the main PDU type. For our Rectangle module, including the Rectangle.h
297file is sufficient:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700298\begin{codesample}
299#include <Rectangle.h>
300\end{codesample}
Lev Walkined44bf42010-11-08 02:04:55 -0800301The header files defines the C structure corresponding to the ASN.1
302definition of a rectangle and the declaration of the ASN.1 type descriptor,
303which is used as an argument to most of the functions provided by
304the ASN.1 module. For example, here is the code which frees the Rectangle\_t
305structure:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700306\begin{codesample}
307Rectangle_t *rect = ...;
Lev Walkined44bf42010-11-08 02:04:55 -0800308
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700309ASN_STRUCT_FREE(asn_DEF_Rectangle, rect);
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700310\end{codesample}
Lev Walkined44bf42010-11-08 02:04:55 -0800311This code defines a \emph{rect} pointer which points to the Rectangle\_t
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700312structure which needs to be freed. The second line uses the generic
313ASN\_STRUCT\_FREE() macro which invokes the memory deallocation routine
314created specifically for this Rectangle\_t structure.
315The \emph{asn\_DEF\_Rectangle} is the type descriptor which holds
316a collection of routines and operations defined for the Rectangle\_t structure.
Lev Walkined44bf42010-11-08 02:04:55 -0800317
318The following member functions of the asn\_DEF\_Rectangle type descriptor
319are of interest:
320\begin{description}
321\item [{ber\_decoder}] This is the generic \emph{restartable}%
Lev Walkin288527b2014-10-26 20:12:53 -0700322\footnote{Restartability mean that if the decoder encounters the end of the buffer it may be invoked again with the rest of the
323buffer to continue decoding.}
324BER decoder (Basic Encoding Rules). This decoder would create and/or
Lev Walkin194b2102013-03-28 01:29:06 -0700325fill the target structure for you. See Section~\ref{sub:Decoding-BER}.
Lev Walkined44bf42010-11-08 02:04:55 -0800326\item [{der\_encoder}] This is the generic DER encoder (Distinguished Encoding
327Rules). This encoder will take the target structure and encode it
Lev Walkin194b2102013-03-28 01:29:06 -0700328into a series of bytes. See Section~\ref{sub:Encoding-DER}. NOTE:
Lev Walkined44bf42010-11-08 02:04:55 -0800329DER encoding is a subset of BER. Any BER decoder should be able to
Lev Walkin6a0b3632017-09-13 01:36:47 -0700330handle any DER input.
331\item [{oer\_decoder}] This is the OER (Octet Encoding Rules) decoder.
332\item [{oer\_encoder}] This is the Canonical OER encoder. This encoder
333will take the target structure and encode it into a series of bytes compatible
334with all BASIC-OER and CANONICAL-OER decoders.
335\item [{uper\_decoder}] This is the Unaligned PER decoder.
336\item [{uper\_encoder}] This is the Unaligned Basic PER encoder. This encoder
337will take the target structure and encode it into a series of bytes.
Lev Walkined44bf42010-11-08 02:04:55 -0800338\item [{xer\_decoder}] This is the generic XER decoder. It takes both BASIC-XER
339or CANONICAL-XER encodings and deserializes the data into a local,
Lev Walkin194b2102013-03-28 01:29:06 -0700340machine-dependent representation. See Section~\ref{sub:Decoding-XER}.
Lev Walkined44bf42010-11-08 02:04:55 -0800341\item [{xer\_encoder}] This is the XER encoder (XML Encoding Rules). This
342encoder will take the target structure and represent it as an XML
343(text) document using either BASIC-XER or CANONICAL-XER encoding rules.
Lev Walkin194b2102013-03-28 01:29:06 -0700344See Section~\ref{sub:Encoding-XER}.
Lev Walkin6a0b3632017-09-13 01:36:47 -0700345
Lev Walkined44bf42010-11-08 02:04:55 -0800346\item [{check\_constraints}] Check that the contents of the target structure
347are semantically valid and constrained to appropriate implicit or
Lev Walkin194b2102013-03-28 01:29:06 -0700348explicit subtype constraints. See Section~\ref{sub:Validating-the-target}.
Lev Walkined44bf42010-11-08 02:04:55 -0800349\item [{print\_struct}] This function convert the contents of the passed
350target structure into human readable form. This form is not formal
351and cannot be converted back into the structure, but it may turn out
Lev Walkin194b2102013-03-28 01:29:06 -0700352to be useful for debugging or quick-n-dirty printing. See Section~\ref{sub:Printing-the-target}.
Lev Walkined44bf42010-11-08 02:04:55 -0800353\item [{free\_struct}] This is a generic disposal which frees the target
Lev Walkin194b2102013-03-28 01:29:06 -0700354structure. See Section~\ref{sub:Freeing-the-target}.
Lev Walkined44bf42010-11-08 02:04:55 -0800355\end{description}
356Each of the above function takes the type descriptor (\emph{asn\_DEF\_\ldots{}})
357and the target structure (\emph{rect}, in the above example).
358
Lev Walkin6a0b3632017-09-13 01:36:47 -0700359\subsection{\label{sub:Generic-Encoding}Generic encoders and decoders}
360
361Before we start describing specific encoders and decoders, let's step back
362a little and check out a simple high level way.
363
364The asn1c runtime supplies (see asn\_application.h) two sets of high level functions, \emph{asn\_encode*} and \emph{asn\_decode*}, which take a transfer syntax selector as the argument. The transfer syntax selector is defined as this:
365
366\begin{codesample}[basicstyle=\scriptsize\listingfont]
367/*
368 * A selection of ASN.1 Transfer Syntaxes to use with generalized encoders and decoders.
369 */
370enum asn_transfer_syntax {
371 ATS_INVALID,
372 ATS_NONSTANDARD_PLAINTEXT,
373 ATS_BER,
374 ATS_DER,
375 ATS_CER,
376 ATS_BASIC_OER,
377 ATS_CANONICAL_OER,
378 ATS_UNALIGNED_BASIC_PER,
379 ATS_UNALIGNED_CANONICAL_PER,
380 ATS_BASIC_XER,
381 ATS_CANONICAL_XER,
382};
383\end{codesample}
384
385Using this encoding selector, encoding and decoding becomes very generic:
386
387\noindent{}Encoding:
388
389\begin{codesample}[basicstyle=\scriptsize\listingfont]
390uint8_t buffer[128];
391size_t buf_size = sizeof(buffer);
392asn_enc_rval_t er;
393
394er = %\textbf{asn\_encode\emph{\_to\_buffer}}%(0, %\textbf{ATS\_BER}%, &asn_DEF_Rectangle, buffer, buf_size);
395
396if(er.encoded > buf_size) {
397 fprintf(stderr, "Buffer of size %\%%zu is too small for %\%%s, need %\%%zu\n",
398 buf_size, asn_DEF_Rectangle.name, er.encoded);
399 ASN_STRUCT_FREE(asn_DEF_Rectangle, rect);
400}
401\end{codesample}
402
403\noindent{}Decoding:
404
405\begin{codesample}[basicstyle=\scriptsize\listingfont]
406Rectangle_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.}!}% */
407
408... = %\textbf{asn\_decode}%(0, %\textbf{ATS\_BER}%, &asn_DEF_Rectangle, (void **)%$\underbracket{\textrm{\listingfont \&rect}}$%, buffer, buf_size);
409\end{codesample}
Lev Walkined44bf42010-11-08 02:04:55 -0800410
411\subsection{\label{sub:Decoding-BER}Decoding BER}
412
413The Basic Encoding Rules describe the most widely used (by the ASN.1
414community) way to encode and decode a given structure in a machine-independent
415way. Several other encoding rules (CER, DER) define a more restrictive
416versions of BER, so the generic BER parser is also capable of decoding
Lev Walkin6a0b3632017-09-13 01:36:47 -0700417the data encoded by the CER and DER encoders. The opposite is not true.
Lev Walkined44bf42010-11-08 02:04:55 -0800418
419\emph{The ASN.1 compiler provides the generic BER decoder which is
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700420capable of decoding BER, CER and DER encoded data.}
Lev Walkined44bf42010-11-08 02:04:55 -0800421
422The decoder is restartable (stream-oriented), which means that in
423case the buffer has less data than it is expected, the decoder will
424process whatever there is available and ask for more data to be provided.
425Please note that the decoder may actually process less data than it
426was given in the buffer, which means that you must be able to make
427the next buffer contain the unprocessed part of the previous buffer.
428
429Suppose, you have two buffers of encoded data: 100 bytes and 200 bytes.
430\begin{itemize}
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700431\item You can concatenate these buffers and feed the BER decoder with 300
Lev Walkined44bf42010-11-08 02:04:55 -0800432bytes of data, or
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700433\item You can feed it the first buffer of 100 bytes of data, realize that
Lev Walkined44bf42010-11-08 02:04:55 -0800434the ber\_decoder consumed only 95 bytes from it and later feed the
435decoder with 205 bytes buffer which consists of 5 unprocessed bytes
436from the first buffer and the additional 200 bytes from the second
437buffer.
438\end{itemize}
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700439This is not as convenient as it could be (the BER encoder could
Lev Walkined44bf42010-11-08 02:04:55 -0800440consume the whole 100 bytes and keep these 5 bytes in some temporary
441storage), but in case of existing stream based processing it might
442actually fit well into existing algorithm. Suggestions are welcome.
443
Lev Walkin6a0b3632017-09-13 01:36:47 -0700444Here is the example of BER decoding of a simple structure:
Lev Walkined44bf42010-11-08 02:04:55 -0800445
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700446\begin{codesample}
447Rectangle_t *
448simple_deserializer(const void *buffer, size_t buf_size) {
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700449 asn_dec_rval_t rval;
Lev Walkin194b2102013-03-28 01:29:06 -0700450 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 -0800451
Lev Walkin6a0b3632017-09-13 01:36:47 -0700452 rval = %\textbf{asn\_DEF\_Rectangle.op->ber\_decoder}%(0,
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700453 &asn_DEF_Rectangle,
Lev Walkin6a0b3632017-09-13 01:36:47 -0700454 (void **)%$\underbracket{\textrm{\listingfont \&rect}}$%, /* Decoder %\emph{changes}% the pointer */
Lev Walkin194b2102013-03-28 01:29:06 -0700455 buffer, buf_size, 0);
Lev Walkined44bf42010-11-08 02:04:55 -0800456
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700457 if(rval%\textbf{.code}% == RC_OK) {
458 return rect; /* Decoding succeeded */
459 } else {
Lev Walkin6a0b3632017-09-13 01:36:47 -0700460 /* Free the partially decoded rectangle */
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700461 ASN_STRUCT_FREE(asn_DEF_Rectangle, rect);
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700462 return 0;
463 }
464}
465\end{codesample}
Lev Walkin6a0b3632017-09-13 01:36:47 -0700466
Lev Walkined44bf42010-11-08 02:04:55 -0800467The code above defines a function, \emph{simple\_deserializer}, which
468takes a buffer and its length and is expected to return a pointer
469to the Rectangle\_t structure. Inside, it tries to convert the bytes
470passed into the target structure (rect) using the BER decoder and
471returns the rect pointer afterwards. If the structure cannot be deserialized,
472it frees the memory which might be left allocated by the unfinished
473\emph{ber\_decoder} routine and returns 0 (no data). (This \textbf{freeing
474is necessary} because the ber\_decoder is a restartable procedure,
475and may fail just because there is more data needs to be provided
476before decoding could be finalized). The code above obviously does
477not take into account the way the \emph{ber\_decoder()} failed, so
478the freeing is necessary because the part of the buffer may already
479be decoded into the structure by the time something goes wrong.
480
481A little less wordy would be to invoke a globally available \emph{ber\_decode()}
482function instead of dereferencing the asn\_DEF\_Rectangle type descriptor:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700483\begin{codesample}
484rval = ber_decode(0, &asn_DEF_Rectangle, (void **)&rect, buffer, buf_size);
485\end{codesample}
Lev Walkin6a0b3632017-09-13 01:36:47 -0700486Note that the initial (asn\_DEF\_Rectangle.op->ber\_decoder) reference
Lev Walkined44bf42010-11-08 02:04:55 -0800487is gone, and also the last argument (0) is no longer necessary.
488
489These two ways of BER decoder invocations are fully equivalent.
490
491The BER de\emph{coder} may fail because of (\emph{the following RC\_\ldots{}
492codes are defined in ber\_decoder.h}):
493\begin{itemize}
494\item RC\_WMORE: There is more data expected than it is provided (stream
495mode continuation feature);
496\item RC\_FAIL: General failure to decode the buffer;
497\item \ldots{} other codes may be defined as well.
498\end{itemize}
499Together with the return code (.code) the asn\_dec\_rval\_t type contains
500the number of bytes which is consumed from the buffer. In the previous
501hypothetical example of two buffers (of 100 and 200 bytes), the first
502call to ber\_decode() would return with .code = RC\_WMORE and .consumed
503= 95. The .consumed field of the BER decoder return value is \textbf{always}
504valid, even if the decoder succeeds or fails with any other return
505code.
506
Lev Walkin464166c2010-11-09 08:34:38 -0800507Look into ber\_decoder.h for the precise definition of ber\_decode()
Lev Walkined44bf42010-11-08 02:04:55 -0800508and related types.
509
510
511\subsection{\label{sub:Encoding-DER}Encoding DER}
512
513The Distinguished Encoding Rules is the \emph{canonical} variant of
514BER encoding rules. The DER is best suited to encode the structures
515where all the lengths are known beforehand. This is probably exactly
516how you want to encode: either after a BER decoding or after a manual
517fill-up, the target structure contains the data which size is implicitly
518known before encoding. Among other uses, the DER encoding is used
519to encode X.509 certificates.
520
521As with BER decoder, the DER encoder may be invoked either directly
522from the ASN.1 type descriptor (asn\_DEF\_Rectangle) or from the stand-alone
523function, which is somewhat simpler:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700524\begin{codesample}
525/*
526 * This is the serializer itself.
527 * It supplies the DER encoder with the
528 * pointer to the custom output function.
529 */
530ssize_t
531simple_serializer(FILE *ostream, Rectangle_t *rect) {
532 asn_enc_rval_t er; /* Encoder return value */
Lev Walkined44bf42010-11-08 02:04:55 -0800533
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700534 er = der_encode(&asn_DEF_Rect, rect, write_stream, ostream);
535 if(er%\textbf{.encoded}% == -1) {
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700536 fprintf(stderr, "Cannot encode %\%%s: %\%%s\n",
537 er%\textbf{.failed\_type}%->name, strerror(errno));
538 return -1;
539 } else {
540 /* Return the number of bytes */
541 return er.encoded;
542 }
543}
544\end{codesample}
Lev Walkined44bf42010-11-08 02:04:55 -0800545As you see, the DER encoder does not write into some sort of buffer
546or something. It just invokes the custom function (possible, multiple
547times) which would save the data into appropriate storage. The optional
548argument \emph{app\_key} is opaque for the DER encoder code and just
549used by \emph{\_write\_stream()} as the pointer to the appropriate
550output stream to be used.
551
552If the custom write function is not given (passed as 0), then the
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700553DER encoder will essentially do the same thing (i.~e., encode the data)
Lev Walkined44bf42010-11-08 02:04:55 -0800554but no callbacks will be invoked (so the data goes nowhere). It may
555prove useful to determine the size of the structure's encoding before
556actually doing the encoding%
557\footnote{It is actually faster too: the encoder might skip over some computations
558which aren't important for the size determination.%
559}.
560
Lev Walkin464166c2010-11-09 08:34:38 -0800561Look into der\_encoder.h for the precise definition of der\_encode()
Lev Walkined44bf42010-11-08 02:04:55 -0800562and related types.
563
564
565\subsection{\label{sub:Encoding-XER}Encoding XER}
566
567The XER stands for XML Encoding Rules, where XML, in turn, is eXtensible
568Markup Language, a text-based format for information exchange. The
569encoder routine API comes in two flavors: stdio-based and callback-based.
570With the callback-based encoder, the encoding process is very similar
Lev Walkin194b2102013-03-28 01:29:06 -0700571to the DER one, described in Section~\ref{sub:Encoding-DER}. The
Lev Walkined44bf42010-11-08 02:04:55 -0800572following example uses the definition of write\_stream() from up there.
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700573\begin{codesample}
574/*
Lev Walkin6a0b3632017-09-13 01:36:47 -0700575 * This procedure generates an XML document
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700576 * by invoking the XER encoder.
577 * NOTE: Do not copy this code verbatim!
578 * If the stdio output is necessary,
579 * use the xer_fprint() procedure instead.
Lev Walkin6a0b3632017-09-13 01:36:47 -0700580 * See Section %\ref{sub:Printing-the-target}%.
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700581 */
Lev Walkined44bf42010-11-08 02:04:55 -0800582int
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700583print_as_XML(FILE *ostream, Rectangle_t *rect) {
584 asn_enc_rval_t er; /* Encoder return value */
Lev Walkined44bf42010-11-08 02:04:55 -0800585
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700586 er = xer_encode(&asn_DEF_Rectangle, rect,
587 XER_F_BASIC, /* BASIC-XER or CANONICAL-XER */
588 write_stream, ostream);
Lev Walkined44bf42010-11-08 02:04:55 -0800589
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700590 return (er.encoded == -1) ? -1 : 0;
591}
592\end{codesample}
Lev Walkin464166c2010-11-09 08:34:38 -0800593Look into xer\_encoder.h for the precise definition of xer\_encode()
Lev Walkined44bf42010-11-08 02:04:55 -0800594and related types.
595
Lev Walkin194b2102013-03-28 01:29:06 -0700596See Section~\ref{sub:Printing-the-target} for the example of stdio-based
Lev Walkined44bf42010-11-08 02:04:55 -0800597XML encoder and other pretty-printing suggestions.
598
599
600\subsection{\label{sub:Decoding-XER}Decoding XER}
601
602The data encoded using the XER rules can be subsequently decoded using
603the xer\_decode() API call:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700604\begin{codesample}
605Rectangle_t *
606XML_to_Rectangle(const void *buffer, size_t buf_size) {
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700607 asn_dec_rval_t rval;
Lev Walkin194b2102013-03-28 01:29:06 -0700608 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 -0800609
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700610 rval = xer_decode(0, &asn_DEF_Rectangle, (void **)&rect, buffer, buf_size);
Lev Walkined44bf42010-11-08 02:04:55 -0800611
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700612 if(rval%\textbf{.code}% == RC_OK) {
613 return rect; /* Decoding succeeded */
614 } else {
615 /* Free partially decoded rect */
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700616 ASN_STRUCT_FREE(asn_DEF_Rectangle, rect);
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700617 return 0;
618 }
619}
620\end{codesample}
Lev Walkined44bf42010-11-08 02:04:55 -0800621The decoder takes both BASIC-XER and CANONICAL-XER encodings.
622
623The decoder shares its data consumption properties with BER decoder;
Lev Walkin194b2102013-03-28 01:29:06 -0700624please read the Section~\ref{sub:Decoding-BER} to know more.
Lev Walkined44bf42010-11-08 02:04:55 -0800625
Lev Walkin464166c2010-11-09 08:34:38 -0800626Look into xer\_decoder.h for the precise definition of xer\_decode()
Lev Walkined44bf42010-11-08 02:04:55 -0800627and related types.
628
629
630\subsection{\label{sub:Validating-the-target}Validating the target structure}
631
632Sometimes the target structure needs to be validated. For example,
633if the structure was created by the application (as opposed to being
634decoded from some external source), some important information required
635by the ASN.1 specification might be missing. On the other hand, the
636successful decoding of the data from some external source does not
637necessarily mean that the data is fully valid either. It might well
638be the case that the specification describes some subtype constraints
639that were not taken into account during decoding, and it would actually
640be useful to perform the last check when the data is ready to be encoded
641or when the data has just been decoded to ensure its validity according
642to some stricter rules.
643
644The asn\_check\_constraints() function checks the type for various
645implicit and explicit constraints. It is recommended to use asn\_check\_constraints()
646function after each decoding and before each encoding.
647
Lev Walkin464166c2010-11-09 08:34:38 -0800648Look into constraints.h for the precise definition of asn\_check\_constraints()
Lev Walkined44bf42010-11-08 02:04:55 -0800649and related types.
650
651
652\subsection{\label{sub:Printing-the-target}Printing the target structure}
653
654There are two ways to print the target structure: either invoke the
655print\_struct member of the ASN.1 type descriptor, or using the asn\_fprint()
656function, which is a simpler wrapper of the former:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700657\begin{codesample}
658asn_fprint(stdout, &asn_DEF_Rectangle, rect);
659\end{codesample}
Lev Walkin464166c2010-11-09 08:34:38 -0800660Look into constr\_TYPE.h for the precise definition of asn\_fprint()
Lev Walkined44bf42010-11-08 02:04:55 -0800661and related types.
662
663Another practical alternative to this custom format printing would
664be to invoke XER encoder. The default BASIC-XER encoder performs reasonable
665formatting for the output to be useful and human readable. To invoke
666the XER decoder in a manner similar to asn\_fprint(), use the xer\_fprint()
667call:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700668\begin{codesample}
669xer_fprint(stdout, &asn_DEF_Rectangle, rect);
670\end{codesample}
Lev Walkin194b2102013-03-28 01:29:06 -0700671See Section~\ref{sub:Encoding-XER} for XML-related details.
Lev Walkined44bf42010-11-08 02:04:55 -0800672
673
674\subsection{\label{sub:Freeing-the-target}Freeing the target structure}
675
676Freeing the structure is slightly more complex than it may seem to.
677When the ASN.1 structure is freed, all the members of the structure
678and their submembers are recursively freed as well. But it might not
679be feasible to free the structure itself. Consider the following case:
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700680\begin{codesample}
681struct my_figure { /* The custom structure */
682 int flags; /* <some custom member> */
683 /* The type is generated by the ASN.1 compiler */
684 Rectangle_t rect;
685 /* other members of the structure */
686};
687\end{codesample}
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700688In this example, the application programmer defines a custom structure
Lev Walkined44bf42010-11-08 02:04:55 -0800689with one ASN.1-derived member (rect). This member is not a reference
690to the Rectangle\_t, but an in-place inclusion of the Rectangle\_t
691structure. If the freeing is necessary, the usual procedure of freeing
692everything must not be applied to the \&rect pointer itself, because
693it does not point to the memory block directly allocated by the memory
694allocation routine, but instead lies within a block allocated for
695the my\_figure structure.
696
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700697To solve this problem, in addition to ASN\_STRUCT\_FREE macro, the asn1c
698skeletons define the ASN\_STRUCT\_RESET macro which doesn't free the passed
699pointer and instead resets the structure into the clean and safe state.
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700700\begin{codesample}
701/* %\textbf{1. Rectangle\_t is defined within my\_figure}% */
702struct my_figure {
703 Rectangle_t rect;
704} *mf = ...;
705/*
706 * Freeing the Rectangle_t
707 * without freeing the mf->rect area.
708 */
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700709ASN_STRUCT_RESET(asn_DEF_Rectangle, &mf->rect);
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700710
711/* %\textbf{2. Rectangle\_t is a stand-alone pointer}% */
712Rectangle_t *rect = ...;
713/*
714 * Freeing the Rectangle_t
715 * and freeing the rect pointer.
716 */
Lev Walkin6a0b3632017-09-13 01:36:47 -0700717ASN_STRUCT_FREE(asn_DEF_Rectangle, rect);
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700718\end{codesample}
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700719It is safe to invoke both macros with the target structure pointer
720set to 0 (NULL). In this case, the function will do nothing.
Lev Walkined44bf42010-11-08 02:04:55 -0800721
722\chapter{\label{cha:Step-by-step-examples}Step by step examples}
723
724
Lev Walkin464166c2010-11-09 08:34:38 -0800725\section{A ``Rectangle'' Encoder}
Lev Walkined44bf42010-11-08 02:04:55 -0800726
727This example will help you create a simple BER and XER encoder of
Lev Walkin464166c2010-11-09 08:34:38 -0800728a ``Rectangle'' type used throughout this document.
Lev Walkined44bf42010-11-08 02:04:55 -0800729\begin{enumerate}
730\item Create a file named \textbf{rectangle.asn1} with the following contents:
731
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700732\begin{asn}
733RectangleModule1 DEFINITIONS ::= BEGIN
Lev Walkined44bf42010-11-08 02:04:55 -0800734
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700735Rectangle ::= SEQUENCE {
736 height INTEGER,
737 width INTEGER
738}
Lev Walkined44bf42010-11-08 02:04:55 -0800739
740END
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700741\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -0800742\item Compile it into the set of .c and .h files using asn1c compiler \cite{ASN1C}:
743
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700744\begin{bash}
Lev Walkin2a744a72013-03-27 01:56:23 -0700745asn1c %\textbf{rectangle.asn1}%
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700746\end{bash}
Lev Walkined44bf42010-11-08 02:04:55 -0800747\item Alternatively, use the Online ASN.1 compiler \cite{AONL} by uploading
748the \textbf{rectangle.asn1} file into the Web form and unpacking the
749produced archive on your computer.
750\item By this time, you should have gotten multiple files in the current
751directory, including the \textbf{Rectangle.c} and \textbf{Rectangle.h}.
752\item Create a main() routine which creates the Rectangle\_t structure in
753memory and encodes it using BER and XER encoding rules. Let's name
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700754the file \textbf{main.c}:
Lev Walkined44bf42010-11-08 02:04:55 -0800755
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700756\begin{codesample}[basicstyle=\scriptsize\listingfont]
757#include <stdio.h>
758#include <sys/types.h>
759#include <Rectangle.h> /* Rectangle ASN.1 type */
Lev Walkined44bf42010-11-08 02:04:55 -0800760
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700761/* Write the encoded output into some FILE stream. */
762static int write_out(const void *buffer, size_t size, void *app_key) {
763 FILE *out_fp = app_key;
764 size_t wrote = fwrite(buffer, 1, size, out_fp);
765 return (wrote == size) ? 0 : -1;
766}
767
768int main(int ac, char **av) {
769 Rectangle_t *rectangle; /* Type to encode */
770 asn_enc_rval_t ec; /* Encoder return value */
Lev Walkined44bf42010-11-08 02:04:55 -0800771
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700772 /* Allocate the Rectangle_t */
773 rectangle = calloc(1, sizeof(Rectangle_t)); /* not malloc! */
774 if(!rectangle) {
775 perror("calloc() failed");
776 exit(1);
777 }
Lev Walkined44bf42010-11-08 02:04:55 -0800778
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700779 /* Initialize the Rectangle members */
780 rectangle->height = 42; /* any random value */
781 rectangle->width = 23; /* any random value */
Lev Walkined44bf42010-11-08 02:04:55 -0800782
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700783 /* BER encode the data if filename is given */
784 if(ac < 2) {
785 fprintf(stderr, "Specify filename for BER output\n");
786 } else {
787 const char *filename = av[1];
788 FILE *fp = fopen(filename, "wb"); /* for BER output */
789
790 if(!fp) {
791 perror(filename);
792 exit(1);
793 }
Lev Walkined44bf42010-11-08 02:04:55 -0800794
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700795 /* Encode the Rectangle type as BER (DER) */
796 ec = der_encode(&asn_DEF_Rectangle, rectangle, write_out, fp);
797 fclose(fp);
798 if(ec.encoded == -1) {
799 fprintf(stderr, "Could not encode Rectangle (at %\%%s)\n",
800 ec.failed_type ? ec.failed_type->name : "unknown");
801 exit(1);
802 } else {
803 fprintf(stderr, "Created %\%%s with BER encoded Rectangle\n", filename);
804 }
805 }
Lev Walkined44bf42010-11-08 02:04:55 -0800806
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700807 /* Also print the constructed Rectangle XER encoded (XML) */
808 xer_fprint(stdout, &asn_DEF_Rectangle, rectangle);
Lev Walkined44bf42010-11-08 02:04:55 -0800809
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700810 return 0; /* Encoding finished successfully */
811 }
812\end{codesample}
Lev Walkined44bf42010-11-08 02:04:55 -0800813\item Compile all files together using C compiler (varies by platform):
814
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700815\begin{bash}
816cc -I. -o %\textbf{\emph{rencode}} \emph{*.c}%
817\end{bash}
Lev Walkined44bf42010-11-08 02:04:55 -0800818\item Voila! You have just created the BER and XER encoder of a Rectangle
819type, named \textbf{rencode}!
820\end{enumerate}
Lev Walkined44bf42010-11-08 02:04:55 -0800821
Lev Walkin464166c2010-11-09 08:34:38 -0800822\section{\label{sec:A-Rectangle-Decoder}A ``Rectangle'' Decoder}
Lev Walkined44bf42010-11-08 02:04:55 -0800823
824This example will help you to create a simple BER decoder of a simple
Lev Walkin464166c2010-11-09 08:34:38 -0800825``Rectangle'' type used throughout this document.
Lev Walkined44bf42010-11-08 02:04:55 -0800826\begin{enumerate}
827\item Create a file named \textbf{rectangle.asn1} with the following contents:
828
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700829\begin{asn}
830RectangleModule1 DEFINITIONS ::= BEGIN
Lev Walkined44bf42010-11-08 02:04:55 -0800831
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700832Rectangle ::= SEQUENCE {
833 height INTEGER,
834 width INTEGER
835}
Lev Walkined44bf42010-11-08 02:04:55 -0800836
837END
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700838\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -0800839\item Compile it into the set of .c and .h files using asn1c compiler \cite{ASN1C}:
840
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700841\begin{bash}
Lev Walkin2a744a72013-03-27 01:56:23 -0700842asn1c %\textbf{rectangle.asn1}%
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700843\end{bash}
Lev Walkined44bf42010-11-08 02:04:55 -0800844\item Alternatively, use the Online ASN.1 compiler \cite{AONL} by uploading
845the \textbf{rectangle.asn1} file into the Web form and unpacking the
846produced archive on your computer.
847\item By this time, you should have gotten multiple files in the current
848directory, including the \textbf{Rectangle.c} and \textbf{Rectangle.h}.
849\item Create a main() routine which takes the binary input file, decodes
850it as it were a BER-encoded Rectangle type, and prints out the text
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700851(XML) representation of the Rectangle type. Let's name the file \textbf{main.c}:
Lev Walkined44bf42010-11-08 02:04:55 -0800852
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700853\begin{codesample}[basicstyle=\scriptsize\listingfont]
854#include <stdio.h>
855#include <sys/types.h>
856#include <Rectangle.h> /* Rectangle ASN.1 type */
Lev Walkined44bf42010-11-08 02:04:55 -0800857
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700858int main(int ac, char **av) {
859 char buf[1024]; /* Temporary buffer */
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700860 asn_dec_rval_t rval; /* Decoder return value */
Lev Walkin194b2102013-03-28 01:29:06 -0700861 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 -0700862 FILE *fp; /* Input file handler */
863 size_t size; /* Number of bytes read */
864 char *filename; /* Input file name */
Lev Walkined44bf42010-11-08 02:04:55 -0800865
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700866 /* Require a single filename argument */
867 if(ac != 2) {
868 fprintf(stderr, "Usage: %\%%s <file.ber>\n", av[0]);
869 exit(1);
870 } else {
871 filename = av[1];
872 }
Lev Walkined44bf42010-11-08 02:04:55 -0800873
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700874 /* Open input file as read-only binary */
875 fp = fopen(filename, "rb");
876 if(!fp) {
877 perror(filename);
878 exit(1);
879 }
Lev Walkined44bf42010-11-08 02:04:55 -0800880
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700881 /* Read up to the buffer size */
882 size = fread(buf, 1, sizeof(buf), fp);
883 fclose(fp);
884 if(!size) {
885 fprintf(stderr, "%\%%s: Empty or broken\n", filename);
886 exit(1);
887 }
Lev Walkined44bf42010-11-08 02:04:55 -0800888
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700889 /* Decode the input buffer as Rectangle type */
890 rval = ber_decode(0, &asn_DEF_Rectangle, (void **)&rectangle, buf, size);
891 if(rval.code != RC_OK) {
892 fprintf(stderr, "%\%%s: Broken Rectangle encoding at byte %\%%ld\n", filename, (long)rval.consumed);
893 exit(1);
894 }
Lev Walkined44bf42010-11-08 02:04:55 -0800895
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700896 /* Print the decoded Rectangle type as XML */
897 xer_fprint(stdout, &asn_DEF_Rectangle, rectangle);
Lev Walkined44bf42010-11-08 02:04:55 -0800898
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700899 return 0; /* Decoding finished successfully */
Lev Walkin194b2102013-03-28 01:29:06 -0700900}
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700901\end{codesample}
Lev Walkined44bf42010-11-08 02:04:55 -0800902\item Compile all files together using C compiler (varies by platform):
903
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700904\begin{bash}
905cc -I. -o %\textbf{\emph{rdecode}} \emph{*.c}%
906\end{bash}
Lev Walkined44bf42010-11-08 02:04:55 -0800907\item Voila! You have just created the BER decoder of a Rectangle type,
908named \textbf{rdecode}!
909\end{enumerate}
910
911\chapter{Constraint validation examples}
912
913This chapter shows how to define ASN.1 constraints and use the generated
914validation code.
915
916
Lev Walkin464166c2010-11-09 08:34:38 -0800917\section{Adding constraints into ``Rectangle'' type}
Lev Walkined44bf42010-11-08 02:04:55 -0800918
919This example shows how to add basic constraints to the ASN.1 specification
920and how to invoke the constraints validation code in your application.
921\begin{enumerate}
922\item Create a file named \textbf{rectangle.asn1} with the following contents:
923
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700924\begin{asn}
925RectangleModuleWithConstraints DEFINITIONS ::= BEGIN
Lev Walkined44bf42010-11-08 02:04:55 -0800926
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700927Rectangle ::= SEQUENCE {
928 height INTEGER (0..100), -- Value range constraint
929 width INTEGER (0..MAX) -- Makes width non-negative
930}
Lev Walkined44bf42010-11-08 02:04:55 -0800931
932END
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700933\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -0800934\item Compile the file according to procedures shown in the previous chapter.
935\item Modify the Rectangle type processing routine (you can start with the
Lev Walkin194b2102013-03-28 01:29:06 -0700936main() routine shown in the Section~\ref{sec:A-Rectangle-Decoder})
Lev Walkined44bf42010-11-08 02:04:55 -0800937by placing the following snippet of code \emph{before} encoding and/or
938\emph{after} decoding the Rectangle type%
Lev Walkin2e554fc2014-10-26 19:21:58 -0700939\footnote{Placing the constraint checking code \emph{before encoding} helps
940to make sure the data is correct and within constraints before
Lev Walkined44bf42010-11-08 02:04:55 -0800941sharing the data with anyone else.
Lev Walkin2e554fc2014-10-26 19:21:58 -0700942Placing the constraint checking code \emph{after decoding} helps to make sure
Lev Walkined44bf42010-11-08 02:04:55 -0800943the application got the valid contents before making use of it.%
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700944}:
Lev Walkined44bf42010-11-08 02:04:55 -0800945
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700946\begin{codesample}
947int ret; /* Return value */
948char errbuf[128]; /* Buffer for error message */
949size_t errlen = sizeof(errbuf); /* Size of the buffer */
Lev Walkined44bf42010-11-08 02:04:55 -0800950
Lev Walkin2e554fc2014-10-26 19:21:58 -0700951/* ... here goes the Rectangle %\emph{decoding}% code ... */
Lev Walkined44bf42010-11-08 02:04:55 -0800952
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700953ret = asn_check_constraints(&asn_DEF_Rectangle, rectangle, errbuf, &errlen);
954/* assert(errlen < sizeof(errbuf)); // you may rely on that */
955if(ret) {
956 fprintf(stderr, "Constraint validation failed: %\%%s\n",
957 errbuf /* errbuf is properly nul-terminated */
958 );
959 /* exit(...); // Replace with appropriate action */
960 }
Lev Walkined44bf42010-11-08 02:04:55 -0800961
Lev Walkin2e554fc2014-10-26 19:21:58 -0700962/* ... here goes the Rectangle %\emph{encoding}% code ... */
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700963\end{codesample}
Lev Walkined44bf42010-11-08 02:04:55 -0800964\item Compile the resulting C code as shown in the previous chapters.
965\item Try to test the constraints checking code by assigning integer value
966101 to the \textbf{.height} member of the Rectangle structure, or
967a negative value to the \textbf{.width} member. In either case, the
Lev Walkin464166c2010-11-09 08:34:38 -0800968program should print ``Constraint validation failed'' message, followed
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700969by a short explanation why validation did not succeed.
Lev Walkined44bf42010-11-08 02:04:55 -0800970\item Done.
971\end{enumerate}
972
973\part{\label{par:ASN.1-Basics}ASN.1 Basics}
974
975
976\chapter{\label{cha:Abstract-Syntax-Notation:}Abstract Syntax Notation: ASN.1}
977
978\emph{This chapter defines some basic ASN.1 concepts and describes
979several most widely used types. It is by no means an authoritative
980or complete reference. For more complete ASN.1 description, please
981refer to Olivier Dubuisson's book \cite{Dub00} or the ASN.1 body
982of standards itself \cite{ITU-T/ASN.1}.}
983
984The Abstract Syntax Notation One is used to formally describe the
Lev Walkin507f6002014-10-26 20:22:16 -0700985data transmitted across the network. Two communicating parties may employ
986different formats of their native data types (e.~g., different number
987of bits for the native integer type), thus it is important to have
Lev Walkined44bf42010-11-08 02:04:55 -0800988a way to describe the data in a manner which is independent from the
Lev Walkin507f6002014-10-26 20:22:16 -0700989particular machine's representation.
990The ASN.1 specifications are used to achieve the following:
Lev Walkined44bf42010-11-08 02:04:55 -0800991\begin{itemize}
992\item The specification expressed in the ASN.1 notation is a formal and
Lev Walkin507f6002014-10-26 20:22:16 -0700993precise way to communicate the structure of data to human readers;
Lev Walkined44bf42010-11-08 02:04:55 -0800994\item The ASN.1 specifications may be used as input for automatic compilers
995which produce the code for some target language (C, C++, Java, etc)
Lev Walkin507f6002014-10-26 20:22:16 -0700996to encode and decode the data according to some encoding formats.
997Several such encoding formats (called Transfer Encoding Rules)
998have been defined by the ASN.1 standard.
Lev Walkined44bf42010-11-08 02:04:55 -0800999\end{itemize}
1000Consider the following example:
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001001\begin{asn}
1002Rectangle ::= SEQUENCE {
1003 height INTEGER,
1004 width INTEGER
1005}
1006\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001007This ASN.1 specification describes a constructed type, \emph{Rectangle},
1008containing two integer fields. This specification may tell the reader
1009that there exists this kind of data structure and that some entity
1010may be prepared to send or receive it. The question on \emph{how}
1011that entity is going to send or receive the \emph{encoded data} is
1012outside the scope of ASN.1. For example, this data structure may be
1013encoded according to some encoding rules and sent to the destination
1014using the TCP protocol. The ASN.1 specifies several ways of encoding
Lev Walkin464166c2010-11-09 08:34:38 -08001015(or ``serializing'', or ``marshaling'') the data: BER, PER, XER
Lev Walkined44bf42010-11-08 02:04:55 -08001016and others, including CER and DER derivatives from BER.
1017
1018The complete specification must be wrapped in a module, which looks
1019like this:
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001020\begin{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001021RectangleModule1
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001022 { iso org(3) dod(6) internet(1) private(4)
1023 enterprise(1) spelio(9363) software(1)
1024 asn1c(5) docs(2) rectangle(1) 1 }
1025 DEFINITIONS AUTOMATIC TAGS ::=
Lev Walkined44bf42010-11-08 02:04:55 -08001026BEGIN
1027
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001028-- This is a comment which describes nothing.
1029Rectangle ::= SEQUENCE {
1030 height INTEGER, -- Height of the rectangle
1031 width INTEGER -- Width of the rectangle
1032}
Lev Walkined44bf42010-11-08 02:04:55 -08001033
1034END
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001035\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001036The module header consists of module name (RectangleModule1), the
Lev Walkin464166c2010-11-09 08:34:38 -08001037module object identifier (\{...\}), a keyword ``DEFINITIONS'', a
1038set of module flags (AUTOMATIC TAGS) and ``::= BEGIN''. The module
1039ends with an ``END'' statement.
Lev Walkined44bf42010-11-08 02:04:55 -08001040
1041
1042\section{Some of the ASN.1 Basic Types}
1043
1044
1045\subsection{The BOOLEAN type}
1046
1047The BOOLEAN type models the simple binary TRUE/FALSE, YES/NO, ON/OFF
1048or a similar kind of two-way choice.
1049
1050
1051\subsection{The INTEGER type}
1052
1053The INTEGER type is a signed natural number type without any restrictions
1054on its size. If the automatic checking on INTEGER value bounds are
1055necessary, the subtype constraints must be used.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001056\begin{asn}
1057SimpleInteger ::= INTEGER
Lev Walkined44bf42010-11-08 02:04:55 -08001058
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001059-- An integer with a very limited range
1060SmallPositiveInt ::= INTEGER (0..127)
Lev Walkined44bf42010-11-08 02:04:55 -08001061
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001062-- Integer, negative
1063NegativeInt ::= INTEGER (MIN..0)
1064\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001065
1066\subsection{The ENUMERATED type}
1067
1068The ENUMERATED type is semantically equivalent to the INTEGER type
1069with some integer values explicitly named.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001070\begin{asn}
1071FruitId ::= ENUMERATED { apple(1), orange(2) }
Lev Walkined44bf42010-11-08 02:04:55 -08001072
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001073-- The numbers in braces are optional,
1074-- the enumeration can be performed
1075-- automatically by the compiler
1076ComputerOSType ::= ENUMERATED {
1077 FreeBSD, -- acquires value 0
1078 Windows, -- acquires value 1
1079 Solaris(5), -- remains 5
1080 Linux, -- becomes 6
1081 MacOS -- becomes 7
1082}
1083\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001084
1085\subsection{The OCTET STRING type}
1086
1087This type models the sequence of 8-bit bytes. This may be used to
1088transmit some opaque data or data serialized by other types of encoders
Lev Walkin507f6002014-10-26 20:22:16 -07001089(e.~g., video file, photo picture, etc).
Lev Walkined44bf42010-11-08 02:04:55 -08001090
1091\subsection{The OBJECT IDENTIFIER type}
1092
1093The OBJECT IDENTIFIER is used to represent the unique identifier of
1094any object, starting from the very root of the registration tree.
1095If your organization needs to uniquely identify something (a router,
1096a room, a person, a standard, or whatever), you are encouraged to
1097get your own identification subtree at \url{http://www.iana.org/protocols/forms.htm}.
1098
1099For example, the very first ASN.1 module in this Chapter (RectangleModule1)
1100has the following OBJECT IDENTIFIER: 1 3 6 1 4 1 9363 1 5 2 1 1.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001101\begin{asn}
1102ExampleOID ::= OBJECT IDENTIFIER
Lev Walkined44bf42010-11-08 02:04:55 -08001103
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001104rectangleModule1-oid ExampleOID
1105 ::= { 1 3 6 1 4 1 9363 1 5 2 1 1 }
Lev Walkined44bf42010-11-08 02:04:55 -08001106
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001107-- An identifier of the Internet.
1108internet-id OBJECT IDENTIFIER
1109 ::= { iso(1) identified-organization(3)
1110 dod(6) internet(1) }
1111\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001112As you see, names are optional.
1113
1114
1115\subsection{The RELATIVE-OID type}
1116
1117The RELATIVE-OID type has the semantics of a subtree of an OBJECT
1118IDENTIFIER. There may be no need to repeat the whole sequence of numbers
1119from the root of the registration tree where the only thing of interest
1120is some of the tree's subsequence.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001121\begin{asn}
1122this-document RELATIVE-OID ::= { docs(2) usage(1) }
Lev Walkined44bf42010-11-08 02:04:55 -08001123
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001124this-example RELATIVE-OID ::= {
1125 this-document assorted-examples(0) this-example(1) }
1126\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001127
1128\section{Some of the ASN.1 String Types}
1129
1130
1131\subsection{The IA5String type}
1132
1133This is essentially the ASCII, with 128 character codes available
1134(7 lower bits of an 8-bit byte).
1135
1136
1137\subsection{The UTF8String type}
1138
1139This is the character string which encodes the full Unicode range
1140(4 bytes) using multibyte character sequences.
1141
1142
1143\subsection{The NumericString type}
1144
1145This type represents the character string with the alphabet consisting
Lev Walkin464166c2010-11-09 08:34:38 -08001146of numbers (``0'' to ``9'') and a space.
Lev Walkined44bf42010-11-08 02:04:55 -08001147
1148
1149\subsection{The PrintableString type}
1150
Lev Walkin464166c2010-11-09 08:34:38 -08001151The character string with the following alphabet: space, ``\textbf{'}''
1152(single quote), ``\textbf{(}'', ``\textbf{)}'', ``\textbf{+}'',
1153``\textbf{,}'' (comma), ``\textbf{-}'', ``\textbf{.}'', ``\textbf{/}'',
1154digits (``0'' to ``9''), ``\textbf{:}'', ``\textbf{=}'', ``\textbf{?}'',
1155upper-case and lower-case letters (``A'' to ``Z'' and ``a''
1156to ``z'').
Lev Walkined44bf42010-11-08 02:04:55 -08001157
1158
1159\subsection{The VisibleString type}
1160
1161The character string with the alphabet which is more or less a subset
Lev Walkin464166c2010-11-09 08:34:38 -08001162of ASCII between the space and the ``\textbf{\textasciitilde{}}''
Lev Walkined44bf42010-11-08 02:04:55 -08001163symbol (tilde).
1164
1165Alternatively, the alphabet may be described as the PrintableString
Lev Walkin464166c2010-11-09 08:34:38 -08001166alphabet presented earlier, plus the following characters: ``\textbf{!}'',
1167``\textbf{``}'', ``\textbf{\#}'', ``\textbf{\$}'', ``\textbf{\%}'',
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001168``\textbf{\&}'', ``\textbf{*}'', ``\textbf{;}'', ``\textbf{<}'',
Lev Walkin464166c2010-11-09 08:34:38 -08001169``\textbf{>}'', ``\textbf{{[}}'', ``\textbf{\textbackslash{}}'',
1170``\textbf{{]}}'', ``\textbf{\textasciicircum{}}'', ``\textbf{\_}'',
1171``\textbf{`}`` (single left quote), ``\textbf{\{}'', ``\textbf{|}'',
1172``\textbf{\}}'', ``\textbf{\textasciitilde{}}''.
Lev Walkined44bf42010-11-08 02:04:55 -08001173
1174
1175\section{ASN.1 Constructed Types}
1176
1177
1178\subsection{The SEQUENCE type}
1179
1180This is an ordered collection of other simple or constructed types.
Lev Walkin464166c2010-11-09 08:34:38 -08001181The SEQUENCE constructed type resembles the C ``struct'' statement.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001182\begin{asn}
1183Address ::= SEQUENCE {
1184 -- The apartment number may be omitted
1185 apartmentNumber NumericString OPTIONAL,
1186 streetName PrintableString,
1187 cityName PrintableString,
1188 stateName PrintableString,
1189 -- This one may be omitted too
1190 zipNo NumericString OPTIONAL
1191}
1192\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001193
1194\subsection{The SET type}
1195
1196This is a collection of other simple or constructed types. Ordering
1197is not important. The data may arrive in the order which is different
1198from the order of specification. Data is encoded in the order not
1199necessarily corresponding to the order of specification.
1200
1201
1202\subsection{The CHOICE type}
1203
1204This type is just a choice between the subtypes specified in it. The
1205CHOICE type contains at most one of the subtypes specified, and it
1206is always implicitly known which choice is being decoded or encoded.
Lev Walkin464166c2010-11-09 08:34:38 -08001207This one resembles the C ``union'' statement.
Lev Walkined44bf42010-11-08 02:04:55 -08001208
1209The following type defines a response code, which may be either an
Lev Walkin464166c2010-11-09 08:34:38 -08001210integer code or a boolean ``true''/``false'' code.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001211\begin{asn}
1212ResponseCode ::= CHOICE {
1213 intCode INTEGER,
1214 boolCode BOOLEAN
1215}
1216\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001217
1218\subsection{The SEQUENCE OF type}
1219
1220This one is the list (array) of simple or constructed types:
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001221\begin{asn}
1222-- Example 1
1223ManyIntegers ::= SEQUENCE OF INTEGER
Lev Walkined44bf42010-11-08 02:04:55 -08001224
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001225-- Example 2
1226ManyRectangles ::= SEQUENCE OF Rectangle
Lev Walkined44bf42010-11-08 02:04:55 -08001227
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001228-- More complex example:
1229-- an array of structures defined in place.
1230ManyCircles ::= SEQUENCE OF SEQUENCE {
1231 radius INTEGER
1232 }
1233\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001234
1235\subsection{The SET OF type}
1236
1237The SET OF type models the bag of structures. It resembles the SEQUENCE
Lev Walkin507f6002014-10-26 20:22:16 -07001238OF type, but the order is not important. The elements may arrive
Lev Walkined44bf42010-11-08 02:04:55 -08001239in the order which is not necessarily the same as the in-memory order
1240on the remote machines.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001241\begin{asn}
1242-- A set of structures defined elsewhere
1243SetOfApples :: SET OF Apple
Lev Walkined44bf42010-11-08 02:04:55 -08001244
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001245-- Set of integers encoding the kind of a fruit
1246FruitBag ::= SET OF ENUMERATED { apple, orange }
1247\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001248\begin{thebibliography}{ITU-T/ASN.1}
1249\bibitem[ASN1C]{ASN1C}The Open Source ASN.1 Compiler. \url{http://lionet.info/asn1c}
1250
1251\bibitem[AONL]{AONL}Online ASN.1 Compiler. \url{http://lionet.info/asn1c/asn1c.cgi}
1252
1253\bibitem[Dub00]{Dub00}Olivier Dubuisson --- \emph{ASN.1 Communication
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001254between heterogeneous systems} --- Morgan Kaufmann Publishers, 2000.
Lev Walkined44bf42010-11-08 02:04:55 -08001255\url{http://asn1.elibel.tm.fr/en/book/}. ISBN:0-12-6333361-0.
1256
Lev Walkin464166c2010-11-09 08:34:38 -08001257\bibitem[ITU-T/ASN.1]{ITU-T/ASN.1}ITU-T Study Group 17 --- Languages
Lev Walkined44bf42010-11-08 02:04:55 -08001258for Telecommunication Systems \url{http://www.itu.int/ITU-T/studygroups/com17/languages/}
1259\end{thebibliography}
1260
1261\end{document}