-
Notifications
You must be signed in to change notification settings - Fork 554
/
asn1c-usage.tex
2173 lines (1720 loc) · 76.8 KB
/
asn1c-usage.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\batchmode
\documentclass[english,oneside,12pt]{book}
\usepackage[no-math]{fontspec}
\usepackage{MnSymbol}
\usepackage{xunicode}
\usepackage{xltxtra}
\usepackage[hmargin={1in,1in},vmargin={1.5in,1.5in}]{geometry}
\defaultfontfeatures{Mapping=tex-text}
\setmainfont{PT Sans}
\setsansfont{PT Sans}
\setmonofont{Consolas}
\usepackage{fancyhdr}
\usepackage{fancyref}
\usepackage{longtable}
\usepackage{array}
\usepackage{enumitem}
\usepackage{booktabs}
\usepackage{url}
\usepackage{xcolor}
\usepackage{listings}
\usepackage{setspace}
\usepackage{unicode-math}
\usepackage{perpage}
\MakePerPage{footnote}
\setstretch{1.1}
% Courier 10 Pitch
\def\courierFont{Courier10 BT WGL4}
%\def\courierFont{Consolas}
\setmonofont[Scale=1.05]{\courierFont}
\setmathfont[Scale=1.05]{Cambria Math}
\makeatletter
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Textclass specific LaTeX commands.
\lstloadlanguages{C,bash}
\newfontfamily\listingfont[Scale=1.05]{\courierFont}
\newfontfamily\inlinelistingfont[Scale=1.05]{\courierFont}
\definecolor{clrlcomment}{gray}{0.3}
\definecolor{clrlkeyword}{rgb}{0.588,0.145,0.18}
\newcommand{\listingkeyword}[1]{\color{clrlkeyword}{#1}}
\newcommand{\listingstring}[1]{\color{clrlcomment}{#1}}
\newcommand{\listingcomment}[1]{\color{clrlcomment}{#1}}
\lstset{tabsize=4,
showstringspaces=false,
showtabs=false,
showspaces=false,
keywordstyle=\listingkeyword,
stringstyle=\listingstring,
commentstyle=\listingcomment,
xleftmargin=\parindent,
columns=fixed,
escapechar=\%,
texcl
}
\lstdefinestyle{listingStyle}{
basicstyle=\small\listingfont,
stringstyle=\listingstring,
breaklines=true,
breakatwhitespace=true,
flexiblecolumns=false
}
\lstdefinelanguage{asn1}{
morekeywords={DEFINITIONS,BEGIN,END,AUTOMATIC,TAGS,SEQUENCE,SET,OF,CHOICE,OPTIONAL,INTEGER,MAX},
morecomment=[l]{--},
morecomment=[n]{/*}{*/}
}
\lstnewenvironment{signature}[1][]{\lstset{style=listingStyle,language=C,xleftmargin=0pt,#1}}{}
\lstnewenvironment{example}[1][]{\lstset{style=listingStyle,language=C,basicstyle=\scriptsize\listingfont,#1}}{}
\lstnewenvironment{codesample}[1][]{\lstset{style=listingStyle,language=C,#1}}{}
\lstnewenvironment{bash}[1][]{\lstset{style=listingStyle,language=bash,#1}}{}
\lstnewenvironment{asn}[1][]{\lstset{style=listingStyle,language=asn1,#1}}{}
\newcommand{\apisection}[2]{\clearpage\section{\label{#1}#2}}
\newcommand{\api}[2]{\hyperref[#1]{\code{#2}}}
\newcommand{\seealso}[2]{\api{#1}{#2} at page \pageref{#1}}
\newcommand{\code}[1]{\texttt{\textbf{\lstinline{#1}}}}
\newcommand{\cmd}[1]{\texttt{#1}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% User specified LaTeX commands.
\usepackage{extramarks}
\lhead{\firstxmark}
\rfoot{\lastxmark}
\definecolor{clrlink}{rgb}{0,0.4,0}
\definecolor{clrurl}{rgb}{0,0,.6}
\usepackage[colorlinks=true,
linkcolor={clrlink},
citecolor={clrlink},
urlcolor={clrurl},
pdfauthor={Lev Walkin},
pdftitle={Using the Open Source ASN.1 Compiler},
pdfkeywords={ASN.1,asn1c,compiler},
bookmarksopen,bookmarksopenlevel=1,
pdffitwindow,
xetex
]{hyperref}
\makeatother
\usepackage{babel}
\begin{document}
\title{Using the Open Source ASN.1 Compiler\\
\vspace*{0.4cm}
\Large Documentation for asn1c version \asnver{}}
\author{Lev Walkin <\href{mailto:vlm@lionet.info?Subject=asn1c}{vlm@lionet.info}>}
\pagestyle{fancy}
\fancyhead[L]{\leftmark}
\fancyhead[R]{\href{http://lionet.info/asn1c}{asn1c-\asnver}}
\maketitle
\tableofcontents{}
\chapter{\label{chap:Quick-start-examples}Quick start examples}
\section{A “Rectangle” converter and debugger}
One of the most common need is to create some sort of analysis tool
for the existing ASN.1 data files. Let's build a converter for existing
Rectangle binary files between BER, OER, PER, and XER (XML).
\begin{enumerate}
\item Create a file named \textbf{rectangle.asn} with the following contents:
\begin{asn}
RectangleModule DEFINITIONS ::= BEGIN
Rectangle ::= SEQUENCE {
height INTEGER,
width INTEGER
}
END
\end{asn}
\item Compile it into the set of .c and .h files using \cmd{asn1c} compiler:
\begin{bash}
asn1c -no-gen-example %\textbf{rectangle.asn}%
\end{bash}
\item Create the converter and dumper:
\begin{bash}
make -f converter-example.mk
\end{bash}
\item Done. The binary file converter is ready:
\begin{bash}
./converter-example -h
\end{bash}
\end{enumerate}
\section{A “Rectangle” Encoder}
This example will help you create a simple BER and XER encoder of
a ``Rectangle'' type used throughout this document.
\begin{enumerate}
\item Create a file named \textbf{rectangle.asn} with the following contents:
\begin{asn}
RectangleModule DEFINITIONS ::= BEGIN
Rectangle ::= SEQUENCE {
height INTEGER,
width INTEGER
}
END
\end{asn}
\item Compile it into the set of .c and .h files using asn1c compiler \cite{ASN1C}:
\begin{bash}
asn1c -no-gen-example %\textbf{rectangle.asn}%
\end{bash}
\item Alternatively, use the Online ASN.1 compiler \cite{AONL} by uploading
the \textbf{rectangle.asn} file into the Web form and unpacking the
produced archive on your computer.
\item By this time, you should have gotten multiple files in the current
directory, including the \textbf{Rectangle.c} and \textbf{Rectangle.h}.
\item Create a main() routine which creates the Rectangle\_t structure in
memory and encodes it using BER and XER encoding rules. Let's name
the file \textbf{main.c}:
\begin{example}
#include <stdio.h>
#include <sys/types.h>
#include <Rectangle.h> /* Rectangle ASN.1 type */
/* Write the encoded output into some FILE stream. */
static int write_out(const void *buffer, size_t size, void *app_key) {
FILE *out_fp = app_key;
size_t wrote = fwrite(buffer, 1, size, out_fp);
return (wrote == size) ? 0 : -1;
}
int main(int ac, char **av) {
Rectangle_t *rectangle; /* Type to encode */
asn_enc_rval_t ec; /* Encoder return value */
/* Allocate the Rectangle_t */
rectangle = calloc(1, sizeof(Rectangle_t)); /* not malloc! */
if(!rectangle) {
perror("calloc() failed");
exit(1);
}
/* Initialize the Rectangle members */
rectangle->height = 42; /* any random value */
rectangle->width = 23; /* any random value */
/* BER encode the data if filename is given */
if(ac < 2) {
fprintf(stderr, "Specify filename for BER output\n");
} else {
const char *filename = av[1];
FILE *fp = fopen(filename, "wb"); /* for BER output */
if(!fp) {
perror(filename);
exit(1);
}
/* Encode the Rectangle type as BER (DER) */
ec = der_encode(&asn_DEF_Rectangle, rectangle, write_out, fp);
fclose(fp);
if(ec.encoded == -1) {
fprintf(stderr, "Could not encode Rectangle (at %\%%s)\n",
ec.failed_type ? ec.failed_type->name : "unknown");
exit(1);
} else {
fprintf(stderr, "Created %\%%s with BER encoded Rectangle\n", filename);
}
}
/* Also print the constructed Rectangle XER encoded (XML) */
xer_fprint(stdout, &asn_DEF_Rectangle, rectangle);
return 0; /* Encoding finished successfully */
}
\end{example}
\item Compile all files together using C compiler (varies by platform):
\begin{bash}
cc -I. -o %\textbf{\emph{rencode}} \emph{*.c}%
\end{bash}
\item Done. You have just created the BER and XER encoder of a Rectangle
type, named \textbf{rencode}!
\end{enumerate}
\section{\label{sec:A-Rectangle-Decoder}A “Rectangle” Decoder}
This example will help you to create a simple BER decoder of a simple
``Rectangle'' type used throughout this document.
\begin{enumerate}
\item Create a file named \textbf{rectangle.asn} with the following contents:
\begin{asn}
RectangleModule DEFINITIONS ::= BEGIN
Rectangle ::= SEQUENCE {
height INTEGER,
width INTEGER
}
END
\end{asn}
\item Compile it into the set of .c and .h files using asn1c compiler \cite{ASN1C}:
\begin{bash}
asn1c -no-gen-example %\textbf{rectangle.asn}%
\end{bash}
\item Alternatively, use the Online ASN.1 compiler \cite{AONL} by uploading
the \textbf{rectangle.asn} file into the Web form and unpacking the
produced archive on your computer.
\item By this time, you should have gotten multiple files in the current
directory, including the \textbf{Rectangle.c} and \textbf{Rectangle.h}.
\item Create a main() routine which takes the binary input file, decodes
it as it were a BER-encoded Rectangle type, and prints out the text
(XML) representation of the Rectangle type. Let's name the file \textbf{main.c}:
\begin{example}
#include <stdio.h>
#include <sys/types.h>
#include <Rectangle.h> /* Rectangle ASN.1 type */
int main(int ac, char **av) {
char buf[1024]; /* Temporary buffer */
asn_dec_rval_t rval; /* Decoder return value */
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.}!}% */
FILE *fp; /* Input file handler */
size_t size; /* Number of bytes read */
char *filename; /* Input file name */
/* Require a single filename argument */
if(ac != 2) {
fprintf(stderr, "Usage: %\%%s <file.ber>\n", av[0]);
exit(1);
} else {
filename = av[1];
}
/* Open input file as read-only binary */
fp = fopen(filename, "rb");
if(!fp) {
perror(filename);
exit(1);
}
/* Read up to the buffer size */
size = fread(buf, 1, sizeof(buf), fp);
fclose(fp);
if(!size) {
fprintf(stderr, "%\%%s: Empty or broken\n", filename);
exit(1);
}
/* Decode the input buffer as Rectangle type */
rval = ber_decode(0, &asn_DEF_Rectangle, (void **)&rectangle, buf, size);
if(rval.code != RC_OK) {
fprintf(stderr, "%\%%s: Broken Rectangle encoding at byte %\%%ld\n", filename, (long)rval.consumed);
exit(1);
}
/* Print the decoded Rectangle type as XML */
xer_fprint(stdout, &asn_DEF_Rectangle, rectangle);
return 0; /* Decoding finished successfully */
}
\end{example}
\item Compile all files together using C compiler (varies by platform):
\begin{bash}
cc -I. -o %\textbf{\emph{rdecode}} \emph{*.c}%
\end{bash}
\item Done. You have just created the BER decoder of a Rectangle type,
named \textbf{rdecode}!
\end{enumerate}
\section{Adding constraints to a “Rectangle”}
This example shows how to add basic constraints to the ASN.1 specification
and how to invoke the constraints validation code in your application.
\begin{enumerate}
\item Create a file named \textbf{rectangle.asn} with the following contents:
\begin{asn}
RectangleModuleWithConstraints DEFINITIONS ::= BEGIN
Rectangle ::= SEQUENCE {
height INTEGER (0..100), -- Value range constraint
width INTEGER (0..MAX) -- Makes width non-negative
}
END
\end{asn}
\item Compile the file according to procedures shown in \fref{sec:A-Rectangle-Decoder}.
\item Modify the Rectangle type processing routine (you can start with the
main() routine shown in the \fref{sec:A-Rectangle-Decoder})
by placing the following snippet of code \emph{before} encoding and/or
\emph{after} decoding the Rectangle type:
\begin{example}
int ret; /* Return value */
char errbuf[128]; /* Buffer for error message */
size_t errlen = sizeof(errbuf); /* Size of the buffer */
/* ... here goes the Rectangle %\emph{decoding}% code ... */
ret = asn_check_constraints(&asn_DEF_Rectangle, rectangle, errbuf, &errlen);
/* assert(errlen < sizeof(errbuf)); // you may rely on that */
if(ret) {
fprintf(stderr, "Constraint validation failed: %\%%s\n", errbuf);
/* exit(...); // Replace with appropriate action */
}
/* ... here goes the Rectangle %\emph{encoding}% code ... */
\end{example}
\item Compile the resulting C code as shown in the previous chapters.
\item Test the constraints checking code by assigning integer value
101 to the \textbf{.height} member of the Rectangle structure, or
a negative value to the \textbf{.width} member.
The program will fail with ``Constraint validation failed'' message.
\item Done.
\end{enumerate}
\chapter{ASN.1 Compiler}
\section{The asn1c compiler tool}
The purpose of the ASN.1 compiler is to convert the specifications
in ASN.1 notation into some other language, such as C.
The compiler reads the specification and emits a series of target
language structures (C structs, unions, enums) describing the corresponding
ASN.1 types. The compiler also creates the code which allows automatic
serialization and deserialization of these structures using several
standardized encoding rules (BER, DER, OER, PER, XER).
Let's take the following ASN.1 example%
\footnote{\Fref{chap:Abstract-Syntax-Notation} provides a quick reference
on the ASN.1 notation.}:
\begin{asn}
RectangleModule DEFINITIONS ::= BEGIN
Rectangle ::= SEQUENCE {
height INTEGER, -- Height of the rectangle
width INTEGER -- Width of the rectangle
}
END
\end{asn}
The asn1c compiler reads this ASN.1 definition and produce the following
C type:
\begin{codesample}
typedef struct Rectangle_s {
long height;
long width;
} Rectangle_t;
\end{codesample}
The asn1c compiler also creates the code for converting this structure into
platform-independent wire representation and the decoder
of such wire representation back into local, machine-specific type.
These encoders and decoders are also called serializers and deserializers,
marshallers and unmarshallers, or codecs.
Compiling ASN.1 modules into C codecs can be as simple as invoking \cmd{asn1c}:
may be used to compile the ASN.1 modules:
\begin{bash}
asn1c %\emph{<modules.asn>}%
\end{bash}
If several ASN.1 modules contain interdependencies, all of the files
must be specified altogether:
\begin{bash}
asn1c %\emph{<module1.asn> <module2.asn> ...}%
\end{bash}
The compiler \textbf{-E} and \textbf{-EF} options are used for testing
the parser and the semantic fixer, respectively. These options will
instruct the compiler to dump out the parsed (and fixed, if \textbf{-F}
is involved) ASN.1 specification as it was understood
by the compiler. It might be useful to check whether a particular
syntactic construct is properly supported by the compiler.
\begin{bash}
asn1c %\textbf{-EF} \emph{<module-to-test.asn>}%
\end{bash}
The \textbf{-P} option is used to dump the compiled output on the
screen instead of creating a bunch of .c and .h files on disk in the
current directory. You would probably want to start with \textbf{-P}
option instead of creating a mess in your current directory. Another
option, \textbf{-R}, asks compiler to only generate the files which
need to be generated, and supress linking in the numerous support
files.
Print the compiled output instead of creating multiple source files:
\begin{bash}
asn1c %\textbf{-P} \emph{<module-to-compile-and-print.asn>}%
\end{bash}
\clearpage{}
\section{Compiler output}
The \cmd{asn1c} compiler produces a number of files:
\begin{itemize}
\item A set of .c and .h files for each type defined
in the ASN.1 specification. These files will be named similarly to
the ASN.1 types (\textbf{Rectangle.c} and \textbf{Rectangle.h} for the
RectangleModule ASN.1 module defined in the beginning of this document).
\item A set of helper .c and .h files which contain the generic encoders,
decoders and other useful routines.
Sometimes they are referred to by the term \emph{skeletons}.
There will be quite a few of them, some
of them are not even always necessary, but the overall amount of code
after compilation will be rather small anyway.
\item A \textbf{Makefile.am.libasncodecs} file which explicitly lists all the
generated files.
This makefile can be used on its own to build the just the codec library.
\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.
\item A \textbf{converter-example.mk} file which binds together
\textbf{Makefile.am.libasncodecs} and \textbf{converter-example.c}
to build a versatile converter and debugger for your data formats.
\end{itemize}
It is possible to compile everything with just a couple of instructions:
\begin{bash}
asn1c -pdu=%\emph{Rectangle}% *.asn
make -f converter-example.mk # If you use `make`
\end{bash}
or
\begin{bash}
asn1c *.asn
cc -I. -DPDU=%\emph{Rectangle}% -o rectangle.exe *.c # ... or like this
\end{bash}
Refer to the \fref{chap:Quick-start-examples} for a sample
\emph{int main()} function if you want some custom logic and not satisfied
with the supplied \emph{converter-example.c}.
\clearpage{}
\section{\label{sec:Command-line-options}Command line options}
The following table summarizes the \cmd{asn1c} command line options.
\renewcommand{\arraystretch}{1.33}
\begin{longtable}{lp{4in}}
\textbf{Stage Selection Options} & \textbf{Description}\\
\midrule
{\ttfamily -E} & {\small Stop after the parsing stage and print the reconstructed ASN.1
specification code to the standard output.}\\
{\ttfamily -F} & {\small Used together with \texttt{-E}, instructs the compiler to stop after
the ASN.1 syntax tree fixing stage and dump the reconstructed ASN.1
specification to the standard output.}\\
{\ttfamily -P} & {\small Dump the compiled output to the standard output instead of
creating the target language files on disk.}\\
{\ttfamily -R} & {\small Restrict the compiler to generate only the ASN.1 tables, omitting the usual support code.}\\
{\ttfamily -S~\emph{<directory>}} & {\small Use the specified directory with ASN.1 skeleton files.}\\
{\ttfamily -X} & {\small Generate the XML DTD for the specified ASN.1 modules.}\\\\
\textbf{Warning Options} & \textbf{Description}\\
\midrule
{\ttfamily -Werror} & {\small Treat warnings as errors; abort if any warning is produced.}\\
{\ttfamily -Wdebug-parser} & {\small Enable the parser debugging during the ASN.1 parsing stage.}\\
{\ttfamily -Wdebug-lexer} & {\small Enable the lexer debugging during the ASN.1 parsing stage.}\\
{\ttfamily -Wdebug-fixer} & {\small Enable the ASN.1 syntax tree fixer debugging during the fixing stage.}\\
{\ttfamily -Wdebug-compiler} & {\small Enable debugging during the actual compile time.}\\ \\
\textbf{Language Options} & \textbf{Description}\\
\midrule
{\ttfamily -fbless-SIZE} & {\small Allow SIZE() constraint for INTEGER, ENUMERATED, and other types for which this constraint is normally prohibited by the standard.
This is a violation of an ASN.1 standard and compiler may fail to produce the meaningful code.}\\
{\ttfamily -fcompound-names} & {\small Use complex names for C structures. Using complex names prevents
name clashes in case the module reuses the same identifiers in multiple
contexts.}\\
{\ttfamily -findirect-choice} & {\small When generating code for a CHOICE type, compile the CHOICE
members as indirect pointers instead of declaring them inline. Consider
using this option together with \texttt{-fno-include-deps}
to prevent circular references.}\\
{\ttfamily -fincludes-quoted} & {\small Generate \#include lines in "double" instead of <angle> quotes.}\\
{\ttfamily -fknown-extern-type=\emph{<name>}} & {\small Pretend the specified type is known. The compiler will assume
the target language source files for the given type have been provided
manually. }\\
{\ttfamily -fline-refs} & {\small Include ASN.1 module's line numbers in generated code comments.}\\
{\ttfamily -fno-constraints} & {\small Do not generate the ASN.1 subtype constraint checking code. This
may produce a shorter executable.}\\
{\ttfamily -fno-include-deps} & {\small Do not generate the courtesy \#include lines for non-critical dependencies.}\\
{\ttfamily -funnamed-unions} & {\small Enable unnamed unions in the definitions of target language's structures.}\\
{\ttfamily -fwide-types} & {\small Use the wide integer types (INTEGER\_t, REAL\_t) instead of machine's native data types (long, double). }\\\\
\textbf{Codecs Generation Options} & \textbf{Description}\\
\midrule
{\ttfamily -no-gen-OER} & {\small Do not generate the Octet Encoding Rules (OER, X.696) support code.}\\
{\ttfamily -no-gen-PER} & {\small Do not generate the Packed Encoding Rules (PER, X.691) support code.}\\
{\ttfamily -no-gen-example} & {\small Do not generate the ASN.1 format converter example.}\\
{\ttfamily -pdu=\{\textbf{all}|\textbf{auto}|\emph{Type}\}} & {\small Create a PDU table for specified types, or discover the Protocol Data Units automatically.
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.}\\ \\
\textbf{Output Options} & \textbf{Description}\\
\midrule
{\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.}\\
{\ttfamily -print-constraints} & {\small With \texttt{-EF}, this option instructs the compiler
to explain its internal understanding of subtype constraints.}\\
{\ttfamily -print-lines} & {\small Generate \texttt{``-{}- \#line''} comments
in \texttt{-E} output.}\\
\end{longtable}
\renewcommand{\arraystretch}{1}
\chapter{API reference}
The functions desribed in this chapter are to be used by the application
programmer. These functions won't likely change change or get removed until
the next major release.
The API calls not listed here are not public and should not be used by the
application level code.
\apisection{sec:ASN_STRUCT_FREE}{ASN\_STRUCT\_FREE() macro}
\subsection*{Synopsis}
\begin{signature}
#define ASN_STRUCT_FREE(type_descriptor, struct_ptr)
\end{signature}
\subsection*{Description}
Recursively releases memory occupied by the structure
described by the \code{type\_descriptor} and referred to
by the \code{struct\_ptr} pointer.
Does nothing when \code{struct\_ptr} is NULL.
\subsection*{Return values}
Does not return a value.
\subsection*{Example}
\begin{example}
Rectangle_t *rect = ...;
ASN_STRUCT_FREE(asn_DEF_Rectangle, rect);
\end{example}
\apisection{sec:ASN_STRUCT_RESET}{ASN\_STRUCT\_RESET() macro}
\subsection*{Synopsis}
\begin{signature}
#define ASN_STRUCT_RESET(type_descriptor, struct_ptr)
\end{signature}
\subsection*{Description}
Recursively releases memory occupied by the members of the structure
described by the \code{type\_descriptor} and referred to
by the \code{struct\_ptr} pointer.
Does not release the memory pointed to by \code{struct\_ptr} itself.
Instead it clears the memory block by filling it out with 0 bytes.
Does nothing when \code{struct\_ptr} is NULL.
\subsection*{Return values}
Does not return a value.
\subsection*{Example}
\begin{example}
struct my_figure { /* The custom structure */
int flags; /* <some custom member> */
/* The type is generated by the ASN.1 compiler */
Rectangle_t rect;
/* other members of the structure */
};
struct my_figure *fig = ...;
ASN_STRUCT_RESET(asn_DEF_Rectangle, &fig->rect);
\end{example}
\apisection{sec:asn_check_constraints}{asn\_check\_constraints()}
\subsection*{Synopsis}
\begin{signature}
int asn_check_constraints(
const asn_TYPE_descriptor_t *type_descriptor,
const void *struct_ptr, /* Target language's structure */
char *errbuf, /* Returned error description */
size_t *errlen /* Length of the error description */
);
\end{signature}
\subsection*{Description}
Validate a given structure according to the ASN.1 constraints.
If \code{errbuf} and \code{errlen} are given, they shall point to the
appropriate buffer space and its length before calling this function.
Alternatively, they could be passed as \code{NULL}s.
If constraints validation fails, \code{errlen} will contain the actual
number of bytes used in \code{errbuf} to encode an error message.
The message is going to be properly 0-terminated.
\subsection*{Return values}
This function returns 0 in case all ASN.1 constraints are met
and -1 if one or more ASN.1 constraints were violated.
\subsection*{Example}
\begin{codesample}[basicstyle=\scriptsize\listingfont]
Rectangle_t *rect = ...;
char errbuf[128]; /* Buffer for error message */
size_t errlen = sizeof(errbuf); /* Size of the buffer */
int ret = asn_check_constraints(&asn_DEF_Rectangle, rectangle, errbuf, &errlen);
/* assert(errlen < sizeof(errbuf)); // Guaranteed: you may rely on that */
if(ret) {
fprintf(stderr, "Constraint validation failed: %\%%s\n", errbuf);
}
\end{codesample}
\apisection{sec:asn_decode}{asn\_decode()}
\subsection*{Synopsis}
\begin{signature}
asn_dec_rval_t asn_decode(
const asn_codec_ctx_t *opt_codec_ctx,
enum asn_transfer_syntax syntax,
const asn_TYPE_descriptor_t *type_descriptor,
void **struct_ptr_ptr,/* Pointer to a target structure's ptr */
const void *buffer, /* Data to be decoded */
size_t size /* Size of that buffer */
);
\end{signature}
\subsection*{Description}
The \code{asn\_decode()} function parses the data given by the \code{buffer}
and \code{size} arguments. The encoding rules are specified in the \code{syntax}
argument and the type to be decoded is specified by the \code{type_descriptor}.
The \code{struct_ptr_ptr} must point to the memory location which contains the
pointer to the structure being decoded. Initially the \code{*struct_ptr_ptr}
pointer is typically set to 0. In that case, \code{asn\_decode()} will
dynamically allocate memory for the structure and its members as needed
during the parsing.
If \code{*struct\_ptr\_ptr} already points to some memory, the \code{asn\_decode()}
will allocate the subsequent members as needed during the parsing.
\subsection*{Return values}
\input{asn_dec_rval.inc}
The \code{.consumed} value is in bytes, even for PER decoding.
For PER, use \code{uper\_decode()} in case you need to get
the number of consumed bits.
\subsection*{Restartability}
Some transfer syntax parsers (such as ATS\_BER) support restartability.
That means that in case the buffer has less data than expected,
the \code{asn_decode()} will process whatever is available and ask for more
data to be provided using the RC\_WMORE return \code{.code}.
Note that in the RC\_WMORE case the decoder may have processed less data than
it is available in the buffer, which means that you must be able to arrange
the next buffer to contain the unprocessed part of the previous buffer.
The \code{RC_WMORE} code may still be returned by parser not supporting
restartabilty. In such cases, the partially decoded structure shall be
discarded and the next invocation should use the extended buffer to parse
from the very beginning.
\subsection*{Example}
\begin{example}
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.}!}% */
asn_dec_rval_t rval;
rval = asn_decode(0, ATS_BER, &asn_DEF_Rectangle, (void **)&rect, buffer, buf_size);
switch(rval.code) {
case RC_OK:
asn_fprint(stdout, &asn_DEF_Rectangle, rect);
ASN_STRUCT_FREE(&asn_DEF_Rectangle, rect);
break;
case RC_WMORE:
case RC_FAIL:
default:
ASN_STRUCT_FREE(&asn_DEF_Rectangle, rect);
break;
}
\end{example}
\subsection*{See also}
\seealso{sec:asn_fprint}{asn_fprint()}.
\apisection{sec:asn_encode}{asn\_encode()}
\subsection*{Synopsis}
\begin{signature}
#include <asn_application.h>
asn_enc_rval_t asn_encode(
const asn_codec_ctx_t *opt_codec_ctx,
enum asn_transfer_syntax syntax,
const asn_TYPE_descriptor_t *type_to_encode,
const void *structure_to_encode,
asn_app_consume_bytes_f *callback, void *callback_key);
\end{signature}
\subsection*{Description}
The \code{asn_encode()} function serializes the given \code{structure_to_encode} using the chosen ASN.1 transfer \code{syntax}.
During serialization, a user-specified \code{callback} is invoked zero
or more times with bytes of data to add to the output stream (if any), and
the \code{callback_key}. The signature for the callback is as follows:
\begin{signature}
typedef int(asn_app_consume_bytes_f)(const void *buffer, size_t size, void *callback_key);
\end{signature}
\subsection*{Return values}
\input{asn_enc_rval.inc}
The serialized output size is returned in \textbf{bytes} irrespectively of the
ASN.1 transfer \code{syntax} chosen.\footnote{This is different from some
lower level encoding functions, such as \api{sec:uper_encode}{uper_encode()},
which returns the number of encoded \emph{bits} instead of bytes.}
On error (when \code{.encoded} is set to -1),
the \code{errno} is set to one of the following values:
\begin{tabular}[h!]{ll}
\texttt{EINVAL} & Incorrect parameters to the function, such as NULLs \\
\texttt{ENOENT} & Encoding transfer syntax is not defined (for this type) \\
\texttt{EBADF} & The structure has invalid form or content constraint failed \\
\texttt{EIO} & The callback has returned negative value during encoding
\end{tabular}
\subsection*{Example}
\begin{example}
static int
save_to_file(const void *data, size_t size, void *key) {
FILE *fp = key;
return (fwrite(data, 1, size, fp) == size) ? 0 : -1;
}
Rectangle_t *rect = ...;
FILE *fp = ...;
asn_enc_rval_t er;
er = asn_encode(0, ATS_DER, &asn_DEF_Rectangle, rect, save_to_file, fp);
if(er.encoded == -1) {
fprintf(stderr, "Failed to encode %\%%s\n", asn_DEF_Rectangle.name);
} else {
fprintf(stderr, "%\%%s encoded in %\%%zd bytes\n", asn_DEF_Rectangle.name, er.encoded);
}
\end{example}
\apisection{sec:asn_encode_to_buffer}{asn\_encode\_to\_buffer()}
\subsection*{Synopsis}
\begin{signature}
#include <asn_application.h>
asn_enc_rval_t asn_encode_to_buffer(
const asn_codec_ctx_t *opt_codec_ctx,
enum asn_transfer_syntax syntax,
const asn_TYPE_descriptor_t *type_to_encode,
const void *structure_to_encode,
void *buffer, size_t buffer_size);
\end{signature}
\subsection*{Description}
The \code{asn_encode_to_buffer()} function serializes the given \code{structure_to_encode} using the chosen ASN.1 transfer \code{syntax}.
The function places the serialized data into the given
\code{buffer} of size \code{buffer_size}.
\subsection*{Return values}
\input{asn_enc_rval.inc}
The serialized output size is returned in \textbf{bytes} irrespectively of the
ASN.1 transfer \code{syntax} chosen.\footnote{This is different from some
lower level encoding functions, such as \api{sec:uper_encode}{uper_encode()},
which returns the number of encoded \emph{bits} instead of bytes.}
If \code{.encoded} size exceeds the specified \code{buffer_size},
the serialization effectively failed due to insufficient space. The function
will succeed if subsequently called with buffer size no less than the returned
\code{.encoded} size. This behavior modeled after \code{snprintf()}.
On error (when \code{.encoded} is set to -1),
the \code{errno} is set to one of the following values:
\begin{tabular}[h!]{ll}
\texttt{EINVAL} & Incorrect parameters to the function, such as NULLs \\
\texttt{ENOENT} & Encoding transfer syntax is not defined (for this type) \\
\texttt{EBADF} & The structure has invalid form or content constraint failed
\end{tabular}
\subsection*{Example}
\begin{example}
Rectangle_t *rect = ...;
uint8_t buffer[128];
asn_enc_rval_t er;
er = asn_encode_to_buffer(0, ATS_DER, &asn_DEF_Rectangle, rect, buffer, sizeof(buffer));
if(er.encoded == -1) {
fprintf(stderr, "Serialization of %\%%s failed.\n", asn_DEF_Rectangle.name);
} else if(er.encoded > sizeof(buffer)) {
fprintf(stderr, "Buffer of size %\%%zu is too small for %\%%s, need %\%%zu\n",
buf_size, asn_DEF_Rectangle.name, er.encoded);
}
\end{example}
\subsection*{See also}
\seealso{sec:asn_encode_to_new_buffer}{asn_encode_to_new_buffer()}.
\apisection{sec:asn_encode_to_new_buffer}{asn\_encode\_to\_new\_buffer()}
\subsection*{Synopsis}
\begin{signature}
#include <asn_application.h>
typedef struct {
void *buffer; /* NULL if failed to encode. */
asn_enc_rval_t result;
} asn_encode_to_new_buffer_result_t;
asn_encode_to_new_buffer_result_t asn_encode_to_new_buffer(
const asn_codec_ctx_t *opt_codec_ctx,
enum asn_transfer_syntax syntax,
const asn_TYPE_descriptor_t *type_to_encode,
const void *structure_to_encode);
\end{signature}
\subsection*{Description}
The \code{asn_encode_to_new_buffer()} function serializes the given \code{structure_to_encode} using the chosen ASN.1 transfer \code{syntax}.
The function places the serialized data into the newly allocated buffer
which it returns in a compound structure.
\subsection*{Return values}
On failure, the \code{.buffer} is set to \code{NULL}
and \code{.result.encoded} is set to -1. The global \code{errno} is set
to one of the following values:
\begin{tabular}[h!]{ll}
\texttt{EINVAL} & Incorrect parameters to the function, such as NULLs \\
\texttt{ENOENT} & Encoding transfer syntax is not defined (for this type) \\
\texttt{EBADF} & The structure has invalid form or content constraint failed \\
\texttt{ENOMEM} & Memory allocation failed due to system or internal limits
\end{tabular}
\noindent{}On success, the \code{.result.encoded} is set to the number of
\textbf{bytes} that it took to serialize the structure.
The \code{.buffer} contains the serialized content.
The user is responsible for freeing the \code{.buffer}.
\subsection*{Example}
\begin{example}
asn_encode_to_new_buffer_result_t res;
res = asn_encode_to_new_buffer(0, ATS_DER, &asn_DEF_Rectangle, rect);
if(res.buffer) {
/* Encoded successfully. */
free(res.buffer);
} else {
fprintf(stderr, "Failed to encode %\%%s, estimated %\%%zd bytes\n",
asn_DEF_Rectangle.name, res.result.encoded);
}
\end{example}
\subsection*{See also}
\seealso{sec:asn_encode_to_buffer}{asn_encode_to_buffer()}.
\apisection{sec:asn_fprint}{asn\_fprint()}
\subsection*{Synopsis}
\begin{signature}
int asn_fprint(FILE *stream, /* Destination file */
const asn_TYPE_descriptor_t *type_descriptor,
const void *struct_ptr /* Structure to be printed */
);
\end{signature}
\subsection*{Description}
The \code{asn_fprint()} function prints human readable description
of the target language's structure into the file stream specified by
\code{stream} pointer.
The output format does not conform to any standard.
The \code{asn_fprint()} function attempts to
produce a valid output even for incomplete and broken structures, which
makes it more suitable for debugging complex cases than
\api{sec:xer_fprint}{xer_fprint()}.
\subsection*{Return values}
\begin{tabular}[h!]{rl}
0 & Output was successfully made \\
-1 & Error printing out the structure
\end{tabular}
\subsection*{Example}
\begin{example}
Rectangle_t *rect = ...;
asn_fprint(stdout, &asn_DEF_Rectangle, rect);
\end{example}
\subsection*{See also}
\seealso{sec:xer_fprint}{xer_fprint()}.
\apisection{sec:asn_random_fill}{asn\_random\_fill()}
\subsection*{Synopsis}
\begin{signature}
int asn_random_fill(
const asn_TYPE_descriptor_t *type_descriptor,
void **struct_ptr_ptr,/* Pointer to a target structure's ptr */
size_t approx_max_length_limit
);
\end{signature}
\subsection*{Description}
Create or initialize a structure with random contents, according to the type
specification and optional member constraints.
For best results the code should be generated without \cmd{-no-gen-PER}