SIM-115: update simulator to use latest E2SM KPM version 3
[sim/e2-interface.git] / e2sim / asn1c / asn_application.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 <asn_application.h>
7 #include <errno.h>
8
9 static asn_enc_rval_t asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,
10                                           enum asn_transfer_syntax syntax,
11                                           const asn_TYPE_descriptor_t *td,
12                                           const void *sptr,
13                                           asn_app_consume_bytes_f *callback,
14                                           void *callback_key);
15
16
17 struct callback_count_bytes_key {
18     asn_app_consume_bytes_f *callback;
19     void *callback_key;
20     size_t computed_size;
21 };
22
23 /*
24  * Encoder which just counts bytes that come through it.
25  */
26 static int
27 callback_count_bytes_cb(const void *data, size_t size, void *keyp) {
28     struct callback_count_bytes_key *key = keyp;
29     int ret;
30
31     ret = key->callback(data, size, key->callback_key);
32     if(ret >= 0) {
33         key->computed_size += size;
34     }
35
36     return ret;
37 }
38
39 struct overrun_encoder_key {
40     void *buffer;
41     size_t buffer_size;
42     size_t computed_size;
43 };
44
45 struct dynamic_encoder_key {
46     void *buffer;
47     size_t buffer_size;
48     size_t computed_size;
49 };
50
51 struct callback_failure_catch_key {
52     asn_app_consume_bytes_f *callback;
53     void *callback_key;
54     int callback_failed;
55 };
56
57 /*
58  * Encoder which doesn't stop counting bytes
59  * even if it reaches the end of the buffer.
60  */
61 static int
62 overrun_encoder_cb(const void *data, size_t size, void *keyp) {
63     struct overrun_encoder_key *key = keyp;
64
65     if(key->computed_size + size > key->buffer_size) {
66         /*
67          * Avoid accident on the next call:
68          * stop adding bytes to the buffer.
69          */
70         key->buffer_size = 0;
71     } else {
72         memcpy((char *)key->buffer + key->computed_size, data, size);
73     }
74     key->computed_size += size;
75
76     return 0;
77 }
78
79 /*
80  * Encoder which dynamically allocates output, and continues
81  * to count even if allocation failed.
82  */
83 static int
84 dynamic_encoder_cb(const void *data, size_t size, void *keyp) {
85     struct dynamic_encoder_key *key = keyp;
86
87     if(key->buffer) {
88         if(key->computed_size + size >= key->buffer_size) {
89             void *p;
90             size_t new_size = key->buffer_size;
91
92             do {
93                 new_size *= 2;
94             } while(new_size <= key->computed_size + size);
95
96             p = REALLOC(key->buffer, new_size);
97             if(p) {
98                 key->buffer = p;
99                 key->buffer_size = new_size;
100             } else {
101                 FREEMEM(key->buffer);
102                 key->buffer = 0;
103                 key->buffer_size = 0;
104                 key->computed_size += size;
105                 return 0;
106             }
107         }
108         memcpy((char *)key->buffer + key->computed_size, data, size);
109     }
110
111     key->computed_size += size;
112
113     return 0;
114 }
115
116 /*
117  * Encoder which help convert the application level encoder failure into EIO.
118  */
119 static int
120 callback_failure_catch_cb(const void *data, size_t size, void *keyp) {
121     struct callback_failure_catch_key *key = keyp;
122     int ret;
123
124     ret = key->callback(data, size, key->callback_key);
125     if(ret < 0) {
126         key->callback_failed = 1;
127     }
128
129     return ret;
130 }
131
132 asn_enc_rval_t
133 asn_encode(const asn_codec_ctx_t *opt_codec_ctx,
134            enum asn_transfer_syntax syntax, const asn_TYPE_descriptor_t *td,
135            const void *sptr, asn_app_consume_bytes_f *callback, void *callback_key) {
136     struct callback_failure_catch_key cb_key;
137     asn_enc_rval_t er = {0,0,0};
138
139     if(!callback) {
140         errno = EINVAL;
141         ASN__ENCODE_FAILED;
142     }
143
144     cb_key.callback = callback;
145     cb_key.callback_key = callback_key;
146     cb_key.callback_failed = 0;
147
148     er = asn_encode_internal(opt_codec_ctx, syntax, td, sptr,
149                              callback_failure_catch_cb, &cb_key);
150     if(cb_key.callback_failed) {
151         assert(er.encoded == -1);
152         assert(errno == EBADF);
153         errno = EIO;
154     }
155
156     return er;
157 }
158
159 asn_enc_rval_t
160 asn_encode_to_buffer(const asn_codec_ctx_t *opt_codec_ctx,
161                      enum asn_transfer_syntax syntax,
162                      const asn_TYPE_descriptor_t *td, const void *sptr,
163                      void *buffer, size_t buffer_size) {
164     struct overrun_encoder_key buf_key;
165     asn_enc_rval_t er = {0,0,0};
166
167     if(buffer_size > 0 && !buffer) {
168         errno = EINVAL;
169         ASN__ENCODE_FAILED;
170     }
171
172     buf_key.buffer = buffer;
173     buf_key.buffer_size = buffer_size;
174     buf_key.computed_size = 0;
175
176     er = asn_encode_internal(opt_codec_ctx, syntax, td, sptr,
177                              overrun_encoder_cb, &buf_key);
178
179     if(er.encoded >= 0 && (size_t)er.encoded != buf_key.computed_size) {
180         ASN_DEBUG("asn_encode() returned %" ASN_PRI_SSIZE
181                   " yet produced %" ASN_PRI_SIZE " bytes",
182                   er.encoded, buf_key.computed_size);
183         assert(er.encoded < 0 || (size_t)er.encoded == buf_key.computed_size);
184     }
185
186     return er;
187 }
188
189 asn_encode_to_new_buffer_result_t
190 asn_encode_to_new_buffer(const asn_codec_ctx_t *opt_codec_ctx,
191                          enum asn_transfer_syntax syntax,
192                          const asn_TYPE_descriptor_t *td, const void *sptr) {
193     struct dynamic_encoder_key buf_key;
194     asn_encode_to_new_buffer_result_t res;
195
196     buf_key.buffer_size = 16;
197     buf_key.buffer = MALLOC(buf_key.buffer_size);
198     buf_key.computed_size = 0;
199
200     res.result = asn_encode_internal(opt_codec_ctx, syntax, td, sptr,
201                                      dynamic_encoder_cb, &buf_key);
202
203     if(res.result.encoded >= 0
204        && (size_t)res.result.encoded != buf_key.computed_size) {
205         ASN_DEBUG("asn_encode() returned %" ASN_PRI_SSIZE
206                   " yet produced %" ASN_PRI_SIZE " bytes",
207                   res.result.encoded, buf_key.computed_size);
208         assert(res.result.encoded < 0
209                || (size_t)res.result.encoded == buf_key.computed_size);
210     }
211
212     res.buffer = buf_key.buffer;
213
214     /* 0-terminate just in case. */
215     if(res.buffer) {
216         assert(buf_key.computed_size < buf_key.buffer_size);
217         ((char *)res.buffer)[buf_key.computed_size] = '\0';
218     }
219
220     return res;
221 }
222
223 static asn_enc_rval_t
224 asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,
225                     enum asn_transfer_syntax syntax,
226                     const asn_TYPE_descriptor_t *td, const void *sptr,
227                     asn_app_consume_bytes_f *callback, void *callback_key) {
228     asn_enc_rval_t er = {0,0,0};
229 #if !defined(ASN_DISABLE_XER_SUPPORT)
230     enum xer_encoder_flags_e xer_flags = XER_F_CANONICAL;
231 #endif  /* !defined(ASN_DISABLE_XER_SUPPORT) */
232
233     (void)opt_codec_ctx; /* Parameters are not checked on encode yet. */
234
235     if(!td || !sptr) {
236         errno = EINVAL;
237         ASN__ENCODE_FAILED;
238     }
239
240     switch(syntax) {
241     case ATS_NONSTANDARD_PLAINTEXT:
242         if(td->op->print_struct) {
243             struct callback_count_bytes_key cb_key;
244             cb_key.callback = callback;
245             cb_key.callback_key = callback_key;
246             cb_key.computed_size = 0;
247             if(td->op->print_struct(td, sptr, 1, callback_count_bytes_cb,
248                                     &cb_key)
249                    < 0
250                || callback_count_bytes_cb("\n", 1, &cb_key) < 0) {
251                 errno = EBADF; /* Structure has incorrect form. */
252                 er.encoded = -1;
253                 er.failed_type = td;
254                 er.structure_ptr = sptr;
255             } else {
256                 er.encoded = cb_key.computed_size;
257                 er.failed_type = 0;
258                 er.structure_ptr = 0;
259             }
260         } else {
261             errno = ENOENT; /* Transfer syntax is not defined for this type. */
262             ASN__ENCODE_FAILED;
263         }
264         break;
265
266     case ATS_RANDOM:
267         errno = ENOENT; /* Randomization doesn't make sense on output. */
268         ASN__ENCODE_FAILED;
269
270 #if !defined(ASN_DISABLE_BER_SUPPORT)
271     case ATS_BER:
272         /* BER is a superset of DER. */
273         /* Fall through. */
274     case ATS_DER:
275         if(td->op->der_encoder) {
276             er = der_encode(td, sptr, callback, callback_key);
277             if(er.encoded == -1) {
278                 if(er.failed_type && er.failed_type->op->der_encoder) {
279                     errno = EBADF;   /* Structure has incorrect form. */
280                 } else {
281                     errno = ENOENT;  /* DER is not defined for this type. */
282                 }
283             }
284         } else {
285             errno = ENOENT;  /* Transfer syntax is not defined for this type. */
286             ASN__ENCODE_FAILED;
287         }
288         break;
289     case ATS_CER:
290         errno = ENOENT;  /* Transfer syntax is not defined for any type. */
291         ASN__ENCODE_FAILED;
292 #else
293     case ATS_BER:
294     case ATS_DER:
295     case ATS_CER:
296         errno = ENOENT;  /* BER is not defined. */
297         ASN__ENCODE_FAILED;
298
299 #endif  /* !defined(ASN_DISABLE_BER_SUPPORT) */
300
301 #if !defined(ASN_DISABLE_OER_SUPPORT)
302     case ATS_BASIC_OER:
303         /* CANONICAL-OER is a superset of BASIC-OER. */
304         /* Fall through. */
305     case ATS_CANONICAL_OER:
306         if(td->op->oer_encoder) {
307             er = oer_encode(td, sptr, callback, callback_key);
308             if(er.encoded == -1) {
309                 if(er.failed_type && er.failed_type->op->oer_encoder) {
310                     errno = EBADF;   /* Structure has incorrect form. */
311                 } else {
312                     errno = ENOENT;  /* OER is not defined for this type. */
313                 }
314             }
315         } else {
316             errno = ENOENT;  /* Transfer syntax is not defined for this type. */
317             ASN__ENCODE_FAILED;
318         }
319         break;
320 #else
321     case ATS_BASIC_OER:
322     case ATS_CANONICAL_OER:
323         errno = ENOENT;  /* OER is not defined. */
324         ASN__ENCODE_FAILED;
325         break;
326 #endif  /* !defined(ASN_DISABLE_OER_SUPPORT) */
327
328 #if !defined(ASN_DISABLE_UPER_SUPPORT)
329     case ATS_UNALIGNED_BASIC_PER:
330         /* CANONICAL-UPER is a superset of BASIC-UPER. */
331         /* Fall through. */
332     case ATS_UNALIGNED_CANONICAL_PER:
333         if(td->op->uper_encoder) {
334             er = uper_encode(td, 0, sptr, callback, callback_key);
335             if(er.encoded == -1) {
336                 if(er.failed_type && er.failed_type->op->uper_encoder) {
337                     errno = EBADF;   /* Structure has incorrect form. */
338                 } else {
339                     errno = ENOENT;  /* UPER is not defined for this type. */
340                 }
341             } else {
342                 ASN_DEBUG("Complete encoded in %ld bits", (long)er.encoded);
343                 if(er.encoded == 0) {
344                     /* Enforce "Complete Encoding" of X.691 #11.1 */
345                     if(callback("\0", 1, callback_key) < 0) {
346                         errno = EBADF;
347                         ASN__ENCODE_FAILED;
348                     }
349                     er.encoded = 8;  /* Exactly 8 zero bits is added. */
350                 }
351                 /* Convert bits into bytes */
352                 er.encoded = (er.encoded + 7) >> 3;
353             }
354         } else {
355             errno = ENOENT;  /* Transfer syntax is not defined for this type. */
356             ASN__ENCODE_FAILED;
357         }
358         break;
359 #else
360     case ATS_UNALIGNED_BASIC_PER:
361     case ATS_UNALIGNED_CANONICAL_PER:
362         errno = ENOENT;  /* UPER is not defined. */
363         ASN__ENCODE_FAILED;
364         break;
365 #endif  /* !defined(ASN_DISABLE_UPER_SUPPORT) */
366 #if !defined(ASN_DISABLE_APER_SUPPORT)
367     case ATS_ALIGNED_BASIC_PER:
368         /* CANONICAL-APER is a superset of BASIC-APER. */
369         /* Fall through. */
370     case ATS_ALIGNED_CANONICAL_PER:
371         if(td->op->aper_encoder) {
372             er = aper_encode(td, 0, sptr, callback, callback_key);
373             if(er.encoded == -1) {
374                 if(er.failed_type && er.failed_type->op->aper_encoder) {
375                     errno = EBADF;   /* Structure has incorrect form. */
376                 } else {
377                     errno = ENOENT;  /* APER is not defined for this type. */
378                 }
379             } else {
380                 ASN_DEBUG("Complete encoded in %ld bits", (long)er.encoded);
381                 if(er.encoded == 0) {
382                     /* Enforce "Complete Encoding" of X.691 #11.1 */
383                     if(callback("\0", 1, callback_key) < 0) {
384                         errno = EBADF;
385                         ASN__ENCODE_FAILED;
386                     }
387                     er.encoded = 8;  /* Exactly 8 zero bits is added. */
388                 }
389                 /* Convert bits into bytes */
390                 er.encoded = (er.encoded + 7) >> 3;
391             }
392         } else {
393             errno = ENOENT;  /* Transfer syntax is not defined for this type. */
394             ASN__ENCODE_FAILED;
395         }
396         break;
397 #else
398     case ATS_ALIGNED_BASIC_PER:
399     case ATS_ALIGNED_CANONICAL_PER:
400         errno = ENOENT;  /* APER is not defined. */
401         ASN__ENCODE_FAILED;
402         break;
403 #endif  /* !defined(ASN_DISABLE_APER_SUPPORT) */
404
405 #if !defined(ASN_DISABLE_XER_SUPPORT)
406     case ATS_BASIC_XER:
407         /* CANONICAL-XER is a superset of BASIC-XER. */
408         xer_flags &= ~XER_F_CANONICAL;
409         xer_flags |= XER_F_BASIC;
410         /* Fall through. */
411     case ATS_CANONICAL_XER:
412         if(td->op->xer_encoder) {
413             er = xer_encode(td, sptr, xer_flags, callback, callback_key);
414             if(er.encoded == -1) {
415                 if(er.failed_type && er.failed_type->op->xer_encoder) {
416                     errno = EBADF;   /* Structure has incorrect form. */
417                 } else {
418                     errno = ENOENT;  /* XER is not defined for this type. */
419                 }
420             }
421         } else {
422             errno = ENOENT;  /* Transfer syntax is not defined for this type. */
423             ASN__ENCODE_FAILED;
424         }
425         break;
426 #else
427     case ATS_BASIC_XER:
428     case ATS_CANONICAL_XER:
429         errno = ENOENT;  /* XER is not defined. */
430         ASN__ENCODE_FAILED;
431         break;
432 #endif  /* !defined(ASN_DISABLE_XER_SUPPORT) */
433
434 #if !defined(ASN_DISABLE_JER_SUPPORT)
435     case ATS_JER:
436         if(td->op->jer_encoder) {
437             er = jer_encode(td, sptr, callback, callback_key);
438             if(er.encoded == -1) {
439                 if(er.failed_type && er.failed_type->op->jer_encoder) {
440                     errno = EBADF;   /* Structure has incorrect form. */
441                 } else {
442                     errno = ENOENT;  /* JER is not defined for this type. */
443                 }
444             }
445         } else {
446             errno = ENOENT;  /* Transfer syntax is not defined for this type. */
447             ASN__ENCODE_FAILED;
448         }
449         break;
450 #endif /* !defined(ASN_DISABLE_JER_SUPPORT) */
451     default:
452         errno = ENOENT;
453         ASN__ENCODE_FAILED;
454     }
455
456     return er;
457 }
458
459 asn_dec_rval_t
460 asn_decode(const asn_codec_ctx_t *opt_codec_ctx,
461            enum asn_transfer_syntax syntax, const asn_TYPE_descriptor_t *td,
462            void **sptr, const void *buffer, size_t size) {
463     if(!td || !td->op || !sptr || (size && !buffer)) {
464         ASN__DECODE_FAILED;
465     }
466
467     switch(syntax) {
468     case ATS_CER:
469     case ATS_NONSTANDARD_PLAINTEXT:
470     default:
471         errno = ENOENT;
472         ASN__DECODE_FAILED;
473
474     case ATS_RANDOM:
475 #if !defined(ASN_DISABLE_RFILL_SUPPORT)
476         if(!td->op->random_fill) {
477             ASN__DECODE_FAILED;
478         } else {
479             if(asn_random_fill(td, sptr, 16000) == 0) {
480                 asn_dec_rval_t ret = {RC_OK, 0};
481                 return ret;
482             } else {
483                 ASN__DECODE_FAILED;
484             }
485         }
486         break;
487 #else
488         errno = ENOENT;
489         ASN__DECODE_FAILED;
490 #endif  /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
491
492     case ATS_DER:
493     case ATS_BER:
494 #if !defined(ASN_DISABLE_BER_SUPPORT)
495         return ber_decode(opt_codec_ctx, td, sptr, buffer, size);
496 #else
497         errno = ENOENT;
498         ASN__DECODE_FAILED;
499 #endif  /* !defined(ASN_DISABLE_BER_SUPPORT) */
500
501     case ATS_BASIC_OER:
502     case ATS_CANONICAL_OER:
503 #if !defined(ASN_DISABLE_OER_SUPPORT)
504         return oer_decode(opt_codec_ctx, td, sptr, buffer, size);
505 #else
506         errno = ENOENT;
507         ASN__DECODE_FAILED;
508 #endif  /* !defined(ASN_DISABLE_OER_SUPPORT) */
509
510     case ATS_UNALIGNED_BASIC_PER:
511     case ATS_UNALIGNED_CANONICAL_PER:
512 #if !defined(ASN_DISABLE_UPER_SUPPORT)
513         return uper_decode_complete(opt_codec_ctx, td, sptr, buffer, size);
514 #else
515         errno = ENOENT;
516         ASN__DECODE_FAILED;
517 #endif  /* !defined(ASN_DISABLE_UPER_SUPPORT) */
518
519     case ATS_ALIGNED_BASIC_PER:
520     case ATS_ALIGNED_CANONICAL_PER:
521 #if !defined(ASN_DISABLE_APER_SUPPORT)
522         return aper_decode_complete(opt_codec_ctx, td, sptr, buffer, size);
523 #else
524         errno = ENOENT;
525         ASN__DECODE_FAILED;
526 #endif  /* !defined(ASN_DISABLE_APER_SUPPORT) */
527
528     case ATS_BASIC_XER:
529     case ATS_CANONICAL_XER:
530 #if !defined(ASN_DISABLE_XER_SUPPORT)
531         return xer_decode(opt_codec_ctx, td, sptr, buffer, size);
532 #else
533         errno = ENOENT;
534         ASN__DECODE_FAILED;
535 #endif  /* !defined(ASN_DISABLE_XER_SUPPORT) */
536     }
537 }
538