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