NativeEnumerated.c vars NULL init and check
[com/asn1c.git] / doc / docsrc / asn1c-usage.tex
1 \batchmode
2 \documentclass[english,oneside,12pt]{book}
3 \usepackage[no-math]{fontspec}
4 \usepackage{MnSymbol}
5 \usepackage{xunicode}
6 \usepackage{xltxtra}
7
8 \usepackage[hmargin={1in,1in},vmargin={1.5in,1.5in}]{geometry}
9
10 \defaultfontfeatures{Mapping=tex-text}
11 \setmainfont{PT Sans}
12 \setsansfont{PT Sans}
13 \setmonofont{Consolas}
14
15 \usepackage{fancyhdr}
16 \usepackage{fancyref}
17 \usepackage{longtable}
18 \usepackage{array}
19 \usepackage{enumitem}
20 \usepackage{booktabs}
21 \usepackage{url}
22 \usepackage{xcolor}
23 \usepackage{listings}
24 \usepackage{setspace}
25 \usepackage{unicode-math}
26 \usepackage{perpage}
27 \MakePerPage{footnote}
28
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}
35 \setmathfont[Scale=1.05]{Cambria Math}
36
37 \makeatletter
38
39 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Textclass specific LaTeX commands.
40 \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}{
68         morekeywords={DEFINITIONS,BEGIN,END,AUTOMATIC,TAGS,SEQUENCE,SET,OF,CHOICE,OPTIONAL,INTEGER,MAX},
69         morecomment=[l]{--},
70         morecomment=[n]{/*}{*/}
71         }
72
73 \lstnewenvironment{signature}[1][]{\lstset{style=listingStyle,language=C,xleftmargin=0pt,#1}}{}
74 \lstnewenvironment{example}[1][]{\lstset{style=listingStyle,language=C,basicstyle=\scriptsize\listingfont,#1}}{}
75 \lstnewenvironment{codesample}[1][]{\lstset{style=listingStyle,language=C,#1}}{}
76 \lstnewenvironment{bash}[1][]{\lstset{style=listingStyle,language=bash,#1}}{}
77 \lstnewenvironment{asn}[1][]{\lstset{style=listingStyle,language=asn1,#1}}{}
78
79 \newcommand{\apisection}[2]{\clearpage\section{\label{#1}#2}}
80 \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}}}}
83 \newcommand{\cmd}[1]{\texttt{#1}}
84
85 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% User specified LaTeX commands.
86 \usepackage{extramarks}
87 \lhead{\firstxmark}
88 \rfoot{\lastxmark}
89 \definecolor{clrlink}{rgb}{0,0.4,0}
90 \definecolor{clrurl}{rgb}{0,0,.6}
91 \usepackage[colorlinks=true,
92         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
101 ]{hyperref}
102
103
104 \makeatother
105
106 \usepackage{babel}
107
108 \begin{document}
109
110 \title{Using the Open Source ASN.1 Compiler\\
111 \vspace*{0.4cm}
112 \Large Documentation for asn1c version \asnver{}}
113 \author{Lev Walkin <\href{mailto:vlm@lionet.info?Subject=asn1c}{vlm@lionet.info}>}
114
115 \pagestyle{fancy}
116 \fancyhead[L]{\leftmark}
117 \fancyhead[R]{\href{http://lionet.info/asn1c}{asn1c-\asnver}}
118 \maketitle
119
120 \tableofcontents{}
121
122 \chapter{\label{chap:Quick-start-examples}Quick start examples}
123
124 \section{A “Rectangle” converter and debugger}
125
126 One of the most common need is to create some sort of analysis tool
127 for the existing ASN.1 data files. Let's build a converter for existing
128 Rectangle 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}
133 RectangleModule DEFINITIONS ::= BEGIN
134
135 Rectangle ::= SEQUENCE {
136     height  INTEGER,
137     width   INTEGER
138 }
139
140 END
141 \end{asn}
142
143 \item Compile it into the set of .c and .h files using \cmd{asn1c} compiler:
144
145 \begin{bash}
146 asn1c -no-gen-example %\textbf{rectangle.asn}%
147 \end{bash}
148
149 \item Create the converter and dumper:
150
151 \begin{bash}
152 make -f converter-example.mk
153 \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}
163
164 This example will help you create a simple BER and XER encoder of
165 a ``Rectangle'' type used throughout this document.
166 \begin{enumerate}
167 \item Create a file named \textbf{rectangle.asn} with the following contents:
168
169 \begin{asn}
170 RectangleModule DEFINITIONS ::= BEGIN
171
172 Rectangle ::= SEQUENCE {
173     height  INTEGER,
174     width   INTEGER
175 }
176
177 END
178 \end{asn}
179 \item Compile it into the set of .c and .h files using asn1c compiler \cite{ASN1C}:
180
181 \begin{bash}
182 asn1c -no-gen-example %\textbf{rectangle.asn}%
183 \end{bash}
184 \item Alternatively, use the Online ASN.1 compiler \cite{AONL} by uploading
185 the \textbf{rectangle.asn} file into the Web form and unpacking the
186 produced archive on your computer.
187 \item By this time, you should have gotten multiple files in the current
188 directory, including the \textbf{Rectangle.c} and \textbf{Rectangle.h}.
189 \item Create a main() routine which creates the Rectangle\_t structure in
190 memory and encodes it using BER and XER encoding rules. Let's name
191 the file \textbf{main.c}:
192
193 \begin{example}
194 #include <stdio.h>
195 #include <sys/types.h>
196 #include <Rectangle.h>   /* Rectangle ASN.1 type  */
197
198 /* Write the encoded output into some FILE stream. */
199 static 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  
205 int main(int ac, char **av) {
206     Rectangle_t *rectangle; /* Type to encode        */
207     asn_enc_rval_t ec;      /* Encoder return value  */
208
209     /* Allocate the Rectangle_t */
210     rectangle = calloc(1, sizeof(Rectangle_t)); /* not malloc! */
211     if(!rectangle) {
212         perror("calloc() failed");
213         exit(1);
214     }
215
216     /* Initialize the Rectangle members */
217     rectangle->height = 42;  /* any random value */
218     rectangle->width  = 23;  /* any random value */
219
220     /* 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         }
231
232         /* 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     }
243
244     /* Also print the constructed Rectangle XER encoded (XML) */
245     xer_fprint(stdout, &asn_DEF_Rectangle, rectangle);
246
247     return 0; /* Encoding finished successfully */
248  }
249 \end{example}
250 \item Compile all files together using C compiler (varies by platform):
251
252 \begin{bash}
253 cc -I. -o %\textbf{\emph{rencode}} \emph{*.c}%
254 \end{bash}
255 \item Done. You have just created the BER and XER encoder of a Rectangle
256 type, named \textbf{rencode}!
257 \end{enumerate}
258
259 \section{\label{sec:A-Rectangle-Decoder}A “Rectangle” Decoder}
260
261 This example will help you to create a simple BER decoder of a simple
262 ``Rectangle'' type used throughout this document.
263 \begin{enumerate}
264 \item Create a file named \textbf{rectangle.asn} with the following contents:
265
266 \begin{asn}
267 RectangleModule DEFINITIONS ::= BEGIN
268
269 Rectangle ::= SEQUENCE {
270     height  INTEGER,
271     width   INTEGER
272 }
273
274 END
275 \end{asn}
276 \item Compile it into the set of .c and .h files using asn1c compiler \cite{ASN1C}:
277
278 \begin{bash}
279 asn1c -no-gen-example %\textbf{rectangle.asn}%
280 \end{bash}
281 \item Alternatively, use the Online ASN.1 compiler \cite{AONL} by uploading
282 the \textbf{rectangle.asn} file into the Web form and unpacking the
283 produced archive on your computer.
284 \item By this time, you should have gotten multiple files in the current
285 directory, including the \textbf{Rectangle.c} and \textbf{Rectangle.h}.
286 \item Create a main() routine which takes the binary input file, decodes
287 it as it were a BER-encoded Rectangle type, and prints out the text
288 (XML) representation of the Rectangle type. Let's name the file \textbf{main.c}:
289
290 \begin{example}
291 #include <stdio.h>
292 #include <sys/types.h>
293 #include <Rectangle.h>   /* Rectangle ASN.1 type  */
294
295 int main(int ac, char **av) {
296     char buf[1024];      /* Temporary buffer      */
297     asn_dec_rval_t rval; /* Decoder return value  */
298     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.}!}% */
299     FILE *fp;            /* Input file handler    */
300     size_t size;         /* Number of bytes read  */
301     char *filename;      /* Input file name */
302
303     /* 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     }
310
311     /* Open input file as read-only binary */
312     fp = fopen(filename, "rb");
313     if(!fp) {
314         perror(filename);
315         exit(1);
316     }
317
318     /* 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     }
325
326     /* 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     }
332
333     /* Print the decoded Rectangle type as XML */
334     xer_fprint(stdout, &asn_DEF_Rectangle, rectangle);
335
336     return 0; /* Decoding finished successfully */
337 }
338 \end{example}
339 \item Compile all files together using C compiler (varies by platform):
340
341 \begin{bash}
342 cc -I. -o %\textbf{\emph{rdecode}} \emph{*.c}%
343 \end{bash}
344 \item Done. You have just created the BER decoder of a Rectangle type,
345 named \textbf{rdecode}!
346 \end{enumerate}
347
348 \section{Adding constraints to a “Rectangle”}
349
350 This example shows how to add basic constraints to the ASN.1 specification
351 and how to invoke the constraints validation code in your application.
352 \begin{enumerate}
353
354 \item Create a file named \textbf{rectangle.asn} with the following contents:
355
356 \begin{asn}
357 RectangleModuleWithConstraints DEFINITIONS ::= BEGIN
358
359 Rectangle ::= SEQUENCE {
360     height  INTEGER (0..100), -- Value range constraint
361     width   INTEGER (0..MAX)  -- Makes width non-negative 
362 }
363
364 END
365 \end{asn}
366
367 \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
369 main() routine shown in the \fref{sec:A-Rectangle-Decoder})
370 by placing the following snippet of code \emph{before} encoding and/or
371 \emph{after} decoding the Rectangle type:
372
373 \begin{example}
374 int ret;           /* Return value */
375 char errbuf[128];  /* Buffer for error message */
376 size_t errlen = sizeof(errbuf);  /* Size of the buffer */
377
378 /* ... here goes the Rectangle %\emph{decoding}% code ... */
379
380 ret = asn_check_constraints(&asn_DEF_Rectangle, rectangle, errbuf, &errlen);
381 /* assert(errlen < sizeof(errbuf)); // you may rely on that */
382 if(ret) {
383     fprintf(stderr, "Constraint validation failed: %\%%s\n", errbuf);
384     /* exit(...); // Replace with appropriate action */
385  }
386
387 /* ... here goes the Rectangle %\emph{encoding}% code ... */
388 \end{example}
389 \item Compile the resulting C code as shown in the previous chapters.
390 \item Test the constraints checking code by assigning integer value
391 101 to the \textbf{.height} member of the Rectangle structure, or
392 a negative value to the \textbf{.width} member.
393 The program will fail with ``Constraint validation failed'' message.
394 \item Done.
395 \end{enumerate}
396
397 \chapter{ASN.1 Compiler}
398
399 \section{The asn1c compiler tool}
400
401 The purpose of the ASN.1 compiler is to convert the specifications
402 in ASN.1 notation into some other language, such as C.
403
404 The compiler reads the specification and emits a series of target
405 language structures (C structs, unions, enums) describing the corresponding
406 ASN.1 types. The compiler also creates the code which allows automatic
407 serialization and deserialization of these structures using several
408 standardized encoding rules (BER, DER, OER, PER, XER).
409
410 Let's take the following ASN.1 example%
411 \footnote{\Fref{chap:Abstract-Syntax-Notation} provides a quick reference
412 on the ASN.1 notation.}:
413 \begin{asn}
414 RectangleModule DEFINITIONS ::= BEGIN
415
416 Rectangle ::= SEQUENCE {
417     height  INTEGER,        -- Height of the rectangle
418     width   INTEGER         -- Width of the rectangle
419 }
420
421 END
422 \end{asn}
423 The asn1c compiler reads this ASN.1 definition and produce the following
424 C type:
425 \begin{codesample}
426 typedef struct Rectangle_s {
427     long height;
428     long width;
429 } Rectangle_t;
430 \end{codesample}
431 The asn1c compiler also creates the code for converting this structure into
432 platform-independent wire representation and the decoder
433 of such wire representation back into local, machine-specific type.
434 These encoders and decoders are also called serializers and deserializers,
435 marshallers and unmarshallers, or codecs.
436
437 Compiling ASN.1 modules into C codecs can be as simple as invoking \cmd{asn1c}:
438 may be used to compile the ASN.1 modules:
439 \begin{bash}
440 asn1c %\emph{<modules.asn>}%
441 \end{bash}
442
443 If several ASN.1 modules contain interdependencies, all of the files
444 must be specified altogether:
445 \begin{bash}
446 asn1c %\emph{<module1.asn> <module2.asn> ...}%
447 \end{bash}
448 The compiler \textbf{-E} and \textbf{-EF} options are used for testing
449 the parser and the semantic fixer, respectively. These options will
450 instruct the compiler to dump out the parsed (and fixed, if \textbf{-F}
451 is involved) ASN.1 specification as it was understood
452 by the compiler. It might be useful to check whether a particular
453 syntactic construct is properly supported by the compiler.
454 \begin{bash}
455 asn1c %\textbf{-EF} \emph{<module-to-test.asn>}%
456 \end{bash}
457 The \textbf{-P} option is used to dump the compiled output on the
458 screen instead of creating a bunch of .c and .h files on disk in the
459 current directory. You would probably want to start with \textbf{-P}
460 option instead of creating a mess in your current directory. Another
461 option, \textbf{-R}, asks compiler to only generate the files which
462 need to be generated, and supress linking in the numerous support
463 files.
464
465 Print the compiled output instead of creating multiple source files:
466 \begin{bash}
467 asn1c %\textbf{-P} \emph{<module-to-compile-and-print.asn>}%
468 \end{bash}
469
470 \clearpage{}
471 \section{Compiler output}
472
473 The \cmd{asn1c} compiler produces a number of files:
474 \begin{itemize}
475 \item A set of .c and .h files for each type defined
476 in the ASN.1 specification. These files will be named similarly to
477 the ASN.1 types (\textbf{Rectangle.c} and \textbf{Rectangle.h} for the
478 RectangleModule 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,
480 decoders and other useful routines.
481 Sometimes they are referred to by the term \emph{skeletons}.
482 There will be quite a few of them, some
483 of them are not even always necessary, but the overall amount of code
484 after compilation will be rather small anyway.
485 \item A \textbf{Makefile.am.libasncodecs} file which explicitly lists all the
486 generated files.
487 This makefile can be used on its own to build the just the codec library.
488 \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.
489 \item A \textbf{converter-example.mk} file which binds together
490 \textbf{Makefile.am.libasncodecs} and \textbf{converter-example.c}
491 to build a versatile converter and debugger for your data formats.
492 \end{itemize}
493 It is possible to compile everything with just a couple of instructions:
494 \begin{bash}
495 asn1c -pdu=%\emph{Rectangle}% *.asn
496 make -f converter-example.mk                   # If you use `make`
497 \end{bash}
498 or
499 \begin{bash}
500 asn1c *.asn
501 cc -I. -DPDU=%\emph{Rectangle}% -o rectangle.exe *.c   # ... or like this
502 \end{bash}
503 Refer to the \fref{chap:Quick-start-examples} for a sample
504 \emph{int main()} function if you want some custom logic and not satisfied
505 with the supplied \emph{converter-example.c}.
506
507 \clearpage{}
508 \section{\label{sec:Command-line-options}Command line options}
509
510 The 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
517 specification code to the standard output.}\\
518 {\ttfamily -F} & {\small Used together with \texttt{-E}, instructs the compiler to stop after
519 the ASN.1 syntax tree fixing stage and dump the reconstructed ASN.1
520 specification to the standard output.}\\
521 {\ttfamily -P} & {\small Dump the compiled output to the standard output instead of
522 creating 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.
536 This 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
538 name clashes in case the module reuses the same identifiers in multiple
539 contexts.}\\
540 {\ttfamily -findirect-choice} & {\small When generating code for a CHOICE type, compile the CHOICE
541 members as indirect pointers instead of declaring them inline. Consider
542 using this option together with \texttt{-fno-include-deps}
543 to 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
546 the target language source files for the given type have been provided
547 manually. }\\
548 {\ttfamily -fline-refs} & {\small Include ASN.1 module's line numbers in generated code comments.}\\
549 {\ttfamily -fno-constraints} & {\small Do not generate the ASN.1 subtype constraint checking code. This
550 may produce a shorter executable.}\\
551 {\ttfamily -fno-include-deps} & {\small Do not generate the courtesy \#include lines for non-critical dependencies.}\\
552 {\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
556 {\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.}\\
559 {\ttfamily -pdu=\{\textbf{all}|\textbf{auto}|\emph{Type}\}} & {\small Create a PDU table for specified types, or discover the Protocol Data Units automatically.
560 In 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
565 to explain its internal understanding of subtype constraints.}\\
566 {\ttfamily -print-lines} & {\small Generate \texttt{``-{}- \#line''} comments
567 in \texttt{-E} output.}\\
568 \end{longtable}
569 \renewcommand{\arraystretch}{1}
570
571
572 \chapter{API reference}
573
574 The functions desribed in this chapter are to be used by the application
575 programmer. These functions won't likely change change or get removed until
576 the next major release.
577
578 The API calls not listed here are not public and should not be used by the
579 application level code.
580
581 \apisection{sec:ASN_STRUCT_FREE}{ASN\_STRUCT\_FREE() macro}
582
583 \subsection*{Synopsis}
584
585 \begin{signature}
586 #define ASN_STRUCT_FREE(type_descriptor, struct_ptr)
587 \end{signature}
588
589 \subsection*{Description}
590
591 Recursively releases memory occupied by the structure
592 described by the \code{type\_descriptor} and referred to
593 by the \code{struct\_ptr} pointer.
594
595 Does nothing when \code{struct\_ptr} is NULL.
596
597 \subsection*{Return values}
598 Does not return a value.
599
600 \subsection*{Example}
601
602 \begin{example}
603 Rectangle_t *rect = ...;
604 ASN_STRUCT_FREE(asn_DEF_Rectangle, rect);
605 \end{example}
606
607 \apisection{sec:ASN_STRUCT_RESET}{ASN\_STRUCT\_RESET() macro}
608
609 \subsection*{Synopsis}
610
611 \begin{signature}
612 #define ASN_STRUCT_RESET(type_descriptor, struct_ptr)
613 \end{signature}
614
615 \subsection*{Description}
616
617 Recursively releases memory occupied by the members of the structure
618 described by the \code{type\_descriptor} and referred to
619 by the \code{struct\_ptr} pointer.
620
621 Does not release the memory pointed to by \code{struct\_ptr} itself.
622 Instead it clears the memory block by filling it out with 0 bytes.
623
624 Does nothing when \code{struct\_ptr} is NULL.
625
626 \subsection*{Return values}
627 Does not return a value.
628
629 \subsection*{Example}
630
631 \begin{example}
632 struct 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
639 struct my_figure *fig = ...;
640 ASN_STRUCT_RESET(asn_DEF_Rectangle, &fig->rect);
641 \end{example}
642
643 \apisection{sec:asn_check_constraints}{asn\_check\_constraints()}
644
645 \subsection*{Synopsis}
646
647 \begin{signature}
648 int 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
658 Validate a given structure according to the ASN.1 constraints.
659 If \code{errbuf} and \code{errlen} are given, they shall point to the
660 appropriate buffer space and its length before calling this function.
661 Alternatively, they could be passed as \code{NULL}s.
662 If constraints validation fails, \code{errlen} will contain the actual
663 number of bytes used in \code{errbuf} to encode an error message.
664 The message is going to be properly 0-terminated.
665
666 \subsection*{Return values}
667
668 This function returns 0 in case all ASN.1 constraints are met
669 and -1 if one or more ASN.1 constraints were violated.
670
671 \subsection*{Example}
672
673 \begin{codesample}[basicstyle=\scriptsize\listingfont]
674 Rectangle_t *rect = ...;
675
676 char errbuf[128];  /* Buffer for error message */
677 size_t errlen = sizeof(errbuf);  /* Size of the buffer */
678
679 int ret = asn_check_constraints(&asn_DEF_Rectangle, rectangle, errbuf, &errlen);
680 /* assert(errlen < sizeof(errbuf)); // Guaranteed: you may rely on that */
681 if(ret) {
682     fprintf(stderr, "Constraint validation failed: %\%%s\n", errbuf);
683 }
684 \end{codesample}
685
686 \apisection{sec:asn_decode}{asn\_decode()}
687
688 \subsection*{Synopsis}
689 \begin{signature}
690 asn_dec_rval_t asn_decode(
691     const asn_codec_ctx_t *opt_codec_ctx,
692     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
702 The \code{asn\_decode()} function parses the data given by the \code{buffer}
703 and \code{size} arguments. The encoding rules are specified in the \code{syntax}
704 argument and the type to be decoded is specified by the \code{type_descriptor}.
705
706 The \code{struct_ptr_ptr} must point to the memory location which contains the
707 pointer to the structure being decoded. Initially the \code{*struct_ptr_ptr}
708 pointer is typically set to 0. In that case, \code{asn\_decode()} will
709 dynamically allocate memory for the structure and its members as needed
710 during the parsing.
711 If \code{*struct\_ptr\_ptr} already points to some memory, the \code{asn\_decode()}
712 will allocate the subsequent members as needed during the parsing.
713
714 \subsection*{Return values}
715
716 \input{asn_dec_rval.inc}
717
718 The \code{.consumed} value is in bytes, even for PER decoding.
719 For PER, use \code{uper\_decode()} in case you need to get
720 the number of consumed bits.
721
722 \subsection*{Restartability}
723
724 Some transfer syntax parsers (such as ATS\_BER) support restartability.
725
726 That means that in case the buffer has less data than expected,
727 the \code{asn_decode()} will process whatever is available and ask for more
728 data to be provided using the RC\_WMORE return \code{.code}.
729
730 Note that in the RC\_WMORE case the decoder may have processed less data than
731 it is available in the buffer, which means that you must be able to arrange
732 the next buffer to contain the unprocessed part of the previous buffer.
733
734 The \code{RC_WMORE} code may still be returned by parser not supporting
735 restartabilty. In such cases, the partially decoded structure shall be
736 discarded and the next invocation should use the extended buffer to parse
737 from the very beginning.
738
739 \subsection*{Example}
740
741 \begin{example}
742 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.}!}% */
743 asn_dec_rval_t rval;
744 rval = asn_decode(0, ATS_BER, &asn_DEF_Rectangle, (void **)&rect, buffer, buf_size);
745 switch(rval.code) {
746 case RC_OK:
747     asn_fprint(stdout, &asn_DEF_Rectangle, rect);
748     ASN_STRUCT_FREE(&asn_DEF_Rectangle, rect);
749     break;
750 case RC_WMORE:
751 case RC_FAIL:
752 default:
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
761 \apisection{sec:asn_encode}{asn\_encode()}
762
763 \subsection*{Synopsis}
764
765 \begin{signature}
766 #include <asn_application.h>
767
768 asn_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
778 The \code{asn_encode()} function serializes the given \code{structure_to_encode} using the chosen ASN.1 transfer \code{syntax}.
779
780 During serialization, a user-specified \code{callback} is invoked zero
781 or more times with bytes of data to add to the output stream (if any), and
782 the \code{callback_key}. The signature for the callback is as follows:
783
784 \begin{signature}
785 typedef 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
791 The serialized output size is returned in \textbf{bytes} irrespectively of the
792 ASN.1 transfer \code{syntax} chosen.\footnote{This is different from some
793 lower level encoding functions, such as \api{sec:uper_encode}{uper_encode()},
794 which returns the number of encoded \emph{bits} instead of bytes.}
795
796 On error (when \code{.encoded} is set to -1),
797 the \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}
805
806 \subsection*{Example}
807 \begin{example}
808 static int
809 save_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
814 Rectangle_t *rect = ...;
815 FILE *fp = ...;
816 asn_enc_rval_t er;
817 er = asn_encode(0, ATS_DER, &asn_DEF_Rectangle, rect, save_to_file, fp);
818 if(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
832 asn_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
842 The \code{asn_encode_to_buffer()} function serializes the given \code{structure_to_encode} using the chosen ASN.1 transfer \code{syntax}.
843
844 The 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
850 The serialized output size is returned in \textbf{bytes} irrespectively of the
851 ASN.1 transfer \code{syntax} chosen.\footnote{This is different from some
852 lower level encoding functions, such as \api{sec:uper_encode}{uper_encode()},
853 which returns the number of encoded \emph{bits} instead of bytes.}
854
855 If \code{.encoded} size exceeds the specified \code{buffer_size},
856 the serialization effectively failed due to insufficient space. The function
857 will succeed if subsequently called with buffer size no less than the returned
858 \code{.encoded} size. This behavior modeled after \code{snprintf()}.
859
860 On error (when \code{.encoded} is set to -1),
861 the \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}
871 Rectangle_t *rect = ...;
872 uint8_t buffer[128];
873 asn_enc_rval_t er;
874 er = asn_encode_to_buffer(0, ATS_DER, &asn_DEF_Rectangle, rect, buffer, sizeof(buffer));
875 if(er.encoded == -1) {
876    fprintf(stderr, "Serialization of %\%%s failed.\n", asn_DEF_Rectangle.name);
877 } else if(er.encoded > sizeof(buffer)) {
878    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
883 \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
893 typedef struct {
894     void *buffer;   /* NULL if failed to encode. */
895     asn_enc_rval_t result;
896 } asn_encode_to_new_buffer_result_t;
897 asn_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
906 The \code{asn_encode_to_new_buffer()} function serializes the given \code{structure_to_encode} using the chosen ASN.1 transfer \code{syntax}.
907
908 The function places the serialized data into the newly allocated buffer
909 which it returns in a compound structure.
910
911 \subsection*{Return values}
912
913 On failure, the \code{.buffer} is set to \code{NULL}
914 and \code{.result.encoded} is set to -1. The global \code{errno} is set
915 to 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.
926 The \code{.buffer} contains the serialized content.
927 The user is responsible for freeing the \code{.buffer}.
928
929 \subsection*{Example}
930 \begin{example}
931 asn_encode_to_new_buffer_result_t res;
932 res = asn_encode_to_new_buffer(0, ATS_DER, &asn_DEF_Rectangle, rect);
933 if(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
942 \subsection*{See also}
943 \seealso{sec:asn_encode_to_buffer}{asn_encode_to_buffer()}.
944
945 \apisection{sec:asn_fprint}{asn\_fprint()}
946
947 \subsection*{Synopsis}
948 \begin{signature}
949 int 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
957 The \code{asn_fprint()} function prints human readable description
958 of the target language's structure into the file stream specified by
959 \code{stream} pointer.
960
961 The output format does not conform to any standard.
962
963 The \code{asn_fprint()} function attempts to
964 produce a valid output even for incomplete and broken structures, which
965 makes 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}
971 0 & Output was successfully made \\
972 -1 & Error printing out the structure
973 \end{tabular}
974
975 \subsection*{Example}
976 \begin{example}
977 Rectangle_t *rect = ...;
978 asn_fprint(stdout, &asn_DEF_Rectangle, rect);
979 \end{example}
980
981 \subsection*{See also}
982 \seealso{sec:xer_fprint}{xer_fprint()}.
983
984 \apisection{sec:asn_random_fill}{asn\_random\_fill()}
985
986 \subsection*{Synopsis}
987 \begin{signature}
988 int 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
997 Create or initialize a structure with random contents, according to the type
998 specification and optional member constraints.
999
1000 For best results the code should be generated without \cmd{-no-gen-PER}
1001 option to \cmd{asn1c}. Making PER constraints code available in runtime
1002 will make \code{asn_random_fill} explore the edges of PER-visible constraints
1003 and sometimes break out of extensible contstraints' ranges.
1004
1005 The \code{asn_random_fill()} function has a bias to generate edge case
1006 values. This property makes it useful for debugging the application level
1007 code and for security testing, as random data can be a good seed to fuzzing.
1008
1009 The \code{approx_max_length_limit} specifies the approximate limit of the
1010 resulting structure in units closely resembling bytes. The actual result
1011 might be several times larger or smaller than the given length limit.
1012 A rule of thumb way to select the initial value for this parameter
1013 is to take a typical structure and use twice its DER output size.
1014
1015 \subsection*{Return values}
1016
1017 \begin{tabular}[h!]{rl}
1018 0 & Structure was properly initialized with random data \\
1019 -1 & Failure to initialize the structure with random data
1020 \end{tabular}
1021
1022 \apisection{sec:ber_decode}{ber\_decode()}
1023
1024 \subsection*{Synopsis}
1025 \begin{signature}
1026 asn_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
1037 Decode BER, DER and CER data
1038 (Basic Encoding Rules, Distinguished Encoding Rules, Canonical Encoding Rules),
1039 as defined by ITU-T~X.690.
1040
1041 DER and CER are different subsets of BER.\newline
1042
1043 \noindent\emph{Consider using a more generic function \api{sec:asn_decode}{asn_decode(ATS_BER)}.}
1044
1045 \subsection*{Return values}
1046 \input{asn_dec_rval.inc}
1047
1048 The \code{.consumed} value is in bytes.
1049
1050 \subsection*{Restartability}
1051
1052 The \code{ber_decode()} function is restartable (stream-oriented).
1053 That means that in case the buffer has less data than expected,
1054 the decoder will process whatever is available and ask for more data
1055 to be provided using the RC\_WMORE return \code{.code}.
1056
1057 Note that in the RC\_WMORE case the decoder may have processed less data than
1058 it is available in the buffer, which means that you must be able to arrange
1059 the next buffer to contain the unprocessed part of the previous buffer.
1060
1061 \subsection*{See also}
1062 \seealso{sec:der_encode}{der_encode()}.
1063
1064 \apisection{sec:der_encode}{der\_encode}
1065
1066 \subsection*{Synopsis}
1067
1068 \begin{signature}
1069 asn_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
1078 The \code{der_encode()} function serializes the given \code{structure_to_encode} using the DER transfer syntax (a variant of BER, Basic Encoding Rules).
1079
1080 During serialization, a user-specified \code{callback} is invoked zero
1081 or more times with bytes of data to add to the output stream (if any), and
1082 the \code{callback_key}. The signature for the callback is as follows:
1083
1084 \begin{signature}
1085 typedef 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
1093 The serialized output size is returned in \textbf{bytes}.
1094
1095 \subsection*{Example}
1096 \begin{example}
1097 static int
1098 save_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
1103 Rectangle_t *rect = ...;
1104 FILE *fp = ...;
1105 asn_enc_rval_t er;
1106 er = der_encode(&asn_DEF_Rectangle, rect, save_to_file, fp);
1107 if(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}
1113
1114 \subsection*{See also}
1115 \seealso{sec:ber_decode}{ber_decode()},
1116 \seealso{sec:asn_decode}{asn_decode(ATS_BER)}.
1117
1118 \apisection{sec:der_encode_to_buffer}{der\_encode\_to\_buffer()}
1119
1120 \subsection*{Synopsis}
1121
1122 \begin{signature}
1123 asn_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
1131 The \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
1133 The 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
1141 The serialized output size is returned in \textbf{bytes}.
1142
1143 The \code{.encoded} never exceeds the available buffer size.\footnote{This
1144 behavior is different from \api{sec:asn_encode_to_buffer}{asn_encode_to_buffer()}.}
1145 If the \code{buffer_size} is not sufficient, the \code{.encoded}
1146 will be set to -1 and encoding would fail.
1147
1148 \subsection*{Example}
1149 \begin{example}
1150 Rectangle_t *rect = ...;
1151 uint8_t buffer[128];
1152 asn_enc_rval_t er;
1153 er = der_encode_to_buffer(&asn_DEF_Rectangle, rect, buffer, sizeof(buffer));
1154 if(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()}
1165
1166 \subsection*{Synopsis}
1167 \begin{signature}
1168 asn_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
1179 Decode the BASIC-OER and CANONICAL-OER (Octet Encoding Rules),
1180 as defined by ITU-T~X.696.\newline
1181
1182 \noindent\emph{Consider using a more generic function \api{sec:asn_decode}{asn_decode(ATS_BASIC_OER)}.}
1183
1184 \subsection*{Return values}
1185 \input{asn_dec_rval.inc}
1186
1187 The \code{.consumed} value is in bytes.
1188
1189 \subsection*{Restartability}
1190
1191 The \code{oer_decode()} function is restartable (stream-oriented).
1192 That means that in case the buffer has less data than expected,
1193 the decoder will process whatever is available and ask for more data
1194 to be provided using the RC\_WMORE return \code{.code}.
1195
1196 Note that in the RC\_WMORE case the decoder may have processed less data than
1197 it is available in the buffer, which means that you must be able to arrange
1198 the next buffer to contain the unprocessed part of the previous buffer.
1199
1200 \apisection{sec:oer_encode}{oer\_encode()}
1201
1202 \subsection*{Synopsis}
1203
1204 \begin{signature}
1205 asn_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
1214 The \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
1216 During serialization, a user-specified \code{callback} is invoked zero
1217 or more times with bytes of data to add to the output stream (if any), and
1218 the \code{callback_key}. The signature for the callback is as follows:
1219
1220 \begin{signature}
1221 typedef 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
1229 The serialized output size is returned in \textbf{bytes}.
1230
1231 \subsection*{Example}
1232 \begin{example}
1233 static int
1234 save_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
1239 Rectangle_t *rect = ...;
1240 FILE *fp = ...;
1241 asn_enc_rval_t er;
1242 er = oer_encode(&asn_DEF_Rectangle, rect, save_to_file, fp);
1243 if(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}
1258 asn_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
1267 The \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
1269 The 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
1277 The serialized output size is returned in \textbf{bytes}.
1278
1279 The \code{.encoded} never exceeds the available buffer size.\footnote{This
1280 behavior is different from \api{sec:asn_encode_to_buffer}{asn_encode_to_buffer()}.}
1281 If the \code{buffer_size} is not sufficient, the \code{.encoded}
1282 will be set to -1 and encoding would fail.
1283
1284 \subsection*{Example}
1285 \begin{example}
1286 Rectangle_t *rect = ...;
1287 uint8_t buffer[128];
1288 asn_enc_rval_t er;
1289 er = oer_encode_to_buffer(&asn_DEF_Rectangle, 0, rect, buffer, sizeof(buffer));
1290 if(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()}
1301
1302 \subsection*{Synopsis}
1303
1304 \begin{signature}
1305 asn_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
1318 Decode the Unaligned BASIC or CANONICAL PER (Packed Encoding Rules),
1319 as defined by ITU-T~X.691.\newline
1320
1321 \noindent\emph{Consider using a more generic function \api{sec:asn_decode}{asn_decode(ATS_UNALIGNED_BASIC_PER)}.}
1322
1323 \subsection*{Return values}
1324 \input{asn_dec_rval.inc}
1325 Note that the \code{.consumed} value is in bits.
1326 Use \code{(.consumed+7)/8} to convert to bytes.
1327
1328 \subsection*{Restartability}
1329 The \code{uper_decode()} function is not restartable.
1330 Failures are final.
1331
1332 \apisection{sec:uper_decode_complete}{uper\_decode\_complete()}
1333
1334 \subsection*{Synopsis}
1335
1336 \begin{signature}
1337 asn_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
1348 Decode a ``Production of a complete encoding'',
1349 according to ITU-T~X.691 (08/2015) \#11.1.\newline
1350
1351 \noindent\emph{Consider using a more generic function \api{sec:asn_decode}{asn_decode(ATS_UNALIGNED_BASIC_PER)}.}
1352
1353 \subsection*{Return values}
1354 \input{asn_dec_rval.inc}
1355
1356 The the \code{.consumed} value is returned in whole \emph{bytes} (NB).
1357
1358 \subsection*{Restartability}
1359 The \code{uper_decode_complete()} function is not restartable.
1360 Failures are final.
1361
1362 The complete encoding contains at least one byte, so on success
1363 \code{.consumed} will be greater or equal to 1.
1364
1365 \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()}
1369
1370 \subsection*{Synopsis}
1371
1372 \begin{signature}
1373 asn_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
1384 Decode the BASIC-XER and CANONICAL-XER (XML Encoding Rules) encoding,
1385 as defined by ITU-T~X.693.\newline
1386
1387 \noindent\emph{Consider using a more generic function \api{sec:asn_decode}{asn_decode(ATS_BASIC_XER)}.}
1388
1389 \subsection*{Return values}
1390 \input{asn_dec_rval.inc}
1391
1392 The \code{.consumed} value is in bytes.
1393
1394 \subsection*{Restartability}
1395
1396 The \code{xer_decode()} function is restartable (stream-oriented).
1397 That means that in case the buffer has less data than expected,
1398 the decoder will process whatever is available and ask for more data
1399 to be provided using the RC\_WMORE return \code{.code}.
1400
1401 Note that in the RC\_WMORE case the decoder may have processed less data than
1402 it is available in the buffer, which means that you must be able to arrange
1403 the next buffer to contain the unprocessed part of the previous buffer.
1404
1405 \apisection{sec:xer_encode}{xer\_encode()}
1406
1407 \subsection*{Synopsis}
1408
1409 \begin{signature}
1410 enum 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 };
1415 asn_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
1425 The \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
1427 During serialization, a user-specified \code{callback} is invoked zero
1428 or more times with bytes of data to add to the output stream (if any), and
1429 the \code{callback_key}. The signature for the callback is as follows:
1430
1431 \begin{signature}
1432 typedef 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
1440 The serialized output size is returned in \textbf{bytes}.
1441
1442 \subsection*{Example}
1443 \begin{example}
1444 static int
1445 save_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
1450 Rectangle_t *rect = ...;
1451 FILE *fp = ...;
1452 asn_enc_rval_t er;
1453 er = xer_encode(&asn_DEF_Rectangle, rect, XER_F_CANONICAL, save_to_file, fp);
1454 if(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()}
1465
1466 \subsection*{Synopsis}
1467 \begin{signature}
1468 int 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
1476 The \code{xer_fprint()} function outputs XML-based serialization
1477 of the given structure into the file stream specified by
1478 \code{stream} pointer.
1479
1480 The output conforms to a BASIC-XER transfer syntax, as defined by ITU-T~X.693.
1481
1482 \subsection*{Return values}
1483
1484 \begin{tabular}[h!]{rl}
1485 0 & 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,
1490 it will likely break on partial structures by writing incomplete data
1491 to the output stream and returning -1. This makes it less suitable for
1492 debugging complex cases than \api{sec:asn_fprint}{asn_fprint()}.
1493
1494 \subsection*{Example}
1495 \begin{example}
1496 Rectangle_t *rect = ...;
1497 xer_fprint(stdout, &asn_DEF_Rectangle, rect);
1498 \end{example}
1499
1500 \subsection*{See also}
1501 \seealso{sec:asn_fprint}{asn_fprint()}.
1502
1503 \chapter{API usage examples}
1504
1505 Let's start with including the necessary header files into your
1506 application. Normally it is enough to include the header file of
1507 the 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}
1511 The header files defines a C structure corresponding to the ASN.1
1512 definition of a rectangle and the declaration of the ASN.1
1513 \emph{type descriptor}. A type descriptor is a special globally accessible
1514 object which is used as an argument to most of the API functions provided by
1515 the 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}
1517 Rectangle_t *rect = ...;
1518
1519 ASN_STRUCT_FREE(%\textbf{asn\_DEF\_}%Rectangle, rect);
1520 \end{codesample}
1521 This code defines a \emph{rect} pointer which points to the Rectangle\_t
1522 structure which needs to be freed. The second line uses a generic
1523 \api{sec:ASN_STRUCT_FREE}{ASN\_STRUCT\_FREE()} macro which invokes the memory deallocation routine
1524 created specifically for this Rectangle\_t structure.
1525 The \emph{asn\_DEF\_Rectangle} is the type descriptor which holds
1526 a collection of routines and operations defined for the Rectangle\_t structure.
1527
1528 \section{\label{sec:Generic-Encoding}Generic encoders and decoders}
1529
1530 Before we start describing specific encoders and decoders, let's step back
1531 a little and check out a simple high level way.
1532
1533 The 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:
1534
1535 \begin{codesample}[basicstyle=\scriptsize\listingfont]
1536 /*
1537  * A selection of ASN.1 Transfer Syntaxes to use with generalized encoders and decoders.
1538  */
1539 enum 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
1554 Using this encoding selector, encoding and decoding becomes very generic:
1555
1556 \noindent{}Encoding:
1557
1558 \begin{codesample}[basicstyle=\scriptsize\listingfont]
1559 uint8_t buffer[128];
1560 size_t buf_size = sizeof(buffer);
1561 asn_enc_rval_t er;
1562
1563 er = %\textbf{asn\_encode\emph{\_to\_buffer}}%(0, %\textbf{ATS\_DER}%, &asn_DEF_Rectangle, buffer, buf_size);
1564
1565 if(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]
1574 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.}!}% */
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
1581 The Basic Encoding Rules describe the most widely used (by the ASN.1
1582 community) way to encode and decode a given structure in a machine-independent
1583 way. Several other encoding rules (CER, DER) define a more restrictive
1584 versions of BER, so the generic BER parser is also capable of decoding
1585 the 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
1588 capable of decoding BER, CER and DER encoded data.}
1589
1590 The decoder is restartable (stream-oriented).
1591 That means that in case the buffer has less data than expected,
1592 the decoder will process whatever is available and ask for more data
1593 to be provided using the RC\_WMORE return \code{.code}.
1594
1595 Note that in the RC\_WMORE case the decoder may have processed less data than
1596 it is available in the buffer, which means that you must be able to arrange
1597 the next buffer to contain the unprocessed part of the previous buffer.
1598
1599 Suppose, 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
1602 bytes of data, or
1603 \item You can feed it the first buffer of 100 bytes of data, realize that
1604 the ber\_decoder consumed only 95 bytes from it and later feed the
1605 decoder with 205 bytes buffer which consists of 5 unprocessed bytes
1606 from the first buffer and the additional 200 bytes from the second
1607 buffer.
1608 \end{itemize}
1609 This is not as convenient as it could be (the BER encoder could
1610 consume the whole 100 bytes and keep these 5 bytes in some temporary
1611 storage), but in case of existing stream based processing it might
1612 actually fit well into existing algorithm. Suggestions are welcome.
1613
1614 Here is the example of BER decoding of a simple structure:
1615
1616 \begin{codesample}
1617 Rectangle_t *
1618 simple_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
1637 The code above defines a function, \emph{simple\_deserializer}, which
1638 takes a buffer and its length and is expected to return a pointer
1639 to the Rectangle\_t structure. Inside, it tries to convert the bytes
1640 passed into the target structure (rect) using the BER decoder and
1641 returns the rect pointer afterwards. If the structure cannot be deserialized,
1642 it frees the memory which might be left allocated by the unfinished
1643 \emph{ber\_decoder} routine and returns 0 (no data). (This \textbf{freeing
1644 is necessary} because the ber\_decoder is a restartable procedure,
1645 and may fail just because there is more data needs to be provided
1646 before decoding could be finalized). The code above obviously does
1647 not take into account the way the \emph{ber\_decoder()} failed, so
1648 the freeing is necessary because the part of the buffer may already
1649 be decoded into the structure by the time something goes wrong.
1650
1651 A little less wordy would be to invoke a globally available \emph{ber\_decode()}
1652 function instead of dereferencing the asn\_DEF\_Rectangle type descriptor:
1653 \begin{codesample}
1654 rval = ber_decode(0, &asn_DEF_Rectangle, (void **)&rect, buffer, buf_size);
1655 \end{codesample}
1656 Note that the initial (asn\_DEF\_Rectangle.op->ber\_decoder) reference
1657 is gone, and also the last argument (0) is no longer necessary.
1658
1659 These two ways of BER decoder invocations are fully equivalent.
1660
1661 The BER de\emph{coder} may fail because of (\emph{the following RC\_\ldots{}
1662 codes are defined in ber\_decoder.h}):
1663 \begin{itemize}
1664 \item RC\_WMORE: There is more data expected than it is provided (stream
1665 mode 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}
1669 Together with the return code (.code) the asn\_dec\_rval\_t type contains
1670 the number of bytes which is consumed from the buffer. In the previous
1671 hypothetical example of two buffers (of 100 and 200 bytes), the first
1672 call 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}
1674 valid, even if the decoder succeeds or fails with any other return
1675 code.
1676
1677 Look into ber\_decoder.h for the precise definition of ber\_decode()
1678 and related types.
1679
1680
1681 \section{\label{sec:Encoding-DER}Encoding DER}
1682
1683 The Distinguished Encoding Rules is the \emph{canonical} variant of
1684 BER encoding rules. The DER is best suited to encode the structures
1685 where all the lengths are known beforehand. This is probably exactly
1686 how you want to encode: either after a BER decoding or after a manual
1687 fill-up, the target structure contains the data which size is implicitly
1688 known before encoding. Among other uses, the DER encoding is used
1689 to encode X.509 certificates.
1690
1691 As with BER decoder, the DER encoder may be invoked either directly
1692 from the ASN.1 type descriptor (asn\_DEF\_Rectangle) or from the stand-alone
1693 function, 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  */
1700 ssize_t
1701 simple_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}
1715 As you see, the DER encoder does not write into some sort of buffer.
1716 It just invokes the custom function (possible, multiple
1717 times) which would save the data into appropriate storage. The optional
1718 argument \emph{app\_key} is opaque for the DER encoder code and just
1719 used by \emph{write\_stream()} as the pointer to the appropriate
1720 output stream to be used.
1721
1722 If the custom write function is not given (passed as 0), then the
1723 DER encoder will essentially do the same thing (i.~e., encode the data)
1724 but no callbacks will be invoked (so the data goes nowhere). It may
1725 prove useful to determine the size of the structure's encoding before
1726 actually doing the encoding%
1727 \footnote{It is actually faster too: the encoder might skip over some computations
1728 which aren't important for the size determination.%
1729 }.
1730
1731 Look into der\_encoder.h for the precise definition of der\_encode()
1732 and related types.
1733
1734
1735 \section{\label{sec:Encoding-XER}Encoding XER}
1736
1737 The XER stands for XML Encoding Rules, where XML, in turn, is eXtensible
1738 Markup Language, a text-based format for information exchange. The
1739 encoder routine API comes in two flavors: stdio-based and callback-based.
1740 With the callback-based encoder, the encoding process is very similar
1741 to the DER one, described in \fref{sec:Encoding-DER}. The
1742 following 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  */
1752 int
1753 print_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}
1763 Look into xer\_encoder.h for the precise definition of xer\_encode()
1764 and related types.
1765
1766 See \fref{sec:Printing-the-target} for the example of stdio-based
1767 XML encoder and other pretty-printing suggestions.
1768
1769
1770 \section{\label{sec:Decoding-XER}Decoding XER}
1771
1772 The data encoded using the XER rules can be subsequently decoded using
1773 the xer\_decode() API call:
1774 \begin{codesample}
1775 Rectangle_t *
1776 XML_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}
1791 The decoder takes both BASIC-XER and CANONICAL-XER encodings.
1792
1793 The decoder shares its data consumption properties with BER decoder;
1794 please read the \fref{sec:Decoding-BER} to know more.
1795
1796 Look into xer\_decoder.h for the precise definition of xer\_decode()
1797 and related types.
1798
1799
1800 \section{\label{sec:Validating-the-target}Validating the target structure}
1801
1802 Sometimes the target structure needs to be validated. For example,
1803 if the structure was created by the application (as opposed to being
1804 decoded from some external source), some important information required
1805 by the ASN.1 specification might be missing. On the other hand, the
1806 successful decoding of the data from some external source does not
1807 necessarily mean that the data is fully valid either. It might well
1808 be the case that the specification describes some subtype constraints
1809 that were not taken into account during decoding, and it would actually
1810 be useful to perform the last check when the data is ready to be encoded
1811 or when the data has just been decoded to ensure its validity according
1812 to some stricter rules.
1813
1814 The \api{sec:asn_check_constraints}{asn_check_constraints()}
1815 function checks the type for various
1816 implicit and explicit constraints. It is recommended to use the
1817 \code{asn_check_constraints()}
1818 function after each decoding and before each encoding.
1819
1820 \section{\label{sec:Printing-the-target}Printing the target structure}
1821
1822 To print out the structure for debugging purposes, use the
1823 \api{sec:asn_fprint}{asn_fprint()} function:
1824 \begin{codesample}
1825 asn_fprint(stdout, &asn_DEF_Rectangle, rect);
1826 \end{codesample}
1827
1828 A practical alternative to this custom format printing is to serialize
1829 the structure into XML. The default BASIC-XER encoder performs reasonable
1830 formatting for the output to be both useful and human readable.
1831 Use the \api{sec:xer_fprint}{xer_fprint()} function:
1832 \begin{codesample}
1833 xer_fprint(stdout, &asn_DEF_Rectangle, rect);
1834 \end{codesample}
1835 See \fref{sec:Encoding-XER} for XML-related details.
1836
1837 \section{\label{sec:Freeing-the-target}Freeing the target structure}
1838
1839 Freeing the structure is slightly more complex than it may seem.
1840 When the ASN.1 structure is freed, all the members of the structure
1841 and their submembers are recursively freed as well.
1842 The ASN\_STRUCT\_FREE() macro helps with that.
1843
1844 But it might not always be feasible to free the whole structure.
1845 In the following example, the application programmer defines a custom
1846 structure with one ASN.1-derived member (rect).
1847 \begin{codesample}
1848 struct 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}
1855 This member is not a reference to the Rectangle\_t, but an in-place inclusion
1856 of the Rectangle\_t structure.
1857 If there's a need to free the \code{rect} member, the usual procedure of
1858 freeing everything must not be applied to the \code{\&rect} pointer itself,
1859 because it does not point to the beginning of memory block allocated by
1860 the memory allocation routine, but instead lies within a block allocated for
1861 the my\_figure structure.
1862
1863 To solve this problem, in addition to ASN\_STRUCT\_FREE() macro, the asn1c
1864 skeletons define the ASN\_STRUCT\_RESET() macro which doesn't free the passed
1865 pointer and instead resets the structure into the clean and safe state.
1866 \begin{codesample}
1867 /* %\textbf{1. Rectangle\_t is defined within my\_figure}% */
1868 struct my_figure {
1869     Rectangle_t rect;
1870 } *mf = ...;
1871 /*
1872  * Freeing the Rectangle_t
1873  * without freeing the mf->rect area.
1874  */
1875 ASN_STRUCT_RESET(asn_DEF_Rectangle, &mf->rect);
1876   
1877 /* %\textbf{2. Rectangle\_t is a stand-alone pointer}% */
1878 Rectangle_t *rect = ...;
1879 /*
1880  * Freeing the Rectangle_t
1881  * and freeing the rect pointer.
1882  */
1883 ASN_STRUCT_FREE(asn_DEF_Rectangle, rect);
1884 \end{codesample}
1885 It is safe to invoke both macros with the target structure pointer
1886 set to 0 (NULL). In this case, the function will do nothing.
1887
1888 \chapter{\label{chap:Abstract-Syntax-Notation}Abstract Syntax Notation: ASN.1}
1889
1890 \emph{This chapter defines some basic ASN.1 concepts and describes
1891 several most widely used types. It is by no means an authoritative
1892 or complete reference. For more complete ASN.1 description, please
1893 refer to Olivier Dubuisson's book \cite{Dub00} or the ASN.1 body
1894 of standards itself \cite{ITU-T/ASN.1}.}
1895
1896 The Abstract Syntax Notation One is used to formally describe the
1897 data transmitted across the network. Two communicating parties may employ
1898 different formats of their native data types (e.~g., different number
1899 of bits for the native integer type), thus it is important to have
1900 a way to describe the data in a manner which is independent from the
1901 particular machine's representation.
1902 The ASN.1 specifications are used to achieve the following:
1903 \begin{itemize}
1904 \item The specification expressed in the ASN.1 notation is a formal and
1905 precise way to communicate the structure of data to human readers;
1906 \item The ASN.1 specifications may be used as input for automatic compilers
1907 which produce the code for some target language (C, C++, Java, etc)
1908 to encode and decode the data according to some encoding formats.
1909 Several such encoding formats (called Transfer Encoding Rules)
1910 have been defined by the ASN.1 standard.
1911 \end{itemize}
1912 Consider the following example:
1913 \begin{asn}
1914 Rectangle ::= SEQUENCE {
1915     height  INTEGER,
1916     width   INTEGER
1917 }
1918 \end{asn}
1919 This ASN.1 specification describes a constructed type, \emph{Rectangle},
1920 containing two integer fields. This specification may tell the reader
1921 that there exists this kind of data structure and that some entity
1922 may be prepared to send or receive it. The question on \emph{how}
1923 that entity is going to send or receive the \emph{encoded data} is
1924 outside the scope of ASN.1. For example, this data structure may be
1925 encoded according to some encoding rules and sent to the destination
1926 using the TCP protocol. The ASN.1 specifies several ways of encoding
1927 (or ``serializing'', or ``marshaling'') the data: BER, PER, XER
1928 and others, including CER and DER derivatives from BER.
1929
1930 The complete specification must be wrapped in a module, which looks
1931 like this:
1932 \begin{asn}
1933 RectangleModule1
1934     { 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 ::=
1938 BEGIN
1939
1940 -- This is a comment which describes nothing.
1941 Rectangle ::= SEQUENCE {
1942     height  INTEGER,        -- Height of the rectangle
1943     width   INTEGER         -- Width of the rectangle
1944 }
1945
1946 END
1947 \end{asn}
1948 The module header consists of module name (RectangleModule1), the
1949 module object identifier (\{...\}), a keyword ``DEFINITIONS'', a
1950 set of module flags (AUTOMATIC TAGS) and ``::= BEGIN''. The module
1951 ends with an ``END'' statement.
1952
1953
1954 \section{Some of the ASN.1 Basic Types}
1955
1956
1957 \subsection{The BOOLEAN type}
1958
1959 The BOOLEAN type models the simple binary TRUE/FALSE, YES/NO, ON/OFF
1960 or a similar kind of two-way choice.
1961
1962
1963 \subsection{The INTEGER type}
1964
1965 The INTEGER type is a signed natural number type without any restrictions
1966 on its size. If the automatic checking on INTEGER value bounds are
1967 necessary, the subtype constraints must be used.
1968 \begin{asn}
1969 SimpleInteger ::= INTEGER
1970
1971 -- An integer with a very limited range
1972 SmallPositiveInt ::= INTEGER (0..127)
1973
1974 -- Integer, negative
1975 NegativeInt ::= INTEGER (MIN..0)
1976 \end{asn}
1977
1978 \subsection{The ENUMERATED type}
1979
1980 The ENUMERATED type is semantically equivalent to the INTEGER type
1981 with some integer values explicitly named.
1982 \begin{asn}
1983 FruitId ::= ENUMERATED { apple(1), orange(2) }
1984
1985 -- The numbers in braces are optional,
1986 -- the enumeration can be performed
1987 -- automatically by the compiler
1988 ComputerOSType ::= 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}
1996
1997 \subsection{The OCTET STRING type}
1998
1999 This type models the sequence of 8-bit bytes. This may be used to
2000 transmit some opaque data or data serialized by other types of encoders
2001 (e.~g., video file, photo picture, etc).
2002
2003 \subsection{The OBJECT IDENTIFIER type}
2004
2005 The OBJECT IDENTIFIER is used to represent the unique identifier of
2006 any object, starting from the very root of the registration tree.
2007 If your organization needs to uniquely identify something (a router,
2008 a room, a person, a standard, or whatever), you are encouraged to
2009 get your own identification subtree at \url{http://www.iana.org/protocols/forms.htm}.
2010
2011 For example, the very first ASN.1 module in this Chapter (RectangleModule1)
2012 has the following OBJECT IDENTIFIER: 1 3 6 1 4 1 9363 1 5 2 1 1.
2013 \begin{asn}
2014 ExampleOID ::= OBJECT IDENTIFIER
2015
2016 rectangleModule1-oid ExampleOID
2017   ::= { 1 3 6 1 4 1 9363 1 5 2 1 1 }
2018
2019 -- An identifier of the Internet.
2020 internet-id OBJECT IDENTIFIER
2021   ::= { iso(1) identified-organization(3)
2022         dod(6) internet(1) }
2023 \end{asn}
2024 As you see, names are optional.
2025
2026
2027 \subsection{The RELATIVE-OID type}
2028
2029 The RELATIVE-OID type has the semantics of a subtree of an OBJECT
2030 IDENTIFIER. There may be no need to repeat the whole sequence of numbers
2031 from the root of the registration tree where the only thing of interest
2032 is some of the tree's subsequence.
2033 \begin{asn}
2034 this-document RELATIVE-OID ::= { docs(2) usage(1) }
2035
2036 this-example RELATIVE-OID ::= {
2037     this-document assorted-examples(0) this-example(1) }
2038 \end{asn}
2039
2040 \section{Some of the ASN.1 String Types}
2041
2042
2043 \subsection{The IA5String type}
2044
2045 This 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
2051 This 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
2057 This type represents the character string with the alphabet consisting
2058 of numbers (``0'' to ``9'') and a space.
2059
2060
2061 \subsection{The PrintableString type}
2062
2063 The character string with the following alphabet: space, ``\textbf{'}''
2064 (single quote), ``\textbf{(}'', ``\textbf{)}'', ``\textbf{+}'',
2065 ``\textbf{,}'' (comma), ``\textbf{-}'', ``\textbf{.}'', ``\textbf{/}'',
2066 digits (``0'' to ``9''), ``\textbf{:}'', ``\textbf{=}'', ``\textbf{?}'',
2067 upper-case and lower-case letters (``A'' to ``Z'' and ``a''
2068 to ``z'').
2069
2070
2071 \subsection{The VisibleString type}
2072
2073 The character string with the alphabet which is more or less a subset
2074 of ASCII between the space and the ``\textbf{\textasciitilde{}}''
2075 symbol (tilde).
2076
2077 Alternatively, the alphabet may be described as the PrintableString
2078 alphabet presented earlier, plus the following characters: ``\textbf{!}'',
2079 ``\textbf{``}'', ``\textbf{\#}'', ``\textbf{\$}'', ``\textbf{\%}'',
2080 ``\textbf{\&}'', ``\textbf{*}'', ``\textbf{;}'', ``\textbf{<}'',
2081 ``\textbf{>}'', ``\textbf{{[}}'', ``\textbf{\textbackslash{}}'',
2082 ``\textbf{{]}}'', ``\textbf{\textasciicircum{}}'', ``\textbf{\_}'',
2083 ``\textbf{`}`` (single left quote), ``\textbf{\{}'', ``\textbf{|}'',
2084 ``\textbf{\}}'', ``\textbf{\textasciitilde{}}''.
2085
2086
2087 \section{ASN.1 Constructed Types}
2088
2089
2090 \subsection{The SEQUENCE type}
2091
2092 This is an ordered collection of other simple or constructed types.
2093 The SEQUENCE constructed type resembles the C ``struct'' statement.
2094 \begin{asn}
2095 Address ::= 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}
2105
2106 \subsection{The SET type}
2107
2108 This is a collection of other simple or constructed types. Ordering
2109 is not important. The data may arrive in the order which is different
2110 from the order of specification. Data is encoded in the order not
2111 necessarily corresponding to the order of specification.
2112
2113
2114 \subsection{The CHOICE type}
2115
2116 This type is just a choice between the subtypes specified in it. The
2117 CHOICE type contains at most one of the subtypes specified, and it
2118 is always implicitly known which choice is being decoded or encoded.
2119 This one resembles the C ``union'' statement.
2120
2121 The following type defines a response code, which may be either an
2122 integer code or a boolean ``true''/``false'' code.
2123 \begin{asn}
2124 ResponseCode ::= CHOICE {
2125     intCode    INTEGER,
2126     boolCode   BOOLEAN
2127 }
2128 \end{asn}
2129
2130 \subsection{The SEQUENCE OF type}
2131
2132 This one is the list (array) of simple or constructed types:
2133 \begin{asn}
2134 -- Example 1
2135 ManyIntegers ::= SEQUENCE OF INTEGER
2136
2137 -- Example 2
2138 ManyRectangles ::= SEQUENCE OF Rectangle
2139
2140 -- More complex example:
2141 -- an array of structures defined in place.
2142 ManyCircles ::= SEQUENCE OF SEQUENCE {
2143                             radius INTEGER
2144                             }
2145 \end{asn}
2146
2147 \subsection{The SET OF type}
2148
2149 The SET OF type models the bag of structures. It resembles the SEQUENCE
2150 OF type, but the order is not important. The elements may arrive
2151 in the order which is not necessarily the same as the in-memory order
2152 on the remote machines.
2153 \begin{asn}
2154 -- A set of structures defined elsewhere
2155 SetOfApples :: SET OF Apple
2156
2157 -- Set of integers encoding the kind of a fruit
2158 FruitBag ::= SET OF ENUMERATED { apple, orange }
2159 \end{asn}
2160 \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
2166 between heterogeneous systems} --- Morgan Kaufmann Publishers, 2000.
2167 \url{http://asn1.elibel.tm.fr/en/book/}. ISBN:0-12-6333361-0.
2168
2169 \bibitem[ITU-T/ASN.1]{ITU-T/ASN.1}ITU-T Study Group 17 --- Languages
2170 for Telecommunication Systems \url{http://www.itu.int/ITU-T/studygroups/com17/languages/}
2171 \end{thebibliography}
2172
2173 \end{document}