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