SIM-115: update simulator to use latest E2SM KPM version 3
[sim/e2-interface.git] / e2sim / asn1c / constr_SEQUENCE_aper.c
1 /*
2  * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
3  * All rights reserved.
4  * Redistribution and modifications are permitted subject to BSD license.
5  */
6 #include <asn_internal.h>
7 #include <constr_SEQUENCE.h>
8 #include <OPEN_TYPE.h>
9 #include <aper_opentype.h>
10
11 /*
12  * Check whether we are inside the extensions group.
13  */
14 #define IN_EXTENSION_GROUP(specs, memb_idx)                \
15     ((specs)->first_extension >= 0                         \
16      && (unsigned)(specs)->first_extension <= (memb_idx))
17
18 asn_dec_rval_t
19 SEQUENCE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
20                      const asn_TYPE_descriptor_t *td,
21                      const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
22     const asn_SEQUENCE_specifics_t *specs = (const asn_SEQUENCE_specifics_t *)td->specifics;
23     void *st = *sptr;  /* Target structure. */
24     int extpresent;    /* Extension additions are present */
25     uint8_t *opres;    /* Presence of optional root members */
26     asn_per_data_t opmd;
27     asn_dec_rval_t rv;
28     size_t edx;
29
30     (void)constraints;
31
32     if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx))
33         ASN__DECODE_FAILED;
34
35     if(!st) {
36         st = *sptr = CALLOC(1, specs->struct_size);
37         if(!st) ASN__DECODE_FAILED;
38     }
39
40     ASN_DEBUG("Decoding %s as SEQUENCE (APER)", td->name);
41
42     /* Handle extensions */
43     if(specs->first_extension < 0) {
44         extpresent = 0;
45     } else {
46         extpresent = per_get_few_bits(pd, 1);
47         if(extpresent < 0) ASN__DECODE_STARVED;
48     }
49
50     /* Prepare a place and read-in the presence bitmap */
51     memset(&opmd, 0, sizeof(opmd));
52     if(specs->roms_count) {
53         opres = (uint8_t *)MALLOC(((specs->roms_count + 7) >> 3) + 1);
54         if(!opres) ASN__DECODE_FAILED;
55         /* Get the presence map */
56         if(per_get_many_bits(pd, opres, 0, specs->roms_count)) {
57             FREEMEM(opres);
58             ASN__DECODE_STARVED;
59         }
60         opmd.buffer = opres;
61         opmd.nbits = specs->roms_count;
62         ASN_DEBUG("Read in presence bitmap for %s of %d bits (%x..)",
63                   td->name, specs->roms_count, *opres);
64     } else {
65         opres = 0;
66     }
67
68     /*
69      * Get the sequence ROOT elements.
70      */
71     for(edx = 0; edx < td->elements_count; edx++) {
72         asn_TYPE_member_t *elm = &td->elements[edx];
73         void *memb_ptr;    /* Pointer to the member */
74         void **memb_ptr2;  /* Pointer to that pointer */
75 #if 0
76         int padding;
77 #endif
78
79         if(IN_EXTENSION_GROUP(specs, edx))
80             continue;
81
82         /* Fetch the pointer to this member */
83         if(elm->flags & ATF_POINTER) {
84             memb_ptr2 = (void **)((char *)st + elm->memb_offset);
85         } else {
86             memb_ptr = (char *)st + elm->memb_offset;
87             memb_ptr2 = &memb_ptr;
88         }
89 #if 0
90         /* Get Padding */
91         padding = (8 - (pd->moved % 8)) % 8;
92         if(padding > 0)
93             ASN_DEBUG("For element %s,offset= %ld Padding bits = %d", td->name, pd->moved, padding);
94 #if 0 /* old way of removing padding */
95         per_get_few_bits(pd, padding);
96 #else /* Experimental fix proposed by @mhanna123 */
97         if(edx != (td->elements_count-1))
98             per_get_few_bits(pd, padding);
99         else {
100             if(specs->roms_count && (padding > 0))
101                 ASN_DEBUG(">>>>> not skipping padding of %d bits for element:%ld out of %d", padding, edx, td->elements_count);
102             else
103                 per_get_few_bits(pd, padding);
104         }
105 #endif /* dealing with padding */
106 #endif
107         /* Deal with optionality */
108         if(elm->optional) {
109             int present = per_get_few_bits(&opmd, 1);
110             ASN_DEBUG("Member %s->%s is optional, p=%d (%d->%d)",
111                       td->name, elm->name, present,
112                       (int)opmd.nboff, (int)opmd.nbits);
113             if(present == 0) {
114                 /* This element is not present */
115                 if(elm->default_value_set) {
116                     /* Fill-in DEFAULT */
117                     if(elm->default_value_set(memb_ptr2)) {
118                         FREEMEM(opres);
119                         ASN__DECODE_FAILED;
120                     }
121                     ASN_DEBUG("Filled-in default");
122                 }
123                 /* The member is just not present */
124                 continue;
125             }
126             /* Fall through */
127         }
128
129         /* Fetch the member from the stream */
130         ASN_DEBUG("Decoding member \"%s\" in %s", elm->name, td->name);
131
132         if(elm->flags & ATF_OPEN_TYPE) {
133             if (OPEN_TYPE_aper_is_unknown_type(td, st, elm)) {
134                 rv = OPEN_TYPE_aper_unknown_type_discard_bytes(pd);
135                 FREEMEM(opres);
136                 return rv;
137             }
138             rv = OPEN_TYPE_aper_get(opt_codec_ctx, td, st, elm, pd);
139         } else {
140             rv = elm->type->op->aper_decoder(opt_codec_ctx, elm->type,
141                                              elm->encoding_constraints.per_constraints,
142                                              memb_ptr2, pd);
143         }
144         if(rv.code != RC_OK) {
145             ASN_DEBUG("Failed decode %s in %s",
146                       elm->name, td->name);
147             FREEMEM(opres);
148             return rv;
149         }
150     }
151
152     /* Optionality map is not needed anymore */
153     FREEMEM(opres);
154
155     /*
156      * Deal with extensions.
157      */
158     if(extpresent) {
159         ssize_t bmlength;
160         uint8_t *epres;  /* Presence of extension members */
161         asn_per_data_t epmd;
162
163         bmlength = aper_get_nslength(pd);
164         if(bmlength < 0) ASN__DECODE_STARVED;
165
166         ASN_DEBUG("Extensions %" ASN_PRI_SSIZE " present in %s", bmlength, td->name);
167
168         epres = (uint8_t *)MALLOC((bmlength + 15) >> 3);
169         if(!epres) ASN__DECODE_STARVED;
170
171         /* Get the extensions map */
172         if(per_get_many_bits(pd, epres, 0, bmlength))
173             ASN__DECODE_STARVED;
174
175         memset(&epmd, 0, sizeof(epmd));
176         epmd.buffer = epres;
177         epmd.nbits = bmlength;
178         ASN_DEBUG("Read in extensions bitmap for %s of %zd bits (%x..)",
179                   td->name, bmlength, *epres);
180
181         /* Deal with padding */
182         if (aper_get_align(pd) < 0)
183             ASN__DECODE_STARVED;
184
185         /* Go over extensions and read them in */
186         for(edx = specs->first_extension; edx < td->elements_count; edx++) {
187             asn_TYPE_member_t *elm = &td->elements[edx];
188             void *memb_ptr;    /* Pointer to the member */
189             void **memb_ptr2;  /* Pointer to that pointer */
190             int present;
191
192             if(!IN_EXTENSION_GROUP(specs, edx)) {
193                 ASN_DEBUG("%zu is not extension", edx);
194                 continue;
195             }
196
197             /* Fetch the pointer to this member */
198             if(elm->flags & ATF_POINTER) {
199                 memb_ptr2 = (void **)((char *)st + elm->memb_offset);
200             } else {
201                 memb_ptr = (void *)((char *)st + elm->memb_offset);
202                 memb_ptr2 = &memb_ptr;
203             }
204
205             present = per_get_few_bits(&epmd, 1);
206             if(present <= 0) {
207                 if(present < 0) break;  /* No more extensions */
208                 continue;
209             }
210
211             ASN_DEBUG("Decoding member %s in %s %p", elm->name, td->name, *memb_ptr2);
212             rv = aper_open_type_get(opt_codec_ctx, elm->type,
213                                     elm->encoding_constraints.per_constraints,
214                                     memb_ptr2, pd);
215             if(rv.code != RC_OK) {
216                 FREEMEM(epres);
217                 return rv;
218             }
219         }
220
221         /* Skip over overflow extensions which aren't present
222          * in this system's version of the protocol */
223         for(;;) {
224             ASN_DEBUG("Getting overflow extensions");
225             switch(per_get_few_bits(&epmd, 1)) {
226             case -1:
227                 break;
228             case 0:
229                 continue;
230             default:
231                 if(aper_open_type_skip(opt_codec_ctx, pd)) {
232                     FREEMEM(epres);
233                     ASN__DECODE_STARVED;
234                 }
235             }
236             break;
237         }
238
239         FREEMEM(epres);
240     }
241
242     /* Fill DEFAULT members in extensions */
243     for(edx = specs->roms_count; edx < specs->roms_count
244             + specs->aoms_count; edx++) {
245         asn_TYPE_member_t *elm = &td->elements[edx];
246         void **memb_ptr2;  /* Pointer to member pointer */
247
248         if(!elm->default_value_set) continue;
249
250         /* Fetch the pointer to this member */
251         if(elm->flags & ATF_POINTER) {
252             memb_ptr2 = (void **)((char *)st + elm->memb_offset);
253             if(*memb_ptr2) continue;
254         } else {
255             continue;  /* Extensions are all optionals */
256         }
257
258         /* Set default value */
259         if(elm->default_value_set(memb_ptr2)) {
260             ASN__DECODE_FAILED;
261         }
262     }
263
264     rv.consumed = 0;
265     rv.code = RC_OK;
266     return rv;
267 }
268
269 static int
270 SEQUENCE_handle_extensions_aper(const asn_TYPE_descriptor_t *td,
271                                 const void *sptr,
272                                 asn_per_outp_t *po1, asn_per_outp_t *po2) {
273     const asn_SEQUENCE_specifics_t *specs
274         = (const asn_SEQUENCE_specifics_t *)td->specifics;
275     int exts_present = 0;
276     int exts_count = 0;
277     size_t edx;
278
279     if(specs->first_extension < 0) {
280         return 0;
281     }
282
283     /* Find out which extensions are present */
284     for(edx = specs->first_extension; edx < td->elements_count; edx++) {
285         asn_TYPE_member_t *elm = &td->elements[edx];
286         const void *memb_ptr;           /* Pointer to the member */
287         const void * const *memb_ptr2;  /* Pointer to that pointer */
288         int present;
289
290         if(!IN_EXTENSION_GROUP(specs, edx)) {
291             ASN_DEBUG("%s (@%zu) is not extension", elm->type->name, edx);
292             continue;
293         }
294
295         /* Fetch the pointer to this member */
296         if(elm->flags & ATF_POINTER) {
297             memb_ptr2 = (const void * const *)((const char *)sptr + elm->memb_offset);
298             present = (*memb_ptr2 != 0);
299         } else {
300             memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
301             memb_ptr2 = &memb_ptr;
302             present = 1;
303         }
304
305         ASN_DEBUG("checking %s (@%zu) present => %d",
306                   elm->type->name, edx, present);
307         exts_count++;
308         exts_present += present;
309
310         /* Encode as presence marker */
311         if(po1 && per_put_few_bits(po1, present, 1))
312             return -1;
313         /* Encode as open type field */
314         if(po2 && present && aper_open_type_put(elm->type,
315                                                 elm->encoding_constraints.per_constraints,
316                                                 *memb_ptr2, po2))
317             return -1;
318
319     }
320
321     return exts_present ? exts_count : 0;
322 }
323
324 asn_enc_rval_t
325 SEQUENCE_encode_aper(const asn_TYPE_descriptor_t *td,
326                      const asn_per_constraints_t *constraints,
327                      const void *sptr, asn_per_outp_t *po) {
328     const asn_SEQUENCE_specifics_t *specs
329         = (const asn_SEQUENCE_specifics_t *)td->specifics;
330     asn_enc_rval_t er = {0,0,0};
331     int n_extensions;
332     size_t edx;
333     size_t i;
334
335     (void)constraints;
336
337     if(!sptr)
338         ASN__ENCODE_FAILED;
339
340     er.encoded = 0;
341
342     ASN_DEBUG("Encoding %s as SEQUENCE (APER)", td->name);
343
344     /*
345      * X.691#18.1 Whether structure is extensible
346      * and whether to encode extensions
347      */
348     if(specs->first_extension < 0) {
349         n_extensions = 0; /* There are no extensions to encode */
350     } else {
351         n_extensions = SEQUENCE_handle_extensions_aper(td, sptr, 0, 0);
352         if(n_extensions < 0) ASN__ENCODE_FAILED;
353         if(per_put_few_bits(po, n_extensions ? 1 : 0, 1)) {
354             ASN__ENCODE_FAILED;
355         }
356     }
357
358     /* Encode a presence bitmap */
359     for(i = 0; i < specs->roms_count; i++) {
360         asn_TYPE_member_t *elm;
361         const void *memb_ptr;           /* Pointer to the member */
362         const void * const *memb_ptr2;  /* Pointer to that pointer */
363         int present;
364
365         edx = specs->oms[i];
366         elm = &td->elements[edx];
367
368         /* Fetch the pointer to this member */
369         if(elm->flags & ATF_POINTER) {
370             memb_ptr2 = (const void * const *)((const char *)sptr + elm->memb_offset);
371             present = (*memb_ptr2 != 0);
372         } else {
373             memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
374             memb_ptr2 = &memb_ptr;
375             present = 1;
376         }
377
378         /* Eliminate default values */
379         if(present && elm->default_value_cmp
380                 && elm->default_value_cmp(*memb_ptr2) == 0)
381             present = 0;
382
383         ASN_DEBUG("Element %s %s %s->%s is %s",
384                   elm->flags & ATF_POINTER ? "ptr" : "inline",
385                   elm->default_value_cmp ? "def" : "wtv",
386                   td->name, elm->name, present ? "present" : "absent");
387         if(per_put_few_bits(po, present, 1))
388             ASN__ENCODE_FAILED;
389     }
390
391     /*
392      * Encode the sequence ROOT elements.
393      */
394     ASN_DEBUG("first_extension = %d, elements = %d", specs->first_extension,
395               td->elements_count);
396     for(edx = 0;
397         edx < ((specs->first_extension < 0) ? td->elements_count
398                                             : (size_t)specs->first_extension);
399         edx++) {
400         asn_TYPE_member_t *elm = &td->elements[edx];
401         const void *memb_ptr;           /* Pointer to the member */
402         const void * const *memb_ptr2;  /* Pointer to that pointer */
403
404         if(IN_EXTENSION_GROUP(specs, edx))
405             continue;
406
407         ASN_DEBUG("About to encode %s", elm->type->name);
408
409         /* Fetch the pointer to this member */
410         if(elm->flags & ATF_POINTER) {
411             memb_ptr2 = (const void * const *)((const char *)sptr + elm->memb_offset);
412             if(!*memb_ptr2) {
413                 ASN_DEBUG("Element %s %zu not present",
414                           elm->name, edx);
415                 if(elm->optional)
416                     continue;
417                 /* Mandatory element is missing */
418                 ASN__ENCODE_FAILED;
419             }
420         } else {
421             memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
422             memb_ptr2 = &memb_ptr;
423         }
424
425         /* Eliminate default values */
426         if(elm->default_value_cmp && elm->default_value_cmp(*memb_ptr2) == 0)
427             continue;
428
429         ASN_DEBUG("Encoding %s->%s", td->name, elm->name);
430         er = elm->type->op->aper_encoder(elm->type,
431                                          elm->encoding_constraints.per_constraints,
432                                          *memb_ptr2, po);
433         if(er.encoded == -1)
434             return er;
435     }
436
437     /* No extensions to encode */
438     if(!n_extensions) ASN__ENCODED_OK(er);
439
440     ASN_DEBUG("Length of %d bit-map", n_extensions);
441     /* #18.8. Write down the presence bit-map length. */
442     if(aper_put_nslength(po, n_extensions))
443         ASN__ENCODE_FAILED;
444
445     ASN_DEBUG("Bit-map of %d elements", n_extensions);
446     /* #18.7. Encoding the extensions presence bit-map. */
447     /* TODO: act upon NOTE in #18.7 for canonical PER */
448     if(SEQUENCE_handle_extensions_aper(td, sptr, po, 0) != n_extensions)
449         ASN__ENCODE_FAILED;
450
451     ASN_DEBUG("Writing %d extensions", n_extensions);
452     /* #18.9. Encode extensions as open type fields. */
453     if(SEQUENCE_handle_extensions_aper(td, sptr, 0, po) != n_extensions)
454         ASN__ENCODE_FAILED;
455
456     ASN__ENCODED_OK(er);
457 }