blob: fe2cb4ae46965e2f1c4000499db86c34c69d707e [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 Walkind5627a12017-11-07 01:04:40 -080016\usepackage{fancyref}
Lev Walkined44bf42010-11-08 02:04:55 -080017\usepackage{longtable}
Lev Walkin9ce64c12017-11-07 06:22:14 -080018\usepackage{array}
19\usepackage{enumitem}
Lev Walkin464166c2010-11-09 08:34:38 -080020\usepackage{booktabs}
Lev Walkined44bf42010-11-08 02:04:55 -080021\usepackage{url}
Lev Walkin11c9a8c2013-03-26 00:46:55 -070022\usepackage{xcolor}
23\usepackage{listings}
24\usepackage{setspace}
Lev Walkin194b2102013-03-28 01:29:06 -070025\usepackage{unicode-math}
26\usepackage{perpage}
27\MakePerPage{footnote}
Lev Walkin11c9a8c2013-03-26 00:46:55 -070028
29\setstretch{1.1}
30
31% Courier 10 Pitch
32\def\courierFont{Courier10 BT WGL4}
33%\def\courierFont{Consolas}
34\setmonofont[Scale=1.05]{\courierFont}
Lev Walkin194b2102013-03-28 01:29:06 -070035\setmathfont[Scale=1.05]{Cambria Math}
Lev Walkin11c9a8c2013-03-26 00:46:55 -070036
Lev Walkined44bf42010-11-08 02:04:55 -080037\makeatletter
38
Lev Walkined44bf42010-11-08 02:04:55 -080039%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Textclass specific LaTeX commands.
Lev Walkin11c9a8c2013-03-26 00:46:55 -070040\lstloadlanguages{C,bash}
41\newfontfamily\listingfont[Scale=1.05]{\courierFont}
42\newfontfamily\inlinelistingfont[Scale=1.05]{\courierFont}
43\definecolor{clrlcomment}{gray}{0.3}
44\definecolor{clrlkeyword}{rgb}{0.588,0.145,0.18}
45\newcommand{\listingkeyword}[1]{\color{clrlkeyword}{#1}}
46\newcommand{\listingstring}[1]{\color{clrlcomment}{#1}}
47\newcommand{\listingcomment}[1]{\color{clrlcomment}{#1}}
48\lstset{tabsize=4,
49 showstringspaces=false,
50 showtabs=false,
51 showspaces=false,
52 keywordstyle=\listingkeyword,
53 stringstyle=\listingstring,
54 commentstyle=\listingcomment,
55 xleftmargin=\parindent,
56 columns=fixed,
57 escapechar=\%,
58 texcl
59}
60\lstdefinestyle{listingStyle}{
61 basicstyle=\small\listingfont,
62 stringstyle=\listingstring,
63 breaklines=true,
64 breakatwhitespace=true,
65 flexiblecolumns=false
66 }
67\lstdefinelanguage{asn1}{
Lev Walkind5627a12017-11-07 01:04:40 -080068 morekeywords={DEFINITIONS,BEGIN,END,AUTOMATIC,TAGS,SEQUENCE,SET,OF,CHOICE,OPTIONAL,INTEGER,MAX},
Lev Walkin11c9a8c2013-03-26 00:46:55 -070069 morecomment=[l]{--},
70 morecomment=[n]{/*}{*/}
71 }
72
Lev Walkin9ce64c12017-11-07 06:22:14 -080073\lstnewenvironment{signature}[1][]{\lstset{style=listingStyle,language=C,xleftmargin=0pt,#1}}{}
74\lstnewenvironment{example}[1][]{\lstset{style=listingStyle,language=C,basicstyle=\scriptsize\listingfont,#1}}{}
Lev Walkin11c9a8c2013-03-26 00:46:55 -070075\lstnewenvironment{codesample}[1][]{\lstset{style=listingStyle,language=C,#1}}{}
Lev Walkin2a744a72013-03-27 01:56:23 -070076\lstnewenvironment{bash}[1][]{\lstset{style=listingStyle,language=bash,#1}}{}
Lev Walkin11c9a8c2013-03-26 00:46:55 -070077\lstnewenvironment{asn}[1][]{\lstset{style=listingStyle,language=asn1,#1}}{}
Lev Walkinf3334582017-11-07 00:02:24 -080078
Lev Walkin9ce64c12017-11-07 06:22:14 -080079\newcommand{\api}[2]{\hyperref[#1]{\code{#2}}}
80\newcommand{\seealso}[2]{\api{#1}{#2} at page \pageref{#1}}
81\newcommand{\code}[1]{\texttt{\textbf{\lstinline{#1}}}}
Lev Walkinf3334582017-11-07 00:02:24 -080082\newcommand{\cmd}[1]{\texttt{#1}}
Lev Walkined44bf42010-11-08 02:04:55 -080083
84%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% User specified LaTeX commands.
85\usepackage{extramarks}
86\lhead{\firstxmark}
87\rfoot{\lastxmark}
Lev Walkin11c9a8c2013-03-26 00:46:55 -070088\definecolor{clrlink}{rgb}{0,0.4,0}
89\definecolor{clrurl}{rgb}{0,0,.6}
Lev Walkined44bf42010-11-08 02:04:55 -080090\usepackage[colorlinks=true,
Lev Walkin11c9a8c2013-03-26 00:46:55 -070091 linkcolor={clrlink},
92 citecolor={clrlink},
93 urlcolor={clrurl},
94 pdfauthor={Lev Walkin},
95 pdftitle={Using the Open Source ASN.1 Compiler},
96 pdfkeywords={ASN.1,asn1c,compiler},
97 bookmarksopen,bookmarksopenlevel=1,
98 pdffitwindow,
99 xetex
Lev Walkined44bf42010-11-08 02:04:55 -0800100]{hyperref}
Lev Walkined44bf42010-11-08 02:04:55 -0800101
Lev Walkin9ce64c12017-11-07 06:22:14 -0800102
Lev Walkined44bf42010-11-08 02:04:55 -0800103\makeatother
104
105\usepackage{babel}
106
107\begin{document}
108
Lev Walkin50155de2014-10-26 19:46:16 -0700109\title{Using the Open Source ASN.1 Compiler\\
Lev Walkin288527b2014-10-26 20:12:53 -0700110\vspace*{0.4cm}
Lev Walkin50155de2014-10-26 19:46:16 -0700111\Large Documentation for asn1c version \asnver{}}
Lev Walkined44bf42010-11-08 02:04:55 -0800112\author{Lev Walkin <\href{mailto:vlm@lionet.info?Subject=asn1c}{vlm@lionet.info}>}
113
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700114\pagestyle{fancy}
115\fancyhead[L]{\leftmark}
Lev Walkin50155de2014-10-26 19:46:16 -0700116\fancyhead[R]{\href{http://lionet.info/asn1c}{asn1c-\asnver}}
Lev Walkined44bf42010-11-08 02:04:55 -0800117\maketitle
Lev Walkined44bf42010-11-08 02:04:55 -0800118
119\tableofcontents{}
120
Lev Walkind5627a12017-11-07 01:04:40 -0800121\chapter{\label{chap:Quick-start-examples}Quick start examples}
Lev Walkined44bf42010-11-08 02:04:55 -0800122
Lev Walkinf3334582017-11-07 00:02:24 -0800123\section{A “Rectangle” converter and debugger}
Lev Walkined44bf42010-11-08 02:04:55 -0800124
Lev Walkinf3334582017-11-07 00:02:24 -0800125One of the most common need is to create some sort of analysis tool
126for the existing ASN.1 data files. Let's build a converter for existing
127Rectangle binary files between BER, OER, PER, and XER (XML).
128
129\begin{enumerate}
130\item Create a file named \textbf{rectangle.asn} with the following contents:
131\begin{asn}
132RectangleModule DEFINITIONS ::= BEGIN
133
134Rectangle ::= SEQUENCE {
135 height INTEGER,
136 width INTEGER
137}
138
139END
140\end{asn}
141
142\item Compile it into the set of .c and .h files using \cmd{asn1c} compiler:
143
144\begin{bash}
Lev Walkind1c28aa2017-11-11 18:04:26 -0800145asn1c -no-gen-example %\textbf{rectangle.asn}%
Lev Walkinf3334582017-11-07 00:02:24 -0800146\end{bash}
147
148\item Create the converter and dumper:
149
150\begin{bash}
151make -f Makefile.am.example
152\end{bash}
153
154\item Done. The binary file converter is ready:
155
156\begin{bash}
157./converter-example -h
158\end{bash}
159\end{enumerate}
160
161\section{A “Rectangle” Encoder}
Lev Walkined44bf42010-11-08 02:04:55 -0800162
163This example will help you create a simple BER and XER encoder of
Lev Walkin464166c2010-11-09 08:34:38 -0800164a ``Rectangle'' type used throughout this document.
Lev Walkined44bf42010-11-08 02:04:55 -0800165\begin{enumerate}
Lev Walkinf3334582017-11-07 00:02:24 -0800166\item Create a file named \textbf{rectangle.asn} with the following contents:
Lev Walkined44bf42010-11-08 02:04:55 -0800167
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700168\begin{asn}
Lev Walkinf3334582017-11-07 00:02:24 -0800169RectangleModule DEFINITIONS ::= BEGIN
Lev Walkined44bf42010-11-08 02:04:55 -0800170
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700171Rectangle ::= SEQUENCE {
172 height INTEGER,
173 width INTEGER
174}
Lev Walkined44bf42010-11-08 02:04:55 -0800175
176END
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700177\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -0800178\item Compile it into the set of .c and .h files using asn1c compiler \cite{ASN1C}:
179
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700180\begin{bash}
Lev Walkind1c28aa2017-11-11 18:04:26 -0800181asn1c -no-gen-example %\textbf{rectangle.asn}%
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700182\end{bash}
Lev Walkined44bf42010-11-08 02:04:55 -0800183\item Alternatively, use the Online ASN.1 compiler \cite{AONL} by uploading
Lev Walkinf3334582017-11-07 00:02:24 -0800184the \textbf{rectangle.asn} file into the Web form and unpacking the
Lev Walkined44bf42010-11-08 02:04:55 -0800185produced archive on your computer.
186\item By this time, you should have gotten multiple files in the current
187directory, including the \textbf{Rectangle.c} and \textbf{Rectangle.h}.
188\item Create a main() routine which creates the Rectangle\_t structure in
189memory and encodes it using BER and XER encoding rules. Let's name
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700190the file \textbf{main.c}:
Lev Walkined44bf42010-11-08 02:04:55 -0800191
Lev Walkin9ce64c12017-11-07 06:22:14 -0800192\begin{example}
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700193#include <stdio.h>
194#include <sys/types.h>
195#include <Rectangle.h> /* Rectangle ASN.1 type */
Lev Walkined44bf42010-11-08 02:04:55 -0800196
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700197/* Write the encoded output into some FILE stream. */
198static int write_out(const void *buffer, size_t size, void *app_key) {
199 FILE *out_fp = app_key;
200 size_t wrote = fwrite(buffer, 1, size, out_fp);
201 return (wrote == size) ? 0 : -1;
202}
203
204int main(int ac, char **av) {
205 Rectangle_t *rectangle; /* Type to encode */
206 asn_enc_rval_t ec; /* Encoder return value */
Lev Walkined44bf42010-11-08 02:04:55 -0800207
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700208 /* Allocate the Rectangle_t */
209 rectangle = calloc(1, sizeof(Rectangle_t)); /* not malloc! */
210 if(!rectangle) {
211 perror("calloc() failed");
212 exit(1);
213 }
Lev Walkined44bf42010-11-08 02:04:55 -0800214
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700215 /* Initialize the Rectangle members */
216 rectangle->height = 42; /* any random value */
217 rectangle->width = 23; /* any random value */
Lev Walkined44bf42010-11-08 02:04:55 -0800218
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700219 /* BER encode the data if filename is given */
220 if(ac < 2) {
221 fprintf(stderr, "Specify filename for BER output\n");
222 } else {
223 const char *filename = av[1];
224 FILE *fp = fopen(filename, "wb"); /* for BER output */
225
226 if(!fp) {
227 perror(filename);
228 exit(1);
229 }
Lev Walkined44bf42010-11-08 02:04:55 -0800230
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700231 /* Encode the Rectangle type as BER (DER) */
232 ec = der_encode(&asn_DEF_Rectangle, rectangle, write_out, fp);
233 fclose(fp);
234 if(ec.encoded == -1) {
235 fprintf(stderr, "Could not encode Rectangle (at %\%%s)\n",
236 ec.failed_type ? ec.failed_type->name : "unknown");
237 exit(1);
238 } else {
239 fprintf(stderr, "Created %\%%s with BER encoded Rectangle\n", filename);
240 }
241 }
Lev Walkined44bf42010-11-08 02:04:55 -0800242
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700243 /* Also print the constructed Rectangle XER encoded (XML) */
244 xer_fprint(stdout, &asn_DEF_Rectangle, rectangle);
Lev Walkined44bf42010-11-08 02:04:55 -0800245
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700246 return 0; /* Encoding finished successfully */
247 }
Lev Walkin9ce64c12017-11-07 06:22:14 -0800248\end{example}
Lev Walkined44bf42010-11-08 02:04:55 -0800249\item Compile all files together using C compiler (varies by platform):
250
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700251\begin{bash}
252cc -I. -o %\textbf{\emph{rencode}} \emph{*.c}%
253\end{bash}
Lev Walkinf3334582017-11-07 00:02:24 -0800254\item Done. You have just created the BER and XER encoder of a Rectangle
Lev Walkined44bf42010-11-08 02:04:55 -0800255type, named \textbf{rencode}!
256\end{enumerate}
Lev Walkined44bf42010-11-08 02:04:55 -0800257
Lev Walkinf3334582017-11-07 00:02:24 -0800258\section{\label{sec:A-Rectangle-Decoder}A “Rectangle” Decoder}
Lev Walkined44bf42010-11-08 02:04:55 -0800259
260This example will help you to create a simple BER decoder of a simple
Lev Walkin464166c2010-11-09 08:34:38 -0800261``Rectangle'' type used throughout this document.
Lev Walkined44bf42010-11-08 02:04:55 -0800262\begin{enumerate}
Lev Walkinf3334582017-11-07 00:02:24 -0800263\item Create a file named \textbf{rectangle.asn} with the following contents:
Lev Walkined44bf42010-11-08 02:04:55 -0800264
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700265\begin{asn}
Lev Walkinf3334582017-11-07 00:02:24 -0800266RectangleModule DEFINITIONS ::= BEGIN
Lev Walkined44bf42010-11-08 02:04:55 -0800267
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700268Rectangle ::= SEQUENCE {
269 height INTEGER,
270 width INTEGER
271}
Lev Walkined44bf42010-11-08 02:04:55 -0800272
273END
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700274\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -0800275\item Compile it into the set of .c and .h files using asn1c compiler \cite{ASN1C}:
276
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700277\begin{bash}
Lev Walkind1c28aa2017-11-11 18:04:26 -0800278asn1c -no-gen-example %\textbf{rectangle.asn}%
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700279\end{bash}
Lev Walkined44bf42010-11-08 02:04:55 -0800280\item Alternatively, use the Online ASN.1 compiler \cite{AONL} by uploading
Lev Walkinf3334582017-11-07 00:02:24 -0800281the \textbf{rectangle.asn} file into the Web form and unpacking the
Lev Walkined44bf42010-11-08 02:04:55 -0800282produced archive on your computer.
283\item By this time, you should have gotten multiple files in the current
284directory, including the \textbf{Rectangle.c} and \textbf{Rectangle.h}.
285\item Create a main() routine which takes the binary input file, decodes
286it as it were a BER-encoded Rectangle type, and prints out the text
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700287(XML) representation of the Rectangle type. Let's name the file \textbf{main.c}:
Lev Walkined44bf42010-11-08 02:04:55 -0800288
Lev Walkin9ce64c12017-11-07 06:22:14 -0800289\begin{example}
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700290#include <stdio.h>
291#include <sys/types.h>
292#include <Rectangle.h> /* Rectangle ASN.1 type */
Lev Walkined44bf42010-11-08 02:04:55 -0800293
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700294int main(int ac, char **av) {
295 char buf[1024]; /* Temporary buffer */
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700296 asn_dec_rval_t rval; /* Decoder return value */
Lev Walkin194b2102013-03-28 01:29:06 -0700297 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 -0700298 FILE *fp; /* Input file handler */
299 size_t size; /* Number of bytes read */
300 char *filename; /* Input file name */
Lev Walkined44bf42010-11-08 02:04:55 -0800301
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700302 /* Require a single filename argument */
303 if(ac != 2) {
304 fprintf(stderr, "Usage: %\%%s <file.ber>\n", av[0]);
305 exit(1);
306 } else {
307 filename = av[1];
308 }
Lev Walkined44bf42010-11-08 02:04:55 -0800309
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700310 /* Open input file as read-only binary */
311 fp = fopen(filename, "rb");
312 if(!fp) {
313 perror(filename);
314 exit(1);
315 }
Lev Walkined44bf42010-11-08 02:04:55 -0800316
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700317 /* Read up to the buffer size */
318 size = fread(buf, 1, sizeof(buf), fp);
319 fclose(fp);
320 if(!size) {
321 fprintf(stderr, "%\%%s: Empty or broken\n", filename);
322 exit(1);
323 }
Lev Walkined44bf42010-11-08 02:04:55 -0800324
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700325 /* Decode the input buffer as Rectangle type */
326 rval = ber_decode(0, &asn_DEF_Rectangle, (void **)&rectangle, buf, size);
327 if(rval.code != RC_OK) {
328 fprintf(stderr, "%\%%s: Broken Rectangle encoding at byte %\%%ld\n", filename, (long)rval.consumed);
329 exit(1);
330 }
Lev Walkined44bf42010-11-08 02:04:55 -0800331
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700332 /* Print the decoded Rectangle type as XML */
333 xer_fprint(stdout, &asn_DEF_Rectangle, rectangle);
Lev Walkined44bf42010-11-08 02:04:55 -0800334
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700335 return 0; /* Decoding finished successfully */
Lev Walkin194b2102013-03-28 01:29:06 -0700336}
Lev Walkin9ce64c12017-11-07 06:22:14 -0800337\end{example}
Lev Walkined44bf42010-11-08 02:04:55 -0800338\item Compile all files together using C compiler (varies by platform):
339
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700340\begin{bash}
341cc -I. -o %\textbf{\emph{rdecode}} \emph{*.c}%
342\end{bash}
Lev Walkinf3334582017-11-07 00:02:24 -0800343\item Done. You have just created the BER decoder of a Rectangle type,
Lev Walkined44bf42010-11-08 02:04:55 -0800344named \textbf{rdecode}!
345\end{enumerate}
346
Lev Walkind5627a12017-11-07 01:04:40 -0800347\section{Adding constraints to a “Rectangle”}
Lev Walkined44bf42010-11-08 02:04:55 -0800348
349This example shows how to add basic constraints to the ASN.1 specification
350and how to invoke the constraints validation code in your application.
351\begin{enumerate}
Lev Walkind5627a12017-11-07 01:04:40 -0800352
Lev Walkinf3334582017-11-07 00:02:24 -0800353\item Create a file named \textbf{rectangle.asn} with the following contents:
Lev Walkined44bf42010-11-08 02:04:55 -0800354
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700355\begin{asn}
356RectangleModuleWithConstraints DEFINITIONS ::= BEGIN
Lev Walkined44bf42010-11-08 02:04:55 -0800357
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700358Rectangle ::= SEQUENCE {
359 height INTEGER (0..100), -- Value range constraint
360 width INTEGER (0..MAX) -- Makes width non-negative
361}
Lev Walkined44bf42010-11-08 02:04:55 -0800362
363END
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700364\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -0800365
Lev Walkind5627a12017-11-07 01:04:40 -0800366\item Compile the file according to procedures shown in \fref{sec:A-Rectangle-Decoder}.
367\item Modify the Rectangle type processing routine (you can start with the
368main() routine shown in the \fref{sec:A-Rectangle-Decoder})
369by placing the following snippet of code \emph{before} encoding and/or
370\emph{after} decoding the Rectangle type:
371
Lev Walkin9ce64c12017-11-07 06:22:14 -0800372\begin{example}
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700373int ret; /* Return value */
374char errbuf[128]; /* Buffer for error message */
375size_t errlen = sizeof(errbuf); /* Size of the buffer */
Lev Walkined44bf42010-11-08 02:04:55 -0800376
Lev Walkin2e554fc2014-10-26 19:21:58 -0700377/* ... here goes the Rectangle %\emph{decoding}% code ... */
Lev Walkined44bf42010-11-08 02:04:55 -0800378
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700379ret = asn_check_constraints(&asn_DEF_Rectangle, rectangle, errbuf, &errlen);
380/* assert(errlen < sizeof(errbuf)); // you may rely on that */
381if(ret) {
Lev Walkind5627a12017-11-07 01:04:40 -0800382 fprintf(stderr, "Constraint validation failed: %\%%s\n", errbuf);
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700383 /* exit(...); // Replace with appropriate action */
384 }
Lev Walkined44bf42010-11-08 02:04:55 -0800385
Lev Walkin2e554fc2014-10-26 19:21:58 -0700386/* ... here goes the Rectangle %\emph{encoding}% code ... */
Lev Walkin9ce64c12017-11-07 06:22:14 -0800387\end{example}
Lev Walkined44bf42010-11-08 02:04:55 -0800388\item Compile the resulting C code as shown in the previous chapters.
Lev Walkind5627a12017-11-07 01:04:40 -0800389\item Test the constraints checking code by assigning integer value
Lev Walkined44bf42010-11-08 02:04:55 -0800390101 to the \textbf{.height} member of the Rectangle structure, or
Lev Walkind5627a12017-11-07 01:04:40 -0800391a negative value to the \textbf{.width} member.
392The program will fail with ``Constraint validation failed'' message.
Lev Walkined44bf42010-11-08 02:04:55 -0800393\item Done.
394\end{enumerate}
395
Lev Walkind5627a12017-11-07 01:04:40 -0800396\chapter{ASN.1 Compiler}
397
398\section{The asn1c compiler tool}
399
400The purpose of the ASN.1 compiler is to convert the specifications
401in ASN.1 notation into some other language, such as C.
402
403The compiler reads the specification and emits a series of target
404language structures (C structs, unions, enums) describing the corresponding
405ASN.1 types. The compiler also creates the code which allows automatic
406serialization and deserialization of these structures using several
407standardized encoding rules (BER, DER, OER, PER, XER).
408
409Let's take the following ASN.1 example%
410\footnote{\Fref{chap:Abstract-Syntax-Notation} provides a quick reference
411on the ASN.1 notation.}:
412\begin{asn}
413RectangleModule DEFINITIONS ::= BEGIN
414
415Rectangle ::= SEQUENCE {
416 height INTEGER, -- Height of the rectangle
417 width INTEGER -- Width of the rectangle
418}
419
420END
421\end{asn}
422The asn1c compiler reads this ASN.1 definition and produce the following
423C type:
424\begin{codesample}
425typedef struct Rectangle_s {
426 long height;
427 long width;
428} Rectangle_t;
429\end{codesample}
430The asn1c compiler also creates the code for converting this structure into
431platform-independent wire representation and the decoder
432of such wire representation back into local, machine-specific type.
433These encoders and decoders are also called serializers and deserializers,
434marshallers and unmarshallers, or codecs.
435
436Compiling ASN.1 modules into C codecs can be as simple as invoking \cmd{asn1c}:
437may be used to compile the ASN.1 modules:
438\begin{bash}
439asn1c %\emph{<modules.asn>}%
440\end{bash}
441
442If several ASN.1 modules contain interdependencies, all of the files
443must be specified altogether:
444\begin{bash}
445asn1c %\emph{<module1.asn> <module2.asn> ...}%
446\end{bash}
447The compiler \textbf{-E} and \textbf{-EF} options are used for testing
448the parser and the semantic fixer, respectively. These options will
449instruct the compiler to dump out the parsed (and fixed, if \textbf{-F}
450is involved) ASN.1 specification as it was understood
451by the compiler. It might be useful to check whether a particular
452syntactic construct is properly supported by the compiler.
453\begin{bash}
454asn1c %\textbf{-EF} \emph{<module-to-test.asn>}%
455\end{bash}
456The \textbf{-P} option is used to dump the compiled output on the
457screen instead of creating a bunch of .c and .h files on disk in the
458current directory. You would probably want to start with \textbf{-P}
459option instead of creating a mess in your current directory. Another
460option, \textbf{-R}, asks compiler to only generate the files which
461need to be generated, and supress linking in the numerous support
462files.
463
464Print the compiled output instead of creating multiple source files:
465\begin{bash}
466asn1c %\textbf{-P} \emph{<module-to-compile-and-print.asn>}%
467\end{bash}
468
469\clearpage{}
470\section{Compiler output}
471
472The \cmd{asn1c} compiler produces a number of files:
473\begin{itemize}
474\item A set of .c and .h files for each type defined
475in the ASN.1 specification. These files will be named similarly to
476the ASN.1 types (\textbf{Rectangle.c} and \textbf{Rectangle.h} for the
477RectangleModule ASN.1 module defined in the beginning of this document).
478\item A set of helper .c and .h files which contain the generic encoders,
479decoders and other useful routines.
480Sometimes they are referred to by the term \emph{skeletons}.
481There will be quite a few of them, some
482of them are not even always necessary, but the overall amount of code
483after compilation will be rather small anyway.
484\item A \textbf{Makefile.am.libasncodecs} file which explicitly lists all the
485generated files.
486This makefile can be used on its own to build the just the codec library.
Lev Walkind1c28aa2017-11-11 18:04:26 -0800487\item A \textbf{converter-example.c} file containing the \emph{int main()} function with a fully functioning encoder and data format converter. It can convert a given PDU between BER, XER, OER and PER. At some point you will want to replace this file with your own file containing the \emph{int main()} function.
Lev Walkind5627a12017-11-07 01:04:40 -0800488\item A \textbf{Makefile.am.example} file which binds together
489\textbf{Makefile.am.libasncodecs} and \textbf{converter-example.c}
490to build a versatile converter and debugger for your data formats.
491\end{itemize}
492It is possible to compile everything with just a couple of instructions:
493\begin{bash}
494asn1c -pdu=%\emph{Rectangle}% *.asn
495make -f Makefile.am.example # If you use `make`
496\end{bash}
497or
498\begin{bash}
499asn1c *.asn
500cc -I. -DPDU=%\emph{Rectangle}% -o rectangle.exe *.c # ... or like this
501\end{bash}
502Refer to the \fref{chap:Quick-start-examples} for a sample
503\emph{int main()} function if you want some custom logic and not satisfied
504with the supplied \emph{converter-example.c}.
505
506\clearpage{}
507\section{\label{sec:Command-line-options}Command line options}
508
509The following table summarizes the \cmd{asn1c} command line options.
510
511\renewcommand{\arraystretch}{1.33}
512\begin{longtable}{lp{4in}}
513\textbf{Stage Selection Options} & \textbf{Description}\\
514\midrule
515{\ttfamily -E} & {\small Stop after the parsing stage and print the reconstructed ASN.1
516specification code to the standard output.}\\
517{\ttfamily -F} & {\small Used together with \texttt{-E}, instructs the compiler to stop after
518the ASN.1 syntax tree fixing stage and dump the reconstructed ASN.1
519specification to the standard output.}\\
520{\ttfamily -P} & {\small Dump the compiled output to the standard output instead of
521creating the target language files on disk.}\\
522{\ttfamily -R} & {\small Restrict the compiler to generate only the ASN.1 tables, omitting the usual support code.}\\
523{\ttfamily -S~\emph{<directory>}} & {\small Use the specified directory with ASN.1 skeleton files.}\\
524{\ttfamily -X} & {\small Generate the XML DTD for the specified ASN.1 modules.}\\\\
525\textbf{Warning Options} & \textbf{Description}\\
526\midrule
527{\ttfamily -Werror} & {\small Treat warnings as errors; abort if any warning is produced.}\\
528{\ttfamily -Wdebug-parser} & {\small Enable the parser debugging during the ASN.1 parsing stage.}\\
529{\ttfamily -Wdebug-lexer} & {\small Enable the lexer debugging during the ASN.1 parsing stage.}\\
530{\ttfamily -Wdebug-fixer} & {\small Enable the ASN.1 syntax tree fixer debugging during the fixing stage.}\\
531{\ttfamily -Wdebug-compiler} & {\small Enable debugging during the actual compile time.}\\ \\
532\textbf{Language Options} & \textbf{Description}\\
533\midrule
534{\ttfamily -fbless-SIZE} & {\small Allow SIZE() constraint for INTEGER, ENUMERATED, and other types for which this constraint is normally prohibited by the standard.
535This is a violation of an ASN.1 standard and compiler may fail to produce the meaningful code.}\\
536{\ttfamily -fcompound-names} & {\small Use complex names for C structures. Using complex names prevents
537name clashes in case the module reuses the same identifiers in multiple
538contexts.}\\
539{\ttfamily -findirect-choice} & {\small When generating code for a CHOICE type, compile the CHOICE
540members as indirect pointers instead of declaring them inline. Consider
541using this option together with \texttt{-fno-include-deps}
542to prevent circular references.}\\
543{\ttfamily -fincludes-quoted} & {\small Generate \#include lines in "double" instead of <angle> quotes.}\\
544{\ttfamily -fknown-extern-type=\emph{<name>}} & {\small Pretend the specified type is known. The compiler will assume
545the target language source files for the given type have been provided
546manually. }\\
547{\ttfamily -fline-refs} & {\small Include ASN.1 module's line numbers in generated code comments.}\\
Lev Walkind1c28aa2017-11-11 18:04:26 -0800548{\ttfamily -fno-constraints} & {\small Do not generate the ASN.1 subtype constraint checking code. This
Lev Walkind5627a12017-11-07 01:04:40 -0800549may produce a shorter executable.}\\
Lev Walkind1c28aa2017-11-11 18:04:26 -0800550{\ttfamily -fno-include-deps} & {\small Do not generate the courtesy \#include lines for non-critical dependencies.}\\
Lev Walkind5627a12017-11-07 01:04:40 -0800551{\ttfamily -funnamed-unions} & {\small Enable unnamed unions in the definitions of target language's structures.}\\
552{\ttfamily -fwide-types} & {\small Use the wide integer types (INTEGER\_t, REAL\_t) instead of machine's native data types (long, double). }\\\\
553\textbf{Codecs Generation Options} & \textbf{Description}\\
554\midrule
Lev Walkind1c28aa2017-11-11 18:04:26 -0800555{\ttfamily -no-gen-OER} & {\small Do not generate the Octet Encoding Rules (OER, X.696) support code.}\\
556{\ttfamily -no-gen-PER} & {\small Do not generate the Packed Encoding Rules (PER, X.691) support code.}\\
557{\ttfamily -no-gen-example} & {\small Do not generate the ASN.1 format converter example.}\\
Lev Walkind5627a12017-11-07 01:04:40 -0800558{\ttfamily -pdu=\{\textbf{all}|\textbf{auto}|\emph{Type}\}} & {\small Create a PDU table for specified types, or discover the Protocol Data Units automatically.
559In 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.}\\ \\
560\textbf{Output Options} & \textbf{Description}\\
561\midrule
562{\ttfamily -print-class-matrix} & {\small When \texttt{-EF} options are given, this option instructs the compiler to print out the collected Information Object Class matrix.}\\
563{\ttfamily -print-constraints} & {\small With \texttt{-EF}, this option instructs the compiler
564to explain its internal understanding of subtype constraints.}\\
565{\ttfamily -print-lines} & {\small Generate \texttt{``-{}- \#line''} comments
566in \texttt{-E} output.}\\
567\end{longtable}
568\renewcommand{\arraystretch}{1}
Lev Walkined44bf42010-11-08 02:04:55 -0800569
570
Lev Walkind5627a12017-11-07 01:04:40 -0800571\chapter{API reference}
572
Lev Walkin9ce64c12017-11-07 06:22:14 -0800573The functions desribed in this chapter are to be used by the application
574programmer. These functions won't likely change change or get removed until
575the next major release.
576
577The API calls not listed here are not public and should not be used by the
578application level code.
579
580\clearpage{}
581\section{\label{sec:ASN_STRUCT_FREE}ASN\_STRUCT\_FREE() macro}
582
583\subsection*{Synopsis}
584
585\begin{signature}
586#define ASN_STRUCT_FREE(type_descriptor, struct_ptr)
587\end{signature}
588
589\subsection*{Description}
590
591Recursively releases memory occupied by the structure
592described by the \code{type\_descriptor} and referred to
593by the \code{struct\_ptr} pointer.
594
595Does nothing when \code{struct\_ptr} is NULL.
596
597\subsection*{Return values}
598Does not return a value.
599
600\subsection*{Example}
601
602\begin{example}
603Rectangle_t *rect = ...;
604ASN_STRUCT_FREE(asn_DEF_Rectangle, rect);
605\end{example}
606
607\section{\label{sec:ASN_STRUCT_RESET}ASN\_STRUCT\_RESET() macro}
608
609\subsection*{Synopsis}
610
611\begin{signature}
612#define ASN_STRUCT_RESET(type_descriptor, struct_ptr)
613\end{signature}
614
615\subsection*{Description}
616
617Recursively releases memory occupied by the members of the structure
618described by the \code{type\_descriptor} and referred to
619by the \code{struct\_ptr} pointer.
620
621Does not release the memory pointed to by \code{struct\_ptr} itself.
622Instead it clears the memory block by filling it out with 0 bytes.
623
624Does nothing when \code{struct\_ptr} is NULL.
625
626\subsection*{Return values}
627Does not return a value.
628
629\subsection*{Example}
630
631\begin{example}
632struct my_figure { /* The custom structure */
633 int flags; /* <some custom member> */
634 /* The type is generated by the ASN.1 compiler */
635 Rectangle_t rect;
636 /* other members of the structure */
637};
638
639struct my_figure *fig = ...;
640ASN_STRUCT_RESET(asn_DEF_Rectangle, &fig->rect);
641\end{example}
642
643\section{asn\_check\_constraints()}
644
645\subsection*{Synopsis}
646
647\begin{signature}
648int asn_check_constraints(
649 const asn_TYPE_descriptor_t *type_descriptor,
650 const void *struct_ptr, /* Target language's structure */
651 char *errbuf, /* Returned error description */
652 size_t *errlen /* Length of the error description */
653);
654\end{signature}
655
656\subsection*{Description}
657
658Validate the structure according to the ASN.1 constraints.
659If errbuf and errlen are given, they shall be pointing to the appropriate
660buffer space and its length before calling this function. Alternatively,
661they could be passed as NULLs. If constraints validation fails,
662errlen will contain the actual number of bytes used in errbuf
663to encode an error message, properly 0-terminated.
664
665\subsection*{Return values}
666
667This function returns 0 in case all ASN.1 constraints are met
668and -1 if one or more ASN.1 constraints were violated.
669
670\subsection*{Example}
671
672\begin{codesample}[basicstyle=\scriptsize\listingfont]
673Rectangle_t *rect = ...;
674
675char errbuf[128]; /* Buffer for error message */
676size_t errlen = sizeof(errbuf); /* Size of the buffer */
677
678int ret = asn_check_constraints(&asn_DEF_Rectangle, rectangle, errbuf, &errlen);
679/* assert(errlen < sizeof(errbuf)); // Guaranteed: you may rely on that */
680if(ret) {
681 fprintf(stderr, "Constraint validation failed: %\%%s\n", errbuf);
682}
683\end{codesample}
684
685\section{\label{sec:asn_decode}asn\_decode()}
686
687\subsection*{Synopsis}
688\begin{signature}
689asn_dec_rval_t asn_decode(
690 const asn_codec_ctx_t *opt_codec_parameters,
691 enum asn_transfer_syntax syntax,
692 const asn_TYPE_descriptor_t *type_descriptor,
693 void **struct_ptr_ptr,/* Pointer to a target structure's ptr */
694 const void *buffer, /* Data to be decoded */
695 size_t size /* Size of that buffer */
696);
697\end{signature}
698
699\subsection*{Description}
700
701The \code{asn\_decode()} function parses the data given by the \code{buffer}
702and \code{size} arguments. The encoding rules are specified in the \code{syntax}
703argument and the type to be decoded is specified by the \code{type_descriptor}.
704
705The \code{struct_ptr_ptr} must point to the memory location which contains the
706pointer to the structure being decoded. Initially the \code{*struct_ptr_ptr}
707pointer is typically set to 0. In that case, \code{asn\_decode()} will
708dynamically allocate memory for the structure and its members as needed
709during the parsing.
710If \code{*struct\_ptr\_ptr} already points to some memory, the \code{asn\_decode()}
711will allocate the subsequent members as needed during the parsing.
712
713\subsection*{Return values}
714
715\input{asn_dec_rval.inc}
716
717The \code{.consumed} value is in bytes, even for PER decoding.
718For PER, use \code{uper\_decode()} in case you need to get
719the number of consumed bits.
720
721\subsection*{Restartability}
722
723Some transfer syntax parsers (such as ATS\_BER) support restartability.
724
725That means that in case the buffer has less data than expected,
726the \code{asn_decode()} will process whatever is available and ask for more
727data to be provided using the RC\_WMORE return \code{.code}.
728
729Note that in the RC\_WMORE case the decoder may have processed less data than
730it is available in the buffer, which means that you must be able to arrange
731the next buffer to contain the unprocessed part of the previous buffer.
732
733The \code{RC_WMORE} code may still be returned by parser not supporting
734restartabilty. In such cases, the partially decoded structure shall be
735discarded and the next invocation should use the extended buffer to parse
736from the very beginning.
737
738\subsection*{Example}
739
740\begin{example}
741Rectangle_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.}!}% */
742asn_dec_rval_t rval;
743rval = asn_decode(0, ATS_BER, &asn_DEF_Rectangle, (void **)&rect, buffer, buf_size);
744switch(rval.code) {
745case RC_OK:
746 asn_fprint(stdout, &asn_DEF_Rectangle, rect);
747 ASN_STRUCT_FREE(&asn_DEF_Rectangle, rect);
748 break;
749case RC_WMORE:
750case RC_FAIL:
751default:
752 ASN_STRUCT_FREE(&asn_DEF_Rectangle, rect);
753 break;
754}
755\end{example}
756
757\subsection*{See also}
758\seealso{sec:asn_fprint}{asn_fprint()}.
759
760\section{\label{sec:asn_encode}asn\_encode()}
Lev Walkind5627a12017-11-07 01:04:40 -0800761\section{asn\_encode\_to\_buffer}
Lev Walkin9ce64c12017-11-07 06:22:14 -0800762
763\subsection*{Example}
764\begin{example}
765uint8_t buffer[128];
766size_t buf_size = sizeof(buffer);
767asn_enc_rval_t er;
768er = asn_encode_to_buffer(0, ATS_DER, &asn_DEF_Rectangle, buffer, buf_size);
769if(er.encoded > buf_size) {
770 fprintf(stderr, "Buffer of size %\%%zu is too small for %\%%s, need %\%%zu\n",
771 buf_size, asn_DEF_Rectangle.name, er.encoded);
772}
773\end{example}
774
Lev Walkind5627a12017-11-07 01:04:40 -0800775\section{asn\_encode\_to\_new\_buffer}
Lev Walkin9ce64c12017-11-07 06:22:14 -0800776
777\subsection*{Example}
778\begin{example}
779asn_encode_to_new_buffer_result_t res;
780res = asn_encode_to_new_buffer(0, ATS_DER, &asn_DEF_Rectangle, buffer, buf_size);
781if(res.buffer) {
782 /* Encoded successfully. */
783 free(res.buffer);
784} else {
785 fprintf(stderr, "Failed to encode %\%%s, estimated %\%%zd bytes\n",
786 asn_DEF_Rectangle.name, res.result.encoded);
787}
788\end{example}
789
790\section{\label{sec:asn_fprint}asn\_fprint()}
791
792\subsection*{Synopsis}
793\begin{signature}
794int asn_fprint(FILE *stream, /* Destination file */
795 const asn_TYPE_descriptor_t *type_descriptor,
796 const void *struct_ptr /* Structure to be printed */
797);
798\end{signature}
799
800\subsection*{Description}
801
802The \code{asn_fprint()} function prints human readable description
803of the target language's structure into the file stream specified by
804\code{stream} pointer.
805
806The output format does not conform to any standard.
807
808The \code{asn_fprint()} function attempts to
809produce a valid output even for incomplete and broken structures, which
810makes it more suitable for debugging complex cases than
811\api{sec:xer_fprint}{xer_fprint()}.
812
813\subsection*{Return values}
814
815\begin{tabular}[h!]{rl}
8160 & Output was successfully made \\
817-1 & Error printing out the structure
818\end{tabular}
819
820\subsection*{Example}
821\begin{example}
822Rectangle_t *rect = ...;
823asn_fprint(stdout, &asn_DEF_Rectangle, rect);
824\end{example}
825
826\subsection*{See also}
827\seealso{sec:xer_fprint}{xer_fprint()}.
828
829\section{\label{sec:asn_random_fill}asn\_random\_fill()}
830
831\subsection*{Synopsis}
832\begin{signature}
833int asn_random_fill(
834 const asn_TYPE_descriptor_t *type_descriptor,
835 void **struct_ptr_ptr,/* Pointer to a target structure's ptr */
836 size_t approx_max_length_limit
837);
838\end{signature}
839
840\subsection*{Description}
841
842Create or initialize a structure with random contents, according to the type
843specification and optional member constraints.
844
Lev Walkind1c28aa2017-11-11 18:04:26 -0800845For best results the code should be generated without \cmd{-no-gen-PER}
846option to \cmd{asn1c}. Making PER constraints code available in runtime
847will make \code{asn_random_fill} explore the edges of PER-visible constraints
848and sometimes break out of extensible contstraints' ranges.
Lev Walkin9ce64c12017-11-07 06:22:14 -0800849
850The \code{asn_random_fill()} function has a bias to generate edge case
851values. This property makes it useful for debugging the application level
852code and for security testing, as random data can be a good seed to fuzzing.
853
854The \code{approx_max_length_limit} specifies the approximate limit of the
855resulting structure in units closely resembling bytes. The actual result
856might be several times larger or smaller than the given length limit.
857A rule of thumb way to select the initial value for this parameter
858is to take a typical structure and use twice its DER output size.
859
860\subsection*{Return values}
861
862\begin{tabular}[h!]{rl}
8630 & Structure was properly initialized with random data \\
864-1 & Failure to initialize the structure with random data
865\end{tabular}
866
867\clearpage{}
868\section{\label{sec:ber_decode}ber\_decode()}
869
870\subsection*{Synopsis}
871\begin{signature}
872asn_dec_rval_t ber_decode(
873 const asn_codec_ctx_t *opt_codec_ctx,
874 const asn_TYPE_descriptor_t *type_descriptor,
875 void **struct_ptr_ptr,/* Pointer to a target structure's ptr */
876 const void *buffer, /* Data to be decoded */
877 size_t size /* Size of that buffer */
878);
879\end{signature}
880
881\subsection*{Description}
882
883Decode BER, DER and CER data
884(Basic Encoding Rules, Distinguished Encoding Rules, Canonical Encoding Rules),
885as defined by ITU-T~X.690.
886
887DER and CER are different subsets of BER.
888
889Consider using a more generic function \api{sec:asn_decode}{asn_decode(ATS_BER)}.
890
891\subsection*{Return values}
892\input{asn_dec_rval.inc}
893
894The \code{.consumed} value is in bytes.
895
896\subsection*{Restartability}
897
898The \code{ber_decode()} function is restartable (stream-oriented).
899That means that in case the buffer has less data than expected,
900the decoder will process whatever is available and ask for more data
901to be provided using the RC\_WMORE return \code{.code}.
902
903Note that in the RC\_WMORE case the decoder may have processed less data than
904it is available in the buffer, which means that you must be able to arrange
905the next buffer to contain the unprocessed part of the previous buffer.
906
907\subsection*{See also}
908\seealso{sec:der_encode}{der_encode()}.
909
910\section{\label{sec:der_encode}der\_encode}
911
912\subsection*{See also}
913\seealso{sec:ber_decode}{ber_decode()},
914\seealso{sec:asn_decode}{asn_decode(ATS_BER)}.
915
Lev Walkind5627a12017-11-07 01:04:40 -0800916\section{der\_encode\_to\_buffer}
Lev Walkin9ce64c12017-11-07 06:22:14 -0800917
918\clearpage{}
919\section{\label{sec:oer_decode}oer\_decode()}
920
921\subsection*{Synopsis}
922\begin{signature}
923asn_dec_rval_t oer_decode(
924 const asn_codec_ctx_t *opt_codec_ctx,
925 const asn_TYPE_descriptor_t *type_descriptor,
926 void **struct_ptr_ptr,/* Pointer to a target structure's ptr */
927 const void *buffer, /* Data to be decoded */
928 size_t size /* Size of that buffer */
929);
930\end{signature}
931
932\subsection*{Description}
933
934Decode the BASIC-OER and CANONICAL-OER (Octet Encoding Rules),
935as defined by ITU-T~X.696.
936
937Consider using a more generic function \api{sec:asn_decode}{asn_decode(ATS_BASIC_OER)}.
938
939\subsection*{Return values}
940\input{asn_dec_rval.inc}
941
942The \code{.consumed} value is in bytes.
943
944\subsection*{Restartability}
945
946The \code{oer_decode()} function is restartable (stream-oriented).
947That means that in case the buffer has less data than expected,
948the decoder will process whatever is available and ask for more data
949to be provided using the RC\_WMORE return \code{.code}.
950
951Note that in the RC\_WMORE case the decoder may have processed less data than
952it is available in the buffer, which means that you must be able to arrange
953the next buffer to contain the unprocessed part of the previous buffer.
954
955\section{\label{sec:oer_encode}oer\_encode}
Lev Walkind5627a12017-11-07 01:04:40 -0800956\section{oer\_encode\_to\_buffer}
Lev Walkin9ce64c12017-11-07 06:22:14 -0800957
958\clearpage{}
959\section{\label{sec:uper_decode}uper\_decode()}
960
961\subsection*{Synopsis}
962
963\begin{signature}
964asn_dec_rval_t uper_decode(
965 const asn_codec_ctx_t *opt_codec_ctx,
966 const asn_TYPE_descriptor_t *type_descriptor,
967 void **struct_ptr_ptr,/* Pointer to a target structure's ptr */
968 const void *buffer, /* Data to be decoded */
969 size_t size, /* Size of the input data buffer, bytes */
970 int skip_bits, /* Number of unused leading bits, 0..7 */
971 int unused_bits /* Number of unused tailing bits, 0..7 */
972);
973\end{signature}
974
975\subsection*{Description}
976
977Decode the Unaligned BASIC or CANONICAL PER (Packed Encoding Rules),
978as defined by ITU-T~X.691
979
980Consider using a more generic function \api{sec:asn_decode}{asn_decode(ATS_UNALIGNED_BASIC_PER)}.
981
982\subsection*{Return values}
983\input{asn_dec_rval.inc}
984Note that the \code{.consumed} value is in bits.
985Use \code{(.consumed+7)/8} to convert to bytes.
986
987\subsection*{Restartability}
988The \code{uper_decode()} function is not restartable.
989Failures are final.
990
991\section{uper\_decode\_complete()}
992
993\subsection*{Synopsis}
994
995\begin{signature}
996asn_dec_rval_t uper_decode_complete(
997 const asn_codec_ctx_t *opt_codec_ctx,
998 const asn_TYPE_descriptor_t *type_descriptor,
999 void **struct_ptr_ptr,/* Pointer to a target structure's ptr */
1000 const void *buffer, /* Data to be decoded */
1001 size_t size /* Size of data buffer */
1002);
1003\end{signature}
1004
1005\subsection*{Description}
1006
1007Decode a ``Production of a complete encoding'',
1008according to ITU-T~X.691 (08/2015) \#11.1.
1009
1010Consider using a more generic function \api{sec:asn_decode}{asn_decode(ATS_UNALIGNED_BASIC_PER)}.
1011
1012\subsection*{Return values}
1013\input{asn_dec_rval.inc}
1014
1015The the \code{.consumed} value is returned in bytes.
1016
1017\subsection*{Restartability}
1018The \code{uper_decode_complete()} function is not restartable.
1019Failures are final.
1020
1021The complete encoding contains at least one byte, so on success
1022\code{.consumed} will be greater or equal to 1.
1023
1024\section{\label{sec:uper_encode}uper\_encode}
Lev Walkind5627a12017-11-07 01:04:40 -08001025\section{uper\_encode\_to\_buffer}
1026\section{uper\_encode\_to\_new\_buffer}
Lev Walkin9ce64c12017-11-07 06:22:14 -08001027\clearpage{}
1028\section{\label{sec:xer_decode}xer\_decode()}
1029
1030\subsection*{Synopsis}
1031
1032\begin{signature}
1033asn_dec_rval_t xer_decode(
1034 const asn_codec_ctx_t *opt_codec_ctx,
1035 const asn_TYPE_descriptor_t *type_descriptor,
1036 void **struct_ptr_ptr,/* Pointer to a target structure's ptr */
1037 const void *buffer, /* Data to be decoded */
1038 size_t size /* Size of data buffer */
1039);
1040\end{signature}
1041
1042\subsection*{Description}
1043
1044Decode the BASIC-XER and CANONICAL-XER (XML Encoding Rules) encoding,
1045as defined by ITU-T~X.693.
1046
1047Consider using a more generic function \api{sec:asn_decode}{asn_decode(ATS_BASIC_XER)}.
1048
1049\subsection*{Return values}
1050\input{asn_dec_rval.inc}
1051
1052The \code{.consumed} value is in bytes.
1053
1054\subsection*{Restartability}
1055
1056The \code{xer_decode()} function is restartable (stream-oriented).
1057That means that in case the buffer has less data than expected,
1058the decoder will process whatever is available and ask for more data
1059to be provided using the RC\_WMORE return \code{.code}.
1060
1061Note that in the RC\_WMORE case the decoder may have processed less data than
1062it is available in the buffer, which means that you must be able to arrange
1063the next buffer to contain the unprocessed part of the previous buffer.
1064
1065\section{\label{sec:xer_encode}xer\_encode}
1066\section{\label{sec:xer_fprint}xer\_fprint()}
1067
1068\subsection*{Synopsis}
1069\begin{signature}
1070int xer_fprint(FILE *stream, /* Destination file */
1071 const asn_TYPE_descriptor_t *type_descriptor,
1072 const void *struct_ptr /* Structure to be printed */
1073);
1074\end{signature}
1075
1076\subsection*{Description}
1077
1078The \code{xer_fprint()} function outputs XML-based serialization
1079of the given structure into the file stream specified by
1080\code{stream} pointer.
1081
1082The output conforms to BASIC-XER, as defined by ITU-T~X.693.
1083
1084\subsection*{Return values}
1085
1086\begin{tabular}[h!]{rl}
10870 & XML output was successfully made \\
1088-1 & Error printing out the structure
1089\end{tabular}
1090
1091\noindent{}Since the \code{xer_fprint()} function attempts to produce a conforming output,
1092it will likely break on partial structures by writing incomplete data
1093to the output stream and returning -1. This makes it less suitable for
1094debugging complex cases than \api{sec:asn_fprint}{asn_fprint()}.
1095
1096\subsection*{Example}
1097\begin{example}
1098Rectangle_t *rect = ...;
1099xer_fprint(stdout, &asn_DEF_Rectangle, rect);
1100\end{example}
1101
1102\subsection*{See also}
1103\seealso{sec:asn_fprint}{asn_fprint()}.
Lev Walkind5627a12017-11-07 01:04:40 -08001104
1105\chapter{API usage examples}
1106
1107Let's start with including the necessary header files into your
1108application. Normally it is enough to include the header file of
1109the main PDU type. For our \emph{Rectangle} module, including the \emph{Rectangle.h} file is sufficient:
1110\begin{codesample}
1111#include <Rectangle.h>
1112\end{codesample}
1113The header files defines a C structure corresponding to the ASN.1
1114definition of a rectangle and the declaration of the ASN.1
1115\emph{type descriptor}. A type descriptor is a special globally accessible
1116object which is used as an argument to most of the API functions provided by
1117the ASN.1 codec. A type descriptor starts with \emph{asn\_DEF\_\ldots{}}. For example, here is the code which frees the Rectangle\_t structure:
1118\begin{codesample}
1119Rectangle_t *rect = ...;
1120
1121ASN_STRUCT_FREE(%\textbf{asn\_DEF\_}%Rectangle, rect);
1122\end{codesample}
1123This code defines a \emph{rect} pointer which points to the Rectangle\_t
1124structure which needs to be freed. The second line uses a generic
Lev Walkin9ce64c12017-11-07 06:22:14 -08001125\api{sec:ASN_STRUCT_FREE}{ASN\_STRUCT\_FREE()} macro which invokes the memory deallocation routine
Lev Walkind5627a12017-11-07 01:04:40 -08001126created specifically for this Rectangle\_t structure.
1127The \emph{asn\_DEF\_Rectangle} is the type descriptor which holds
1128a collection of routines and operations defined for the Rectangle\_t structure.
1129
1130\section{\label{sec:Generic-Encoding}Generic encoders and decoders}
1131
1132Before we start describing specific encoders and decoders, let's step back
1133a little and check out a simple high level way.
1134
Lev Walkin9ce64c12017-11-07 06:22:14 -08001135The asn1c runtime supplies (see \emph{asn\_application.h}) two sets of high level functions, \api{sec:asn_encode}{asn_encode*} and \api{sec:asn_decode}{asn_decode*}, which take a transfer syntax selector as an argument. The transfer syntax selector is defined as this:
Lev Walkind5627a12017-11-07 01:04:40 -08001136
1137\begin{codesample}[basicstyle=\scriptsize\listingfont]
1138/*
1139 * A selection of ASN.1 Transfer Syntaxes to use with generalized encoders and decoders.
1140 */
1141enum asn_transfer_syntax {
1142 ATS_INVALID,
1143 ATS_NONSTANDARD_PLAINTEXT,
1144 ATS_BER,
1145 ATS_DER,
1146 ATS_CER,
1147 ATS_BASIC_OER,
1148 ATS_CANONICAL_OER,
1149 ATS_UNALIGNED_BASIC_PER,
1150 ATS_UNALIGNED_CANONICAL_PER,
1151 ATS_BASIC_XER,
1152 ATS_CANONICAL_XER,
1153};
1154\end{codesample}
1155
1156Using this encoding selector, encoding and decoding becomes very generic:
1157
1158\noindent{}Encoding:
1159
1160\begin{codesample}[basicstyle=\scriptsize\listingfont]
1161uint8_t buffer[128];
1162size_t buf_size = sizeof(buffer);
1163asn_enc_rval_t er;
1164
1165er = %\textbf{asn\_encode\emph{\_to\_buffer}}%(0, %\textbf{ATS\_DER}%, &asn_DEF_Rectangle, buffer, buf_size);
1166
1167if(er.encoded > buf_size) {
1168 fprintf(stderr, "Buffer of size %\%%zu is too small for %\%%s, need %\%%zu\n",
1169 buf_size, asn_DEF_Rectangle.name, er.encoded);
1170}
1171\end{codesample}
1172
1173\noindent{}Decoding:
1174
1175\begin{codesample}[basicstyle=\scriptsize\listingfont]
1176Rectangle_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.}!}% */
1177
1178... = %\textbf{asn\_decode}%(0, %\textbf{ATS\_BER}%, &asn_DEF_Rectangle, (void **)%$\underbracket{\textrm{\listingfont \&rect}}$%, buffer, buf_size);
1179\end{codesample}
1180
1181\section{\label{sec:Decoding-BER}Decoding BER}
1182
1183The Basic Encoding Rules describe the most widely used (by the ASN.1
1184community) way to encode and decode a given structure in a machine-independent
1185way. Several other encoding rules (CER, DER) define a more restrictive
1186versions of BER, so the generic BER parser is also capable of decoding
1187the data encoded by the CER and DER encoders. The opposite is not true.
1188
1189\emph{The ASN.1 compiler provides the generic BER decoder which is
1190capable of decoding BER, CER and DER encoded data.}
1191
Lev Walkin9ce64c12017-11-07 06:22:14 -08001192The decoder is restartable (stream-oriented).
1193That means that in case the buffer has less data than expected,
1194the decoder will process whatever is available and ask for more data
1195to be provided using the RC\_WMORE return \code{.code}.
1196
1197Note that in the RC\_WMORE case the decoder may have processed less data than
1198it is available in the buffer, which means that you must be able to arrange
1199the next buffer to contain the unprocessed part of the previous buffer.
Lev Walkind5627a12017-11-07 01:04:40 -08001200
1201Suppose, you have two buffers of encoded data: 100 bytes and 200 bytes.
1202\begin{itemize}
1203\item You can concatenate these buffers and feed the BER decoder with 300
1204bytes of data, or
1205\item You can feed it the first buffer of 100 bytes of data, realize that
1206the ber\_decoder consumed only 95 bytes from it and later feed the
1207decoder with 205 bytes buffer which consists of 5 unprocessed bytes
1208from the first buffer and the additional 200 bytes from the second
1209buffer.
1210\end{itemize}
1211This is not as convenient as it could be (the BER encoder could
1212consume the whole 100 bytes and keep these 5 bytes in some temporary
1213storage), but in case of existing stream based processing it might
1214actually fit well into existing algorithm. Suggestions are welcome.
1215
1216Here is the example of BER decoding of a simple structure:
1217
1218\begin{codesample}
1219Rectangle_t *
1220simple_deserializer(const void *buffer, size_t buf_size) {
1221 asn_dec_rval_t rval;
1222 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.}!}% */
1223
1224 rval = %\textbf{asn\_DEF\_Rectangle.op->ber\_decoder}%(0,
1225 &asn_DEF_Rectangle,
1226 (void **)%$\underbracket{\textrm{\listingfont \&rect}}$%, /* Decoder %\emph{changes}% the pointer */
1227 buffer, buf_size, 0);
1228
1229 if(rval%\textbf{.code}% == RC_OK) {
1230 return rect; /* Decoding succeeded */
1231 } else {
1232 /* Free the partially decoded rectangle */
1233 ASN_STRUCT_FREE(asn_DEF_Rectangle, rect);
1234 return 0;
1235 }
1236}
1237\end{codesample}
1238
1239The code above defines a function, \emph{simple\_deserializer}, which
1240takes a buffer and its length and is expected to return a pointer
1241to the Rectangle\_t structure. Inside, it tries to convert the bytes
1242passed into the target structure (rect) using the BER decoder and
1243returns the rect pointer afterwards. If the structure cannot be deserialized,
1244it frees the memory which might be left allocated by the unfinished
1245\emph{ber\_decoder} routine and returns 0 (no data). (This \textbf{freeing
1246is necessary} because the ber\_decoder is a restartable procedure,
1247and may fail just because there is more data needs to be provided
1248before decoding could be finalized). The code above obviously does
1249not take into account the way the \emph{ber\_decoder()} failed, so
1250the freeing is necessary because the part of the buffer may already
1251be decoded into the structure by the time something goes wrong.
1252
1253A little less wordy would be to invoke a globally available \emph{ber\_decode()}
1254function instead of dereferencing the asn\_DEF\_Rectangle type descriptor:
1255\begin{codesample}
1256rval = ber_decode(0, &asn_DEF_Rectangle, (void **)&rect, buffer, buf_size);
1257\end{codesample}
1258Note that the initial (asn\_DEF\_Rectangle.op->ber\_decoder) reference
1259is gone, and also the last argument (0) is no longer necessary.
1260
1261These two ways of BER decoder invocations are fully equivalent.
1262
1263The BER de\emph{coder} may fail because of (\emph{the following RC\_\ldots{}
1264codes are defined in ber\_decoder.h}):
1265\begin{itemize}
1266\item RC\_WMORE: There is more data expected than it is provided (stream
1267mode continuation feature);
1268\item RC\_FAIL: General failure to decode the buffer;
1269\item \ldots{} other codes may be defined as well.
1270\end{itemize}
1271Together with the return code (.code) the asn\_dec\_rval\_t type contains
1272the number of bytes which is consumed from the buffer. In the previous
1273hypothetical example of two buffers (of 100 and 200 bytes), the first
1274call to ber\_decode() would return with .code = RC\_WMORE and .consumed
1275= 95. The .consumed field of the BER decoder return value is \textbf{always}
1276valid, even if the decoder succeeds or fails with any other return
1277code.
1278
1279Look into ber\_decoder.h for the precise definition of ber\_decode()
1280and related types.
1281
1282
1283\section{\label{sec:Encoding-DER}Encoding DER}
1284
1285The Distinguished Encoding Rules is the \emph{canonical} variant of
1286BER encoding rules. The DER is best suited to encode the structures
1287where all the lengths are known beforehand. This is probably exactly
1288how you want to encode: either after a BER decoding or after a manual
1289fill-up, the target structure contains the data which size is implicitly
1290known before encoding. Among other uses, the DER encoding is used
1291to encode X.509 certificates.
1292
1293As with BER decoder, the DER encoder may be invoked either directly
1294from the ASN.1 type descriptor (asn\_DEF\_Rectangle) or from the stand-alone
1295function, which is somewhat simpler:
1296\begin{codesample}
1297/*
1298 * This is the serializer itself.
1299 * It supplies the DER encoder with the
1300 * pointer to the custom output function.
1301 */
1302ssize_t
1303simple_serializer(FILE *ostream, Rectangle_t *rect) {
1304 asn_enc_rval_t er; /* Encoder return value */
1305
1306 er = der_encode(&asn_DEF_Rect, rect, write_stream, ostream);
1307 if(er%\textbf{.encoded}% == -1) {
1308 fprintf(stderr, "Cannot encode %\%%s: %\%%s\n",
1309 er%\textbf{.failed\_type}%->name, strerror(errno));
1310 return -1;
1311 } else {
1312 /* Return the number of bytes */
1313 return er.encoded;
1314 }
1315}
1316\end{codesample}
1317As you see, the DER encoder does not write into some sort of buffer.
1318It just invokes the custom function (possible, multiple
1319times) which would save the data into appropriate storage. The optional
1320argument \emph{app\_key} is opaque for the DER encoder code and just
1321used by \emph{\_write\_stream()} as the pointer to the appropriate
1322output stream to be used.
1323
1324If the custom write function is not given (passed as 0), then the
1325DER encoder will essentially do the same thing (i.~e., encode the data)
1326but no callbacks will be invoked (so the data goes nowhere). It may
1327prove useful to determine the size of the structure's encoding before
1328actually doing the encoding%
1329\footnote{It is actually faster too: the encoder might skip over some computations
1330which aren't important for the size determination.%
1331}.
1332
1333Look into der\_encoder.h for the precise definition of der\_encode()
1334and related types.
1335
1336
1337\section{\label{sec:Encoding-XER}Encoding XER}
1338
1339The XER stands for XML Encoding Rules, where XML, in turn, is eXtensible
1340Markup Language, a text-based format for information exchange. The
1341encoder routine API comes in two flavors: stdio-based and callback-based.
1342With the callback-based encoder, the encoding process is very similar
1343to the DER one, described in \fref{sec:Encoding-DER}. The
1344following example uses the definition of write\_stream() from up there.
1345\begin{codesample}
1346/*
1347 * This procedure generates an XML document
1348 * by invoking the XER encoder.
1349 * NOTE: Do not copy this code verbatim!
1350 * If the stdio output is necessary,
1351 * use the xer_fprint() procedure instead.
1352 * See %\fref{sec:Printing-the-target}%.
1353 */
1354int
1355print_as_XML(FILE *ostream, Rectangle_t *rect) {
1356 asn_enc_rval_t er; /* Encoder return value */
1357
1358 er = xer_encode(&asn_DEF_Rectangle, rect,
1359 XER_F_BASIC, /* BASIC-XER or CANONICAL-XER */
1360 write_stream, ostream);
1361
1362 return (er.encoded == -1) ? -1 : 0;
1363}
1364\end{codesample}
1365Look into xer\_encoder.h for the precise definition of xer\_encode()
1366and related types.
1367
1368See \fref{sec:Printing-the-target} for the example of stdio-based
1369XML encoder and other pretty-printing suggestions.
1370
1371
1372\section{\label{sec:Decoding-XER}Decoding XER}
1373
1374The data encoded using the XER rules can be subsequently decoded using
1375the xer\_decode() API call:
1376\begin{codesample}
1377Rectangle_t *
1378XML_to_Rectangle(const void *buffer, size_t buf_size) {
1379 asn_dec_rval_t rval;
1380 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.}!}% */
1381
1382 rval = xer_decode(0, &asn_DEF_Rectangle, (void **)&rect, buffer, buf_size);
1383
1384 if(rval%\textbf{.code}% == RC_OK) {
1385 return rect; /* Decoding succeeded */
1386 } else {
1387 /* Free partially decoded rect */
1388 ASN_STRUCT_FREE(asn_DEF_Rectangle, rect);
1389 return 0;
1390 }
1391}
1392\end{codesample}
1393The decoder takes both BASIC-XER and CANONICAL-XER encodings.
1394
1395The decoder shares its data consumption properties with BER decoder;
1396please read the \fref{sec:Decoding-BER} to know more.
1397
1398Look into xer\_decoder.h for the precise definition of xer\_decode()
1399and related types.
1400
1401
1402\section{\label{sec:Validating-the-target}Validating the target structure}
1403
1404Sometimes the target structure needs to be validated. For example,
1405if the structure was created by the application (as opposed to being
1406decoded from some external source), some important information required
1407by the ASN.1 specification might be missing. On the other hand, the
1408successful decoding of the data from some external source does not
1409necessarily mean that the data is fully valid either. It might well
1410be the case that the specification describes some subtype constraints
1411that were not taken into account during decoding, and it would actually
1412be useful to perform the last check when the data is ready to be encoded
1413or when the data has just been decoded to ensure its validity according
1414to some stricter rules.
1415
1416The asn\_check\_constraints() function checks the type for various
1417implicit and explicit constraints. It is recommended to use asn\_check\_constraints()
1418function after each decoding and before each encoding.
1419
1420Look into constraints.h for the precise definition of asn\_check\_constraints()
1421and related types.
1422
1423
1424\section{\label{sec:Printing-the-target}Printing the target structure}
1425
1426There are two ways to print the target structure: either invoke the
1427print\_struct member of the ASN.1 type descriptor, or using the asn\_fprint()
1428function, which is a simpler wrapper of the former:
1429\begin{codesample}
1430asn_fprint(stdout, &asn_DEF_Rectangle, rect);
1431\end{codesample}
1432Look into constr\_TYPE.h for the precise definition of asn\_fprint()
1433and related types.
1434
1435Another practical alternative to this custom format printing would
1436be to invoke XER encoder. The default BASIC-XER encoder performs reasonable
1437formatting for the output to be useful and human readable. To invoke
1438the XER decoder in a manner similar to asn\_fprint(), use the xer\_fprint()
1439call:
1440\begin{codesample}
1441xer_fprint(stdout, &asn_DEF_Rectangle, rect);
1442\end{codesample}
1443See \fref{sec:Encoding-XER} for XML-related details.
1444
1445
1446\section{\label{sec:Freeing-the-target}Freeing the target structure}
1447
1448Freeing the structure is slightly more complex than it may seem to.
1449When the ASN.1 structure is freed, all the members of the structure
1450and their submembers are recursively freed as well.
1451The ASN\_STRUCT\_FREE() macro helps with that.
1452
1453But it might not always be feasible to free the whole structure.
1454In the following example, the application programmer defines a custom
1455structure with one ASN.1-derived member (rect).
1456\begin{codesample}
1457struct my_figure { /* The custom structure */
1458 int flags; /* <some custom member> */
1459 /* The type is generated by the ASN.1 compiler */
1460 Rectangle_t rect;
1461 /* other members of the structure */
1462};
1463\end{codesample}
1464This member is not a reference to the Rectangle\_t, but an in-place inclusion
1465of the Rectangle\_t structure.
1466If there's a need to free the \code{rect} member, the usual procedure of
1467freeing everything must not be applied to the \code{\&rect} pointer itself,
1468because it does not point to the beginning of memory block allocated by
1469the memory allocation routine, but instead lies within a block allocated for
1470the my\_figure structure.
1471
1472To solve this problem, in addition to ASN\_STRUCT\_FREE() macro, the asn1c
1473skeletons define the ASN\_STRUCT\_RESET() macro which doesn't free the passed
1474pointer and instead resets the structure into the clean and safe state.
1475\begin{codesample}
1476/* %\textbf{1. Rectangle\_t is defined within my\_figure}% */
1477struct my_figure {
1478 Rectangle_t rect;
1479} *mf = ...;
1480/*
1481 * Freeing the Rectangle_t
1482 * without freeing the mf->rect area.
1483 */
1484ASN_STRUCT_RESET(asn_DEF_Rectangle, &mf->rect);
1485
1486/* %\textbf{2. Rectangle\_t is a stand-alone pointer}% */
1487Rectangle_t *rect = ...;
1488/*
1489 * Freeing the Rectangle_t
1490 * and freeing the rect pointer.
1491 */
1492ASN_STRUCT_FREE(asn_DEF_Rectangle, rect);
1493\end{codesample}
1494It is safe to invoke both macros with the target structure pointer
1495set to 0 (NULL). In this case, the function will do nothing.
1496
1497\chapter{\label{chap:Abstract-Syntax-Notation}Abstract Syntax Notation: ASN.1}
Lev Walkined44bf42010-11-08 02:04:55 -08001498
1499\emph{This chapter defines some basic ASN.1 concepts and describes
1500several most widely used types. It is by no means an authoritative
1501or complete reference. For more complete ASN.1 description, please
1502refer to Olivier Dubuisson's book \cite{Dub00} or the ASN.1 body
1503of standards itself \cite{ITU-T/ASN.1}.}
1504
1505The Abstract Syntax Notation One is used to formally describe the
Lev Walkin507f6002014-10-26 20:22:16 -07001506data transmitted across the network. Two communicating parties may employ
1507different formats of their native data types (e.~g., different number
1508of bits for the native integer type), thus it is important to have
Lev Walkined44bf42010-11-08 02:04:55 -08001509a way to describe the data in a manner which is independent from the
Lev Walkin507f6002014-10-26 20:22:16 -07001510particular machine's representation.
1511The ASN.1 specifications are used to achieve the following:
Lev Walkined44bf42010-11-08 02:04:55 -08001512\begin{itemize}
1513\item The specification expressed in the ASN.1 notation is a formal and
Lev Walkin507f6002014-10-26 20:22:16 -07001514precise way to communicate the structure of data to human readers;
Lev Walkined44bf42010-11-08 02:04:55 -08001515\item The ASN.1 specifications may be used as input for automatic compilers
1516which produce the code for some target language (C, C++, Java, etc)
Lev Walkin507f6002014-10-26 20:22:16 -07001517to encode and decode the data according to some encoding formats.
1518Several such encoding formats (called Transfer Encoding Rules)
1519have been defined by the ASN.1 standard.
Lev Walkined44bf42010-11-08 02:04:55 -08001520\end{itemize}
1521Consider the following example:
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001522\begin{asn}
1523Rectangle ::= SEQUENCE {
1524 height INTEGER,
1525 width INTEGER
1526}
1527\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001528This ASN.1 specification describes a constructed type, \emph{Rectangle},
1529containing two integer fields. This specification may tell the reader
1530that there exists this kind of data structure and that some entity
1531may be prepared to send or receive it. The question on \emph{how}
1532that entity is going to send or receive the \emph{encoded data} is
1533outside the scope of ASN.1. For example, this data structure may be
1534encoded according to some encoding rules and sent to the destination
1535using the TCP protocol. The ASN.1 specifies several ways of encoding
Lev Walkin464166c2010-11-09 08:34:38 -08001536(or ``serializing'', or ``marshaling'') the data: BER, PER, XER
Lev Walkined44bf42010-11-08 02:04:55 -08001537and others, including CER and DER derivatives from BER.
1538
1539The complete specification must be wrapped in a module, which looks
1540like this:
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001541\begin{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001542RectangleModule1
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001543 { iso org(3) dod(6) internet(1) private(4)
1544 enterprise(1) spelio(9363) software(1)
1545 asn1c(5) docs(2) rectangle(1) 1 }
1546 DEFINITIONS AUTOMATIC TAGS ::=
Lev Walkined44bf42010-11-08 02:04:55 -08001547BEGIN
1548
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001549-- This is a comment which describes nothing.
1550Rectangle ::= SEQUENCE {
1551 height INTEGER, -- Height of the rectangle
1552 width INTEGER -- Width of the rectangle
1553}
Lev Walkined44bf42010-11-08 02:04:55 -08001554
1555END
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001556\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001557The module header consists of module name (RectangleModule1), the
Lev Walkin464166c2010-11-09 08:34:38 -08001558module object identifier (\{...\}), a keyword ``DEFINITIONS'', a
1559set of module flags (AUTOMATIC TAGS) and ``::= BEGIN''. The module
1560ends with an ``END'' statement.
Lev Walkined44bf42010-11-08 02:04:55 -08001561
1562
1563\section{Some of the ASN.1 Basic Types}
1564
1565
1566\subsection{The BOOLEAN type}
1567
1568The BOOLEAN type models the simple binary TRUE/FALSE, YES/NO, ON/OFF
1569or a similar kind of two-way choice.
1570
1571
1572\subsection{The INTEGER type}
1573
1574The INTEGER type is a signed natural number type without any restrictions
1575on its size. If the automatic checking on INTEGER value bounds are
1576necessary, the subtype constraints must be used.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001577\begin{asn}
1578SimpleInteger ::= INTEGER
Lev Walkined44bf42010-11-08 02:04:55 -08001579
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001580-- An integer with a very limited range
1581SmallPositiveInt ::= INTEGER (0..127)
Lev Walkined44bf42010-11-08 02:04:55 -08001582
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001583-- Integer, negative
1584NegativeInt ::= INTEGER (MIN..0)
1585\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001586
1587\subsection{The ENUMERATED type}
1588
1589The ENUMERATED type is semantically equivalent to the INTEGER type
1590with some integer values explicitly named.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001591\begin{asn}
1592FruitId ::= ENUMERATED { apple(1), orange(2) }
Lev Walkined44bf42010-11-08 02:04:55 -08001593
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001594-- The numbers in braces are optional,
1595-- the enumeration can be performed
1596-- automatically by the compiler
1597ComputerOSType ::= ENUMERATED {
1598 FreeBSD, -- acquires value 0
1599 Windows, -- acquires value 1
1600 Solaris(5), -- remains 5
1601 Linux, -- becomes 6
1602 MacOS -- becomes 7
1603}
1604\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001605
1606\subsection{The OCTET STRING type}
1607
1608This type models the sequence of 8-bit bytes. This may be used to
1609transmit some opaque data or data serialized by other types of encoders
Lev Walkin507f6002014-10-26 20:22:16 -07001610(e.~g., video file, photo picture, etc).
Lev Walkined44bf42010-11-08 02:04:55 -08001611
1612\subsection{The OBJECT IDENTIFIER type}
1613
1614The OBJECT IDENTIFIER is used to represent the unique identifier of
1615any object, starting from the very root of the registration tree.
1616If your organization needs to uniquely identify something (a router,
1617a room, a person, a standard, or whatever), you are encouraged to
1618get your own identification subtree at \url{http://www.iana.org/protocols/forms.htm}.
1619
1620For example, the very first ASN.1 module in this Chapter (RectangleModule1)
1621has the following OBJECT IDENTIFIER: 1 3 6 1 4 1 9363 1 5 2 1 1.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001622\begin{asn}
1623ExampleOID ::= OBJECT IDENTIFIER
Lev Walkined44bf42010-11-08 02:04:55 -08001624
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001625rectangleModule1-oid ExampleOID
1626 ::= { 1 3 6 1 4 1 9363 1 5 2 1 1 }
Lev Walkined44bf42010-11-08 02:04:55 -08001627
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001628-- An identifier of the Internet.
1629internet-id OBJECT IDENTIFIER
1630 ::= { iso(1) identified-organization(3)
1631 dod(6) internet(1) }
1632\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001633As you see, names are optional.
1634
1635
1636\subsection{The RELATIVE-OID type}
1637
1638The RELATIVE-OID type has the semantics of a subtree of an OBJECT
1639IDENTIFIER. There may be no need to repeat the whole sequence of numbers
1640from the root of the registration tree where the only thing of interest
1641is some of the tree's subsequence.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001642\begin{asn}
1643this-document RELATIVE-OID ::= { docs(2) usage(1) }
Lev Walkined44bf42010-11-08 02:04:55 -08001644
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001645this-example RELATIVE-OID ::= {
1646 this-document assorted-examples(0) this-example(1) }
1647\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001648
1649\section{Some of the ASN.1 String Types}
1650
1651
1652\subsection{The IA5String type}
1653
1654This is essentially the ASCII, with 128 character codes available
1655(7 lower bits of an 8-bit byte).
1656
1657
1658\subsection{The UTF8String type}
1659
1660This is the character string which encodes the full Unicode range
1661(4 bytes) using multibyte character sequences.
1662
1663
1664\subsection{The NumericString type}
1665
1666This type represents the character string with the alphabet consisting
Lev Walkin464166c2010-11-09 08:34:38 -08001667of numbers (``0'' to ``9'') and a space.
Lev Walkined44bf42010-11-08 02:04:55 -08001668
1669
1670\subsection{The PrintableString type}
1671
Lev Walkin464166c2010-11-09 08:34:38 -08001672The character string with the following alphabet: space, ``\textbf{'}''
1673(single quote), ``\textbf{(}'', ``\textbf{)}'', ``\textbf{+}'',
1674``\textbf{,}'' (comma), ``\textbf{-}'', ``\textbf{.}'', ``\textbf{/}'',
1675digits (``0'' to ``9''), ``\textbf{:}'', ``\textbf{=}'', ``\textbf{?}'',
1676upper-case and lower-case letters (``A'' to ``Z'' and ``a''
1677to ``z'').
Lev Walkined44bf42010-11-08 02:04:55 -08001678
1679
1680\subsection{The VisibleString type}
1681
1682The character string with the alphabet which is more or less a subset
Lev Walkin464166c2010-11-09 08:34:38 -08001683of ASCII between the space and the ``\textbf{\textasciitilde{}}''
Lev Walkined44bf42010-11-08 02:04:55 -08001684symbol (tilde).
1685
1686Alternatively, the alphabet may be described as the PrintableString
Lev Walkin464166c2010-11-09 08:34:38 -08001687alphabet presented earlier, plus the following characters: ``\textbf{!}'',
1688``\textbf{``}'', ``\textbf{\#}'', ``\textbf{\$}'', ``\textbf{\%}'',
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001689``\textbf{\&}'', ``\textbf{*}'', ``\textbf{;}'', ``\textbf{<}'',
Lev Walkin464166c2010-11-09 08:34:38 -08001690``\textbf{>}'', ``\textbf{{[}}'', ``\textbf{\textbackslash{}}'',
1691``\textbf{{]}}'', ``\textbf{\textasciicircum{}}'', ``\textbf{\_}'',
1692``\textbf{`}`` (single left quote), ``\textbf{\{}'', ``\textbf{|}'',
1693``\textbf{\}}'', ``\textbf{\textasciitilde{}}''.
Lev Walkined44bf42010-11-08 02:04:55 -08001694
1695
1696\section{ASN.1 Constructed Types}
1697
1698
1699\subsection{The SEQUENCE type}
1700
1701This is an ordered collection of other simple or constructed types.
Lev Walkin464166c2010-11-09 08:34:38 -08001702The SEQUENCE constructed type resembles the C ``struct'' statement.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001703\begin{asn}
1704Address ::= SEQUENCE {
1705 -- The apartment number may be omitted
1706 apartmentNumber NumericString OPTIONAL,
1707 streetName PrintableString,
1708 cityName PrintableString,
1709 stateName PrintableString,
1710 -- This one may be omitted too
1711 zipNo NumericString OPTIONAL
1712}
1713\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001714
1715\subsection{The SET type}
1716
1717This is a collection of other simple or constructed types. Ordering
1718is not important. The data may arrive in the order which is different
1719from the order of specification. Data is encoded in the order not
1720necessarily corresponding to the order of specification.
1721
1722
1723\subsection{The CHOICE type}
1724
1725This type is just a choice between the subtypes specified in it. The
1726CHOICE type contains at most one of the subtypes specified, and it
1727is always implicitly known which choice is being decoded or encoded.
Lev Walkin464166c2010-11-09 08:34:38 -08001728This one resembles the C ``union'' statement.
Lev Walkined44bf42010-11-08 02:04:55 -08001729
1730The following type defines a response code, which may be either an
Lev Walkin464166c2010-11-09 08:34:38 -08001731integer code or a boolean ``true''/``false'' code.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001732\begin{asn}
1733ResponseCode ::= CHOICE {
1734 intCode INTEGER,
1735 boolCode BOOLEAN
1736}
1737\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001738
1739\subsection{The SEQUENCE OF type}
1740
1741This one is the list (array) of simple or constructed types:
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001742\begin{asn}
1743-- Example 1
1744ManyIntegers ::= SEQUENCE OF INTEGER
Lev Walkined44bf42010-11-08 02:04:55 -08001745
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001746-- Example 2
1747ManyRectangles ::= SEQUENCE OF Rectangle
Lev Walkined44bf42010-11-08 02:04:55 -08001748
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001749-- More complex example:
1750-- an array of structures defined in place.
1751ManyCircles ::= SEQUENCE OF SEQUENCE {
1752 radius INTEGER
1753 }
1754\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001755
1756\subsection{The SET OF type}
1757
1758The SET OF type models the bag of structures. It resembles the SEQUENCE
Lev Walkin507f6002014-10-26 20:22:16 -07001759OF type, but the order is not important. The elements may arrive
Lev Walkined44bf42010-11-08 02:04:55 -08001760in the order which is not necessarily the same as the in-memory order
1761on the remote machines.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001762\begin{asn}
1763-- A set of structures defined elsewhere
1764SetOfApples :: SET OF Apple
Lev Walkined44bf42010-11-08 02:04:55 -08001765
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001766-- Set of integers encoding the kind of a fruit
1767FruitBag ::= SET OF ENUMERATED { apple, orange }
1768\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001769\begin{thebibliography}{ITU-T/ASN.1}
1770\bibitem[ASN1C]{ASN1C}The Open Source ASN.1 Compiler. \url{http://lionet.info/asn1c}
1771
1772\bibitem[AONL]{AONL}Online ASN.1 Compiler. \url{http://lionet.info/asn1c/asn1c.cgi}
1773
1774\bibitem[Dub00]{Dub00}Olivier Dubuisson --- \emph{ASN.1 Communication
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001775between heterogeneous systems} --- Morgan Kaufmann Publishers, 2000.
Lev Walkined44bf42010-11-08 02:04:55 -08001776\url{http://asn1.elibel.tm.fr/en/book/}. ISBN:0-12-6333361-0.
1777
Lev Walkin464166c2010-11-09 08:34:38 -08001778\bibitem[ITU-T/ASN.1]{ITU-T/ASN.1}ITU-T Study Group 17 --- Languages
Lev Walkined44bf42010-11-08 02:04:55 -08001779for Telecommunication Systems \url{http://www.itu.int/ITU-T/studygroups/com17/languages/}
1780\end{thebibliography}
1781
1782\end{document}