4113b36238f3964f76813e749527280c594e78f8
[yaz-moved-to-github.git] / asn / proto.c
1 /*
2  * Copyright (C) 1994, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: proto.c,v $
7  * Revision 1.6  1995-03-01 14:46:03  quinn
8  * Fixed protocol bug in 8777query.
9  *
10  * Revision 1.5  1995/02/14  11:54:22  quinn
11  * Fixing include.
12  *
13  * Revision 1.4  1995/02/10  15:54:30  quinn
14  * Small adjustments.
15  *
16  * Revision 1.3  1995/02/09  15:51:39  quinn
17  * Works better now.
18  *
19  * Revision 1.2  1995/02/06  21:26:07  quinn
20  * Repaired this evening's damages..
21  *
22  * Revision 1.1  1995/02/06  16:44:47  quinn
23  * First hack at Z/SR protocol
24  *
25  */
26
27 #include <odr.h>
28
29 #include <proto.h>
30
31 /* ---------------------- GLOBAL DEFS ------------------- */
32
33 int z_ReferenceId(ODR o, Z_ReferenceId **p, int opt)
34 {
35     return odr_implicit(o, odr_octetstring, (Odr_oct**) p, ODR_CONTEXT, 2, opt);
36 }
37
38 int z_DatabaseName(ODR o, Z_DatabaseName **p, int opt)
39 {
40     return odr_implicit(o, odr_visiblestring, (char **) p, ODR_CONTEXT, 105,
41         opt);
42 }
43
44 int z_ResultSetId(ODR o, char **p, int opt)
45 {
46     return odr_implicit(o, odr_visiblestring, (char **) p, ODR_CONTEXT, 31,
47         opt);
48 }
49
50 int z_UserInformationField(ODR o, Z_UserInformationField **p, int opt)
51 {
52     return odr_explicit(o, odr_external, (Odr_external **)p, ODR_CONTEXT,
53         11, opt);
54 }
55
56 /* ---------------------- INITIALIZE SERVICE ------------------- */
57
58 int z_InitRequest(ODR o, Z_InitRequest **p, int opt)
59 {
60     Z_InitRequest *pp;
61
62     if (!odr_sequence_begin(o, p, sizeof(**p)))
63         return opt;
64     pp = *p;
65     return
66         z_ReferenceId(o, &pp->referenceId, 1) &&
67         odr_implicit(o, odr_bitstring, &pp->protocolVersion, ODR_CONTEXT, 
68             3, 0) &&
69         odr_implicit(o, odr_bitstring, &pp->options, ODR_CONTEXT, 4, 0) &&
70         odr_implicit(o, odr_integer, &pp->preferredMessageSize, ODR_CONTEXT,
71             5, 0) &&
72         odr_implicit(o, odr_integer, &pp->maximumRecordSize, ODR_CONTEXT,
73             6, 0) &&
74         odr_implicit(o, odr_visiblestring, &pp->idAuthentication, ODR_CONTEXT,
75             7, 1) &&
76         odr_implicit(o, odr_visiblestring, &pp->implementationId, ODR_CONTEXT,
77             110, 1) &&
78         odr_implicit(o, odr_visiblestring, &pp->implementationName, ODR_CONTEXT,
79             111, 1) &&
80         odr_implicit(o, odr_visiblestring, &pp->implementationVersion,
81             ODR_CONTEXT, 112, 1) &&
82         z_UserInformationField(o, &pp->userInformationField, 1) &&
83         odr_sequence_end(o);
84 }
85
86 int z_InitResponse(ODR o, Z_InitResponse **p, int opt)
87 {
88     Z_InitResponse *pp;
89
90     if (!odr_sequence_begin(o, p, sizeof(**p)))
91         return opt;
92     pp = *p;
93     return
94         z_ReferenceId(o, &pp->referenceId, 1) &&
95         odr_implicit(o, odr_bitstring, &pp->protocolVersion, ODR_CONTEXT, 
96             3, 0) &&
97         odr_implicit(o, odr_bitstring, &pp->options, ODR_CONTEXT, 4, 0) &&
98         odr_implicit(o, odr_integer, &pp->preferredMessageSize, ODR_CONTEXT,
99             5, 0) &&
100         odr_implicit(o, odr_integer, &pp->maximumRecordSize, ODR_CONTEXT,
101             6, 0) &&
102         odr_implicit(o, odr_bool, &pp->result, ODR_CONTEXT, 12, 0) &&
103         odr_implicit(o, odr_visiblestring, &pp->implementationId, ODR_CONTEXT,
104             110, 1) &&
105         odr_implicit(o, odr_visiblestring, &pp->implementationName, ODR_CONTEXT,
106             111, 1) &&
107         odr_implicit(o, odr_visiblestring, &pp->implementationVersion,
108             ODR_CONTEXT, 112, 1) &&
109         z_UserInformationField(o, &pp->userInformationField, 1) &&
110         odr_sequence_end(o);
111 }
112
113 /* ------------------------ SEARCH SERVICE ----------------------- */
114
115 int z_ElementSetName(ODR o, char **p, int opt)
116 {
117     return odr_implicit(o, odr_visiblestring, (char**) p, ODR_CONTEXT, 103,
118         opt);
119 }
120
121 int z_PreferredRecordSyntax(ODR o, Z_PreferredRecordSyntax **p, int opt)
122 {
123     return odr_implicit(o, odr_oid, (Odr_oid**) p, ODR_CONTEXT, 104, opt);
124 }
125
126 int z_DatabaseSpecificUnit(ODR o, Z_DatabaseSpecificUnit **p, int opt)
127 {
128     if (!odr_sequence_begin(o, p, sizeof(**p)))
129         return opt;
130     return
131         z_DatabaseName(o, &(*p)->databaseName, 0) &&
132         z_ElementSetName(o, &(*p)->elementSetName, 0) &&
133         odr_sequence_end(o);
134 }
135
136 int z_DatabaseSpecific(ODR o, Z_DatabaseSpecific **p, int opt)
137 {
138     if (o->direction == ODR_DECODE)
139         *p = nalloc(o, sizeof(**p));
140     else if (!*p)
141         return opt;
142
143     odr_implicit_settag(o, ODR_CONTEXT, 1);
144     if (odr_sequence_of(o, z_DatabaseSpecificUnit, &(*p)->elements,
145         &(*p)->num_elements))
146         return 1;
147     *p = 0;
148     return 0;
149 }
150
151 int z_ElementSetNames(ODR o, Z_ElementSetNames **p, int opt)
152 {
153     static Odr_arm arm[] =
154     {
155         {ODR_IMPLICIT, ODR_CONTEXT, 0, Z_ElementSetNames_generic,
156             z_ElementSetName},
157         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_ElementSetNames_databaseSpecific,
158             z_DatabaseSpecific},
159         {-1, -1, -1, -1, 0}
160     };
161
162     if (!odr_constructed_begin(o, p, ODR_CONTEXT, 19))
163         return opt;
164
165     if (o->direction == ODR_DECODE)
166         *p = nalloc(o, sizeof(**p));
167
168     if (odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
169         odr_constructed_end(o))
170         return 1;
171     *p = 0;
172     return 0;
173 }
174
175 /* ----------------------- RPN QUERY -----------------------*/
176
177 int z_AttributeElement(ODR o, Z_AttributeElement **p, int opt)
178 {
179     if (!odr_sequence_begin(o, p, sizeof(**p)))
180         return opt;
181     return
182         odr_implicit(o, odr_integer, &(*p)->attributeType, ODR_CONTEXT,
183             120, 1) &&
184         odr_implicit(o, odr_integer, &(*p)->attributeValue, ODR_CONTEXT,
185             121, 1) &&
186         odr_sequence_end(o);
187 }
188
189 int z_AttributesPlusTerm(ODR o, Z_AttributesPlusTerm **p, int opt)
190 {
191     if (!(odr_implicit_settag(o, ODR_CONTEXT, 102) &&
192         odr_sequence_begin(o, p, sizeof(**p))))
193         return opt;
194     return
195         odr_implicit_settag(o, ODR_CONTEXT, 44) &&
196         odr_sequence_of(o, z_AttributeElement, &(*p)->attributeList,
197             &(*p)->num_attributes) &&
198         odr_implicit(o, odr_octetstring, &(*p)->term, ODR_CONTEXT, 45, 0) &&
199         odr_sequence_end(o);
200 }
201
202 int z_Operator(ODR o, Z_Operator **p, int opt)
203 {
204     static Odr_arm arm[] =
205     {
206         {ODR_IMPLICIT, ODR_CONTEXT, 0, Z_Operator_and, odr_null},
207         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_Operator_or, odr_null},
208         {ODR_IMPLICIT, ODR_CONTEXT, 2, Z_Operator_and_not, odr_null},
209         {-1, -1, -1, -1, 0}
210     };
211     int dummy = 999;
212
213     if (!*p && o->direction != ODR_DECODE)
214         return opt;
215     if (!odr_constructed_begin(o, p, ODR_CONTEXT, 46))
216         return opt;
217     if (o->direction == ODR_DECODE)
218         *p = nalloc(o, sizeof(**p));
219     else
220         (*p)->u.and = &dummy;
221
222     if (odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
223         odr_constructed_end(o))
224         return 1;
225     *p = 0;
226     return opt;
227 }
228
229 int z_Operand(ODR o, Z_Operand **p, int opt)
230 {
231     static Odr_arm arm[] =
232     {
233         {-1, -1, -1, Z_Operand_APT, z_AttributesPlusTerm},
234         {-1, -1, -1, Z_Operand_resultSetId, z_ResultSetId},
235         {-1, -1, -1, -1, 0}
236     };
237
238     if (o->direction ==ODR_DECODE)
239         *p = nalloc(o, sizeof(**p));
240     else if (!*p)
241         return opt;
242     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
243         return 1;
244     *p = 0;
245     return opt;
246 }
247
248 int z_RPNStructure(ODR o, Z_RPNStructure **p, int opt);
249
250 int z_Complex(ODR o, Z_Complex **p, int opt)
251 {
252     if (!odr_sequence_begin(o, p, sizeof(**p)))
253         return opt;
254     return
255         z_RPNStructure(o, &(*p)->s1, 0) &&
256         z_RPNStructure(o, &(*p)->s2, 0) &&
257         z_Operator(o, &(*p)->operator, 0) &&
258         odr_sequence_end(o);
259 }
260
261 int z_RPNStructure(ODR o, Z_RPNStructure **p, int opt)
262 {
263     static Odr_arm arm[] = 
264     {
265         {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_RPNStructure_simple, z_Operand},
266         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_RPNStructure_complex, z_Complex},
267         {-1 -1, -1, -1, 0}
268     };
269
270     if (o->direction == ODR_DECODE)
271         *p = nalloc(o, sizeof(**p));
272     else if (!*p)
273         return opt;
274     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
275         return 1;
276     *p = 0;
277     return opt;
278 }
279
280 int z_RPNQuery(ODR o, Z_RPNQuery **p, int opt)
281 {
282     if (!odr_sequence_begin(o, p, sizeof(**p)))
283         return opt;
284     return
285         odr_oid(o, &(*p)->attributeSetId, 0) &&
286         z_RPNStructure(o, &(*p)->RPNStructure, 0) &&
287         odr_sequence_end(o);
288 }
289
290 /* -----------------------END RPN QUERY ----------------------- */
291
292 int z_Query(ODR o, Z_Query **p, int opt)
293 {
294     static Odr_arm arm[] = 
295     {
296         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_Query_type_1, z_RPNQuery},
297         {ODR_EXPLICIT, ODR_CONTEXT, 2, Z_Query_type_2, odr_octetstring},
298         {-1, -1, -1, -1, 0}
299     };
300
301     if (o->direction == ODR_DECODE)
302         *p = nalloc(o, sizeof(**p));
303     else if (!*p)
304         return opt;
305     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
306         return 1;
307     *p = 0;
308     return opt;
309 }
310
311 int z_SearchRequest(ODR o, Z_SearchRequest **p, int opt)
312 {
313     Z_SearchRequest *pp;
314
315     if (!odr_sequence_begin(o, p, sizeof(**p)))
316         return opt;
317     pp = *p;
318     return
319         z_ReferenceId(o, &pp->referenceId, 1) &&
320         odr_implicit(o, odr_integer, &pp->smallSetUpperBound, ODR_CONTEXT,
321             13, 0) &&
322         odr_implicit(o, odr_integer, &pp->largeSetLowerBound, ODR_CONTEXT,
323             14, 0) &&
324         odr_implicit(o, odr_integer, &pp->mediumSetPresentNumber, ODR_CONTEXT,
325             15, 0) &&
326         odr_implicit(o, odr_bool, &pp->replaceIndicator, ODR_CONTEXT, 16, 1) &&
327         odr_implicit(o, odr_visiblestring, &pp->resultSetName, ODR_CONTEXT,
328             17, 9) &&
329         odr_implicit_settag(o, ODR_CONTEXT, 18) &&
330         odr_sequence_of(o, z_DatabaseName, &pp->databaseNames,
331             &pp->num_databaseNames) &&
332         odr_implicit(o, z_ElementSetNames, &pp->smallSetElementSetNames,
333             ODR_CONTEXT, 100, 1) &&
334         odr_implicit(o, z_ElementSetNames, &pp->mediumSetElementSetNames,
335             ODR_CONTEXT, 101, 1) &&
336         z_PreferredRecordSyntax(o, &pp->preferredRecordSyntax, 1) &&
337         odr_explicit(o, z_Query, &pp->query, ODR_CONTEXT, 21, 0) &&
338         odr_sequence_end(o);
339 }
340
341 /* ------------------------ RECORD ------------------------- */
342
343 int z_DatabaseRecord(ODR o, Z_DatabaseRecord **p, int opt)
344 {
345     return odr_external(o, (Odr_external **) p, opt);
346 }
347
348 int z_DiagRec(ODR o, Z_DiagRec **p, int opt)
349 {
350     if (!odr_sequence_begin(o, p, sizeof(**p)))
351         return opt;
352     return
353         odr_oid(o, &(*p)->diagnosticSetId, 1) &&       /* SHOULD NOT BE OPT */
354         odr_integer(o, &(*p)->condition, 0) &&
355         (odr_visiblestring(o, &(*p)->addinfo, 0) ||
356         odr_implicit(o, odr_cstring, &(*p)->addinfo, ODR_CONTEXT, ODR_VISIBLESTRING, 1)) &&
357         odr_sequence_end(o);
358 }
359
360 int z_NamePlusRecord(ODR o, Z_NamePlusRecord **p, int opt)
361 {
362     static Odr_arm arm[] =
363     {
364         {ODR_EXPLICIT, ODR_CONTEXT, 1, Z_NamePlusRecord_databaseRecord,
365             z_DatabaseRecord},
366         {ODR_EXPLICIT, ODR_CONTEXT, 2, Z_NamePlusRecord_surrogateDiagnostic,
367             z_DiagRec},
368         {-1, -1, -1, -1, 0}
369     };
370
371     if (!odr_sequence_begin(o, p, sizeof(**p)))
372         return opt;
373     return
374         odr_implicit(o, z_DatabaseName, &(*p)->databaseName, ODR_CONTEXT,
375             0, 1) &&
376         odr_constructed_begin(o, &(*p)->u, ODR_CONTEXT, 1) &&
377         odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
378         odr_constructed_end(o) &&
379         odr_sequence_end(o);
380 }
381
382 int z_NamePlusRecordList(ODR o, Z_NamePlusRecordList **p, int opt)
383 {
384     if (o->direction == ODR_DECODE)
385         *p = nalloc(o, sizeof(**p));
386     if (odr_sequence_of(o, z_NamePlusRecord, &(*p)->records,
387         &(*p)->num_records))
388         return 1;
389     *p = 0;
390     return 0;
391 }
392
393 int z_Records(ODR o, Z_Records **p, int opt)
394 {
395     Odr_arm arm[] = 
396     {
397         {ODR_IMPLICIT, ODR_CONTEXT, 28, Z_Records_DBOSD, z_NamePlusRecordList},
398         {ODR_IMPLICIT, ODR_CONTEXT, 130, Z_Records_NSD, z_DiagRec},
399         {-1, -1, -1, -1, 0}
400     };
401
402     if (o->direction == ODR_DECODE)
403         *p = nalloc(o, sizeof(**p));
404     else if (!*p)
405         return opt;
406     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
407         return 1;
408     *p = 0;
409     return opt;
410 }
411
412 /* ------------------------ SEARCHRESPONSE ----------------*/
413
414 int z_NumberOfRecordsReturned(ODR o, int **p, int opt)
415 {
416     return odr_implicit(o, odr_integer, p, ODR_CONTEXT, 24, opt);
417 }
418
419 int z_NextResultSetPosition(ODR o, int **p, int opt)
420 {
421     return odr_implicit(o, odr_integer, p, ODR_CONTEXT, 25, opt);
422 }
423
424 int z_PresentStatus(ODR o, int **p, int opt)
425 {
426     return odr_implicit(o, odr_integer, p, ODR_CONTEXT, 27, opt);
427 }
428
429 int z_SearchResponse(ODR o, Z_SearchResponse **p, int opt)
430 {
431     Z_SearchResponse *pp;
432
433     if (!odr_sequence_begin(o, p, sizeof(**p)))
434         return opt;
435     pp = *p;
436     return
437         z_ReferenceId(o, &pp->referenceId, 1) &&
438         odr_implicit(o, odr_integer, &pp->resultCount, ODR_CONTEXT, 23, 0) &&
439         z_NumberOfRecordsReturned(o, &pp->numberOfRecordsReturned, 0) &&
440         z_NextResultSetPosition(o, &pp->nextResultSetPosition, 0) &&
441         odr_implicit(o, odr_bool, &pp->searchStatus, ODR_CONTEXT, 22, 0) &&
442         odr_implicit(o, odr_integer, &pp->resultSetStatus, ODR_CONTEXT, 26, 1) &&
443         z_PresentStatus(o, &pp->presentStatus, 1) &&
444         z_Records(o, &pp->records, 1) &&
445         odr_sequence_end(o);
446 }
447
448 /* --------------------- PRESENT SERVICE ---------------------- */
449
450 int z_PresentRequest(ODR o, Z_PresentRequest **p, int opt)
451 {
452     Z_PresentRequest *pp;
453
454     if (!odr_sequence_begin(o, p, sizeof(**p)))
455         return opt;
456     pp = *p;
457     return
458         z_ReferenceId(o, &pp->referenceId, 1) &&
459         z_ResultSetId(o, &pp->resultSetId, 0) &&
460         odr_implicit(o, odr_integer, &pp->resultSetStartPoint, ODR_CONTEXT,
461             30, 0) &&
462         odr_implicit(o, odr_integer, &pp->numberOfRecordsRequested, ODR_CONTEXT,
463             29, 0) &&
464         z_ElementSetNames(o, &pp->elementSetNames, 1) &&
465         z_PreferredRecordSyntax(o, &pp->preferredRecordSyntax, 1) &&
466         odr_sequence_end(o);
467 }
468
469 int z_PresentResponse(ODR o, Z_PresentResponse **p, int opt)
470 {
471     Z_PresentResponse *pp;
472
473     if (!odr_sequence_begin(o, p, sizeof(**p)))
474         return opt;
475     pp = *p;
476     return
477         z_ReferenceId(o, &pp->referenceId, 1) &&
478         z_NumberOfRecordsReturned(o, &pp->numberOfRecordsReturned, 0) &&
479         z_NextResultSetPosition(o, &pp->nextResultSetPosition, 0) &&
480         z_PresentStatus(o, &pp->presentStatus, 0) &&
481         z_Records(o, &pp->records, 1) &&
482         odr_sequence_end(o);
483 }
484
485 /* ------------------------ APDU ------------------------- */
486
487 int z_APDU(ODR o, Z_APDU **p, int opt)
488 {
489     static Odr_arm arm[] =
490     {
491         {ODR_IMPLICIT, ODR_CONTEXT, 20, Z_APDU_initRequest, z_InitRequest},
492         {ODR_IMPLICIT, ODR_CONTEXT, 21, Z_APDU_initResponse, z_InitResponse},
493         {ODR_IMPLICIT, ODR_CONTEXT, 22, Z_APDU_searchRequest, z_SearchRequest},
494         {ODR_IMPLICIT, ODR_CONTEXT, 23, Z_APDU_searchResponse, z_SearchResponse},
495         {ODR_IMPLICIT, ODR_CONTEXT, 24, Z_APDU_presentRequest, z_PresentRequest},
496         {ODR_IMPLICIT, ODR_CONTEXT, 25, Z_APDU_presentResponse, z_PresentResponse},
497
498         {-1, -1, -1, -1, 0}
499     };
500
501     if (o->direction == ODR_DECODE)
502         *p = nalloc(o, sizeof(**p));
503     if (!odr_choice(o, arm, &(*p)->u, &(*p)->which))
504     {
505         if (o->direction == ODR_DECODE)
506         {
507             *p = 0;
508             return opt;
509         }
510     }
511     return 1;
512 }