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