Enhanced SIM for E2AP v1 for TS UC
[sim/e2-interface.git] / e2sim / e2apv1sim / ASN1c / OPEN_TYPE.c
1 /*
2  * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
3  * Redistribution and modifications are permitted subject to BSD license.
4  */
5 #include <asn_internal.h>
6 #include <OPEN_TYPE.h>
7 #include <constr_CHOICE.h>
8 #include <per_opentype.h>
9 #include <errno.h>
10
11 asn_TYPE_operation_t asn_OP_OPEN_TYPE = {
12         OPEN_TYPE_free,
13         OPEN_TYPE_print,
14         OPEN_TYPE_compare,
15         OPEN_TYPE_decode_ber,
16         OPEN_TYPE_encode_der,
17         OPEN_TYPE_decode_xer,
18         OPEN_TYPE_encode_xer,
19 #ifdef ASN_DISABLE_OER_SUPPORT
20         0, 0,   /* No OER support, use "-gen-OER" to enable */
21 #else
22         OPEN_TYPE_decode_oer,
23         OPEN_TYPE_encode_oer,
24 #endif
25 #ifdef ASN_DISABLE_PER_SUPPORT
26         0, 0, 0, 0,
27 #else
28         OPEN_TYPE_decode_uper,
29         OPEN_TYPE_encode_uper,
30         OPEN_TYPE_decode_aper,
31         OPEN_TYPE_encode_aper,
32 #endif
33         0,  /* Random fill is not supported for open type */
34         0       /* Use generic outmost tag fetcher */
35 };
36
37 #undef  ADVANCE
38 #define ADVANCE(num_bytes)               \
39     do {                                 \
40         size_t num = num_bytes;          \
41         ptr = ((const char *)ptr) + num; \
42         size -= num;                     \
43         consumed_myself += num;          \
44     } while(0)
45
46 asn_dec_rval_t
47 OPEN_TYPE_ber_get(const asn_codec_ctx_t *opt_codec_ctx,
48                   const asn_TYPE_descriptor_t *td, void *sptr,
49                   const asn_TYPE_member_t *elm, const void *ptr, size_t size) {
50     size_t consumed_myself = 0;
51     asn_type_selector_result_t selected;
52     void *memb_ptr;   /* Pointer to the member */
53     void **memb_ptr2; /* Pointer to that pointer */
54     void *inner_value;
55     asn_dec_rval_t rv;
56
57     if(!(elm->flags & ATF_OPEN_TYPE)) {
58         ASN__DECODE_FAILED;
59     }
60
61     if(!elm->type_selector) {
62         ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
63                   td->name, elm->name, elm->type->name);
64         ASN__DECODE_FAILED;
65     }
66
67     selected = elm->type_selector(td, sptr);
68     if(!selected.presence_index) {
69         ASN__DECODE_FAILED;
70     }
71
72     /* Fetch the pointer to this member */
73     if(elm->flags & ATF_POINTER) {
74         memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
75     } else {
76         memb_ptr = (char *)sptr + elm->memb_offset;
77         memb_ptr2 = &memb_ptr;
78     }
79     if(*memb_ptr2 != NULL) {
80         /* Make sure we reset the structure first before encoding */
81         if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0) != 0) {
82             ASN__DECODE_FAILED;
83         }
84     }
85
86     inner_value =
87         (char *)*memb_ptr2
88         + elm->type->elements[selected.presence_index - 1].memb_offset;
89
90     ASN_DEBUG("presence %d\n", selected.presence_index);
91
92     rv = selected.type_descriptor->op->ber_decoder(
93         opt_codec_ctx, selected.type_descriptor, &inner_value, ptr, size,
94         elm->tag_mode);
95     ADVANCE(rv.consumed);
96     rv.consumed = 0;
97     switch(rv.code) {
98     case RC_OK:
99         if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
100                                        selected.presence_index)
101            == 0) {
102             rv.code = RC_OK;
103             rv.consumed = consumed_myself;
104             return rv;
105         } else {
106             /* Oh, now a full-blown failure failure */
107         }
108         /* Fall through */
109     case RC_FAIL:
110         rv.consumed = consumed_myself;
111         /* Fall through */
112     case RC_WMORE:
113         break;
114     }
115
116     if(*memb_ptr2) {
117         if(elm->flags & ATF_POINTER) {
118             ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
119             *memb_ptr2 = NULL;
120         } else {
121             ASN_STRUCT_RESET(*selected.type_descriptor,
122                                           inner_value);
123         }
124     }
125     return rv;
126 }
127
128 asn_dec_rval_t
129 OPEN_TYPE_xer_get(const asn_codec_ctx_t *opt_codec_ctx,
130                   const asn_TYPE_descriptor_t *td, void *sptr,
131                   const asn_TYPE_member_t *elm, const void *ptr, size_t size) {
132     size_t consumed_myself = 0;
133     asn_type_selector_result_t selected;
134     void *memb_ptr;   /* Pointer to the member */
135     void **memb_ptr2; /* Pointer to that pointer */
136     void *inner_value;
137     asn_dec_rval_t rv;
138
139     int xer_context = 0;
140     ssize_t ch_size;
141     pxer_chunk_type_e ch_type;
142
143     if(!(elm->flags & ATF_OPEN_TYPE)) {
144         ASN__DECODE_FAILED;
145     }
146
147     if(!elm->type_selector) {
148         ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
149                   td->name, elm->name, elm->type->name);
150         ASN__DECODE_FAILED;
151     }
152
153     selected = elm->type_selector(td, sptr);
154     if(!selected.presence_index) {
155         ASN__DECODE_FAILED;
156     }
157
158     /* Fetch the pointer to this member */
159     assert(elm->flags == ATF_OPEN_TYPE);
160     if(elm->flags & ATF_POINTER) {
161         memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
162     } else {
163         memb_ptr = (char *)sptr + elm->memb_offset;
164         memb_ptr2 = &memb_ptr;
165     }
166     if(*memb_ptr2 != NULL) {
167         /* Make sure we reset the structure first before encoding */
168         if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
169            != 0) {
170             ASN__DECODE_FAILED;
171         }
172     }
173
174     /*
175      * Confirm wrapper.
176      */
177     for(;;) {
178         ch_size = xer_next_token(&xer_context, ptr, size, &ch_type);
179         if(ch_size < 0) {
180             ASN__DECODE_FAILED;
181         } else {
182             switch(ch_type) {
183             case PXER_WMORE:
184                 ASN__DECODE_STARVED;
185             case PXER_COMMENT:
186             case PXER_TEXT:
187                 ADVANCE(ch_size);
188                 continue;
189             case PXER_TAG:
190                 break;
191             }
192             break;
193         }
194     }
195
196     /*
197      * Wrapper value confirmed.
198      */
199     switch(xer_check_tag(ptr, ch_size, elm->name)) {
200     case XCT_OPENING:
201         ADVANCE(ch_size);
202         break;
203     case XCT_BROKEN:
204     default:
205         ASN__DECODE_FAILED;
206     }
207
208     inner_value =
209         (char *)*memb_ptr2
210         + elm->type->elements[selected.presence_index - 1].memb_offset;
211
212     rv = selected.type_descriptor->op->xer_decoder(
213         opt_codec_ctx, selected.type_descriptor, &inner_value, NULL, ptr, size);
214     ADVANCE(rv.consumed);
215     rv.consumed = 0;
216     switch(rv.code) {
217     case RC_OK:
218         if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
219                                        selected.presence_index)
220            == 0) {
221             break;
222         } else {
223             rv.code = RC_FAIL;
224         }
225         /* Fall through */
226     case RC_FAIL:
227         /* Point to a best position where failure occurred */
228         rv.consumed = consumed_myself;
229         /* Fall through */
230     case RC_WMORE:
231         /* Wrt. rv.consumed==0:
232          * In case a genuine RC_WMORE, the whole Open Type decoding
233          * will have to be restarted.
234          */
235         if(*memb_ptr2) {
236             if(elm->flags & ATF_POINTER) {
237                 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
238                 *memb_ptr2 = NULL;
239             } else {
240                 ASN_STRUCT_RESET(*selected.type_descriptor,
241                                               inner_value);
242             }
243         }
244         return rv;
245     }
246
247     /*
248      * Finalize wrapper.
249      */
250     for(;;) {
251         ch_size = xer_next_token(&xer_context, ptr, size, &ch_type);
252         if(ch_size < 0) {
253             ASN__DECODE_FAILED;
254         } else {
255             switch(ch_type) {
256             case PXER_WMORE:
257                 ASN__DECODE_STARVED;
258             case PXER_COMMENT:
259             case PXER_TEXT:
260                 ADVANCE(ch_size);
261                 continue;
262             case PXER_TAG:
263                 break;
264             }
265             break;
266         }
267     }
268
269     /*
270      * Wrapper value confirmed.
271      */
272     switch(xer_check_tag(ptr, ch_size, elm->name)) {
273     case XCT_CLOSING:
274         ADVANCE(ch_size);
275         break;
276     case XCT_BROKEN:
277     default:
278         ASN__DECODE_FAILED;
279     }
280
281     rv.consumed += consumed_myself;
282
283     return rv;
284 }
285
286
287 #ifndef  ASN_DISABLE_PER_SUPPORT
288
289 asn_dec_rval_t
290 OPEN_TYPE_uper_get(const asn_codec_ctx_t *opt_codec_ctx,
291                    const asn_TYPE_descriptor_t *td, void *sptr,
292                    const asn_TYPE_member_t *elm, asn_per_data_t *pd) {
293     asn_type_selector_result_t selected;
294     void *memb_ptr;   /* Pointer to the member */
295     void **memb_ptr2; /* Pointer to that pointer */
296     void *inner_value;
297     asn_dec_rval_t rv;
298
299     if(!(elm->flags & ATF_OPEN_TYPE)) {
300         ASN__DECODE_FAILED;
301     }
302
303     if(!elm->type_selector) {
304         ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
305                   td->name, elm->name, elm->type->name);
306         ASN__DECODE_FAILED;
307     }
308
309     selected = elm->type_selector(td, sptr);
310     if(!selected.presence_index) {
311         ASN__DECODE_FAILED;
312     }
313
314     /* Fetch the pointer to this member */
315     assert(elm->flags == ATF_OPEN_TYPE);
316     if(elm->flags & ATF_POINTER) {
317         memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
318     } else {
319         memb_ptr = (char *)sptr + elm->memb_offset;
320         memb_ptr2 = &memb_ptr;
321     }
322     if(*memb_ptr2 != NULL) {
323         /* Make sure we reset the structure first before encoding */
324         if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
325            != 0) {
326             ASN__DECODE_FAILED;
327         }
328     }
329
330     inner_value =
331         (char *)*memb_ptr2
332         + elm->type->elements[selected.presence_index - 1].memb_offset;
333
334     rv = uper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
335                             &inner_value, pd);
336     switch(rv.code) {
337     case RC_OK:
338         if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
339                                        selected.presence_index)
340            == 0) {
341             break;
342         } else {
343             rv.code = RC_FAIL;
344         }
345         /* Fall through */
346     case RC_WMORE:
347     case RC_FAIL:
348         if(*memb_ptr2) {
349             if(elm->flags & ATF_POINTER) {
350                 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
351                 *memb_ptr2 = NULL;
352             } else {
353                 ASN_STRUCT_RESET(*selected.type_descriptor,
354                                               inner_value);
355             }
356         }
357     }
358     return rv;
359 }
360
361 asn_enc_rval_t
362 OPEN_TYPE_encode_uper(const asn_TYPE_descriptor_t *td,
363                       const asn_per_constraints_t *constraints,
364                       const void *sptr, asn_per_outp_t *po) {
365     const void *memb_ptr;   /* Pointer to the member */
366     asn_TYPE_member_t *elm; /* CHOICE's element */
367     asn_enc_rval_t er = {0,0,0};
368     unsigned present;
369
370     (void)constraints;
371
372     present = CHOICE_variant_get_presence(td, sptr);
373     if(present == 0 || present > td->elements_count) {
374         ASN__ENCODE_FAILED;
375     } else {
376         present--;
377     }
378
379     ASN_DEBUG("Encoding %s OPEN TYPE element %d", td->name, present);
380
381     elm = &td->elements[present];
382     if(elm->flags & ATF_POINTER) {
383         /* Member is a pointer to another structure */
384         memb_ptr =
385             *(const void *const *)((const char *)sptr + elm->memb_offset);
386         if(!memb_ptr) ASN__ENCODE_FAILED;
387     } else {
388         memb_ptr = (const char *)sptr + elm->memb_offset;
389     }
390
391     if(uper_open_type_put(elm->type, NULL, memb_ptr, po) < 0) {
392         ASN__ENCODE_FAILED;
393     }
394
395     er.encoded = 0;
396     ASN__ENCODED_OK(er);
397 }
398
399 asn_dec_rval_t
400 OPEN_TYPE_aper_get(const asn_codec_ctx_t *opt_codec_ctx,
401                    const asn_TYPE_descriptor_t *td, void *sptr,
402                    const asn_TYPE_member_t *elm, asn_per_data_t *pd) {
403     asn_type_selector_result_t selected;
404     void *memb_ptr;   /* Pointer to the member */
405     void **memb_ptr2; /* Pointer to that pointer */
406     void *inner_value;
407     asn_dec_rval_t rv;
408
409     if(!(elm->flags & ATF_OPEN_TYPE)) {
410         ASN__DECODE_FAILED;
411     }
412
413     if(!elm->type_selector) {
414         ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
415                   td->name, elm->name, elm->type->name);
416         ASN__DECODE_FAILED;
417     }
418
419     selected = elm->type_selector(td, sptr);
420     if(!selected.presence_index) {
421         ASN__DECODE_FAILED;
422     }
423
424     /* Fetch the pointer to this member */
425     assert(elm->flags == ATF_OPEN_TYPE);
426     if(elm->flags & ATF_POINTER) {
427         memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
428     } else {
429         memb_ptr = (char *)sptr + elm->memb_offset;
430         memb_ptr2 = &memb_ptr;
431     }
432     if(*memb_ptr2 != NULL) {
433         /* Make sure we reset the structure first before encoding */
434         if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
435            != 0) {
436             ASN__DECODE_FAILED;
437         }
438     }
439
440     inner_value =
441         (char *)*memb_ptr2
442         + elm->type->elements[selected.presence_index - 1].memb_offset;
443
444     rv = aper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
445                             &inner_value, pd);
446     switch(rv.code) {
447     case RC_OK:
448         if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
449                                        selected.presence_index)
450            == 0) {
451             break;
452         } else {
453             rv.code = RC_FAIL;
454         }
455         /* Fall through */
456     case RC_WMORE:
457     case RC_FAIL:
458         if(*memb_ptr2) {
459             if(elm->flags & ATF_POINTER) {
460                 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
461                 *memb_ptr2 = NULL;
462             } else {
463                 ASN_STRUCT_RESET(*selected.type_descriptor,
464                                               inner_value);
465             }
466         }
467     }
468     return rv;
469 }
470
471 asn_enc_rval_t
472 OPEN_TYPE_encode_aper(const asn_TYPE_descriptor_t *td,
473                       const asn_per_constraints_t *constraints,
474                       const void *sptr, asn_per_outp_t *po) {
475     const void *memb_ptr;   /* Pointer to the member */
476     asn_TYPE_member_t *elm; /* CHOICE's element */
477     asn_enc_rval_t er = {0,0,0};
478     unsigned present;
479
480     (void)constraints;
481
482     present = CHOICE_variant_get_presence(td, sptr);
483     if(present == 0 || present > td->elements_count) {
484         ASN__ENCODE_FAILED;
485     } else {
486         present--;
487     }
488
489     ASN_DEBUG("Encoding %s OPEN TYPE element %d", td->name, present);
490
491     elm = &td->elements[present];
492     if(elm->flags & ATF_POINTER) {
493         /* Member is a pointer to another structure */
494         memb_ptr =
495             *(const void *const *)((const char *)sptr + elm->memb_offset);
496         if(!memb_ptr) ASN__ENCODE_FAILED;
497     } else {
498         memb_ptr = (const char *)sptr + elm->memb_offset;
499     }
500
501     if(aper_open_type_put(elm->type, NULL, memb_ptr, po) < 0) {
502         ASN__ENCODE_FAILED;
503     }
504
505     er.encoded = 0;
506     ASN__ENCODED_OK(er);
507 }
508
509 #endif  /* ASN_DISABLE_PER_SUPPORT */