1 <chapter id="asn"><title>The Z39.50 ASN.1 Module</title>
2 <sect1 id="asn.introduction"><title>Introduction</title>
4 The &asn; module provides you with a set of C struct definitions for the
5 various PDUs of the Z39.50 protocol, as well as for the complex types
6 appearing within the PDUs. For the primitive data types, the C
7 representation often takes the form of an ordinary C language type,
8 such as <literal>Odr_int</literal> which is equivalent to an integral
9 C integer. For ASN.1 constructs that have no direct
10 representation in C, such as general octet strings and bit strings,
11 the &odr; module (see section <link linkend="odr">The ODR Module</link>)
12 provides auxiliary definitions.
15 The &asn; module is located in sub directory <filename>z39.50</filename>.
16 There you'll find C files that implements encoders and decoders for the
17 Z39.50 types. You'll also find the protocol definitions:
18 <filename>z3950v3.asn</filename>, <filename>esupdate.asn</filename>,
22 <sect1 id="asn.preparing"><title>Preparing PDUs</title>
25 A structure representing a complex ASN.1 type doesn't in itself contain the
26 members of that type. Instead, the structure contains
27 <emphasis>pointers</emphasis> to the members of the type.
28 This is necessary, in part, to allow a mechanism for specifying which
29 of the optional structure (SEQUENCE) members are present, and which
30 are not. It follows that you will need to somehow provide space for
31 the individual members of the structure, and set the pointers to
35 The conversion routines don't care how you allocate and maintain your
36 C structures - they just follow the pointers that you provide.
37 Depending on the complexity of your application, and your personal
38 taste, there are at least three different approaches that you may take
39 when you allocate the structures.
43 You can use static or automatic local variables in the function that
44 prepares the PDU. This is a simple approach, and it provides the most
45 efficient form of memory management. While it works well for flat
46 PDUs like the InitReqest, it will generally not be sufficient for say,
47 the generation of an arbitrarily complex RPN query structure.
50 You can individually create the structure and its members using the
51 <function>malloc(2)</function> function. If you want to ensure that
52 the data is freed when it is no longer needed, you will have to
53 define a function that individually releases each member of a
54 structure before freeing the structure itself.
57 You can use the <function>odr_malloc()</function> function (see
58 <xref linkend="odr.use"/> for details). When you use
59 <function>odr_malloc()</function>, you can release all of the
60 allocated data in a single operation, independent of any pointers and
61 relations between the data. <function>odr_malloc()</function> is based on a
62 "nibble-memory"
63 scheme, in which large portions of memory are allocated, and then
64 gradually handed out with each call to <function>odr_malloc()</function>.
65 The next time you call <function>odr_reset()</function>, all of the
66 memory allocated since the last call is recycled for future use (actually,
67 it is placed on a free-list).
70 You can combine all of the methods described here. This will often be
71 the most practical approach. For instance, you might use
72 <function>odr_malloc()</function> to allocate an entire structure and
73 some of its elements, while you leave other elements pointing to global
74 or per-session default variables.
78 The &asn; module provides an important aid in creating new PDUs. For
79 each of the PDU types (say, <function>Z_InitRequest</function>), a
80 function is provided that allocates and initializes an instance of
81 that PDU type for you. In the case of the InitRequest, the function is
82 simply named <function>zget_InitRequest()</function>, and it sets up
83 reasonable default value for all of the mandatory members. The optional
84 members are generally initialized to null pointers. This last aspect
85 is very important: it ensures that if the PDU definitions are
86 extended after you finish your implementation (to accommodate
87 new versions of the protocol, say), you won't get into trouble with
88 uninitialized pointers in your structures. The functions use
89 <function>odr_malloc()</function> to
90 allocate the PDUs and its members, so you can free everything again with a
91 single call to <function>odr_reset()</function>. We strongly recommend
92 that you use the <literal>zget_*</literal>
93 functions whenever you are preparing a PDU (in a C++ API, the
94 <literal>zget_</literal>
95 functions would probably be promoted to constructors for the
99 The prototype for the individual PDU types generally look like this:
102 Z_<type> *zget_<type>(ODR o);
110 Z_InitRequest *zget_InitRequest(ODR o);
114 The &odr; handle should generally be your encoding stream, but it
118 As well as the individual PDU functions, a function
119 <function>zget_APDU()</function> is provided, which allocates
120 a top-level Z-APDU of the type requested:
124 Z_APDU *zget_APDU(ODR o, int which);
128 The <varname>which</varname> parameter is (of course) the discriminator
129 belonging to the <varname>Z_APDU</varname> <literal>CHOICE</literal> type.
130 All of the interface described here is provided by the &asn; module, and
131 you access it through the <filename>proto.h</filename> header file.
135 <sect1 id="asn.external"><title>EXTERNAL Data</title>
138 In order to achieve extensibility and adaptability to different
139 application domains, the new version of the protocol defines many
140 structures outside of the main ASN.1 specification, referencing them
141 through ASN.1 EXTERNAL constructs. To simplify the construction and
142 access to the externally referenced data, the &asn; module defines a
143 specialized version of the EXTERNAL construct, called
144 <literal>Z_External</literal>.It is defined thus:
148 typedef struct Z_External
150 Odr_oid *direct_reference;
151 int *indirect_reference;
156 Z_External_single = 0,
158 Z_External_arbitrary,
162 Z_External_explainRecord,
163 Z_External_resourceReport1,
164 Z_External_resourceReport2
172 Odr_any *single_ASN1_type;
173 Odr_oct *octet_aligned;
174 Odr_bitmask *arbitrary;
178 Z_ExplainRecord *explainRecord;
179 Z_ResourceReport1 *resourceReport1;
180 Z_ResourceReport2 *resourceReport2;
189 When decoding, the &asn; module will attempt to determine which
190 syntax describes the data by looking at the reference fields
191 (currently only the direct-reference). For ASN.1 structured data, you
192 need only consult the <literal>which</literal> field to determine the
193 type of data. You can the access the data directly through the union.
194 When constructing data for encoding, you set the union pointer to point
195 to the data, and set the <literal>which</literal> field accordingly.
196 Remember also to set the direct (or indirect) reference to the correct
197 OID for the data type.
198 For non-ASN.1 data such as MARC records, use the
199 <literal>octet_aligned</literal> arm of the union.
203 Some servers return ASN.1 structured data values (eg. database
204 records) as BER-encoded records placed in the
205 <literal>octet-aligned</literal> branch of the EXTERNAL CHOICE.
206 The ASN-module will <emphasis>not</emphasis> automatically decode
207 these records. To help you decode the records in the application, the
212 Z_ext_typeent *z_ext_gettypebyref(const oid *oid);
216 Can be used to retrieve information about the known, external data
217 types. The function return a pointer to a static area, or NULL, if no
218 match for the given direct reference is found. The
219 <literal>Z_ext_typeent</literal>
224 typedef struct Z_ext_typeent
226 int oid[OID_SIZE]; /* the direct-reference OID. */
227 int what; /* discriminator value for the external CHOICE */
228 Odr_fun fun; /* decoder function */
233 The <literal>what</literal> member contains the
234 <literal>Z_External</literal> union discriminator value for the
235 given type: For the SUTRS record syntax, the value would be
236 <literal>Z_External_sutrs</literal>.
237 The <literal>fun</literal> member contains a pointer to the
238 function which encodes/decodes the given type. Again, for the SUTRS
239 record syntax, the value of <literal>fun</literal> would be
240 <literal>z_SUTRS</literal> (a function pointer).
244 If you receive an EXTERNAL which contains an octet-string value that
245 you suspect of being an ASN.1-structured data value, you can use
246 <literal>z_ext_gettypebyref</literal> to look for the provided
248 If the return value is different from NULL, you can use the provided
249 function to decode the BER string (see <xref linkend="odr.use"/>
254 If you want to <emphasis>send</emphasis> EXTERNALs containing
255 ASN.1-structured values in the occtet-aligned branch of the CHOICE, this
256 is possible too. However, on the encoding phase, it requires a somewhat
257 involved juggling around of the various buffers involved.
260 If you need to add new, externally defined data types, you must update
261 the struct above, in the source file <filename>prt-ext.h</filename>, as
262 well as the encoder/decoder in the file <filename>prt-ext.c</filename>.
263 When changing the latter, remember to update both the
264 <literal>arm</literal> arrary and the list
265 <literal>type_table</literal>, which drives the CHOICE biasing that
266 is necessary to tell the different, structured types apart
272 Eventually, the EXTERNAL processing will most likely
273 automatically insert the correct OIDs or indirect-refs. First,
274 however, we need to determine how application-context management
275 (specifically the presentation-context-list) should fit into the
281 <sect1 id="asn.pdu"><title>PDU Contents Table</title>
284 We include, for reference, a listing of the fields of each top-level
285 PDU, as well as their default settings.
288 <table frame="top" id="asn.default.initialize.request">
289 <title>Default settings for PDU Initialize Request</title>
291 <colspec colwidth="7*" colname="field"></colspec>
292 <colspec colwidth="5*" colname="type"></colspec>
293 <colspec colwidth="7*" colname="value"></colspec>
298 <entry>Default Value</entry>
303 referenceId</entry><entry>Z_ReferenceId</entry><entry>NULL
306 protocolVersion</entry><entry>Odr_bitmask</entry><entry>Empty bitmask
309 options</entry><entry>Odr_bitmask</entry><entry>Empty bitmask
312 preferredMessageSize</entry><entry>Odr_int</entry><entry>30*1024
315 maximumRecordSize</entry><entry>Odr_int</entry><entry>30*1024
318 idAuthentication</entry><entry>Z_IdAuthentication</entry><entry>NULL
321 implementationId</entry><entry>char*</entry><entry>"81"
324 implementationName</entry><entry>char*</entry><entry>"YAZ"
327 implementationVersion</entry><entry>char*</entry><entry>YAZ_VERSION
330 userInformationField</entry><entry>Z_UserInformation</entry><entry>NULL
333 otherInfo</entry><entry>Z_OtherInformation</entry><entry>NULL
339 <table frame="top" id="asn.default.initialize.response">
340 <title>Default settings for PDU Initialize
343 <colspec colwidth="7*" colname="field"></colspec>
344 <colspec colwidth="5*" colname="type"></colspec>
345 <colspec colwidth="7*" colname="value"></colspec>
350 <entry>Default Value</entry>
355 referenceId</entry><entry>Z_ReferenceId</entry><entry>NULL
358 protocolVersion</entry><entry>Odr_bitmask</entry><entry>Empty bitmask
361 options</entry><entry>Odr_bitmask</entry><entry>Empty bitmask
364 preferredMessageSize</entry><entry>Odr_int</entry><entry>30*1024
367 maximumRecordSize</entry><entry>Odr_int</entry><entry>30*1024
370 result</entry><entry>Odr_bool</entry><entry>TRUE
373 implementationId</entry><entry>char*</entry><entry>"id)"
376 implementationName</entry><entry>char*</entry><entry>"YAZ"
379 implementationVersion</entry><entry>char*</entry><entry>YAZ_VERSION
382 userInformationField</entry><entry>Z_UserInformation</entry><entry>NULL
385 otherInfo</entry><entry>Z_OtherInformation</entry><entry>NULL
391 <table frame="top" id="asn.default.search.request">
392 <title>Default settings for PDU Search Request</title>
394 <colspec colwidth="7*" colname="field"></colspec>
395 <colspec colwidth="5*" colname="type"></colspec>
396 <colspec colwidth="7*" colname="value"></colspec>
401 <entry>Default Value</entry>
406 referenceId</entry><entry>Z_ReferenceId</entry><entry>NULL
409 smallSetUpperBound</entry><entry>Odr_int</entry><entry>0
412 largeSetLowerBound</entry><entry>Odr_int</entry><entry>1
415 mediumSetPresentNumber</entry><entry>Odr_int</entry><entry>0
418 replaceIndicator</entry><entry>Odr_bool</entry><entry>TRUE
421 resultSetName</entry><entry>char *</entry><entry>"default"
424 num_databaseNames</entry><entry>Odr_int</entry><entry>0
427 databaseNames</entry><entry>char **</entry><entry>NULL
430 smallSetElementSetNames</entry><entry>Z_ElementSetNames
434 mediumSetElementSetNames</entry><entry>Z_ElementSetNames
438 preferredRecordSyntax</entry><entry>Odr_oid</entry><entry>NULL
441 query</entry><entry>Z_Query</entry><entry>NULL
444 additionalSearchInfo</entry><entry>Z_OtherInformation
448 otherInfo</entry><entry>Z_OtherInformation</entry><entry>NULL
454 <table frame="top" id="asn.default.search.response">
455 <title>Default settings for PDU Search Response</title>
457 <colspec colwidth="7*" colname="field"></colspec>
458 <colspec colwidth="5*" colname="type"></colspec>
459 <colspec colwidth="7*" colname="value"></colspec>
464 <entry>Default Value</entry>
470 referenceId</entry><entry>Z_ReferenceId</entry><entry>NULL
473 resultCount</entry><entry>Odr_int</entry><entry>0
476 numberOfRecordsReturned</entry><entry>Odr_int</entry><entry>0
479 nextResultSetPosition</entry><entry>Odr_int</entry><entry>0
482 searchStatus</entry><entry>Odr_bool</entry><entry>TRUE
485 resultSetStatus</entry><entry>Odr_int</entry><entry>NULL
488 presentStatus</entry><entry>Odr_int</entry><entry>NULL
491 records</entry><entry>Z_Records</entry><entry>NULL
494 additionalSearchInfo</entry>
495 <entry>Z_OtherInformation</entry><entry>NULL
498 otherInfo</entry><entry>Z_OtherInformation</entry><entry>NULL
504 <table frame="top" id="asn.default.present.request">
505 <title>Default settings for PDU Present Request</title>
507 <colspec colwidth="7*" colname="field"></colspec>
508 <colspec colwidth="5*" colname="type"></colspec>
509 <colspec colwidth="7*" colname="value"></colspec>
514 <entry>Default Value</entry>
519 referenceId</entry><entry>Z_ReferenceId</entry><entry>NULL
522 resultSetId</entry><entry>char*</entry><entry>"default"
525 resultSetStartPoint</entry><entry>Odr_int</entry><entry>1
528 numberOfRecordsRequested</entry><entry>Odr_int</entry><entry>10
531 num_ranges</entry><entry>Odr_int</entry><entry>0
534 additionalRanges</entry><entry>Z_Range</entry><entry>NULL
537 recordComposition</entry><entry>Z_RecordComposition</entry><entry>NULL
540 preferredRecordSyntax</entry><entry>Odr_oid</entry><entry>NULL
543 maxSegmentCount</entry><entry>Odr_int</entry><entry>NULL
546 maxRecordSize</entry><entry>Odr_int</entry><entry>NULL
549 maxSegmentSize</entry><entry>Odr_int</entry><entry>NULL
552 otherInfo</entry><entry>Z_OtherInformation</entry><entry>NULL
558 <table frame="top" id="asn.default.present.response">
559 <title>Default settings for PDU Present Response</title>
561 <colspec colwidth="7*" colname="field"></colspec>
562 <colspec colwidth="5*" colname="type"></colspec>
563 <colspec colwidth="7*" colname="value"></colspec>
568 <entry>Default Value</entry>
573 referenceId</entry><entry>Z_ReferenceId</entry><entry>NULL
576 numberOfRecordsReturned</entry><entry>Odr_int</entry><entry>0
579 nextResultSetPosition</entry><entry>Odr_int</entry><entry>0
582 presentStatus</entry><entry>Odr_int</entry><entry>Z_PresentStatus_success
585 records</entry><entry>Z_Records</entry><entry>NULL
588 otherInfo</entry><entry>Z_OtherInformation</entry><entry>NULL
594 <table frame="top" id="asn.default.delete.result.set.request">
595 <title>Default settings for Delete Result Set Request
598 <colspec colwidth="7*" colname="field"></colspec>
599 <colspec colwidth="5*" colname="type"></colspec>
600 <colspec colwidth="7*" colname="value"></colspec>
605 <entry>Default Value</entry>
609 <row><entry>referenceId
610 </entry><entry>Z_ReferenceId</entry><entry>NULL
613 deleteFunction</entry><entry>Odr_int</entry><entry>Z_DeleteResultSetRequest_list
616 num_ids</entry><entry>Odr_int</entry><entry>0
619 resultSetList</entry><entry>char**</entry><entry>NULL
622 otherInfo</entry><entry>Z_OtherInformation</entry><entry>NULL
628 <table frame="top" id="asn.default.delete.result.set.response">
629 <title>Default settings for Delete Result Set Response
632 <colspec colwidth="7*" colname="field"></colspec>
633 <colspec colwidth="5*" colname="type"></colspec>
634 <colspec colwidth="7*" colname="value"></colspec>
639 <entry>Default Value</entry>
644 referenceId</entry><entry>Z_ReferenceId</entry><entry>NULL
647 deleteOperationStatus</entry><entry>Odr_int</entry>
648 <entry>Z_DeleteStatus_success</entry></row>
650 num_statuses</entry><entry>Odr_int</entry><entry>0
653 deleteListStatuses</entry><entry>Z_ListStatus**</entry><entry>NULL
656 numberNotDeleted</entry><entry>Odr_int</entry><entry>NULL
659 num_bulkStatuses</entry><entry>Odr_int</entry><entry>0
662 bulkStatuses</entry><entry>Z_ListStatus</entry><entry>NUL
665 deleteMessage</entry><entry>char*</entry><entry>NULL
668 otherInfo</entry><entry>Z_OtherInformation</entry><entry>NULL
674 <table frame="top" id="asn.default.scan.request">
675 <title>Default settings for Scan Request
678 <colspec colwidth="7*" colname="field"></colspec>
679 <colspec colwidth="5*" colname="type"></colspec>
680 <colspec colwidth="7*" colname="value"></colspec>
685 <entry>Default Value</entry>
690 referenceId</entry><entry>Z_ReferenceId</entry><entry>NULL
693 num_databaseNames</entry><entry>Odr_int</entry><entry>0
696 databaseNames</entry><entry>char**</entry><entry>NULL
699 attributeSet</entry><entry>Odr_oid</entry><entry>NULL
702 termListAndStartPoint</entry><entry>Z_AttributesPlus...
703 </entry><entry>NULL</entry></row>
705 stepSize</entry><entry>Odr_int</entry><entry>NULL
708 numberOfTermsRequested</entry><entry>Odr_int</entry><entry>20
711 preferredPositionInResponse</entry><entry>Odr_int</entry><entry>NULL
714 otherInfo</entry><entry>Z_OtherInformation</entry><entry>NULL
720 <table frame="top" id="asn.default.scan.response">
721 <title>Default settings for Scan Response
724 <colspec colwidth="7*" colname="field"></colspec>
725 <colspec colwidth="5*" colname="type"></colspec>
726 <colspec colwidth="7*" colname="value"></colspec>
731 <entry>Default Value</entry>
737 referenceId</entry><entry>Z_ReferenceId</entry><entry>NULL
740 stepSize</entry><entry>Odr_int</entry><entry>NULL
743 scanStatus</entry><entry>Odr_int</entry><entry>Z_Scan_success
746 numberOfEntriesReturned</entry><entry>Odr_int</entry><entry>0
749 positionOfTerm</entry><entry>Odr_int</entry><entry>NULL
752 entries</entry><entry>Z_ListEntris</entry><entry>NULL
755 attributeSet</entry><entry>Odr_oid</entry><entry>NULL
758 otherInfo</entry><entry>Z_OtherInformation</entry><entry>NULL
764 <table frame="top" id="asn.default.trigger.resource.control.request">
765 <title>Default settings for Trigger Resource Control Request </title>
767 <colspec colwidth="7*" colname="field"></colspec>
768 <colspec colwidth="5*" colname="type"></colspec>
769 <colspec colwidth="7*" colname="value"></colspec>
774 <entry>Default Value</entry>
780 referenceId</entry><entry>Z_ReferenceId</entry><entry>NULL
783 requestedAction</entry><entry>Odr_int</entry><entry>
784 Z_TriggerResourceCtrl_resou..
787 prefResourceReportFormat</entry><entry>Odr_oid</entry><entry>NULL
790 resultSetWanted</entry><entry>Odr_bool</entry><entry>NULL
793 otherInfo</entry><entry>Z_OtherInformation</entry><entry>NULL
800 <table frame="top" id="asn.default.resource.control.request">
801 <title>Default settings for Resource Control Request</title>
803 <colspec colwidth="7*" colname="field"></colspec>
804 <colspec colwidth="5*" colname="type"></colspec>
805 <colspec colwidth="7*" colname="value"></colspec>
810 <entry>Default Value</entry>
816 referenceId</entry><entry>Z_ReferenceId</entry><entry>NULL
819 suspendedFlag</entry><entry>Odr_bool</entry><entry>NULL
822 resourceReport</entry><entry>Z_External</entry><entry>NULL
825 partialResultsAvailable</entry><entry>Odr_int</entry><entry>NULL
828 responseRequired</entry><entry>Odr_bool</entry><entry>FALSE
831 triggeredRequestFlag</entry><entry>Odr_bool</entry><entry>NULL
834 otherInfo</entry><entry>Z_OtherInformation</entry><entry>NULL
840 <table frame="top" id="asn.default.resource.control.response">
841 <title>Default settings for Resource Control Response</title>
843 <colspec colwidth="7*" colname="field"></colspec>
844 <colspec colwidth="5*" colname="type"></colspec>
845 <colspec colwidth="7*" colname="value"></colspec>
850 <entry>Default Value</entry>
856 referenceId</entry><entry>Z_ReferenceId</entry><entry>NULL
859 continueFlag</entry><entry>bool_t</entry><entry>TRUE
862 resultSetWanted</entry><entry>bool_t</entry><entry>NULL
865 otherInfo</entry><entry>Z_OtherInformation</entry><entry>NULL
871 <table frame="top" id="asn.default.access.control.request">
872 <title>Default settings for Access Control Request</title>
874 <colspec colwidth="7*" colname="field"></colspec>
875 <colspec colwidth="5*" colname="type"></colspec>
876 <colspec colwidth="7*" colname="value"></colspec>
881 <entry>Default Value</entry>
887 referenceId</entry><entry>Z_ReferenceId</entry><entry>NULL
890 which</entry><entry>enum</entry><entry>Z_AccessRequest_simpleForm;
893 u</entry><entry>union</entry><entry>NULL
896 otherInfo</entry><entry>Z_OtherInformation</entry><entry>NULL
902 <table frame="top" id="asn.default.access.control.response">
903 <title>Default settings for Access Control Response</title>
905 <colspec colwidth="7*" colname="field"></colspec>
906 <colspec colwidth="5*" colname="type"></colspec>
907 <colspec colwidth="7*" colname="value"></colspec>
912 <entry>Default Value</entry>
918 referenceId</entry><entry>Z_ReferenceId</entry><entry>NULL
921 which</entry><entry>enum</entry><entry>Z_AccessResponse_simpleForm
924 u</entry><entry>union</entry><entry>NULL
927 diagnostic</entry><entry>Z_DiagRec</entry><entry>NULL
930 otherInfo</entry><entry>Z_OtherInformation</entry><entry>NULL
936 <table frame="top" id="asn.default.segment">
937 <title>Default settings for Segment</title>
939 <colspec colwidth="7*" colname="field"></colspec>
940 <colspec colwidth="5*" colname="type"></colspec>
941 <colspec colwidth="7*" colname="value"></colspec>
946 <entry>Default Value</entry>
952 referenceId</entry><entry>Z_ReferenceId</entry><entry>NULL
955 numberOfRecordsReturned</entry><entry>Odr_int</entry><entry>value=0
958 num_segmentRecords</entry><entry>Odr_int</entry><entry>0
961 segmentRecords</entry><entry>Z_NamePlusRecord</entry><entry>NULL
963 <row><entry>otherInfo</entry><entry>Z_OtherInformation</entry><entry>NULL
969 <table frame="top" id="asn.default.close">
970 <title>Default settings for Close</title>
972 <colspec colwidth="7*" colname="field"></colspec>
973 <colspec colwidth="5*" colname="type"></colspec>
974 <colspec colwidth="7*" colname="value"></colspec>
979 <entry>Default Value</entry>
985 referenceId</entry><entry>Z_ReferenceId</entry><entry>NULL
988 closeReason</entry><entry>Odr_int</entry><entry>Z_Close_finished
991 diagnosticInformation</entry><entry>char*</entry><entry>NULL
994 resourceReportFormat</entry><entry>Odr_oid</entry><entry>NULL
997 resourceFormat</entry><entry>Z_External</entry><entry>NULL
1000 otherInfo</entry><entry>Z_OtherInformation</entry><entry>NULL
1010 <!-- Keep this comment at the end of the file
1015 sgml-minimize-attributes:nil
1016 sgml-always-quote-attributes:t
1019 sgml-parent-document: "yaz.xml"
1020 sgml-local-catalogs: nil
1021 sgml-namecase-general:t