blob: 001b7f6168a9d01dfeece30b9ee25f008381e4ec [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 Walkin07f8c3e2017-11-15 00:21:51 -080079\newcommand{\apisection}[2]{\clearpage\section{\label{#1}#2}}
Lev Walkin9ce64c12017-11-07 06:22:14 -080080\newcommand{\api}[2]{\hyperref[#1]{\code{#2}}}
81\newcommand{\seealso}[2]{\api{#1}{#2} at page \pageref{#1}}
82\newcommand{\code}[1]{\texttt{\textbf{\lstinline{#1}}}}
Lev Walkinf3334582017-11-07 00:02:24 -080083\newcommand{\cmd}[1]{\texttt{#1}}
Lev Walkined44bf42010-11-08 02:04:55 -080084
85%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% User specified LaTeX commands.
86\usepackage{extramarks}
87\lhead{\firstxmark}
88\rfoot{\lastxmark}
Lev Walkin11c9a8c2013-03-26 00:46:55 -070089\definecolor{clrlink}{rgb}{0,0.4,0}
90\definecolor{clrurl}{rgb}{0,0,.6}
Lev Walkined44bf42010-11-08 02:04:55 -080091\usepackage[colorlinks=true,
Lev Walkin11c9a8c2013-03-26 00:46:55 -070092 linkcolor={clrlink},
93 citecolor={clrlink},
94 urlcolor={clrurl},
95 pdfauthor={Lev Walkin},
96 pdftitle={Using the Open Source ASN.1 Compiler},
97 pdfkeywords={ASN.1,asn1c,compiler},
98 bookmarksopen,bookmarksopenlevel=1,
99 pdffitwindow,
100 xetex
Lev Walkined44bf42010-11-08 02:04:55 -0800101]{hyperref}
Lev Walkined44bf42010-11-08 02:04:55 -0800102
Lev Walkin9ce64c12017-11-07 06:22:14 -0800103
Lev Walkined44bf42010-11-08 02:04:55 -0800104\makeatother
105
106\usepackage{babel}
107
108\begin{document}
109
Lev Walkin50155de2014-10-26 19:46:16 -0700110\title{Using the Open Source ASN.1 Compiler\\
Lev Walkin288527b2014-10-26 20:12:53 -0700111\vspace*{0.4cm}
Lev Walkin50155de2014-10-26 19:46:16 -0700112\Large Documentation for asn1c version \asnver{}}
Lev Walkined44bf42010-11-08 02:04:55 -0800113\author{Lev Walkin <\href{mailto:vlm@lionet.info?Subject=asn1c}{vlm@lionet.info}>}
114
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700115\pagestyle{fancy}
116\fancyhead[L]{\leftmark}
Lev Walkin50155de2014-10-26 19:46:16 -0700117\fancyhead[R]{\href{http://lionet.info/asn1c}{asn1c-\asnver}}
Lev Walkined44bf42010-11-08 02:04:55 -0800118\maketitle
Lev Walkined44bf42010-11-08 02:04:55 -0800119
120\tableofcontents{}
121
Lev Walkind5627a12017-11-07 01:04:40 -0800122\chapter{\label{chap:Quick-start-examples}Quick start examples}
Lev Walkined44bf42010-11-08 02:04:55 -0800123
Lev Walkinf3334582017-11-07 00:02:24 -0800124\section{A “Rectangle” converter and debugger}
Lev Walkined44bf42010-11-08 02:04:55 -0800125
Lev Walkinf3334582017-11-07 00:02:24 -0800126One of the most common need is to create some sort of analysis tool
127for the existing ASN.1 data files. Let's build a converter for existing
128Rectangle binary files between BER, OER, PER, and XER (XML).
129
130\begin{enumerate}
131\item Create a file named \textbf{rectangle.asn} with the following contents:
132\begin{asn}
133RectangleModule DEFINITIONS ::= BEGIN
134
135Rectangle ::= SEQUENCE {
136 height INTEGER,
137 width INTEGER
138}
139
140END
141\end{asn}
142
143\item Compile it into the set of .c and .h files using \cmd{asn1c} compiler:
144
145\begin{bash}
Lev Walkind1c28aa2017-11-11 18:04:26 -0800146asn1c -no-gen-example %\textbf{rectangle.asn}%
Lev Walkinf3334582017-11-07 00:02:24 -0800147\end{bash}
148
149\item Create the converter and dumper:
150
151\begin{bash}
Jon Ringle3016fd52017-11-15 02:06:47 -0500152make -f converter-example.mk
Lev Walkinf3334582017-11-07 00:02:24 -0800153\end{bash}
154
155\item Done. The binary file converter is ready:
156
157\begin{bash}
158./converter-example -h
159\end{bash}
160\end{enumerate}
161
162\section{A “Rectangle” Encoder}
Lev Walkined44bf42010-11-08 02:04:55 -0800163
164This example will help you create a simple BER and XER encoder of
Lev Walkin464166c2010-11-09 08:34:38 -0800165a ``Rectangle'' type used throughout this document.
Lev Walkined44bf42010-11-08 02:04:55 -0800166\begin{enumerate}
Lev Walkinf3334582017-11-07 00:02:24 -0800167\item Create a file named \textbf{rectangle.asn} with the following contents:
Lev Walkined44bf42010-11-08 02:04:55 -0800168
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700169\begin{asn}
Lev Walkinf3334582017-11-07 00:02:24 -0800170RectangleModule DEFINITIONS ::= BEGIN
Lev Walkined44bf42010-11-08 02:04:55 -0800171
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700172Rectangle ::= SEQUENCE {
173 height INTEGER,
174 width INTEGER
175}
Lev Walkined44bf42010-11-08 02:04:55 -0800176
177END
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700178\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -0800179\item Compile it into the set of .c and .h files using asn1c compiler \cite{ASN1C}:
180
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700181\begin{bash}
Lev Walkind1c28aa2017-11-11 18:04:26 -0800182asn1c -no-gen-example %\textbf{rectangle.asn}%
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700183\end{bash}
Lev Walkined44bf42010-11-08 02:04:55 -0800184\item Alternatively, use the Online ASN.1 compiler \cite{AONL} by uploading
Lev Walkinf3334582017-11-07 00:02:24 -0800185the \textbf{rectangle.asn} file into the Web form and unpacking the
Lev Walkined44bf42010-11-08 02:04:55 -0800186produced archive on your computer.
187\item By this time, you should have gotten multiple files in the current
188directory, including the \textbf{Rectangle.c} and \textbf{Rectangle.h}.
189\item Create a main() routine which creates the Rectangle\_t structure in
190memory and encodes it using BER and XER encoding rules. Let's name
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700191the file \textbf{main.c}:
Lev Walkined44bf42010-11-08 02:04:55 -0800192
Lev Walkin9ce64c12017-11-07 06:22:14 -0800193\begin{example}
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700194#include <stdio.h>
195#include <sys/types.h>
196#include <Rectangle.h> /* Rectangle ASN.1 type */
Lev Walkined44bf42010-11-08 02:04:55 -0800197
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700198/* Write the encoded output into some FILE stream. */
199static int write_out(const void *buffer, size_t size, void *app_key) {
200 FILE *out_fp = app_key;
201 size_t wrote = fwrite(buffer, 1, size, out_fp);
202 return (wrote == size) ? 0 : -1;
203}
204
205int main(int ac, char **av) {
206 Rectangle_t *rectangle; /* Type to encode */
207 asn_enc_rval_t ec; /* Encoder return value */
Lev Walkined44bf42010-11-08 02:04:55 -0800208
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700209 /* Allocate the Rectangle_t */
fei4xu878dc3b2019-06-06 15:14:22 +0800210 rectangle = calloc(1, sizeof(Rectangle_t)); /* must initialize to zero, not malloc! */
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700211 if(!rectangle) {
212 perror("calloc() failed");
213 exit(1);
214 }
Lev Walkined44bf42010-11-08 02:04:55 -0800215
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700216 /* Initialize the Rectangle members */
217 rectangle->height = 42; /* any random value */
218 rectangle->width = 23; /* any random value */
Lev Walkined44bf42010-11-08 02:04:55 -0800219
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700220 /* BER encode the data if filename is given */
221 if(ac < 2) {
222 fprintf(stderr, "Specify filename for BER output\n");
223 } else {
224 const char *filename = av[1];
225 FILE *fp = fopen(filename, "wb"); /* for BER output */
226
227 if(!fp) {
228 perror(filename);
229 exit(1);
230 }
Lev Walkined44bf42010-11-08 02:04:55 -0800231
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700232 /* Encode the Rectangle type as BER (DER) */
233 ec = der_encode(&asn_DEF_Rectangle, rectangle, write_out, fp);
234 fclose(fp);
235 if(ec.encoded == -1) {
236 fprintf(stderr, "Could not encode Rectangle (at %\%%s)\n",
237 ec.failed_type ? ec.failed_type->name : "unknown");
238 exit(1);
239 } else {
240 fprintf(stderr, "Created %\%%s with BER encoded Rectangle\n", filename);
241 }
242 }
Lev Walkined44bf42010-11-08 02:04:55 -0800243
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700244 /* Also print the constructed Rectangle XER encoded (XML) */
245 xer_fprint(stdout, &asn_DEF_Rectangle, rectangle);
Lev Walkined44bf42010-11-08 02:04:55 -0800246
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700247 return 0; /* Encoding finished successfully */
248 }
Lev Walkin9ce64c12017-11-07 06:22:14 -0800249\end{example}
Lev Walkined44bf42010-11-08 02:04:55 -0800250\item Compile all files together using C compiler (varies by platform):
251
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700252\begin{bash}
253cc -I. -o %\textbf{\emph{rencode}} \emph{*.c}%
254\end{bash}
Lev Walkinf3334582017-11-07 00:02:24 -0800255\item Done. You have just created the BER and XER encoder of a Rectangle
Lev Walkined44bf42010-11-08 02:04:55 -0800256type, named \textbf{rencode}!
257\end{enumerate}
Lev Walkined44bf42010-11-08 02:04:55 -0800258
Lev Walkinf3334582017-11-07 00:02:24 -0800259\section{\label{sec:A-Rectangle-Decoder}A “Rectangle” Decoder}
Lev Walkined44bf42010-11-08 02:04:55 -0800260
261This example will help you to create a simple BER decoder of a simple
Lev Walkin464166c2010-11-09 08:34:38 -0800262``Rectangle'' type used throughout this document.
Lev Walkined44bf42010-11-08 02:04:55 -0800263\begin{enumerate}
Lev Walkinf3334582017-11-07 00:02:24 -0800264\item Create a file named \textbf{rectangle.asn} with the following contents:
Lev Walkined44bf42010-11-08 02:04:55 -0800265
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700266\begin{asn}
Lev Walkinf3334582017-11-07 00:02:24 -0800267RectangleModule DEFINITIONS ::= BEGIN
Lev Walkined44bf42010-11-08 02:04:55 -0800268
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700269Rectangle ::= SEQUENCE {
270 height INTEGER,
271 width INTEGER
272}
Lev Walkined44bf42010-11-08 02:04:55 -0800273
274END
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700275\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -0800276\item Compile it into the set of .c and .h files using asn1c compiler \cite{ASN1C}:
277
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700278\begin{bash}
Lev Walkind1c28aa2017-11-11 18:04:26 -0800279asn1c -no-gen-example %\textbf{rectangle.asn}%
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700280\end{bash}
Lev Walkined44bf42010-11-08 02:04:55 -0800281\item Alternatively, use the Online ASN.1 compiler \cite{AONL} by uploading
Lev Walkinf3334582017-11-07 00:02:24 -0800282the \textbf{rectangle.asn} file into the Web form and unpacking the
Lev Walkined44bf42010-11-08 02:04:55 -0800283produced archive on your computer.
284\item By this time, you should have gotten multiple files in the current
285directory, including the \textbf{Rectangle.c} and \textbf{Rectangle.h}.
286\item Create a main() routine which takes the binary input file, decodes
287it as it were a BER-encoded Rectangle type, and prints out the text
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700288(XML) representation of the Rectangle type. Let's name the file \textbf{main.c}:
Lev Walkined44bf42010-11-08 02:04:55 -0800289
Lev Walkin9ce64c12017-11-07 06:22:14 -0800290\begin{example}
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700291#include <stdio.h>
292#include <sys/types.h>
293#include <Rectangle.h> /* Rectangle ASN.1 type */
Lev Walkined44bf42010-11-08 02:04:55 -0800294
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700295int main(int ac, char **av) {
296 char buf[1024]; /* Temporary buffer */
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700297 asn_dec_rval_t rval; /* Decoder return value */
Lev Walkin194b2102013-03-28 01:29:06 -0700298 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 -0700299 FILE *fp; /* Input file handler */
300 size_t size; /* Number of bytes read */
301 char *filename; /* Input file name */
Lev Walkined44bf42010-11-08 02:04:55 -0800302
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700303 /* Require a single filename argument */
304 if(ac != 2) {
305 fprintf(stderr, "Usage: %\%%s <file.ber>\n", av[0]);
306 exit(1);
307 } else {
308 filename = av[1];
309 }
Lev Walkined44bf42010-11-08 02:04:55 -0800310
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700311 /* Open input file as read-only binary */
312 fp = fopen(filename, "rb");
313 if(!fp) {
314 perror(filename);
315 exit(1);
316 }
Lev Walkined44bf42010-11-08 02:04:55 -0800317
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700318 /* Read up to the buffer size */
319 size = fread(buf, 1, sizeof(buf), fp);
320 fclose(fp);
321 if(!size) {
322 fprintf(stderr, "%\%%s: Empty or broken\n", filename);
323 exit(1);
324 }
Lev Walkined44bf42010-11-08 02:04:55 -0800325
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700326 /* Decode the input buffer as Rectangle type */
327 rval = ber_decode(0, &asn_DEF_Rectangle, (void **)&rectangle, buf, size);
328 if(rval.code != RC_OK) {
329 fprintf(stderr, "%\%%s: Broken Rectangle encoding at byte %\%%ld\n", filename, (long)rval.consumed);
330 exit(1);
331 }
Lev Walkined44bf42010-11-08 02:04:55 -0800332
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700333 /* Print the decoded Rectangle type as XML */
334 xer_fprint(stdout, &asn_DEF_Rectangle, rectangle);
Lev Walkined44bf42010-11-08 02:04:55 -0800335
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700336 return 0; /* Decoding finished successfully */
Lev Walkin194b2102013-03-28 01:29:06 -0700337}
Lev Walkin9ce64c12017-11-07 06:22:14 -0800338\end{example}
Lev Walkined44bf42010-11-08 02:04:55 -0800339\item Compile all files together using C compiler (varies by platform):
340
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700341\begin{bash}
342cc -I. -o %\textbf{\emph{rdecode}} \emph{*.c}%
343\end{bash}
Lev Walkinf3334582017-11-07 00:02:24 -0800344\item Done. You have just created the BER decoder of a Rectangle type,
Lev Walkined44bf42010-11-08 02:04:55 -0800345named \textbf{rdecode}!
346\end{enumerate}
347
Lev Walkind5627a12017-11-07 01:04:40 -0800348\section{Adding constraints to a “Rectangle”}
Lev Walkined44bf42010-11-08 02:04:55 -0800349
350This example shows how to add basic constraints to the ASN.1 specification
351and how to invoke the constraints validation code in your application.
352\begin{enumerate}
Lev Walkind5627a12017-11-07 01:04:40 -0800353
Lev Walkinf3334582017-11-07 00:02:24 -0800354\item Create a file named \textbf{rectangle.asn} with the following contents:
Lev Walkined44bf42010-11-08 02:04:55 -0800355
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700356\begin{asn}
357RectangleModuleWithConstraints DEFINITIONS ::= BEGIN
Lev Walkined44bf42010-11-08 02:04:55 -0800358
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700359Rectangle ::= SEQUENCE {
360 height INTEGER (0..100), -- Value range constraint
361 width INTEGER (0..MAX) -- Makes width non-negative
362}
Lev Walkined44bf42010-11-08 02:04:55 -0800363
364END
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700365\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -0800366
Lev Walkind5627a12017-11-07 01:04:40 -0800367\item Compile the file according to procedures shown in \fref{sec:A-Rectangle-Decoder}.
368\item Modify the Rectangle type processing routine (you can start with the
369main() routine shown in the \fref{sec:A-Rectangle-Decoder})
370by placing the following snippet of code \emph{before} encoding and/or
371\emph{after} decoding the Rectangle type:
372
Lev Walkin9ce64c12017-11-07 06:22:14 -0800373\begin{example}
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700374int ret; /* Return value */
375char errbuf[128]; /* Buffer for error message */
376size_t errlen = sizeof(errbuf); /* Size of the buffer */
Lev Walkined44bf42010-11-08 02:04:55 -0800377
Lev Walkin2e554fc2014-10-26 19:21:58 -0700378/* ... here goes the Rectangle %\emph{decoding}% code ... */
Lev Walkined44bf42010-11-08 02:04:55 -0800379
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700380ret = asn_check_constraints(&asn_DEF_Rectangle, rectangle, errbuf, &errlen);
381/* assert(errlen < sizeof(errbuf)); // you may rely on that */
382if(ret) {
Lev Walkind5627a12017-11-07 01:04:40 -0800383 fprintf(stderr, "Constraint validation failed: %\%%s\n", errbuf);
Lev Walkin11c9a8c2013-03-26 00:46:55 -0700384 /* exit(...); // Replace with appropriate action */
385 }
Lev Walkined44bf42010-11-08 02:04:55 -0800386
Lev Walkin2e554fc2014-10-26 19:21:58 -0700387/* ... here goes the Rectangle %\emph{encoding}% code ... */
Lev Walkin9ce64c12017-11-07 06:22:14 -0800388\end{example}
Lev Walkined44bf42010-11-08 02:04:55 -0800389\item Compile the resulting C code as shown in the previous chapters.
Lev Walkind5627a12017-11-07 01:04:40 -0800390\item Test the constraints checking code by assigning integer value
Lev Walkined44bf42010-11-08 02:04:55 -0800391101 to the \textbf{.height} member of the Rectangle structure, or
Lev Walkind5627a12017-11-07 01:04:40 -0800392a negative value to the \textbf{.width} member.
393The program will fail with ``Constraint validation failed'' message.
Lev Walkined44bf42010-11-08 02:04:55 -0800394\item Done.
395\end{enumerate}
396
Lev Walkind5627a12017-11-07 01:04:40 -0800397\chapter{ASN.1 Compiler}
398
399\section{The asn1c compiler tool}
400
401The purpose of the ASN.1 compiler is to convert the specifications
402in ASN.1 notation into some other language, such as C.
403
404The compiler reads the specification and emits a series of target
405language structures (C structs, unions, enums) describing the corresponding
406ASN.1 types. The compiler also creates the code which allows automatic
407serialization and deserialization of these structures using several
408standardized encoding rules (BER, DER, OER, PER, XER).
409
410Let's take the following ASN.1 example%
411\footnote{\Fref{chap:Abstract-Syntax-Notation} provides a quick reference
412on the ASN.1 notation.}:
413\begin{asn}
414RectangleModule DEFINITIONS ::= BEGIN
415
416Rectangle ::= SEQUENCE {
417 height INTEGER, -- Height of the rectangle
418 width INTEGER -- Width of the rectangle
419}
420
421END
422\end{asn}
423The asn1c compiler reads this ASN.1 definition and produce the following
424C type:
425\begin{codesample}
426typedef struct Rectangle_s {
427 long height;
428 long width;
429} Rectangle_t;
430\end{codesample}
431The asn1c compiler also creates the code for converting this structure into
432platform-independent wire representation and the decoder
433of such wire representation back into local, machine-specific type.
434These encoders and decoders are also called serializers and deserializers,
435marshallers and unmarshallers, or codecs.
436
437Compiling ASN.1 modules into C codecs can be as simple as invoking \cmd{asn1c}:
438may be used to compile the ASN.1 modules:
439\begin{bash}
440asn1c %\emph{<modules.asn>}%
441\end{bash}
442
443If several ASN.1 modules contain interdependencies, all of the files
444must be specified altogether:
445\begin{bash}
446asn1c %\emph{<module1.asn> <module2.asn> ...}%
447\end{bash}
448The compiler \textbf{-E} and \textbf{-EF} options are used for testing
449the parser and the semantic fixer, respectively. These options will
450instruct the compiler to dump out the parsed (and fixed, if \textbf{-F}
451is involved) ASN.1 specification as it was understood
452by the compiler. It might be useful to check whether a particular
453syntactic construct is properly supported by the compiler.
454\begin{bash}
455asn1c %\textbf{-EF} \emph{<module-to-test.asn>}%
456\end{bash}
457The \textbf{-P} option is used to dump the compiled output on the
458screen instead of creating a bunch of .c and .h files on disk in the
459current directory. You would probably want to start with \textbf{-P}
460option instead of creating a mess in your current directory. Another
461option, \textbf{-R}, asks compiler to only generate the files which
462need to be generated, and supress linking in the numerous support
463files.
464
465Print the compiled output instead of creating multiple source files:
466\begin{bash}
467asn1c %\textbf{-P} \emph{<module-to-compile-and-print.asn>}%
468\end{bash}
469
470\clearpage{}
471\section{Compiler output}
472
473The \cmd{asn1c} compiler produces a number of files:
474\begin{itemize}
475\item A set of .c and .h files for each type defined
476in the ASN.1 specification. These files will be named similarly to
477the ASN.1 types (\textbf{Rectangle.c} and \textbf{Rectangle.h} for the
478RectangleModule ASN.1 module defined in the beginning of this document).
479\item A set of helper .c and .h files which contain the generic encoders,
480decoders and other useful routines.
481Sometimes they are referred to by the term \emph{skeletons}.
482There will be quite a few of them, some
483of them are not even always necessary, but the overall amount of code
484after compilation will be rather small anyway.
485\item A \textbf{Makefile.am.libasncodecs} file which explicitly lists all the
486generated files.
487This makefile can be used on its own to build the just the codec library.
Lev Walkind1c28aa2017-11-11 18:04:26 -0800488\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.
Jon Ringle3016fd52017-11-15 02:06:47 -0500489\item A \textbf{converter-example.mk} file which binds together
Lev Walkind5627a12017-11-07 01:04:40 -0800490\textbf{Makefile.am.libasncodecs} and \textbf{converter-example.c}
491to build a versatile converter and debugger for your data formats.
492\end{itemize}
493It is possible to compile everything with just a couple of instructions:
494\begin{bash}
495asn1c -pdu=%\emph{Rectangle}% *.asn
Jon Ringle3016fd52017-11-15 02:06:47 -0500496make -f converter-example.mk # If you use `make`
Lev Walkind5627a12017-11-07 01:04:40 -0800497\end{bash}
498or
499\begin{bash}
500asn1c *.asn
501cc -I. -DPDU=%\emph{Rectangle}% -o rectangle.exe *.c # ... or like this
502\end{bash}
503Refer to the \fref{chap:Quick-start-examples} for a sample
504\emph{int main()} function if you want some custom logic and not satisfied
505with the supplied \emph{converter-example.c}.
506
507\clearpage{}
508\section{\label{sec:Command-line-options}Command line options}
509
510The following table summarizes the \cmd{asn1c} command line options.
511
512\renewcommand{\arraystretch}{1.33}
513\begin{longtable}{lp{4in}}
514\textbf{Stage Selection Options} & \textbf{Description}\\
515\midrule
516{\ttfamily -E} & {\small Stop after the parsing stage and print the reconstructed ASN.1
517specification code to the standard output.}\\
518{\ttfamily -F} & {\small Used together with \texttt{-E}, instructs the compiler to stop after
519the ASN.1 syntax tree fixing stage and dump the reconstructed ASN.1
520specification to the standard output.}\\
521{\ttfamily -P} & {\small Dump the compiled output to the standard output instead of
522creating the target language files on disk.}\\
523{\ttfamily -R} & {\small Restrict the compiler to generate only the ASN.1 tables, omitting the usual support code.}\\
524{\ttfamily -S~\emph{<directory>}} & {\small Use the specified directory with ASN.1 skeleton files.}\\
525{\ttfamily -X} & {\small Generate the XML DTD for the specified ASN.1 modules.}\\\\
526\textbf{Warning Options} & \textbf{Description}\\
527\midrule
528{\ttfamily -Werror} & {\small Treat warnings as errors; abort if any warning is produced.}\\
529{\ttfamily -Wdebug-parser} & {\small Enable the parser debugging during the ASN.1 parsing stage.}\\
530{\ttfamily -Wdebug-lexer} & {\small Enable the lexer debugging during the ASN.1 parsing stage.}\\
531{\ttfamily -Wdebug-fixer} & {\small Enable the ASN.1 syntax tree fixer debugging during the fixing stage.}\\
532{\ttfamily -Wdebug-compiler} & {\small Enable debugging during the actual compile time.}\\ \\
533\textbf{Language Options} & \textbf{Description}\\
534\midrule
535{\ttfamily -fbless-SIZE} & {\small Allow SIZE() constraint for INTEGER, ENUMERATED, and other types for which this constraint is normally prohibited by the standard.
536This is a violation of an ASN.1 standard and compiler may fail to produce the meaningful code.}\\
537{\ttfamily -fcompound-names} & {\small Use complex names for C structures. Using complex names prevents
538name clashes in case the module reuses the same identifiers in multiple
539contexts.}\\
540{\ttfamily -findirect-choice} & {\small When generating code for a CHOICE type, compile the CHOICE
541members as indirect pointers instead of declaring them inline. Consider
542using this option together with \texttt{-fno-include-deps}
543to prevent circular references.}\\
544{\ttfamily -fincludes-quoted} & {\small Generate \#include lines in "double" instead of <angle> quotes.}\\
545{\ttfamily -fknown-extern-type=\emph{<name>}} & {\small Pretend the specified type is known. The compiler will assume
546the target language source files for the given type have been provided
547manually. }\\
548{\ttfamily -fline-refs} & {\small Include ASN.1 module's line numbers in generated code comments.}\\
Lev Walkind1c28aa2017-11-11 18:04:26 -0800549{\ttfamily -fno-constraints} & {\small Do not generate the ASN.1 subtype constraint checking code. This
Lev Walkind5627a12017-11-07 01:04:40 -0800550may produce a shorter executable.}\\
Lev Walkind1c28aa2017-11-11 18:04:26 -0800551{\ttfamily -fno-include-deps} & {\small Do not generate the courtesy \#include lines for non-critical dependencies.}\\
Lev Walkind5627a12017-11-07 01:04:40 -0800552{\ttfamily -funnamed-unions} & {\small Enable unnamed unions in the definitions of target language's structures.}\\
553{\ttfamily -fwide-types} & {\small Use the wide integer types (INTEGER\_t, REAL\_t) instead of machine's native data types (long, double). }\\\\
554\textbf{Codecs Generation Options} & \textbf{Description}\\
555\midrule
Lev Walkind1c28aa2017-11-11 18:04:26 -0800556{\ttfamily -no-gen-OER} & {\small Do not generate the Octet Encoding Rules (OER, X.696) support code.}\\
557{\ttfamily -no-gen-PER} & {\small Do not generate the Packed Encoding Rules (PER, X.691) support code.}\\
558{\ttfamily -no-gen-example} & {\small Do not generate the ASN.1 format converter example.}\\
Lev Walkind5627a12017-11-07 01:04:40 -0800559{\ttfamily -pdu=\{\textbf{all}|\textbf{auto}|\emph{Type}\}} & {\small Create a PDU table for specified types, or discover the Protocol Data Units automatically.
560In 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.}\\ \\
561\textbf{Output Options} & \textbf{Description}\\
562\midrule
563{\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.}\\
564{\ttfamily -print-constraints} & {\small With \texttt{-EF}, this option instructs the compiler
565to explain its internal understanding of subtype constraints.}\\
566{\ttfamily -print-lines} & {\small Generate \texttt{``-{}- \#line''} comments
567in \texttt{-E} output.}\\
568\end{longtable}
569\renewcommand{\arraystretch}{1}
Lev Walkined44bf42010-11-08 02:04:55 -0800570
571
Lev Walkind5627a12017-11-07 01:04:40 -0800572\chapter{API reference}
573
Lev Walkin9ce64c12017-11-07 06:22:14 -0800574The functions desribed in this chapter are to be used by the application
575programmer. These functions won't likely change change or get removed until
576the next major release.
577
578The API calls not listed here are not public and should not be used by the
579application level code.
580
Lev Walkin07f8c3e2017-11-15 00:21:51 -0800581\apisection{sec:ASN_STRUCT_FREE}{ASN\_STRUCT\_FREE() macro}
Lev Walkin9ce64c12017-11-07 06:22:14 -0800582
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
Lev Walkin07f8c3e2017-11-15 00:21:51 -0800607\apisection{sec:ASN_STRUCT_RESET}{ASN\_STRUCT\_RESET() macro}
Lev Walkin9ce64c12017-11-07 06:22:14 -0800608
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
Lev Walkin07f8c3e2017-11-15 00:21:51 -0800643\apisection{sec:asn_check_constraints}{asn\_check\_constraints()}
Lev Walkin9ce64c12017-11-07 06:22:14 -0800644
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
Lev Walkin07f8c3e2017-11-15 00:21:51 -0800658Validate a given structure according to the ASN.1 constraints.
659If \code{errbuf} and \code{errlen} are given, they shall point to the
660appropriate buffer space and its length before calling this function.
661Alternatively, they could be passed as \code{NULL}s.
662If constraints validation fails, \code{errlen} will contain the actual
663number of bytes used in \code{errbuf} to encode an error message.
664The message is going to be properly 0-terminated.
Lev Walkin9ce64c12017-11-07 06:22:14 -0800665
666\subsection*{Return values}
667
668This function returns 0 in case all ASN.1 constraints are met
669and -1 if one or more ASN.1 constraints were violated.
670
671\subsection*{Example}
672
673\begin{codesample}[basicstyle=\scriptsize\listingfont]
674Rectangle_t *rect = ...;
675
676char errbuf[128]; /* Buffer for error message */
677size_t errlen = sizeof(errbuf); /* Size of the buffer */
678
679int ret = asn_check_constraints(&asn_DEF_Rectangle, rectangle, errbuf, &errlen);
680/* assert(errlen < sizeof(errbuf)); // Guaranteed: you may rely on that */
681if(ret) {
682 fprintf(stderr, "Constraint validation failed: %\%%s\n", errbuf);
683}
684\end{codesample}
685
Lev Walkin07f8c3e2017-11-15 00:21:51 -0800686\apisection{sec:asn_decode}{asn\_decode()}
Lev Walkin9ce64c12017-11-07 06:22:14 -0800687
688\subsection*{Synopsis}
689\begin{signature}
690asn_dec_rval_t asn_decode(
Lev Walkin07f8c3e2017-11-15 00:21:51 -0800691 const asn_codec_ctx_t *opt_codec_ctx,
Lev Walkin9ce64c12017-11-07 06:22:14 -0800692 enum asn_transfer_syntax syntax,
693 const asn_TYPE_descriptor_t *type_descriptor,
694 void **struct_ptr_ptr,/* Pointer to a target structure's ptr */
695 const void *buffer, /* Data to be decoded */
696 size_t size /* Size of that buffer */
697);
698\end{signature}
699
700\subsection*{Description}
701
702The \code{asn\_decode()} function parses the data given by the \code{buffer}
703and \code{size} arguments. The encoding rules are specified in the \code{syntax}
704argument and the type to be decoded is specified by the \code{type_descriptor}.
705
706The \code{struct_ptr_ptr} must point to the memory location which contains the
707pointer to the structure being decoded. Initially the \code{*struct_ptr_ptr}
708pointer is typically set to 0. In that case, \code{asn\_decode()} will
709dynamically allocate memory for the structure and its members as needed
710during the parsing.
711If \code{*struct\_ptr\_ptr} already points to some memory, the \code{asn\_decode()}
712will allocate the subsequent members as needed during the parsing.
713
714\subsection*{Return values}
715
716\input{asn_dec_rval.inc}
717
718The \code{.consumed} value is in bytes, even for PER decoding.
719For PER, use \code{uper\_decode()} in case you need to get
720the number of consumed bits.
721
722\subsection*{Restartability}
723
724Some transfer syntax parsers (such as ATS\_BER) support restartability.
725
726That means that in case the buffer has less data than expected,
727the \code{asn_decode()} will process whatever is available and ask for more
728data to be provided using the RC\_WMORE return \code{.code}.
729
730Note that in the RC\_WMORE case the decoder may have processed less data than
731it is available in the buffer, which means that you must be able to arrange
732the next buffer to contain the unprocessed part of the previous buffer.
733
734The \code{RC_WMORE} code may still be returned by parser not supporting
735restartabilty. In such cases, the partially decoded structure shall be
736discarded and the next invocation should use the extended buffer to parse
737from the very beginning.
738
739\subsection*{Example}
740
741\begin{example}
742Rectangle_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.}!}% */
743asn_dec_rval_t rval;
744rval = asn_decode(0, ATS_BER, &asn_DEF_Rectangle, (void **)&rect, buffer, buf_size);
745switch(rval.code) {
746case RC_OK:
747 asn_fprint(stdout, &asn_DEF_Rectangle, rect);
748 ASN_STRUCT_FREE(&asn_DEF_Rectangle, rect);
749 break;
750case RC_WMORE:
751case RC_FAIL:
752default:
753 ASN_STRUCT_FREE(&asn_DEF_Rectangle, rect);
754 break;
755}
756\end{example}
757
758\subsection*{See also}
759\seealso{sec:asn_fprint}{asn_fprint()}.
760
Lev Walkin07f8c3e2017-11-15 00:21:51 -0800761\apisection{sec:asn_encode}{asn\_encode()}
762
763\subsection*{Synopsis}
764
765\begin{signature}
766#include <asn_application.h>
767
768asn_enc_rval_t asn_encode(
769 const asn_codec_ctx_t *opt_codec_ctx,
770 enum asn_transfer_syntax syntax,
771 const asn_TYPE_descriptor_t *type_to_encode,
772 const void *structure_to_encode,
773 asn_app_consume_bytes_f *callback, void *callback_key);
774\end{signature}
775
776\subsection*{Description}
777
778The \code{asn_encode()} function serializes the given \code{structure_to_encode} using the chosen ASN.1 transfer \code{syntax}.
779
780During serialization, a user-specified \code{callback} is invoked zero
781or more times with bytes of data to add to the output stream (if any), and
782the \code{callback_key}. The signature for the callback is as follows:
783
784\begin{signature}
785typedef int(asn_app_consume_bytes_f)(const void *buffer, size_t size, void *callback_key);
786\end{signature}
787
788\subsection*{Return values}
789\input{asn_enc_rval.inc}
790
791The serialized output size is returned in \textbf{bytes} irrespectively of the
792ASN.1 transfer \code{syntax} chosen.\footnote{This is different from some
793lower level encoding functions, such as \api{sec:uper_encode}{uper_encode()},
794which returns the number of encoded \emph{bits} instead of bytes.}
795
796On error (when \code{.encoded} is set to -1),
797the \code{errno} is set to one of the following values:
798
799\begin{tabular}[h!]{ll}
800\texttt{EINVAL} & Incorrect parameters to the function, such as NULLs \\
801\texttt{ENOENT} & Encoding transfer syntax is not defined (for this type) \\
802\texttt{EBADF} & The structure has invalid form or content constraint failed \\
803\texttt{EIO} & The callback has returned negative value during encoding
804\end{tabular}
Lev Walkin9ce64c12017-11-07 06:22:14 -0800805
806\subsection*{Example}
807\begin{example}
Lev Walkin07f8c3e2017-11-15 00:21:51 -0800808static int
809save_to_file(const void *data, size_t size, void *key) {
810 FILE *fp = key;
811 return (fwrite(data, 1, size, fp) == size) ? 0 : -1;
812}
813
814Rectangle_t *rect = ...;
815FILE *fp = ...;
Lev Walkin9ce64c12017-11-07 06:22:14 -0800816asn_enc_rval_t er;
Lev Walkin07f8c3e2017-11-15 00:21:51 -0800817er = asn_encode(0, ATS_DER, &asn_DEF_Rectangle, rect, save_to_file, fp);
818if(er.encoded == -1) {
819 fprintf(stderr, "Failed to encode %\%%s\n", asn_DEF_Rectangle.name);
820} else {
821 fprintf(stderr, "%\%%s encoded in %\%%zd bytes\n", asn_DEF_Rectangle.name, er.encoded);
822}
823\end{example}
824
825\apisection{sec:asn_encode_to_buffer}{asn\_encode\_to\_buffer()}
826
827\subsection*{Synopsis}
828
829\begin{signature}
830#include <asn_application.h>
831
832asn_enc_rval_t asn_encode_to_buffer(
833 const asn_codec_ctx_t *opt_codec_ctx,
834 enum asn_transfer_syntax syntax,
835 const asn_TYPE_descriptor_t *type_to_encode,
836 const void *structure_to_encode,
837 void *buffer, size_t buffer_size);
838\end{signature}
839
840\subsection*{Description}
841
842The \code{asn_encode_to_buffer()} function serializes the given \code{structure_to_encode} using the chosen ASN.1 transfer \code{syntax}.
843
844The function places the serialized data into the given
845\code{buffer} of size \code{buffer_size}.
846
847\subsection*{Return values}
848\input{asn_enc_rval.inc}
849
850The serialized output size is returned in \textbf{bytes} irrespectively of the
851ASN.1 transfer \code{syntax} chosen.\footnote{This is different from some
852lower level encoding functions, such as \api{sec:uper_encode}{uper_encode()},
853which returns the number of encoded \emph{bits} instead of bytes.}
854
855If \code{.encoded} size exceeds the specified \code{buffer_size},
856the serialization effectively failed due to insufficient space. The function
857will succeed if subsequently called with buffer size no less than the returned
858\code{.encoded} size. This behavior modeled after \code{snprintf()}.
859
860On error (when \code{.encoded} is set to -1),
861the \code{errno} is set to one of the following values:
862
863\begin{tabular}[h!]{ll}
864\texttt{EINVAL} & Incorrect parameters to the function, such as NULLs \\
865\texttt{ENOENT} & Encoding transfer syntax is not defined (for this type) \\
866\texttt{EBADF} & The structure has invalid form or content constraint failed
867\end{tabular}
868
869\subsection*{Example}
870\begin{example}
871Rectangle_t *rect = ...;
872uint8_t buffer[128];
873asn_enc_rval_t er;
874er = asn_encode_to_buffer(0, ATS_DER, &asn_DEF_Rectangle, rect, buffer, sizeof(buffer));
875if(er.encoded == -1) {
876 fprintf(stderr, "Serialization of %\%%s failed.\n", asn_DEF_Rectangle.name);
877} else if(er.encoded > sizeof(buffer)) {
Lev Walkin9ce64c12017-11-07 06:22:14 -0800878 fprintf(stderr, "Buffer of size %\%%zu is too small for %\%%s, need %\%%zu\n",
879 buf_size, asn_DEF_Rectangle.name, er.encoded);
880}
881\end{example}
882
Lev Walkin07f8c3e2017-11-15 00:21:51 -0800883\subsection*{See also}
884\seealso{sec:asn_encode_to_new_buffer}{asn_encode_to_new_buffer()}.
885
886\apisection{sec:asn_encode_to_new_buffer}{asn\_encode\_to\_new\_buffer()}
887
888\subsection*{Synopsis}
889
890\begin{signature}
891#include <asn_application.h>
892
893typedef struct {
894 void *buffer; /* NULL if failed to encode. */
895 asn_enc_rval_t result;
896} asn_encode_to_new_buffer_result_t;
897asn_encode_to_new_buffer_result_t asn_encode_to_new_buffer(
898 const asn_codec_ctx_t *opt_codec_ctx,
899 enum asn_transfer_syntax syntax,
900 const asn_TYPE_descriptor_t *type_to_encode,
901 const void *structure_to_encode);
902\end{signature}
903
904\subsection*{Description}
905
906The \code{asn_encode_to_new_buffer()} function serializes the given \code{structure_to_encode} using the chosen ASN.1 transfer \code{syntax}.
907
908The function places the serialized data into the newly allocated buffer
909which it returns in a compound structure.
910
911\subsection*{Return values}
912
913On failure, the \code{.buffer} is set to \code{NULL}
914and \code{.result.encoded} is set to -1. The global \code{errno} is set
915to one of the following values:
916
917\begin{tabular}[h!]{ll}
918\texttt{EINVAL} & Incorrect parameters to the function, such as NULLs \\
919\texttt{ENOENT} & Encoding transfer syntax is not defined (for this type) \\
920\texttt{EBADF} & The structure has invalid form or content constraint failed \\
921\texttt{ENOMEM} & Memory allocation failed due to system or internal limits
922\end{tabular}
923
924\noindent{}On success, the \code{.result.encoded} is set to the number of
925\textbf{bytes} that it took to serialize the structure.
926The \code{.buffer} contains the serialized content.
927The user is responsible for freeing the \code{.buffer}.
Lev Walkin9ce64c12017-11-07 06:22:14 -0800928
929\subsection*{Example}
930\begin{example}
931asn_encode_to_new_buffer_result_t res;
Lev Walkin07f8c3e2017-11-15 00:21:51 -0800932res = asn_encode_to_new_buffer(0, ATS_DER, &asn_DEF_Rectangle, rect);
Lev Walkin9ce64c12017-11-07 06:22:14 -0800933if(res.buffer) {
934 /* Encoded successfully. */
935 free(res.buffer);
936} else {
937 fprintf(stderr, "Failed to encode %\%%s, estimated %\%%zd bytes\n",
938 asn_DEF_Rectangle.name, res.result.encoded);
939}
940\end{example}
941
Lev Walkin07f8c3e2017-11-15 00:21:51 -0800942\subsection*{See also}
943\seealso{sec:asn_encode_to_buffer}{asn_encode_to_buffer()}.
944
945\apisection{sec:asn_fprint}{asn\_fprint()}
Lev Walkin9ce64c12017-11-07 06:22:14 -0800946
947\subsection*{Synopsis}
948\begin{signature}
949int asn_fprint(FILE *stream, /* Destination file */
950 const asn_TYPE_descriptor_t *type_descriptor,
951 const void *struct_ptr /* Structure to be printed */
952);
953\end{signature}
954
955\subsection*{Description}
956
957The \code{asn_fprint()} function prints human readable description
958of the target language's structure into the file stream specified by
959\code{stream} pointer.
960
961The output format does not conform to any standard.
962
963The \code{asn_fprint()} function attempts to
964produce a valid output even for incomplete and broken structures, which
965makes it more suitable for debugging complex cases than
966\api{sec:xer_fprint}{xer_fprint()}.
967
968\subsection*{Return values}
969
970\begin{tabular}[h!]{rl}
9710 & Output was successfully made \\
972-1 & Error printing out the structure
973\end{tabular}
974
975\subsection*{Example}
976\begin{example}
977Rectangle_t *rect = ...;
978asn_fprint(stdout, &asn_DEF_Rectangle, rect);
979\end{example}
980
981\subsection*{See also}
982\seealso{sec:xer_fprint}{xer_fprint()}.
983
Lev Walkin07f8c3e2017-11-15 00:21:51 -0800984\apisection{sec:asn_random_fill}{asn\_random\_fill()}
Lev Walkin9ce64c12017-11-07 06:22:14 -0800985
986\subsection*{Synopsis}
987\begin{signature}
988int asn_random_fill(
989 const asn_TYPE_descriptor_t *type_descriptor,
990 void **struct_ptr_ptr,/* Pointer to a target structure's ptr */
991 size_t approx_max_length_limit
992);
993\end{signature}
994
995\subsection*{Description}
996
997Create or initialize a structure with random contents, according to the type
998specification and optional member constraints.
999
Lev Walkind1c28aa2017-11-11 18:04:26 -08001000For best results the code should be generated without \cmd{-no-gen-PER}
1001option to \cmd{asn1c}. Making PER constraints code available in runtime
1002will make \code{asn_random_fill} explore the edges of PER-visible constraints
1003and sometimes break out of extensible contstraints' ranges.
Lev Walkin9ce64c12017-11-07 06:22:14 -08001004
1005The \code{asn_random_fill()} function has a bias to generate edge case
1006values. This property makes it useful for debugging the application level
1007code and for security testing, as random data can be a good seed to fuzzing.
1008
1009The \code{approx_max_length_limit} specifies the approximate limit of the
1010resulting structure in units closely resembling bytes. The actual result
1011might be several times larger or smaller than the given length limit.
1012A rule of thumb way to select the initial value for this parameter
1013is to take a typical structure and use twice its DER output size.
1014
1015\subsection*{Return values}
1016
1017\begin{tabular}[h!]{rl}
10180 & Structure was properly initialized with random data \\
1019-1 & Failure to initialize the structure with random data
1020\end{tabular}
1021
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001022\apisection{sec:ber_decode}{ber\_decode()}
Lev Walkin9ce64c12017-11-07 06:22:14 -08001023
1024\subsection*{Synopsis}
1025\begin{signature}
1026asn_dec_rval_t ber_decode(
1027 const asn_codec_ctx_t *opt_codec_ctx,
1028 const asn_TYPE_descriptor_t *type_descriptor,
1029 void **struct_ptr_ptr,/* Pointer to a target structure's ptr */
1030 const void *buffer, /* Data to be decoded */
1031 size_t size /* Size of that buffer */
1032);
1033\end{signature}
1034
1035\subsection*{Description}
1036
1037Decode BER, DER and CER data
1038(Basic Encoding Rules, Distinguished Encoding Rules, Canonical Encoding Rules),
1039as defined by ITU-T~X.690.
1040
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001041DER and CER are different subsets of BER.\newline
Lev Walkin9ce64c12017-11-07 06:22:14 -08001042
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001043\noindent\emph{Consider using a more generic function \api{sec:asn_decode}{asn_decode(ATS_BER)}.}
Lev Walkin9ce64c12017-11-07 06:22:14 -08001044
1045\subsection*{Return values}
1046\input{asn_dec_rval.inc}
1047
1048The \code{.consumed} value is in bytes.
1049
1050\subsection*{Restartability}
1051
1052The \code{ber_decode()} function is restartable (stream-oriented).
1053That means that in case the buffer has less data than expected,
1054the decoder will process whatever is available and ask for more data
1055to be provided using the RC\_WMORE return \code{.code}.
1056
1057Note that in the RC\_WMORE case the decoder may have processed less data than
1058it is available in the buffer, which means that you must be able to arrange
1059the next buffer to contain the unprocessed part of the previous buffer.
1060
1061\subsection*{See also}
1062\seealso{sec:der_encode}{der_encode()}.
1063
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001064\apisection{sec:der_encode}{der\_encode}
1065
1066\subsection*{Synopsis}
1067
1068\begin{signature}
1069asn_enc_rval_t der_encode(
1070 const asn_TYPE_descriptor_t *type_descriptor,
1071 const void *structure_to_encode,
1072 asn_app_consume_bytes_f *callback,
1073 void *callback_key
1074\end{signature}
1075
1076\subsection*{Description}
1077
1078The \code{der_encode()} function serializes the given \code{structure_to_encode} using the DER transfer syntax (a variant of BER, Basic Encoding Rules).
1079
1080During serialization, a user-specified \code{callback} is invoked zero
1081or more times with bytes of data to add to the output stream (if any), and
1082the \code{callback_key}. The signature for the callback is as follows:
1083
1084\begin{signature}
1085typedef int(asn_app_consume_bytes_f)(const void *buffer, size_t size, void *callback_key);
1086\end{signature}
1087
1088\noindent\emph{Consider using a more generic function \api{sec:asn_encode}{asn_encode(ATS_DER)}.}
1089
1090\subsection*{Return values}
1091\input{asn_enc_rval.inc}
1092
1093The serialized output size is returned in \textbf{bytes}.
1094
1095\subsection*{Example}
1096\begin{example}
1097static int
1098save_to_file(const void *data, size_t size, void *key) {
1099 FILE *fp = key;
1100 return (fwrite(data, 1, size, fp) == size) ? 0 : -1;
1101}
1102
1103Rectangle_t *rect = ...;
1104FILE *fp = ...;
1105asn_enc_rval_t er;
1106er = der_encode(&asn_DEF_Rectangle, rect, save_to_file, fp);
1107if(er.encoded == -1) {
1108 fprintf(stderr, "Failed to encode %\%%s\n", asn_DEF_Rectangle.name);
1109} else {
1110 fprintf(stderr, "%\%%s encoded in %\%%zd bytes\n", asn_DEF_Rectangle.name, er.encoded);
1111}
1112\end{example}
Lev Walkin9ce64c12017-11-07 06:22:14 -08001113
1114\subsection*{See also}
1115\seealso{sec:ber_decode}{ber_decode()},
1116\seealso{sec:asn_decode}{asn_decode(ATS_BER)}.
1117
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001118\apisection{sec:der_encode_to_buffer}{der\_encode\_to\_buffer()}
Lev Walkin9ce64c12017-11-07 06:22:14 -08001119
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001120\subsection*{Synopsis}
1121
1122\begin{signature}
1123asn_enc_rval_t der_encode_to_buffer(
1124 const asn_TYPE_descriptor_t *type_descriptor,
1125 const void *structure_to_encode,
1126 void *buffer, size_t buffer_size);
1127\end{signature}
1128
1129\subsection*{Description}
1130
1131The \code{der_encode_to_buffer()} function serializes the given \code{structure_to_encode} using the DER transfer syntax (a variant of BER, Basic Encoding Rules).
1132
1133The function places the serialized data into the given
1134\code{buffer} of size \code{buffer_size}.\newline
1135
1136\noindent\emph{Consider using a more generic function \api{sec:asn_encode_to_buffer}{asn_encode_to_buffer(ATS_DER)}.}
1137
1138\subsection*{Return values}
1139\input{asn_enc_rval.inc}
1140
1141The serialized output size is returned in \textbf{bytes}.
1142
1143The \code{.encoded} never exceeds the available buffer size.\footnote{This
1144behavior is different from \api{sec:asn_encode_to_buffer}{asn_encode_to_buffer()}.}
1145If the \code{buffer_size} is not sufficient, the \code{.encoded}
1146will be set to -1 and encoding would fail.
1147
1148\subsection*{Example}
1149\begin{example}
1150Rectangle_t *rect = ...;
1151uint8_t buffer[128];
1152asn_enc_rval_t er;
1153er = der_encode_to_buffer(&asn_DEF_Rectangle, rect, buffer, sizeof(buffer));
1154if(er.encoded == -1) {
1155 fprintf(stderr, "Serialization of %\%%s failed.\n", asn_DEF_Rectangle.name);
1156}
1157\end{example}
1158
1159\subsection*{See also}
1160\seealso{sec:ber_decode}{ber_decode()},
1161\seealso{sec:asn_decode}{asn_decode(ATS_BER)},
1162\seealso{sec:asn_encode_to_buffer}{asn_encode_to_buffer(ATS_DER)}.
1163
1164\apisection{sec:oer_decode}{oer\_decode()}
Lev Walkin9ce64c12017-11-07 06:22:14 -08001165
1166\subsection*{Synopsis}
1167\begin{signature}
1168asn_dec_rval_t oer_decode(
1169 const asn_codec_ctx_t *opt_codec_ctx,
1170 const asn_TYPE_descriptor_t *type_descriptor,
1171 void **struct_ptr_ptr,/* Pointer to a target structure's ptr */
1172 const void *buffer, /* Data to be decoded */
1173 size_t size /* Size of that buffer */
1174);
1175\end{signature}
1176
1177\subsection*{Description}
1178
1179Decode the BASIC-OER and CANONICAL-OER (Octet Encoding Rules),
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001180as defined by ITU-T~X.696.\newline
Lev Walkin9ce64c12017-11-07 06:22:14 -08001181
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001182\noindent\emph{Consider using a more generic function \api{sec:asn_decode}{asn_decode(ATS_BASIC_OER)}.}
Lev Walkin9ce64c12017-11-07 06:22:14 -08001183
1184\subsection*{Return values}
1185\input{asn_dec_rval.inc}
1186
1187The \code{.consumed} value is in bytes.
1188
1189\subsection*{Restartability}
1190
1191The \code{oer_decode()} function is restartable (stream-oriented).
1192That means that in case the buffer has less data than expected,
1193the decoder will process whatever is available and ask for more data
1194to be provided using the RC\_WMORE return \code{.code}.
1195
1196Note that in the RC\_WMORE case the decoder may have processed less data than
1197it is available in the buffer, which means that you must be able to arrange
1198the next buffer to contain the unprocessed part of the previous buffer.
1199
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001200\apisection{sec:oer_encode}{oer\_encode()}
Lev Walkin9ce64c12017-11-07 06:22:14 -08001201
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001202\subsection*{Synopsis}
1203
1204\begin{signature}
1205asn_enc_rval_t oer_encode(
1206 const asn_TYPE_descriptor_t *type_descriptor,
1207 const void *structure_to_encode,
1208 asn_app_consume_bytes_f *callback,
1209 void *callback_key);
1210\end{signature}
1211
1212\subsection*{Description}
1213
1214The \code{oer_encode()} function serializes the given \code{structure_to_encode} using the CANONICAL-OER transfer syntax (Octet Encoding Rules, ITU-T~X.691).
1215
1216During serialization, a user-specified \code{callback} is invoked zero
1217or more times with bytes of data to add to the output stream (if any), and
1218the \code{callback_key}. The signature for the callback is as follows:
1219
1220\begin{signature}
1221typedef int(asn_app_consume_bytes_f)(const void *buffer, size_t size, void *callback_key);
1222\end{signature}
1223
1224\noindent\emph{Consider using a more generic function \api{sec:asn_encode}{asn_encode(ATS_CANONICAL_OER)}.}
1225
1226\subsection*{Return values}
1227\input{asn_enc_rval.inc}
1228
1229The serialized output size is returned in \textbf{bytes}.
1230
1231\subsection*{Example}
1232\begin{example}
1233static int
1234save_to_file(const void *data, size_t size, void *key) {
1235 FILE *fp = key;
1236 return (fwrite(data, 1, size, fp) == size) ? 0 : -1;
1237}
1238
1239Rectangle_t *rect = ...;
1240FILE *fp = ...;
1241asn_enc_rval_t er;
1242er = oer_encode(&asn_DEF_Rectangle, rect, save_to_file, fp);
1243if(er.encoded == -1) {
1244 fprintf(stderr, "Failed to encode %\%%s\n", asn_DEF_Rectangle.name);
1245} else {
1246 fprintf(stderr, "%\%%s encoded in %\%%zd bytes\n", asn_DEF_Rectangle.name, er.encoded);
1247}
1248\end{example}
1249
1250\subsection*{See also}
1251\seealso{sec:asn_encode}{asn_encode(ATS_CANONICAL_OER)}.
1252
1253\apisection{sec:oer_encode_to_buffer}{oer\_encode\_to\_buffer()}
1254
1255\subsection*{Synopsis}
1256
1257\begin{signature}
1258asn_enc_rval_t oer_encode_to_buffer(
1259 const asn_TYPE_descriptor_t *type_descriptor,
1260 const asn_oer_constraints_t *constraints,
1261 const void *structure_to_encode,
1262 void *buffer, size_t buffer_size);
1263\end{signature}
1264
1265\subsection*{Description}
1266
1267The \code{oer_encode_to_buffer()} function serializes the given \code{structure_to_encode} using the CANONICAL-OER transfer syntax (Octet Encoding Rules, ITU-T~X.691).
1268
1269The function places the serialized data into the given
1270\code{buffer} of size \code{buffer_size}.\newline
1271
1272\noindent\emph{Consider using a more generic function \api{sec:asn_encode_to_buffer}{asn_encode_to_buffer(ATS_CANONICAL_OER)}.}
1273
1274\subsection*{Return values}
1275\input{asn_enc_rval.inc}
1276
1277The serialized output size is returned in \textbf{bytes}.
1278
1279The \code{.encoded} never exceeds the available buffer size.\footnote{This
1280behavior is different from \api{sec:asn_encode_to_buffer}{asn_encode_to_buffer()}.}
1281If the \code{buffer_size} is not sufficient, the \code{.encoded}
1282will be set to -1 and encoding would fail.
1283
1284\subsection*{Example}
1285\begin{example}
1286Rectangle_t *rect = ...;
1287uint8_t buffer[128];
1288asn_enc_rval_t er;
1289er = oer_encode_to_buffer(&asn_DEF_Rectangle, 0, rect, buffer, sizeof(buffer));
1290if(er.encoded == -1) {
1291 fprintf(stderr, "Serialization of %\%%s failed.\n", asn_DEF_Rectangle.name);
1292}
1293\end{example}
1294
1295\subsection*{See also}
1296\seealso{sec:ber_decode}{ber_decode()},
1297\seealso{sec:asn_decode}{asn_decode(ATS_BER)},
1298\seealso{sec:asn_encode_to_buffer}{asn_encode_to_buffer(ATS_DER)}.
1299
1300\apisection{sec:uper_decode}{uper\_decode()}
Lev Walkin9ce64c12017-11-07 06:22:14 -08001301
1302\subsection*{Synopsis}
1303
1304\begin{signature}
1305asn_dec_rval_t uper_decode(
1306 const asn_codec_ctx_t *opt_codec_ctx,
1307 const asn_TYPE_descriptor_t *type_descriptor,
1308 void **struct_ptr_ptr,/* Pointer to a target structure's ptr */
1309 const void *buffer, /* Data to be decoded */
1310 size_t size, /* Size of the input data buffer, bytes */
1311 int skip_bits, /* Number of unused leading bits, 0..7 */
1312 int unused_bits /* Number of unused tailing bits, 0..7 */
1313);
1314\end{signature}
1315
1316\subsection*{Description}
1317
1318Decode the Unaligned BASIC or CANONICAL PER (Packed Encoding Rules),
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001319as defined by ITU-T~X.691.\newline
Lev Walkin9ce64c12017-11-07 06:22:14 -08001320
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001321\noindent\emph{Consider using a more generic function \api{sec:asn_decode}{asn_decode(ATS_UNALIGNED_BASIC_PER)}.}
Lev Walkin9ce64c12017-11-07 06:22:14 -08001322
1323\subsection*{Return values}
1324\input{asn_dec_rval.inc}
1325Note that the \code{.consumed} value is in bits.
1326Use \code{(.consumed+7)/8} to convert to bytes.
1327
1328\subsection*{Restartability}
1329The \code{uper_decode()} function is not restartable.
1330Failures are final.
1331
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001332\apisection{sec:uper_decode_complete}{uper\_decode\_complete()}
Lev Walkin9ce64c12017-11-07 06:22:14 -08001333
1334\subsection*{Synopsis}
1335
1336\begin{signature}
1337asn_dec_rval_t uper_decode_complete(
1338 const asn_codec_ctx_t *opt_codec_ctx,
1339 const asn_TYPE_descriptor_t *type_descriptor,
1340 void **struct_ptr_ptr,/* Pointer to a target structure's ptr */
1341 const void *buffer, /* Data to be decoded */
1342 size_t size /* Size of data buffer */
1343);
1344\end{signature}
1345
1346\subsection*{Description}
1347
1348Decode a ``Production of a complete encoding'',
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001349according to ITU-T~X.691 (08/2015) \#11.1.\newline
Lev Walkin9ce64c12017-11-07 06:22:14 -08001350
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001351\noindent\emph{Consider using a more generic function \api{sec:asn_decode}{asn_decode(ATS_UNALIGNED_BASIC_PER)}.}
Lev Walkin9ce64c12017-11-07 06:22:14 -08001352
1353\subsection*{Return values}
1354\input{asn_dec_rval.inc}
1355
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001356The the \code{.consumed} value is returned in whole \emph{bytes} (NB).
Lev Walkin9ce64c12017-11-07 06:22:14 -08001357
1358\subsection*{Restartability}
1359The \code{uper_decode_complete()} function is not restartable.
1360Failures are final.
1361
1362The complete encoding contains at least one byte, so on success
1363\code{.consumed} will be greater or equal to 1.
1364
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001365\apisection{sec:uper_encode}{uper\_encode()}
1366\apisection{sec:uper_encode_to_buffer}{uper\_encode\_to\_buffer()}
1367\apisection{sec:uper_encode_to_new_buffer}{uper\_encode\_to\_new\_buffer()}
1368\apisection{sec:xer_decode}{xer\_decode()}
Lev Walkin9ce64c12017-11-07 06:22:14 -08001369
1370\subsection*{Synopsis}
1371
1372\begin{signature}
1373asn_dec_rval_t xer_decode(
1374 const asn_codec_ctx_t *opt_codec_ctx,
1375 const asn_TYPE_descriptor_t *type_descriptor,
1376 void **struct_ptr_ptr,/* Pointer to a target structure's ptr */
1377 const void *buffer, /* Data to be decoded */
1378 size_t size /* Size of data buffer */
1379);
1380\end{signature}
1381
1382\subsection*{Description}
1383
1384Decode the BASIC-XER and CANONICAL-XER (XML Encoding Rules) encoding,
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001385as defined by ITU-T~X.693.\newline
Lev Walkin9ce64c12017-11-07 06:22:14 -08001386
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001387\noindent\emph{Consider using a more generic function \api{sec:asn_decode}{asn_decode(ATS_BASIC_XER)}.}
Lev Walkin9ce64c12017-11-07 06:22:14 -08001388
1389\subsection*{Return values}
1390\input{asn_dec_rval.inc}
1391
1392The \code{.consumed} value is in bytes.
1393
1394\subsection*{Restartability}
1395
1396The \code{xer_decode()} function is restartable (stream-oriented).
1397That means that in case the buffer has less data than expected,
1398the decoder will process whatever is available and ask for more data
1399to be provided using the RC\_WMORE return \code{.code}.
1400
1401Note that in the RC\_WMORE case the decoder may have processed less data than
1402it is available in the buffer, which means that you must be able to arrange
1403the next buffer to contain the unprocessed part of the previous buffer.
1404
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001405\apisection{sec:xer_encode}{xer\_encode()}
1406
1407\subsection*{Synopsis}
1408
1409\begin{signature}
1410enum xer_encoder_flags_e {
1411 /* Mode of encoding */
1412 XER_F_BASIC = 0x01, /* BASIC-XER (pretty-printing) */
1413 XER_F_CANONICAL = 0x02 /* Canonical XER (strict rules) */
1414};
1415asn_enc_rval_t xer_encode(
1416 const asn_TYPE_descriptor_t *type_descriptor,
1417 const void *structure_to_encode,
1418 enum xer_encoder_flags_e xer_flags,
1419 asn_app_consume_bytes_f *callback,
1420 void *callback_key);
1421\end{signature}
1422
1423\subsection*{Description}
1424
1425The \code{xer_encode()} function serializes the given \code{structure_to_encode} using the BASIC-XER or CANONICAL-XER transfer syntax (XML Encoding Rules, ITU-T~X.693).
1426
1427During serialization, a user-specified \code{callback} is invoked zero
1428or more times with bytes of data to add to the output stream (if any), and
1429the \code{callback_key}. The signature for the callback is as follows:
1430
1431\begin{signature}
1432typedef int(asn_app_consume_bytes_f)(const void *buffer, size_t size, void *callback_key);
1433\end{signature}
1434
1435\noindent\emph{Consider using a more generic function \api{sec:asn_encode}{asn_encode()} with \texttt{ATS\_BASIC\_XER} or \texttt{ATS\_CANONICAL\_XER} transfer syntax option.}
1436
1437\subsection*{Return values}
1438\input{asn_enc_rval.inc}
1439
1440The serialized output size is returned in \textbf{bytes}.
1441
1442\subsection*{Example}
1443\begin{example}
1444static int
1445save_to_file(const void *data, size_t size, void *key) {
1446 FILE *fp = key;
1447 return (fwrite(data, 1, size, fp) == size) ? 0 : -1;
1448}
1449
1450Rectangle_t *rect = ...;
1451FILE *fp = ...;
1452asn_enc_rval_t er;
1453er = xer_encode(&asn_DEF_Rectangle, rect, XER_F_CANONICAL, save_to_file, fp);
1454if(er.encoded == -1) {
1455 fprintf(stderr, "Failed to encode %\%%s\n", asn_DEF_Rectangle.name);
1456} else {
1457 fprintf(stderr, "%\%%s encoded in %\%%zd bytes\n", asn_DEF_Rectangle.name, er.encoded);
1458}
1459\end{example}
1460
1461\subsection*{See also}
1462\seealso{sec:xer_fprint}{xer_fprint()}.
1463
1464\apisection{sec:xer_fprint}{xer\_fprint()}
Lev Walkin9ce64c12017-11-07 06:22:14 -08001465
1466\subsection*{Synopsis}
1467\begin{signature}
1468int xer_fprint(FILE *stream, /* Destination file */
1469 const asn_TYPE_descriptor_t *type_descriptor,
1470 const void *struct_ptr /* Structure to be printed */
1471);
1472\end{signature}
1473
1474\subsection*{Description}
1475
1476The \code{xer_fprint()} function outputs XML-based serialization
1477of the given structure into the file stream specified by
1478\code{stream} pointer.
1479
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001480The output conforms to a BASIC-XER transfer syntax, as defined by ITU-T~X.693.
Lev Walkin9ce64c12017-11-07 06:22:14 -08001481
1482\subsection*{Return values}
1483
1484\begin{tabular}[h!]{rl}
14850 & XML output was successfully made \\
1486-1 & Error printing out the structure
1487\end{tabular}
1488
1489\noindent{}Since the \code{xer_fprint()} function attempts to produce a conforming output,
1490it will likely break on partial structures by writing incomplete data
1491to the output stream and returning -1. This makes it less suitable for
1492debugging complex cases than \api{sec:asn_fprint}{asn_fprint()}.
1493
1494\subsection*{Example}
1495\begin{example}
1496Rectangle_t *rect = ...;
1497xer_fprint(stdout, &asn_DEF_Rectangle, rect);
1498\end{example}
1499
1500\subsection*{See also}
1501\seealso{sec:asn_fprint}{asn_fprint()}.
Lev Walkind5627a12017-11-07 01:04:40 -08001502
1503\chapter{API usage examples}
1504
1505Let's start with including the necessary header files into your
1506application. Normally it is enough to include the header file of
1507the main PDU type. For our \emph{Rectangle} module, including the \emph{Rectangle.h} file is sufficient:
1508\begin{codesample}
1509#include <Rectangle.h>
1510\end{codesample}
1511The header files defines a C structure corresponding to the ASN.1
1512definition of a rectangle and the declaration of the ASN.1
1513\emph{type descriptor}. A type descriptor is a special globally accessible
1514object which is used as an argument to most of the API functions provided by
1515the ASN.1 codec. A type descriptor starts with \emph{asn\_DEF\_\ldots{}}. For example, here is the code which frees the Rectangle\_t structure:
1516\begin{codesample}
1517Rectangle_t *rect = ...;
1518
1519ASN_STRUCT_FREE(%\textbf{asn\_DEF\_}%Rectangle, rect);
1520\end{codesample}
1521This code defines a \emph{rect} pointer which points to the Rectangle\_t
1522structure which needs to be freed. The second line uses a generic
Lev Walkin9ce64c12017-11-07 06:22:14 -08001523\api{sec:ASN_STRUCT_FREE}{ASN\_STRUCT\_FREE()} macro which invokes the memory deallocation routine
Lev Walkind5627a12017-11-07 01:04:40 -08001524created specifically for this Rectangle\_t structure.
1525The \emph{asn\_DEF\_Rectangle} is the type descriptor which holds
1526a collection of routines and operations defined for the Rectangle\_t structure.
1527
1528\section{\label{sec:Generic-Encoding}Generic encoders and decoders}
1529
1530Before we start describing specific encoders and decoders, let's step back
1531a little and check out a simple high level way.
1532
Lev Walkin9ce64c12017-11-07 06:22:14 -08001533The 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 -08001534
1535\begin{codesample}[basicstyle=\scriptsize\listingfont]
1536/*
1537 * A selection of ASN.1 Transfer Syntaxes to use with generalized encoders and decoders.
1538 */
1539enum asn_transfer_syntax {
1540 ATS_INVALID,
1541 ATS_NONSTANDARD_PLAINTEXT,
1542 ATS_BER,
1543 ATS_DER,
1544 ATS_CER,
1545 ATS_BASIC_OER,
1546 ATS_CANONICAL_OER,
1547 ATS_UNALIGNED_BASIC_PER,
1548 ATS_UNALIGNED_CANONICAL_PER,
1549 ATS_BASIC_XER,
1550 ATS_CANONICAL_XER,
1551};
1552\end{codesample}
1553
1554Using this encoding selector, encoding and decoding becomes very generic:
1555
1556\noindent{}Encoding:
1557
1558\begin{codesample}[basicstyle=\scriptsize\listingfont]
1559uint8_t buffer[128];
1560size_t buf_size = sizeof(buffer);
1561asn_enc_rval_t er;
1562
1563er = %\textbf{asn\_encode\emph{\_to\_buffer}}%(0, %\textbf{ATS\_DER}%, &asn_DEF_Rectangle, buffer, buf_size);
1564
1565if(er.encoded > buf_size) {
1566 fprintf(stderr, "Buffer of size %\%%zu is too small for %\%%s, need %\%%zu\n",
1567 buf_size, asn_DEF_Rectangle.name, er.encoded);
1568}
1569\end{codesample}
1570
1571\noindent{}Decoding:
1572
1573\begin{codesample}[basicstyle=\scriptsize\listingfont]
1574Rectangle_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.}!}% */
1575
1576... = %\textbf{asn\_decode}%(0, %\textbf{ATS\_BER}%, &asn_DEF_Rectangle, (void **)%$\underbracket{\textrm{\listingfont \&rect}}$%, buffer, buf_size);
1577\end{codesample}
1578
1579\section{\label{sec:Decoding-BER}Decoding BER}
1580
1581The Basic Encoding Rules describe the most widely used (by the ASN.1
1582community) way to encode and decode a given structure in a machine-independent
1583way. Several other encoding rules (CER, DER) define a more restrictive
1584versions of BER, so the generic BER parser is also capable of decoding
1585the data encoded by the CER and DER encoders. The opposite is not true.
1586
1587\emph{The ASN.1 compiler provides the generic BER decoder which is
1588capable of decoding BER, CER and DER encoded data.}
1589
Lev Walkin9ce64c12017-11-07 06:22:14 -08001590The decoder is restartable (stream-oriented).
1591That means that in case the buffer has less data than expected,
1592the decoder will process whatever is available and ask for more data
1593to be provided using the RC\_WMORE return \code{.code}.
1594
1595Note that in the RC\_WMORE case the decoder may have processed less data than
1596it is available in the buffer, which means that you must be able to arrange
1597the next buffer to contain the unprocessed part of the previous buffer.
Lev Walkind5627a12017-11-07 01:04:40 -08001598
1599Suppose, you have two buffers of encoded data: 100 bytes and 200 bytes.
1600\begin{itemize}
1601\item You can concatenate these buffers and feed the BER decoder with 300
1602bytes of data, or
1603\item You can feed it the first buffer of 100 bytes of data, realize that
1604the ber\_decoder consumed only 95 bytes from it and later feed the
1605decoder with 205 bytes buffer which consists of 5 unprocessed bytes
1606from the first buffer and the additional 200 bytes from the second
1607buffer.
1608\end{itemize}
1609This is not as convenient as it could be (the BER encoder could
1610consume the whole 100 bytes and keep these 5 bytes in some temporary
1611storage), but in case of existing stream based processing it might
1612actually fit well into existing algorithm. Suggestions are welcome.
1613
1614Here is the example of BER decoding of a simple structure:
1615
1616\begin{codesample}
1617Rectangle_t *
1618simple_deserializer(const void *buffer, size_t buf_size) {
1619 asn_dec_rval_t rval;
1620 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.}!}% */
1621
1622 rval = %\textbf{asn\_DEF\_Rectangle.op->ber\_decoder}%(0,
1623 &asn_DEF_Rectangle,
1624 (void **)%$\underbracket{\textrm{\listingfont \&rect}}$%, /* Decoder %\emph{changes}% the pointer */
1625 buffer, buf_size, 0);
1626
1627 if(rval%\textbf{.code}% == RC_OK) {
1628 return rect; /* Decoding succeeded */
1629 } else {
1630 /* Free the partially decoded rectangle */
1631 ASN_STRUCT_FREE(asn_DEF_Rectangle, rect);
1632 return 0;
1633 }
1634}
1635\end{codesample}
1636
1637The code above defines a function, \emph{simple\_deserializer}, which
1638takes a buffer and its length and is expected to return a pointer
1639to the Rectangle\_t structure. Inside, it tries to convert the bytes
1640passed into the target structure (rect) using the BER decoder and
1641returns the rect pointer afterwards. If the structure cannot be deserialized,
1642it frees the memory which might be left allocated by the unfinished
1643\emph{ber\_decoder} routine and returns 0 (no data). (This \textbf{freeing
1644is necessary} because the ber\_decoder is a restartable procedure,
1645and may fail just because there is more data needs to be provided
1646before decoding could be finalized). The code above obviously does
1647not take into account the way the \emph{ber\_decoder()} failed, so
1648the freeing is necessary because the part of the buffer may already
1649be decoded into the structure by the time something goes wrong.
1650
1651A little less wordy would be to invoke a globally available \emph{ber\_decode()}
1652function instead of dereferencing the asn\_DEF\_Rectangle type descriptor:
1653\begin{codesample}
1654rval = ber_decode(0, &asn_DEF_Rectangle, (void **)&rect, buffer, buf_size);
1655\end{codesample}
1656Note that the initial (asn\_DEF\_Rectangle.op->ber\_decoder) reference
1657is gone, and also the last argument (0) is no longer necessary.
1658
1659These two ways of BER decoder invocations are fully equivalent.
1660
1661The BER de\emph{coder} may fail because of (\emph{the following RC\_\ldots{}
1662codes are defined in ber\_decoder.h}):
1663\begin{itemize}
1664\item RC\_WMORE: There is more data expected than it is provided (stream
1665mode continuation feature);
1666\item RC\_FAIL: General failure to decode the buffer;
1667\item \ldots{} other codes may be defined as well.
1668\end{itemize}
1669Together with the return code (.code) the asn\_dec\_rval\_t type contains
1670the number of bytes which is consumed from the buffer. In the previous
1671hypothetical example of two buffers (of 100 and 200 bytes), the first
1672call to ber\_decode() would return with .code = RC\_WMORE and .consumed
1673= 95. The .consumed field of the BER decoder return value is \textbf{always}
1674valid, even if the decoder succeeds or fails with any other return
1675code.
1676
1677Look into ber\_decoder.h for the precise definition of ber\_decode()
1678and related types.
1679
1680
1681\section{\label{sec:Encoding-DER}Encoding DER}
1682
1683The Distinguished Encoding Rules is the \emph{canonical} variant of
1684BER encoding rules. The DER is best suited to encode the structures
1685where all the lengths are known beforehand. This is probably exactly
1686how you want to encode: either after a BER decoding or after a manual
1687fill-up, the target structure contains the data which size is implicitly
1688known before encoding. Among other uses, the DER encoding is used
1689to encode X.509 certificates.
1690
1691As with BER decoder, the DER encoder may be invoked either directly
1692from the ASN.1 type descriptor (asn\_DEF\_Rectangle) or from the stand-alone
1693function, which is somewhat simpler:
1694\begin{codesample}
1695/*
1696 * This is the serializer itself.
1697 * It supplies the DER encoder with the
1698 * pointer to the custom output function.
1699 */
1700ssize_t
1701simple_serializer(FILE *ostream, Rectangle_t *rect) {
1702 asn_enc_rval_t er; /* Encoder return value */
1703
1704 er = der_encode(&asn_DEF_Rect, rect, write_stream, ostream);
1705 if(er%\textbf{.encoded}% == -1) {
1706 fprintf(stderr, "Cannot encode %\%%s: %\%%s\n",
1707 er%\textbf{.failed\_type}%->name, strerror(errno));
1708 return -1;
1709 } else {
1710 /* Return the number of bytes */
1711 return er.encoded;
1712 }
1713}
1714\end{codesample}
1715As you see, the DER encoder does not write into some sort of buffer.
1716It just invokes the custom function (possible, multiple
1717times) which would save the data into appropriate storage. The optional
1718argument \emph{app\_key} is opaque for the DER encoder code and just
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001719used by \emph{write\_stream()} as the pointer to the appropriate
Lev Walkind5627a12017-11-07 01:04:40 -08001720output stream to be used.
1721
1722If the custom write function is not given (passed as 0), then the
1723DER encoder will essentially do the same thing (i.~e., encode the data)
1724but no callbacks will be invoked (so the data goes nowhere). It may
1725prove useful to determine the size of the structure's encoding before
1726actually doing the encoding%
1727\footnote{It is actually faster too: the encoder might skip over some computations
1728which aren't important for the size determination.%
1729}.
1730
1731Look into der\_encoder.h for the precise definition of der\_encode()
1732and related types.
1733
1734
1735\section{\label{sec:Encoding-XER}Encoding XER}
1736
1737The XER stands for XML Encoding Rules, where XML, in turn, is eXtensible
1738Markup Language, a text-based format for information exchange. The
1739encoder routine API comes in two flavors: stdio-based and callback-based.
1740With the callback-based encoder, the encoding process is very similar
1741to the DER one, described in \fref{sec:Encoding-DER}. The
1742following example uses the definition of write\_stream() from up there.
1743\begin{codesample}
1744/*
1745 * This procedure generates an XML document
1746 * by invoking the XER encoder.
1747 * NOTE: Do not copy this code verbatim!
1748 * If the stdio output is necessary,
1749 * use the xer_fprint() procedure instead.
1750 * See %\fref{sec:Printing-the-target}%.
1751 */
1752int
1753print_as_XML(FILE *ostream, Rectangle_t *rect) {
1754 asn_enc_rval_t er; /* Encoder return value */
1755
1756 er = xer_encode(&asn_DEF_Rectangle, rect,
1757 XER_F_BASIC, /* BASIC-XER or CANONICAL-XER */
1758 write_stream, ostream);
1759
1760 return (er.encoded == -1) ? -1 : 0;
1761}
1762\end{codesample}
1763Look into xer\_encoder.h for the precise definition of xer\_encode()
1764and related types.
1765
1766See \fref{sec:Printing-the-target} for the example of stdio-based
1767XML encoder and other pretty-printing suggestions.
1768
1769
1770\section{\label{sec:Decoding-XER}Decoding XER}
1771
1772The data encoded using the XER rules can be subsequently decoded using
1773the xer\_decode() API call:
1774\begin{codesample}
1775Rectangle_t *
1776XML_to_Rectangle(const void *buffer, size_t buf_size) {
1777 asn_dec_rval_t rval;
1778 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.}!}% */
1779
1780 rval = xer_decode(0, &asn_DEF_Rectangle, (void **)&rect, buffer, buf_size);
1781
1782 if(rval%\textbf{.code}% == RC_OK) {
1783 return rect; /* Decoding succeeded */
1784 } else {
1785 /* Free partially decoded rect */
1786 ASN_STRUCT_FREE(asn_DEF_Rectangle, rect);
1787 return 0;
1788 }
1789}
1790\end{codesample}
1791The decoder takes both BASIC-XER and CANONICAL-XER encodings.
1792
1793The decoder shares its data consumption properties with BER decoder;
1794please read the \fref{sec:Decoding-BER} to know more.
1795
1796Look into xer\_decoder.h for the precise definition of xer\_decode()
1797and related types.
1798
1799
1800\section{\label{sec:Validating-the-target}Validating the target structure}
1801
1802Sometimes the target structure needs to be validated. For example,
1803if the structure was created by the application (as opposed to being
1804decoded from some external source), some important information required
1805by the ASN.1 specification might be missing. On the other hand, the
1806successful decoding of the data from some external source does not
1807necessarily mean that the data is fully valid either. It might well
1808be the case that the specification describes some subtype constraints
1809that were not taken into account during decoding, and it would actually
1810be useful to perform the last check when the data is ready to be encoded
1811or when the data has just been decoded to ensure its validity according
1812to some stricter rules.
1813
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001814The \api{sec:asn_check_constraints}{asn_check_constraints()}
1815function checks the type for various
1816implicit and explicit constraints. It is recommended to use the
1817\code{asn_check_constraints()}
Lev Walkind5627a12017-11-07 01:04:40 -08001818function after each decoding and before each encoding.
1819
Lev Walkind5627a12017-11-07 01:04:40 -08001820\section{\label{sec:Printing-the-target}Printing the target structure}
1821
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001822To print out the structure for debugging purposes, use the
1823\api{sec:asn_fprint}{asn_fprint()} function:
Lev Walkind5627a12017-11-07 01:04:40 -08001824\begin{codesample}
1825asn_fprint(stdout, &asn_DEF_Rectangle, rect);
1826\end{codesample}
Lev Walkind5627a12017-11-07 01:04:40 -08001827
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001828A practical alternative to this custom format printing is to serialize
1829the structure into XML. The default BASIC-XER encoder performs reasonable
1830formatting for the output to be both useful and human readable.
1831Use the \api{sec:xer_fprint}{xer_fprint()} function:
Lev Walkind5627a12017-11-07 01:04:40 -08001832\begin{codesample}
1833xer_fprint(stdout, &asn_DEF_Rectangle, rect);
1834\end{codesample}
1835See \fref{sec:Encoding-XER} for XML-related details.
1836
Lev Walkind5627a12017-11-07 01:04:40 -08001837\section{\label{sec:Freeing-the-target}Freeing the target structure}
1838
Lev Walkin07f8c3e2017-11-15 00:21:51 -08001839Freeing the structure is slightly more complex than it may seem.
Lev Walkind5627a12017-11-07 01:04:40 -08001840When the ASN.1 structure is freed, all the members of the structure
1841and their submembers are recursively freed as well.
1842The ASN\_STRUCT\_FREE() macro helps with that.
1843
1844But it might not always be feasible to free the whole structure.
1845In the following example, the application programmer defines a custom
1846structure with one ASN.1-derived member (rect).
1847\begin{codesample}
1848struct my_figure { /* The custom structure */
1849 int flags; /* <some custom member> */
1850 /* The type is generated by the ASN.1 compiler */
1851 Rectangle_t rect;
1852 /* other members of the structure */
1853};
1854\end{codesample}
1855This member is not a reference to the Rectangle\_t, but an in-place inclusion
1856of the Rectangle\_t structure.
1857If there's a need to free the \code{rect} member, the usual procedure of
1858freeing everything must not be applied to the \code{\&rect} pointer itself,
1859because it does not point to the beginning of memory block allocated by
1860the memory allocation routine, but instead lies within a block allocated for
1861the my\_figure structure.
1862
1863To solve this problem, in addition to ASN\_STRUCT\_FREE() macro, the asn1c
1864skeletons define the ASN\_STRUCT\_RESET() macro which doesn't free the passed
1865pointer and instead resets the structure into the clean and safe state.
1866\begin{codesample}
1867/* %\textbf{1. Rectangle\_t is defined within my\_figure}% */
1868struct my_figure {
1869 Rectangle_t rect;
1870} *mf = ...;
1871/*
1872 * Freeing the Rectangle_t
1873 * without freeing the mf->rect area.
1874 */
1875ASN_STRUCT_RESET(asn_DEF_Rectangle, &mf->rect);
1876
1877/* %\textbf{2. Rectangle\_t is a stand-alone pointer}% */
1878Rectangle_t *rect = ...;
1879/*
1880 * Freeing the Rectangle_t
1881 * and freeing the rect pointer.
1882 */
1883ASN_STRUCT_FREE(asn_DEF_Rectangle, rect);
1884\end{codesample}
1885It is safe to invoke both macros with the target structure pointer
1886set to 0 (NULL). In this case, the function will do nothing.
1887
1888\chapter{\label{chap:Abstract-Syntax-Notation}Abstract Syntax Notation: ASN.1}
Lev Walkined44bf42010-11-08 02:04:55 -08001889
1890\emph{This chapter defines some basic ASN.1 concepts and describes
1891several most widely used types. It is by no means an authoritative
1892or complete reference. For more complete ASN.1 description, please
1893refer to Olivier Dubuisson's book \cite{Dub00} or the ASN.1 body
1894of standards itself \cite{ITU-T/ASN.1}.}
1895
1896The Abstract Syntax Notation One is used to formally describe the
Lev Walkin507f6002014-10-26 20:22:16 -07001897data transmitted across the network. Two communicating parties may employ
1898different formats of their native data types (e.~g., different number
1899of bits for the native integer type), thus it is important to have
Lev Walkined44bf42010-11-08 02:04:55 -08001900a way to describe the data in a manner which is independent from the
Lev Walkin507f6002014-10-26 20:22:16 -07001901particular machine's representation.
1902The ASN.1 specifications are used to achieve the following:
Lev Walkined44bf42010-11-08 02:04:55 -08001903\begin{itemize}
1904\item The specification expressed in the ASN.1 notation is a formal and
Lev Walkin507f6002014-10-26 20:22:16 -07001905precise way to communicate the structure of data to human readers;
Lev Walkined44bf42010-11-08 02:04:55 -08001906\item The ASN.1 specifications may be used as input for automatic compilers
1907which produce the code for some target language (C, C++, Java, etc)
Lev Walkin507f6002014-10-26 20:22:16 -07001908to encode and decode the data according to some encoding formats.
1909Several such encoding formats (called Transfer Encoding Rules)
1910have been defined by the ASN.1 standard.
Lev Walkined44bf42010-11-08 02:04:55 -08001911\end{itemize}
1912Consider the following example:
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001913\begin{asn}
1914Rectangle ::= SEQUENCE {
1915 height INTEGER,
1916 width INTEGER
1917}
1918\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001919This ASN.1 specification describes a constructed type, \emph{Rectangle},
1920containing two integer fields. This specification may tell the reader
1921that there exists this kind of data structure and that some entity
1922may be prepared to send or receive it. The question on \emph{how}
1923that entity is going to send or receive the \emph{encoded data} is
1924outside the scope of ASN.1. For example, this data structure may be
1925encoded according to some encoding rules and sent to the destination
1926using the TCP protocol. The ASN.1 specifies several ways of encoding
Lev Walkin464166c2010-11-09 08:34:38 -08001927(or ``serializing'', or ``marshaling'') the data: BER, PER, XER
Lev Walkined44bf42010-11-08 02:04:55 -08001928and others, including CER and DER derivatives from BER.
1929
1930The complete specification must be wrapped in a module, which looks
1931like this:
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001932\begin{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001933RectangleModule1
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001934 { iso org(3) dod(6) internet(1) private(4)
1935 enterprise(1) spelio(9363) software(1)
1936 asn1c(5) docs(2) rectangle(1) 1 }
1937 DEFINITIONS AUTOMATIC TAGS ::=
Lev Walkined44bf42010-11-08 02:04:55 -08001938BEGIN
1939
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001940-- This is a comment which describes nothing.
1941Rectangle ::= SEQUENCE {
1942 height INTEGER, -- Height of the rectangle
1943 width INTEGER -- Width of the rectangle
1944}
Lev Walkined44bf42010-11-08 02:04:55 -08001945
1946END
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001947\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001948The module header consists of module name (RectangleModule1), the
Lev Walkin464166c2010-11-09 08:34:38 -08001949module object identifier (\{...\}), a keyword ``DEFINITIONS'', a
1950set of module flags (AUTOMATIC TAGS) and ``::= BEGIN''. The module
1951ends with an ``END'' statement.
Lev Walkined44bf42010-11-08 02:04:55 -08001952
1953
1954\section{Some of the ASN.1 Basic Types}
1955
1956
1957\subsection{The BOOLEAN type}
1958
1959The BOOLEAN type models the simple binary TRUE/FALSE, YES/NO, ON/OFF
1960or a similar kind of two-way choice.
1961
1962
1963\subsection{The INTEGER type}
1964
1965The INTEGER type is a signed natural number type without any restrictions
1966on its size. If the automatic checking on INTEGER value bounds are
1967necessary, the subtype constraints must be used.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001968\begin{asn}
1969SimpleInteger ::= INTEGER
Lev Walkined44bf42010-11-08 02:04:55 -08001970
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001971-- An integer with a very limited range
1972SmallPositiveInt ::= INTEGER (0..127)
Lev Walkined44bf42010-11-08 02:04:55 -08001973
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001974-- Integer, negative
1975NegativeInt ::= INTEGER (MIN..0)
1976\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001977
1978\subsection{The ENUMERATED type}
1979
1980The ENUMERATED type is semantically equivalent to the INTEGER type
1981with some integer values explicitly named.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001982\begin{asn}
1983FruitId ::= ENUMERATED { apple(1), orange(2) }
Lev Walkined44bf42010-11-08 02:04:55 -08001984
Lev Walkin11c9a8c2013-03-26 00:46:55 -07001985-- The numbers in braces are optional,
1986-- the enumeration can be performed
1987-- automatically by the compiler
1988ComputerOSType ::= ENUMERATED {
1989 FreeBSD, -- acquires value 0
1990 Windows, -- acquires value 1
1991 Solaris(5), -- remains 5
1992 Linux, -- becomes 6
1993 MacOS -- becomes 7
1994}
1995\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08001996
1997\subsection{The OCTET STRING type}
1998
1999This type models the sequence of 8-bit bytes. This may be used to
2000transmit some opaque data or data serialized by other types of encoders
Lev Walkin507f6002014-10-26 20:22:16 -07002001(e.~g., video file, photo picture, etc).
Lev Walkined44bf42010-11-08 02:04:55 -08002002
2003\subsection{The OBJECT IDENTIFIER type}
2004
2005The OBJECT IDENTIFIER is used to represent the unique identifier of
2006any object, starting from the very root of the registration tree.
2007If your organization needs to uniquely identify something (a router,
2008a room, a person, a standard, or whatever), you are encouraged to
2009get your own identification subtree at \url{http://www.iana.org/protocols/forms.htm}.
2010
2011For example, the very first ASN.1 module in this Chapter (RectangleModule1)
2012has the following OBJECT IDENTIFIER: 1 3 6 1 4 1 9363 1 5 2 1 1.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07002013\begin{asn}
2014ExampleOID ::= OBJECT IDENTIFIER
Lev Walkined44bf42010-11-08 02:04:55 -08002015
Lev Walkin11c9a8c2013-03-26 00:46:55 -07002016rectangleModule1-oid ExampleOID
2017 ::= { 1 3 6 1 4 1 9363 1 5 2 1 1 }
Lev Walkined44bf42010-11-08 02:04:55 -08002018
Lev Walkin11c9a8c2013-03-26 00:46:55 -07002019-- An identifier of the Internet.
2020internet-id OBJECT IDENTIFIER
2021 ::= { iso(1) identified-organization(3)
2022 dod(6) internet(1) }
2023\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08002024As you see, names are optional.
2025
2026
2027\subsection{The RELATIVE-OID type}
2028
2029The RELATIVE-OID type has the semantics of a subtree of an OBJECT
2030IDENTIFIER. There may be no need to repeat the whole sequence of numbers
2031from the root of the registration tree where the only thing of interest
2032is some of the tree's subsequence.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07002033\begin{asn}
2034this-document RELATIVE-OID ::= { docs(2) usage(1) }
Lev Walkined44bf42010-11-08 02:04:55 -08002035
Lev Walkin11c9a8c2013-03-26 00:46:55 -07002036this-example RELATIVE-OID ::= {
2037 this-document assorted-examples(0) this-example(1) }
2038\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08002039
2040\section{Some of the ASN.1 String Types}
2041
2042
2043\subsection{The IA5String type}
2044
2045This is essentially the ASCII, with 128 character codes available
2046(7 lower bits of an 8-bit byte).
2047
2048
2049\subsection{The UTF8String type}
2050
2051This is the character string which encodes the full Unicode range
2052(4 bytes) using multibyte character sequences.
2053
2054
2055\subsection{The NumericString type}
2056
2057This type represents the character string with the alphabet consisting
Lev Walkin464166c2010-11-09 08:34:38 -08002058of numbers (``0'' to ``9'') and a space.
Lev Walkined44bf42010-11-08 02:04:55 -08002059
2060
2061\subsection{The PrintableString type}
2062
Lev Walkin464166c2010-11-09 08:34:38 -08002063The character string with the following alphabet: space, ``\textbf{'}''
2064(single quote), ``\textbf{(}'', ``\textbf{)}'', ``\textbf{+}'',
2065``\textbf{,}'' (comma), ``\textbf{-}'', ``\textbf{.}'', ``\textbf{/}'',
2066digits (``0'' to ``9''), ``\textbf{:}'', ``\textbf{=}'', ``\textbf{?}'',
2067upper-case and lower-case letters (``A'' to ``Z'' and ``a''
2068to ``z'').
Lev Walkined44bf42010-11-08 02:04:55 -08002069
2070
2071\subsection{The VisibleString type}
2072
2073The character string with the alphabet which is more or less a subset
Lev Walkin464166c2010-11-09 08:34:38 -08002074of ASCII between the space and the ``\textbf{\textasciitilde{}}''
Lev Walkined44bf42010-11-08 02:04:55 -08002075symbol (tilde).
2076
2077Alternatively, the alphabet may be described as the PrintableString
Lev Walkin464166c2010-11-09 08:34:38 -08002078alphabet presented earlier, plus the following characters: ``\textbf{!}'',
2079``\textbf{``}'', ``\textbf{\#}'', ``\textbf{\$}'', ``\textbf{\%}'',
Lev Walkin11c9a8c2013-03-26 00:46:55 -07002080``\textbf{\&}'', ``\textbf{*}'', ``\textbf{;}'', ``\textbf{<}'',
Lev Walkin464166c2010-11-09 08:34:38 -08002081``\textbf{>}'', ``\textbf{{[}}'', ``\textbf{\textbackslash{}}'',
2082``\textbf{{]}}'', ``\textbf{\textasciicircum{}}'', ``\textbf{\_}'',
2083``\textbf{`}`` (single left quote), ``\textbf{\{}'', ``\textbf{|}'',
2084``\textbf{\}}'', ``\textbf{\textasciitilde{}}''.
Lev Walkined44bf42010-11-08 02:04:55 -08002085
2086
2087\section{ASN.1 Constructed Types}
2088
2089
2090\subsection{The SEQUENCE type}
2091
2092This is an ordered collection of other simple or constructed types.
Lev Walkin464166c2010-11-09 08:34:38 -08002093The SEQUENCE constructed type resembles the C ``struct'' statement.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07002094\begin{asn}
2095Address ::= SEQUENCE {
2096 -- The apartment number may be omitted
2097 apartmentNumber NumericString OPTIONAL,
2098 streetName PrintableString,
2099 cityName PrintableString,
2100 stateName PrintableString,
2101 -- This one may be omitted too
2102 zipNo NumericString OPTIONAL
2103}
2104\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08002105
2106\subsection{The SET type}
2107
2108This is a collection of other simple or constructed types. Ordering
2109is not important. The data may arrive in the order which is different
2110from the order of specification. Data is encoded in the order not
2111necessarily corresponding to the order of specification.
2112
2113
2114\subsection{The CHOICE type}
2115
2116This type is just a choice between the subtypes specified in it. The
2117CHOICE type contains at most one of the subtypes specified, and it
2118is always implicitly known which choice is being decoded or encoded.
Lev Walkin464166c2010-11-09 08:34:38 -08002119This one resembles the C ``union'' statement.
Lev Walkined44bf42010-11-08 02:04:55 -08002120
2121The following type defines a response code, which may be either an
Lev Walkin464166c2010-11-09 08:34:38 -08002122integer code or a boolean ``true''/``false'' code.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07002123\begin{asn}
2124ResponseCode ::= CHOICE {
2125 intCode INTEGER,
2126 boolCode BOOLEAN
2127}
2128\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08002129
2130\subsection{The SEQUENCE OF type}
2131
2132This one is the list (array) of simple or constructed types:
Lev Walkin11c9a8c2013-03-26 00:46:55 -07002133\begin{asn}
2134-- Example 1
2135ManyIntegers ::= SEQUENCE OF INTEGER
Lev Walkined44bf42010-11-08 02:04:55 -08002136
Lev Walkin11c9a8c2013-03-26 00:46:55 -07002137-- Example 2
2138ManyRectangles ::= SEQUENCE OF Rectangle
Lev Walkined44bf42010-11-08 02:04:55 -08002139
Lev Walkin11c9a8c2013-03-26 00:46:55 -07002140-- More complex example:
2141-- an array of structures defined in place.
2142ManyCircles ::= SEQUENCE OF SEQUENCE {
2143 radius INTEGER
2144 }
2145\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08002146
2147\subsection{The SET OF type}
2148
2149The SET OF type models the bag of structures. It resembles the SEQUENCE
Lev Walkin507f6002014-10-26 20:22:16 -07002150OF type, but the order is not important. The elements may arrive
Lev Walkined44bf42010-11-08 02:04:55 -08002151in the order which is not necessarily the same as the in-memory order
2152on the remote machines.
Lev Walkin11c9a8c2013-03-26 00:46:55 -07002153\begin{asn}
2154-- A set of structures defined elsewhere
2155SetOfApples :: SET OF Apple
Lev Walkined44bf42010-11-08 02:04:55 -08002156
Lev Walkin11c9a8c2013-03-26 00:46:55 -07002157-- Set of integers encoding the kind of a fruit
2158FruitBag ::= SET OF ENUMERATED { apple, orange }
2159\end{asn}
Lev Walkined44bf42010-11-08 02:04:55 -08002160\begin{thebibliography}{ITU-T/ASN.1}
2161\bibitem[ASN1C]{ASN1C}The Open Source ASN.1 Compiler. \url{http://lionet.info/asn1c}
2162
2163\bibitem[AONL]{AONL}Online ASN.1 Compiler. \url{http://lionet.info/asn1c/asn1c.cgi}
2164
2165\bibitem[Dub00]{Dub00}Olivier Dubuisson --- \emph{ASN.1 Communication
Lev Walkin11c9a8c2013-03-26 00:46:55 -07002166between heterogeneous systems} --- Morgan Kaufmann Publishers, 2000.
Lev Walkined44bf42010-11-08 02:04:55 -08002167\url{http://asn1.elibel.tm.fr/en/book/}. ISBN:0-12-6333361-0.
2168
Lev Walkin464166c2010-11-09 08:34:38 -08002169\bibitem[ITU-T/ASN.1]{ITU-T/ASN.1}ITU-T Study Group 17 --- Languages
Lev Walkined44bf42010-11-08 02:04:55 -08002170for Telecommunication Systems \url{http://www.itu.int/ITU-T/studygroups/com17/languages/}
2171\end{thebibliography}
2172
2173\end{document}