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