From cfc16d354a5d88c6cb0f7ebf02ff6d5ee71992df Mon Sep 17 00:00:00 2001 From: Lev Walkin Date: Wed, 30 Aug 2017 19:15:08 -0700 Subject: [PATCH] BIT STRING decode for OER --- examples/sample.source.1609.2/Makefile | 1 + skeletons/BIT_STRING.c | 4 +- skeletons/BIT_STRING.h | 2 + skeletons/BIT_STRING_oer.c | 101 +++++++++++++++++++++++++ skeletons/Makefile.am | 1 + skeletons/constr_SEQUENCE_oer.c | 20 +++-- skeletons/file-dependencies | 1 + 7 files changed, 122 insertions(+), 8 deletions(-) create mode 100644 skeletons/BIT_STRING_oer.c diff --git a/examples/sample.source.1609.2/Makefile b/examples/sample.source.1609.2/Makefile index b57dc688..43b96206 100644 --- a/examples/sample.source.1609.2/Makefile +++ b/examples/sample.source.1609.2/Makefile @@ -288,6 +288,7 @@ ASN_MODULE_SOURCES+=NativeEnumerated_oer.c ASN_MODULE_SOURCES+=constr_SEQUENCE_oer.c ASN_MODULE_SOURCES+=constr_CHOICE_oer.c ASN_MODULE_SOURCES+=constr_SET_OF_oer.c +ASN_MODULE_SOURCES+=BIT_STRING_oer.c ASN_CONVERTER_SOURCES+=pdu_collection.c diff --git a/skeletons/BIT_STRING.c b/skeletons/BIT_STRING.c index 7e9b82c4..3eabf0c1 100644 --- a/skeletons/BIT_STRING.c +++ b/skeletons/BIT_STRING.c @@ -30,8 +30,8 @@ asn_TYPE_operation_t asn_OP_BIT_STRING = { 0, 0, #else - 0, - 0, + BIT_STRING_decode_oer, + BIT_STRING_encode_oer, #endif /* ASN_DISABLE_OER_SUPPORT */ #ifdef ASN_DISABLE_PER_SUPPORT 0, diff --git a/skeletons/BIT_STRING.h b/skeletons/BIT_STRING.h index ed3d108b..2b195848 100644 --- a/skeletons/BIT_STRING.h +++ b/skeletons/BIT_STRING.h @@ -28,6 +28,8 @@ asn_struct_print_f BIT_STRING_print; /* Human-readable output */ asn_struct_compare_f BIT_STRING_compare; asn_constr_check_f BIT_STRING_constraint; xer_type_encoder_f BIT_STRING_encode_xer; +oer_type_decoder_f BIT_STRING_decode_oer; +oer_type_encoder_f BIT_STRING_encode_oer; #define BIT_STRING_free OCTET_STRING_free #define BIT_STRING_decode_ber OCTET_STRING_decode_ber diff --git a/skeletons/BIT_STRING_oer.c b/skeletons/BIT_STRING_oer.c new file mode 100644 index 00000000..55cee4a4 --- /dev/null +++ b/skeletons/BIT_STRING_oer.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2017 Lev Walkin . + * All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#ifndef ASN_DISABLE_OER_SUPPORT + +#include +#include +#include + +asn_dec_rval_t +BIT_STRING_decode_oer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, + const asn_oer_constraints_t *constraints, void **sptr, + const void *ptr, size_t size) { + BIT_STRING_t *st = (BIT_STRING_t *)*sptr; + const asn_oer_constraints_t *cts = + constraints ? constraints : td->oer_constraints; + ssize_t ct_size = cts ? cts->size : -1; + asn_dec_rval_t rval = {RC_OK, 0}; + size_t expected_length = 0; + + (void)opt_codec_ctx; + + if(!st) { + st = (BIT_STRING_t *)(*sptr = CALLOC(1, sizeof(*st))); + if(!st) ASN__DECODE_FAILED; + } + + if(ct_size >= 0) { + expected_length = (ct_size + 7) >> 3; + st->bits_unused = (8 - (ct_size & 7)) & 7; + } else { + /* + * X.696 (08/2015) #13.3.1 + * Encode length determinant as _number of octets_, but only + * if upper bound is not equal to lower bound. + */ + ssize_t len_len = oer_fetch_length(ptr, size, &expected_length); + if(len_len > 0) { + ptr = (const char *)ptr + len_len; + size -= len_len; + } else if(len_len == 0) { + ASN__DECODE_STARVED; + } else if(len_len < 0) { + ASN__DECODE_FAILED; + } + + if(expected_length < 1) { + ASN__DECODE_STARVED; + } + + st->bits_unused = ((const uint8_t *)ptr)[0]; + if(st->bits_unused & ~7) { + ASN_DEBUG("%s: unused bits outside of 0..7 range", td->name); + ASN__DECODE_FAILED; + } + ptr = (const char *)ptr + 1; + size--; + expected_length--; + rval.consumed = len_len + 1; + } + + if(size < expected_length) { + ASN__DECODE_STARVED; + } else { + uint8_t *buf = MALLOC(expected_length + 1); + if(buf == NULL) { + ASN__DECODE_FAILED; + } else { + memcpy(buf, ptr, expected_length); + buf[expected_length] = '\0'; + } + FREEMEM(st->buf); + st->buf = buf; + st->size = expected_length; + if(expected_length > 0) { + buf[expected_length - 1] &= (0xff << st->bits_unused); + } + + rval.consumed += expected_length; + return rval; + } +} + +/* + * Encode as Canonical OER. + */ +asn_enc_rval_t +BIT_STRING_encode_oer(asn_TYPE_descriptor_t *td, + const asn_oer_constraints_t *constraints, void *sptr, + asn_app_consume_bytes_f *cb, void *app_key) { + asn_enc_rval_t er = {-1,td,sptr}; + (void)constraints; + (void)cb; + (void)app_key; + return er; +} + + +#endif /* ASN_DISABLE_OER_SUPPORT */ diff --git a/skeletons/Makefile.am b/skeletons/Makefile.am index 4b36622f..d61c66c5 100644 --- a/skeletons/Makefile.am +++ b/skeletons/Makefile.am @@ -24,6 +24,7 @@ libasn1cskeletons_la_CFLAGS = $(SKELETONS_CFLAGS) libasn1cskeletons_la_SOURCES = \ ANY.c ANY.h \ BIT_STRING.c BIT_STRING.h \ + BIT_STRING_oer.c \ BMPString.c BMPString.h \ BOOLEAN.c BOOLEAN.h \ ENUMERATED.c ENUMERATED.h \ diff --git a/skeletons/constr_SEQUENCE_oer.c b/skeletons/constr_SEQUENCE_oer.c index 85566a3e..5b2a0bde 100644 --- a/skeletons/constr_SEQUENCE_oer.c +++ b/skeletons/constr_SEQUENCE_oer.c @@ -54,10 +54,16 @@ /* * Return pointer to a member. */ -static void **element_ptrptr(void *struct_ptr, asn_TYPE_member_t *elm) { - assert(elm->flags & ATF_POINTER); - /* Member is a pointer to another structure */ - return (void **)((char *)struct_ptr + elm->memb_offset); +static void ** +element_ptrptr(void *struct_ptr, asn_TYPE_member_t *elm, void **tmp_save_ptr) { + if(elm->flags & ATF_POINTER) { + /* Member is a pointer to another structure */ + return (void **)((char *)struct_ptr + elm->memb_offset); + } else { + assert(tmp_save_ptr); + *tmp_save_ptr = (void *)((char *)struct_ptr + elm->memb_offset); + return tmp_save_ptr; + } } static void *element_ptr(void *struct_ptr, asn_TYPE_member_t *elm) { @@ -172,7 +178,9 @@ SEQUENCE_decode_oer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, } else if(present == 0) { if(elm->default_value) { /* Fill-in DEFAULT */ - if(elm->default_value(1, element_ptrptr(st, elm))) { + void *tmp; + if(elm->default_value(1, + element_ptrptr(st, elm, &tmp))) { RETURN(RC_FAIL); } } @@ -306,7 +314,7 @@ SEQUENCE_decode_oer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, asn_bit_data_t *extadds = ctx->ptr; size_t edx = ctx->step; asn_TYPE_member_t *elm = &td->elements[edx]; - void **memb_ptr2 = element_ptrptr(st, elm); + void **memb_ptr2 = element_ptrptr(st, elm, 0); switch(asn_get_few_bits(extadds, 1)) { case -1: diff --git a/skeletons/file-dependencies b/skeletons/file-dependencies index 6a9e1354..8814d68f 100644 --- a/skeletons/file-dependencies +++ b/skeletons/file-dependencies @@ -79,5 +79,6 @@ NativeEnumerated_oer.c constr_SEQUENCE_oer.c constr_CHOICE_oer.c constr_SET_OF_oer.c constr_SET_OF.h asn_SET_OF.h asn_SET_OF.c +BIT_STRING_oer.c CODEC-PER: # THIS IS A SPECIAL SECTION