Moving in e2sim originally from it/test/simulators
[sim/e2-interface.git] / e2sim / ASN1c / ANY.c
1 /*****************************************************************************
2 #                                                                            *
3 # Copyright 2019 AT&T Intellectual Property                                  *
4 #                                                                            *
5 # Licensed under the Apache License, Version 2.0 (the "License");            *
6 # you may not use this file except in compliance with the License.           *
7 # You may obtain a copy of the License at                                    *
8 #                                                                            *
9 #      http://www.apache.org/licenses/LICENSE-2.0                            *
10 #                                                                            *
11 # Unless required by applicable law or agreed to in writing, software        *
12 # distributed under the License is distributed on an "AS IS" BASIS,          *
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
14 # See the License for the specific language governing permissions and        *
15 # limitations under the License.                                             *
16 #                                                                            *
17 ******************************************************************************/
18
19 /*
20  * Copyright (c) 2004-2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
21  * Redistribution and modifications are permitted subject to BSD license.
22  */
23 #include <asn_internal.h>
24 #include <ANY.h>
25 #include <errno.h>
26
27 asn_OCTET_STRING_specifics_t asn_SPC_ANY_specs = {
28         sizeof(ANY_t),
29         offsetof(ANY_t, _asn_ctx),
30         ASN_OSUBV_ANY
31 };
32 asn_TYPE_operation_t asn_OP_ANY = {
33         OCTET_STRING_free,
34         OCTET_STRING_print,
35         OCTET_STRING_compare,
36         OCTET_STRING_decode_ber,
37         OCTET_STRING_encode_der,
38         OCTET_STRING_decode_xer_hex,
39         ANY_encode_xer,
40 #ifdef  ASN_DISABLE_OER_SUPPORT
41         0,
42         0,
43 #else
44         0,
45         0,
46 #endif  /* ASN_DISABLE_OER_SUPPORT */
47 #ifdef  ASN_DISABLE_PER_SUPPORT
48         0, 0, 0, 0,
49 #else
50         ANY_decode_uper,
51         ANY_encode_uper,
52         ANY_decode_aper,
53         ANY_encode_aper,
54 #endif  /* ASN_DISABLE_PER_SUPPORT */
55         0,      /* Random fill is not defined for ANY type */
56         0       /* Use generic outmost tag fetcher */
57 };
58 asn_TYPE_descriptor_t asn_DEF_ANY = {
59         "ANY",
60         "ANY",
61         &asn_OP_ANY,
62         0, 0, 0, 0,
63         { 0, 0, asn_generic_no_constraint },    /* No constraints */
64         0, 0,   /* No members */
65         &asn_SPC_ANY_specs,
66 };
67
68 #undef RETURN
69 #define RETURN(_code)                       \
70     do {                                    \
71         asn_dec_rval_t tmprval;             \
72         tmprval.code = _code;               \
73         tmprval.consumed = consumed_myself; \
74         return tmprval;                     \
75     } while(0)
76
77 asn_enc_rval_t
78 ANY_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
79                enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb,
80                void *app_key) {
81     if(flags & XER_F_CANONICAL) {
82                 /*
83                  * Canonical XER-encoding of ANY type is not supported.
84                  */
85                 ASN__ENCODE_FAILED;
86         }
87
88         /* Dump as binary */
89         return OCTET_STRING_encode_xer(td, sptr, ilevel, flags, cb, app_key);
90 }
91
92 struct _callback_arg {
93         uint8_t *buffer;
94         size_t offset;
95         size_t size;
96 };
97
98 static int ANY__consume_bytes(const void *buffer, size_t size, void *key);
99
100 int
101 ANY_fromType(ANY_t *st, asn_TYPE_descriptor_t *td, void *sptr) {
102         struct _callback_arg arg;
103         asn_enc_rval_t erval = {0,0,0};
104
105         if(!st || !td) {
106                 errno = EINVAL;
107                 return -1;
108         }
109
110         if(!sptr) {
111                 if(st->buf) FREEMEM(st->buf);
112                 st->size = 0;
113                 return 0;
114         }
115
116         arg.offset = arg.size = 0;
117         arg.buffer = 0;
118
119         erval = der_encode(td, sptr, ANY__consume_bytes, &arg);
120         if(erval.encoded == -1) {
121                 if(arg.buffer) FREEMEM(arg.buffer);
122                 return -1;
123         }
124         assert((size_t)erval.encoded == arg.offset);
125
126         if(st->buf) FREEMEM(st->buf);
127         st->buf = arg.buffer;
128         st->size = arg.offset;
129
130         return 0;
131 }
132
133 int
134 ANY_fromType_aper(ANY_t *st, asn_TYPE_descriptor_t *td, void *sptr) {
135         uint8_t *buffer = NULL;
136         ssize_t erval;
137
138         if(!st || !td) {
139                 errno = EINVAL;
140                 return -1;
141         }
142
143         if(!sptr) {
144                 if(st->buf) FREEMEM(st->buf);
145                 st->size = 0;
146                 return 0;
147         }
148
149         erval = aper_encode_to_new_buffer(td, td->encoding_constraints.per_constraints, sptr, (void**)&buffer);
150
151         if(erval == -1) {
152                 if(buffer) FREEMEM(buffer);
153                 return -1;
154         }
155         assert((size_t)erval > 0);
156
157         if(st->buf) FREEMEM(st->buf);
158         st->buf = buffer;
159         st->size = erval;
160
161         return 0;
162 }
163
164 ANY_t *
165 ANY_new_fromType(asn_TYPE_descriptor_t *td, void *sptr) {
166         ANY_t tmp;
167         ANY_t *st;
168
169         if(!td || !sptr) {
170                 errno = EINVAL;
171                 return 0;
172         }
173
174         memset(&tmp, 0, sizeof(tmp));
175
176         if(ANY_fromType(&tmp, td, sptr)) return 0;
177
178         st = (ANY_t *)CALLOC(1, sizeof(ANY_t));
179         if(st) {
180                 *st = tmp;
181                 return st;
182         } else {
183                 FREEMEM(tmp.buf);
184                 return 0;
185         }
186 }
187
188 ANY_t *
189 ANY_new_fromType_aper(asn_TYPE_descriptor_t *td, void *sptr) {
190         ANY_t tmp;
191         ANY_t *st;
192
193         if(!td || !sptr) {
194                 errno = EINVAL;
195                 return 0;
196         }
197
198         memset(&tmp, 0, sizeof(tmp));
199
200         if(ANY_fromType_aper(&tmp, td, sptr)) return 0;
201
202         st = (ANY_t *)CALLOC(1, sizeof(ANY_t));
203         if(st) {
204                 *st = tmp;
205                 return st;
206         } else {
207                 FREEMEM(tmp.buf);
208                 return 0;
209         }
210 }
211
212 int
213 ANY_to_type(ANY_t *st, asn_TYPE_descriptor_t *td, void **struct_ptr) {
214         asn_dec_rval_t rval;
215         void *newst = 0;
216
217         if(!st || !td || !struct_ptr) {
218                 errno = EINVAL;
219                 return -1;
220         }
221
222         if(st->buf == 0) {
223                 /* Nothing to convert, make it empty. */
224                 *struct_ptr = (void *)0;
225                 return 0;
226         }
227
228         rval = ber_decode(0, td, (void **)&newst, st->buf, st->size);
229         if(rval.code == RC_OK) {
230                 *struct_ptr = newst;
231                 return 0;
232         } else {
233                 /* Remove possibly partially decoded data. */
234                 ASN_STRUCT_FREE(*td, newst);
235                 return -1;
236         }
237 }
238
239 int
240 ANY_to_type_aper(ANY_t *st, asn_TYPE_descriptor_t *td, void **struct_ptr) {
241         asn_dec_rval_t rval;
242         void *newst = 0;
243
244         if(!st || !td || !struct_ptr) {
245                 errno = EINVAL;
246                 return -1;
247         }
248
249         if(st->buf == 0) {
250                 /* Nothing to convert, make it empty. */
251                 *struct_ptr = (void *)0;
252                 return 0;
253         }
254
255         rval = aper_decode(0, td, (void **)&newst, st->buf, st->size, 0, 0);
256         if(rval.code == RC_OK) {
257                 *struct_ptr = newst;
258                 return 0;
259         } else {
260                 /* Remove possibly partially decoded data. */
261                 ASN_STRUCT_FREE(*td, newst);
262                 return -1;
263         }
264 }
265
266 static int ANY__consume_bytes(const void *buffer, size_t size, void *key) {
267         struct _callback_arg *arg = (struct _callback_arg *)key;
268
269         if((arg->offset + size) >= arg->size) {
270                 size_t nsize = (arg->size ? arg->size << 2 : 16) + size;
271                 void *p = REALLOC(arg->buffer, nsize);
272                 if(!p) return -1;
273                 arg->buffer = (uint8_t *)p;
274                 arg->size = nsize;
275         }
276
277         memcpy(arg->buffer + arg->offset, buffer, size);
278         arg->offset += size;
279         assert(arg->offset < arg->size);
280
281         return 0;
282 }
283
284 #ifndef ASN_DISABLE_PER_SUPPORT
285
286 asn_dec_rval_t
287 ANY_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
288                 const asn_TYPE_descriptor_t *td,
289                 const asn_per_constraints_t *constraints, void **sptr,
290                 asn_per_data_t *pd) {
291     const asn_OCTET_STRING_specifics_t *specs =
292         td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics
293                       : &asn_SPC_ANY_specs;
294     size_t consumed_myself = 0;
295     int repeat;
296     ANY_t *st = (ANY_t *)*sptr;
297
298     (void)opt_codec_ctx;
299     (void)constraints;
300
301     /*
302      * Allocate the structure.
303      */
304     if(!st) {
305         st = (ANY_t *)(*sptr = CALLOC(1, specs->struct_size));
306         if(!st) RETURN(RC_FAIL);
307     }
308
309     ASN_DEBUG("UPER Decoding ANY type");
310
311     st->size = 0;
312     do {
313         ssize_t raw_len;
314         ssize_t len_bytes;
315         ssize_t len_bits;
316         void *p;
317         int ret;
318
319         /* Get the PER length */
320         raw_len = uper_get_length(pd, -1, 0, &repeat);
321         if(raw_len < 0) RETURN(RC_WMORE);
322         if(raw_len == 0 && st->buf) break;
323
324         ASN_DEBUG("Got PER length len %" ASN_PRI_SIZE ", %s (%s)", raw_len,
325                   repeat ? "repeat" : "once", td->name);
326         len_bytes = raw_len;
327         len_bits = len_bytes * 8;
328
329         p = REALLOC(st->buf, st->size + len_bytes + 1);
330         if(!p) RETURN(RC_FAIL);
331         st->buf = (uint8_t *)p;
332
333         ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits);
334         if(ret < 0) RETURN(RC_WMORE);
335         consumed_myself += len_bits;
336         st->size += len_bytes;
337     } while(repeat);
338     st->buf[st->size] = 0; /* nul-terminate */
339
340     RETURN(RC_OK);
341 }
342
343 asn_enc_rval_t
344 ANY_encode_uper(const asn_TYPE_descriptor_t *td,
345                 const asn_per_constraints_t *constraints, const void *sptr,
346                 asn_per_outp_t *po) {
347     const ANY_t *st = (const ANY_t *)sptr;
348     asn_enc_rval_t er = {0, 0, 0};
349     const uint8_t *buf;
350     size_t size;
351     int ret;
352
353     (void)constraints;
354
355     if(!st || (!st->buf && st->size)) ASN__ENCODE_FAILED;
356
357     buf = st->buf;
358     size = st->size;
359     do {
360         int need_eom = 0;
361         ssize_t may_save = uper_put_length(po, size, &need_eom);
362         if(may_save < 0) ASN__ENCODE_FAILED;
363
364         ret = per_put_many_bits(po, buf, may_save * 8);
365         if(ret) ASN__ENCODE_FAILED;
366
367         buf += may_save;
368         size -= may_save;
369         assert(!(may_save & 0x07) || !size);
370         if(need_eom && uper_put_length(po, 0, 0))
371             ASN__ENCODE_FAILED; /* End of Message length */
372     } while(size);
373
374     ASN__ENCODED_OK(er);
375 }
376
377 asn_dec_rval_t
378 ANY_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
379                 const asn_TYPE_descriptor_t *td,
380                 const asn_per_constraints_t *constraints, void **sptr,
381                 asn_per_data_t *pd) {
382     const asn_OCTET_STRING_specifics_t *specs =
383         td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics
384                       : &asn_SPC_ANY_specs;
385     size_t consumed_myself = 0;
386     int repeat;
387     ANY_t *st = (ANY_t *)*sptr;
388
389     (void)opt_codec_ctx;
390     (void)constraints;
391
392     /*
393      * Allocate the structure.
394      */
395     if(!st) {
396         st = (ANY_t *)(*sptr = CALLOC(1, specs->struct_size));
397         if(!st) RETURN(RC_FAIL);
398     }
399
400     ASN_DEBUG("APER Decoding ANY type");
401
402     st->size = 0;
403     do {
404         ssize_t raw_len;
405         ssize_t len_bytes;
406         ssize_t len_bits;
407         void *p;
408         int ret;
409
410         /* Get the PER length */
411         raw_len = aper_get_length(pd, -1, 0, &repeat);
412         if(raw_len < 0) RETURN(RC_WMORE);
413         if(raw_len == 0 && st->buf) break;
414
415         ASN_DEBUG("Got PER length len %" ASN_PRI_SIZE ", %s (%s)", raw_len,
416                   repeat ? "repeat" : "once", td->name);
417         len_bytes = raw_len;
418         len_bits = len_bytes * 8;
419
420         p = REALLOC(st->buf, st->size + len_bytes + 1);
421         if(!p) RETURN(RC_FAIL);
422         st->buf = (uint8_t *)p;
423
424         ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits);
425         if(ret < 0) RETURN(RC_WMORE);
426         consumed_myself += len_bits;
427         st->size += len_bytes;
428     } while(repeat);
429     st->buf[st->size] = 0; /* nul-terminate */
430
431     RETURN(RC_OK);
432 }
433
434 asn_enc_rval_t
435 ANY_encode_aper(const asn_TYPE_descriptor_t *td,
436                 const asn_per_constraints_t *constraints, const void *sptr,
437                 asn_per_outp_t *po) {
438     const ANY_t *st = (const ANY_t *)sptr;
439     asn_enc_rval_t er = {0, 0, 0};
440     const uint8_t *buf;
441     size_t size;
442     int ret;
443
444     (void)constraints;
445
446     if(!st || (!st->buf && st->size)) ASN__ENCODE_FAILED;
447
448     buf = st->buf;
449     size = st->size;
450     do {
451         int need_eom = 0;
452         ssize_t may_save = uper_put_length(po, size, &need_eom);
453         if(may_save < 0) ASN__ENCODE_FAILED;
454
455         ret = per_put_many_bits(po, buf, may_save * 8);
456         if(ret) ASN__ENCODE_FAILED;
457
458         buf += may_save;
459         size -= may_save;
460         assert(!(may_save & 0x07) || !size);
461         if(need_eom && uper_put_length(po, 0, 0))
462             ASN__ENCODE_FAILED; /* End of Message length */
463     } while(size);
464
465     ASN__ENCODED_OK(er);
466 }
467 #endif /* ASN_DISABLE_PER_SUPPORT */
468