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