diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 4738acb7f3c1c5989fb3a210100cdf9d1f50dce1..56da5cdf82c1c651cf0ba66539ca258bcf3c03ec 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -397,13 +397,9 @@ install_asn1c_from_source(){ asn1_install_log=$OPENAIR_DIR/cmake_targets/log/asn1c_install_log.txt echo_info "\nInstalling ASN1. The log file for ASN1 installation is here: $asn1_install_log " ( - $SUDO rm -rf /tmp/asn1c-r1516 - svn co https://github.com/vlm/asn1c/trunk /tmp/asn1c-r1516 -r 1516 - cd /tmp/asn1c-r1516 - patch -p0 < $OPENAIR_DIR/openair3/S1AP/MESSAGES/ASN1/asn1cpatch.p0 - patch -p0 < $OPENAIR_DIR/openair3/S1AP/MESSAGES/ASN1/asn1cpatch_2.p0 - patch -p0 < $OPENAIR_DIR/openair2/RRC/LITE/MESSAGES/asn1c/asn1cpatch.p0 - patch -p0 < $OPENAIR_DIR/openair3/S1AP/MESSAGES/ASN1/asn1cpatch_3.p0 + $SUDO rm -rf /tmp/asn1c + git clone https://gitlab.eurecom.fr/oai/asn1c.git /tmp/asn1c + cd /tmp/asn1c ./configure make -j`nproc` $SUDO make install diff --git a/openair2/RRC/LITE/MESSAGES/asn1c/asn1cpatch.p0 b/openair2/RRC/LITE/MESSAGES/asn1c/asn1cpatch.p0 deleted file mode 100644 index 18dc516285b45214f9dd88598ce8ed08753a7588..0000000000000000000000000000000000000000 --- a/openair2/RRC/LITE/MESSAGES/asn1c/asn1cpatch.p0 +++ /dev/null @@ -1,13 +0,0 @@ -Index: skeletons/per_opentype.c -=================================================================== ---- skeletons/per_opentype.c (revision 1516) -+++ skeletons/per_opentype.c (working copy) -@@ -277,7 +306,7 @@ - (void)constraints; - (void)sptr; - -- while(per_get_few_bits(pd, 24) >= 0); -+ while(per_get_few_bits(pd, 1 /*24*/) >= 0); - - rv.code = RC_OK; - rv.consumed = pd->moved; diff --git a/openair2/RRC/LITE/rrc_eNB_S1AP.c b/openair2/RRC/LITE/rrc_eNB_S1AP.c index 1414c4e1b305f116b2fe1121722010c4cb74e0f1..cdb2ddc0ca2bf42cfac591217cbcf32bb9438258 100644 --- a/openair2/RRC/LITE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LITE/rrc_eNB_S1AP.c @@ -60,6 +60,8 @@ #endif #include "msc.h" +#include "UERadioAccessCapabilityInformation.h" + #include "gtpv1u_eNB_task.h" #include "RRC/LITE/rrc_eNB_GTPV1U.h" @@ -584,29 +586,42 @@ void rrc_eNB_send_S1AP_UE_CAPABILITIES_IND( //------------------------------------------------------------------------------ { UECapabilityInformation_t *ueCapabilityInformation = &ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation; - - if ((ueCapabilityInformation->criticalExtensions.present == UECapabilityInformation__criticalExtensions_PR_c1) - && (ueCapabilityInformation->criticalExtensions.choice.c1.present - == UECapabilityInformation__criticalExtensions__c1_PR_ueCapabilityInformation_r8) - && (ueCapabilityInformation->criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.count > 0)) { - UE_CapabilityRAT_ContainerList_t* ue_CapabilityRAT_ContainerList = - &ueCapabilityInformation->criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList; - MessageDef *msg_p; - - msg_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_UE_CAPABILITIES_IND); - S1AP_UE_CAPABILITIES_IND (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; - S1AP_UE_CAPABILITIES_IND (msg_p).ue_radio_cap.length = ue_CapabilityRAT_ContainerList->list.array[0]->ueCapabilityRAT_Container.size; - S1AP_UE_CAPABILITIES_IND (msg_p).ue_radio_cap.buffer = ue_CapabilityRAT_ContainerList->list.array[0]->ueCapabilityRAT_Container.buf; - - itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p); - - if (ue_CapabilityRAT_ContainerList->list.count > 1) { - LOG_W (RRC,"[eNB %d][UE %x] can only handle 1 UE capability RAT item for now (%d)\n", - ctxt_pP->module_id, - ue_context_pP->ue_context.rnti, - ue_CapabilityRAT_ContainerList->list.count); - } + /* 4096 is arbitrary, should be big enough */ + unsigned char buf[4096]; + unsigned char *buf2; + UERadioAccessCapabilityInformation_t rac; + + if (ueCapabilityInformation->criticalExtensions.present != UECapabilityInformation__criticalExtensions_PR_c1 + || ueCapabilityInformation->criticalExtensions.choice.c1.present != UECapabilityInformation__criticalExtensions__c1_PR_ueCapabilityInformation_r8) { + LOG_E(RRC, "[eNB %d][UE %x] bad UE capabilities\n", ctxt_pP->module_id, ue_context_pP->ue_context.rnti); + return; } + + asn_enc_rval_t ret = uper_encode_to_buffer(&asn_DEF_UECapabilityInformation, ueCapabilityInformation, buf, 4096); + if (ret.encoded == -1) abort(); + + memset(&rac, 0, sizeof(UERadioAccessCapabilityInformation_t)); + + rac.criticalExtensions.present = UERadioAccessCapabilityInformation__criticalExtensions_PR_c1; + rac.criticalExtensions.choice.c1.present = UERadioAccessCapabilityInformation__criticalExtensions__c1_PR_ueRadioAccessCapabilityInformation_r8; + rac.criticalExtensions.choice.c1.choice.ueRadioAccessCapabilityInformation_r8.ue_RadioAccessCapabilityInfo.buf = buf; + rac.criticalExtensions.choice.c1.choice.ueRadioAccessCapabilityInformation_r8.ue_RadioAccessCapabilityInfo.size = (ret.encoded+7)/8; + rac.criticalExtensions.choice.c1.choice.ueRadioAccessCapabilityInformation_r8.nonCriticalExtension = NULL; + + /* 8192 is arbitrary, should be big enough */ + buf2 = malloc16(8192); + if (buf2 == NULL) abort(); + ret = uper_encode_to_buffer(&asn_DEF_UERadioAccessCapabilityInformation, &rac, buf2, 8192); + if (ret.encoded == -1) abort(); + + MessageDef *msg_p; + + msg_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_UE_CAPABILITIES_IND); + S1AP_UE_CAPABILITIES_IND (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; + S1AP_UE_CAPABILITIES_IND (msg_p).ue_radio_cap.length = (ret.encoded+7)/8; + S1AP_UE_CAPABILITIES_IND (msg_p).ue_radio_cap.buffer = buf2; + + itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p); } //------------------------------------------------------------------------------ diff --git a/openair3/S1AP/MESSAGES/ASN1/asn1cpatch.p0 b/openair3/S1AP/MESSAGES/ASN1/asn1cpatch.p0 deleted file mode 100644 index b3a5b8d39f5059fabb85b65f03f23ea8f6760784..0000000000000000000000000000000000000000 --- a/openair3/S1AP/MESSAGES/ASN1/asn1cpatch.p0 +++ /dev/null @@ -1,5082 +0,0 @@ -Index: asn1c/unber.c -=================================================================== ---- asn1c/unber.c (revision 1516) -+++ asn1c/unber.c (working copy) -@@ -775,4 +775,8 @@ - - asn_enc_rval_t OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *cts, void *sptr, asn_per_outp_t *po) { asn_enc_rval_t er = { 0, 0, 0 }; (void)td; (void)cts; (void)sptr; (void)po; return er; } - -+asn_dec_rval_t OCTET_STRING_decode_aper(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, asn_per_constraints_t *cts, void **sptr, asn_per_data_t *pd) { asn_dec_rval_t rv = { 0, 0 }; (void)ctx; (void)td; (void)cts; (void)sptr; (void)pd; return rv; } -+ -+asn_enc_rval_t OCTET_STRING_encode_aper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *cts, void *sptr, asn_per_outp_t *po) { asn_enc_rval_t er = { 0, 0, 0 }; (void)td; (void)cts; (void)sptr; (void)po; return er; } -+ - size_t xer_whitespace_span(const void *chunk_buf, size_t chunk_size) { (void)chunk_buf; (void)chunk_size; return 0; } -Index: asn1c/asn1c.c -=================================================================== ---- asn1c/asn1c.c (revision 1516) -+++ asn1c/asn1c.c (working copy) -@@ -111,6 +111,8 @@ - asn1_compiler_flags &= ~A1C_LINK_SKELETONS; - } else if(strcmp(optarg, "link-skeletons") == 0) { - asn1_compiler_flags |= A1C_LINK_SKELETONS; -+ } else if(strcmp(optarg, "have_native64") == 0) { -+ asn1_compiler_flags |= A1C_HAVE_NATIVE_64; - } else { - fprintf(stderr, "-f%s: Invalid argument\n", optarg); - exit(EX_USAGE); -@@ -471,6 +473,7 @@ - " -fno-include-deps Do not generate courtesy #includes for dependencies\n" - " -funnamed-unions Enable unnamed unions in structures\n" - " -fwide-types Use INTEGER_t instead of \"long\" by default, etc.\n" -+" -fhave_native64 Use int64_t/uint64_t for target platform\n" - "\n" - - " -gen-PER Generate PER support code\n" -Index: examples/README -=================================================================== ---- examples/README (revision 1516) -+++ examples/README (working copy) -@@ -25,6 +25,8 @@ - UserPlane Location Protocol decoder. Before trying to compile, read the - README file in that directory. - -+The clyx2asn1.pl script can be used to extract ASN.1 data from LyX editor files. -+ - The crfc2asn1.pl script can be used to extract ASN.1 data from RFC texts. - For instance, it is used to extract X.509, MEGACO, and LDAPv3 ASN.1 modules - from the corresponding RFC texts (rfc3280.txt, rfc3525.txt, rfc4211.txt). -Index: skeletons/UTF8String.c -=================================================================== ---- skeletons/UTF8String.c (revision 1516) -+++ skeletons/UTF8String.c (working copy) -@@ -25,6 +25,8 @@ - OCTET_STRING_encode_xer_utf8, - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_UTF8String_tags, - sizeof(asn_DEF_UTF8String_tags) -Index: skeletons/constr_TYPE.h -=================================================================== ---- skeletons/constr_TYPE.h (revision 1516) -+++ skeletons/constr_TYPE.h (working copy) -@@ -99,6 +99,8 @@ - xer_type_encoder_f *xer_encoder; /* [Canonical] XER encoder */ - per_type_decoder_f *uper_decoder; /* Unaligned PER decoder */ - per_type_encoder_f *uper_encoder; /* Unaligned PER encoder */ -+ per_type_decoder_f *aper_decoder; /* Aligned PER decoder */ -+ per_type_encoder_f *aper_encoder; /* Aligned PER encoder */ - - /*********************************************************************** - * Internally useful members. Not to be used by applications directly. * -Index: skeletons/RELATIVE-OID.c -=================================================================== ---- skeletons/RELATIVE-OID.c (revision 1516) -+++ skeletons/RELATIVE-OID.c (working copy) -@@ -28,6 +28,8 @@ - RELATIVE_OID_encode_xer, - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_RELATIVE_OID_tags, - sizeof(asn_DEF_RELATIVE_OID_tags) -Index: skeletons/per_encoder.c -=================================================================== ---- skeletons/per_encoder.c (revision 1516) -+++ skeletons/per_encoder.c (working copy) -@@ -4,6 +4,7 @@ - - static asn_enc_rval_t uper_encode_internal(asn_TYPE_descriptor_t *td, asn_per_constraints_t *, void *sptr, asn_app_consume_bytes_f *cb, void *app_key); - -+static asn_enc_rval_t aper_encode_internal(asn_TYPE_descriptor_t *td, asn_per_constraints_t *, void *sptr, asn_app_consume_bytes_f *cb, void *app_key); - asn_enc_rval_t - uper_encode(asn_TYPE_descriptor_t *td, void *sptr, asn_app_consume_bytes_f *cb, void *app_key) { - return uper_encode_internal(td, 0, sptr, cb, app_key); -@@ -41,6 +42,18 @@ - return uper_encode_internal(td, 0, sptr, encode_to_buffer_cb, &key); - } - -+asn_enc_rval_t -+aper_encode_to_buffer(asn_TYPE_descriptor_t *td, void *sptr, void *buffer, size_t buffer_size) { -+ enc_to_buf_arg key; -+ -+ key.buffer = buffer; -+ key.left = buffer_size; -+ -+ if(td) ASN_DEBUG("Encoding \"%s\" using ALIGNED PER", td->name); -+ -+ return aper_encode_internal(td, 0, sptr, encode_to_buffer_cb, &key); -+} -+ - typedef struct enc_dyn_arg { - void *buffer; - size_t length; -@@ -93,6 +106,35 @@ - } - } - -+ssize_t -+aper_encode_to_new_buffer(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, void **buffer_r) { -+ asn_enc_rval_t er; -+ enc_dyn_arg key; -+ -+ memset(&key, 0, sizeof(key)); -+ -+ er = aper_encode_internal(td, constraints, sptr, encode_dyn_cb, &key); -+ switch(er.encoded) { -+ case -1: -+ FREEMEM(key.buffer); -+ return -1; -+ case 0: -+ FREEMEM(key.buffer); -+ key.buffer = MALLOC(1); -+ if(key.buffer) { -+ *(char *)key.buffer = '\0'; -+ *buffer_r = key.buffer; -+ return 1; -+ } else { -+ return -1; -+ } -+ default: -+ *buffer_r = key.buffer; -+ ASN_DEBUG("Complete encoded in %ld bits", (long)er.encoded); -+ return ((er.encoded + 7) >> 3); -+ } -+} -+ - /* - * Internally useful functions. - */ -@@ -115,6 +157,23 @@ - return po->outper(po->tmpspace, buf - po->tmpspace, po->op_key); - } - -+static int -+_aper_encode_flush_outp(asn_per_outp_t *po) { -+ uint8_t *buf; -+ -+ if(po->nboff == 0 && po->buffer == po->tmpspace) -+ return 0; -+ -+ buf = po->buffer + (po->nboff >> 3); -+ /* Make sure we account for the last, partially filled */ -+ if(po->nboff & 0x07) { -+ buf[0] &= 0xff << (8 - (po->nboff & 0x07)); -+ buf++; -+ } -+ -+ return po->outper(po->tmpspace, buf - po->tmpspace, po->op_key); -+} -+ - static asn_enc_rval_t - uper_encode_internal(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_app_consume_bytes_f *cb, void *app_key) { - asn_per_outp_t po; -@@ -149,3 +208,37 @@ - return er; - } - -+static asn_enc_rval_t -+aper_encode_internal(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_app_consume_bytes_f *cb, void *app_key) { -+ asn_per_outp_t po; -+ asn_enc_rval_t er; -+ -+ /* -+ * Invoke type-specific encoder. -+ */ -+ if(!td || !td->aper_encoder) -+ _ASN_ENCODE_FAILED; /* PER is not compiled in */ -+ -+ po.buffer = po.tmpspace; -+ po.nboff = 0; -+ po.nbits = 8 * sizeof(po.tmpspace); -+ po.outper = cb; -+ po.op_key = app_key; -+ po.flushed_bytes = 0; -+ -+ er = td->aper_encoder(td, constraints, sptr, &po); -+ if(er.encoded != -1) { -+ size_t bits_to_flush; -+ -+ bits_to_flush = ((po.buffer - po.tmpspace) << 3) + po.nboff; -+ -+ /* Set number of bits encoded to a firm value */ -+ er.encoded = (po.flushed_bytes << 3) + bits_to_flush; -+ -+ if(_aper_encode_flush_outp(&po)) -+ _ASN_ENCODE_FAILED; -+ } -+ -+ return er; -+} -+ -Index: skeletons/NumericString.c -=================================================================== ---- skeletons/NumericString.c (revision 1516) -+++ skeletons/NumericString.c (working copy) -@@ -49,6 +49,8 @@ - OCTET_STRING_encode_xer_utf8, - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_NumericString_tags, - sizeof(asn_DEF_NumericString_tags) -Index: skeletons/per_encoder.h -=================================================================== ---- skeletons/per_encoder.h (revision 1516) -+++ skeletons/per_encoder.h (working copy) -@@ -38,6 +38,12 @@ - size_t buffer_size /* Initial buffer size (max) */ - ); - -+asn_enc_rval_t aper_encode_to_buffer( -+ struct asn_TYPE_descriptor_s *type_descriptor, -+ void *struct_ptr, /* Structure to be encoded */ -+ void *buffer, /* Pre-allocated buffer */ -+ size_t buffer_size /* Initial buffer size (max) */ -+); - /* - * A variant of uper_encode_to_buffer() which allocates buffer itself. - * Returns the number of bytes in the buffer or -1 in case of failure. -@@ -52,6 +58,11 @@ - void **buffer_r /* Buffer allocated and returned */ - ); - -+ssize_t -+aper_encode_to_new_buffer(struct asn_TYPE_descriptor_s *td, -+ asn_per_constraints_t *constraints, -+ void *sptr, -+ void **buffer_r); - /* - * Type of the generic PER encoder function. - */ -Index: skeletons/T61String.c -=================================================================== ---- skeletons/T61String.c (revision 1516) -+++ skeletons/T61String.c (working copy) -@@ -24,6 +24,8 @@ - OCTET_STRING_encode_xer, - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_T61String_tags, - sizeof(asn_DEF_T61String_tags) -Index: skeletons/TeletexString.c -=================================================================== ---- skeletons/TeletexString.c (revision 1516) -+++ skeletons/TeletexString.c (working copy) -@@ -24,6 +24,8 @@ - OCTET_STRING_encode_xer, - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_TeletexString_tags, - sizeof(asn_DEF_TeletexString_tags) -Index: skeletons/BMPString.c -=================================================================== ---- skeletons/BMPString.c (revision 1516) -+++ skeletons/BMPString.c (working copy) -@@ -35,6 +35,8 @@ - BMPString_encode_xer, /* Convert to UTF-8 */ - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, /* Aligned PER decoder */ -+ OCTET_STRING_encode_aper, /* Aligned PER encoder */ - 0, /* Use generic outmost tag fetcher */ - asn_DEF_BMPString_tags, - sizeof(asn_DEF_BMPString_tags) -Index: skeletons/ObjectDescriptor.c -=================================================================== ---- skeletons/ObjectDescriptor.c (revision 1516) -+++ skeletons/ObjectDescriptor.c (working copy) -@@ -24,6 +24,8 @@ - OCTET_STRING_encode_xer_utf8, - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_ObjectDescriptor_tags, - sizeof(asn_DEF_ObjectDescriptor_tags) -Index: skeletons/PrintableString.c -=================================================================== ---- skeletons/PrintableString.c (revision 1516) -+++ skeletons/PrintableString.c (working copy) -@@ -59,6 +59,8 @@ - OCTET_STRING_encode_xer_utf8, - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_PrintableString_tags, - sizeof(asn_DEF_PrintableString_tags) -Index: skeletons/constr_SET_OF.c -=================================================================== ---- skeletons/constr_SET_OF.c (revision 1516) -+++ skeletons/constr_SET_OF.c (working copy) -@@ -34,7 +34,7 @@ - #undef ADVANCE - #define ADVANCE(num_bytes) do { \ - size_t num = num_bytes; \ -- ptr = ((const void *)ptr) + num;\ -+ ptr = ((const char *)ptr) + num;\ - size -= num; \ - if(ctx->left >= 0) \ - ctx->left -= num; \ -@@ -100,7 +100,7 @@ - /* - * Restore parsing context. - */ -- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset); -+ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset); - - /* - * Start to parse where left previously -@@ -457,7 +457,7 @@ - #undef XER_ADVANCE - #define XER_ADVANCE(num_bytes) do { \ - size_t num = num_bytes; \ -- buf_ptr = ((const void *)buf_ptr) + num;\ -+ buf_ptr = ((const char *)buf_ptr) + num;\ - size -= num; \ - consumed_myself += num; \ - } while(0) -@@ -505,7 +505,7 @@ - /* - * Restore parsing context. - */ -- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset); -+ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset); - - /* - * Phases of XER/XML processing: -@@ -627,7 +627,7 @@ - t->buffer = p; - t->size = newsize; - } -- memcpy((void *)t->buffer + t->offset, buffer, size); -+ memcpy((char *)t->buffer + t->offset, buffer, size); - t->offset += size; - return 0; - } -@@ -809,7 +809,7 @@ - asn_set_empty(list); /* Remove (list->array) */ - - specs = (asn_SET_OF_specifics_t *)td->specifics; -- ctx = (asn_struct_ctx_t *)((void *)ptr + specs->ctx_offset); -+ ctx = (asn_struct_ctx_t *)((char *)ptr + specs->ctx_offset); - if(ctx->ptr) { - ASN_STRUCT_FREE(*elm->type, ctx->ptr); - ctx->ptr = 0; -@@ -884,7 +884,7 @@ - if(!st) { - st = *sptr = CALLOC(1, specs->struct_size); - if(!st) _ASN_DECODE_FAILED; -- } -+ } - list = _A_SET_FROM_VOID(st); - - /* Figure out which constraints to use */ -@@ -901,7 +901,7 @@ - if(ct && ct->effective_bits >= 0) { - /* X.691, #19.5: No length determinant */ - nelems = per_get_few_bits(pd, ct->effective_bits); -- ASN_DEBUG("Preparing to fetch %ld+%ld elements from %s", -+ ASN_DEBUG("Preparing to fetch %ld+%"PRIdMAX" elements from %s", - (long)nelems, ct->lower_bound, td->name); - if(nelems < 0) _ASN_DECODE_STARVED; - nelems += ct->lower_bound; -@@ -951,3 +951,91 @@ - return rv; - } - -+asn_dec_rval_t -+SET_OF_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { -+ asn_dec_rval_t rv; -+ asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics; -+ asn_TYPE_member_t *elm = td->elements; /* Single one */ -+ void *st = *sptr; -+ asn_anonymous_set_ *list; -+ asn_per_constraint_t *ct; -+ int repeat = 0; -+ ssize_t nelems; -+ -+ if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx)) -+ _ASN_DECODE_FAILED; -+ -+ /* -+ * Create the target structure if it is not present already. -+ */ -+ if(!st) { -+ st = *sptr = CALLOC(1, specs->struct_size); -+ if(!st) _ASN_DECODE_FAILED; -+ } -+ list = _A_SET_FROM_VOID(st); -+ -+ /* Figure out which constraints to use */ -+ if(constraints) ct = &constraints->size; -+ else if(td->per_constraints) ct = &td->per_constraints->size; -+ else ct = 0; -+ -+ if(ct && ct->flags & APC_EXTENSIBLE) { -+ int value = per_get_few_bits(pd, 1); -+ if(value < 0) _ASN_DECODE_STARVED; -+ if(value) ct = 0; /* Not restricted! */ -+ } -+ -+ if(ct && ct->effective_bits >= 0) { -+ /* X.691, #19.5: No length determinant */ -+// nelems = per_get_few_bits(pd, ct->effective_bits); -+ nelems = aper_get_nsnnwn(pd, ct->upper_bound - ct->lower_bound); -+ ASN_DEBUG("Preparing to fetch %ld+%"PRIdMAX" elements from %s", -+ (long)nelems, ct->lower_bound, td->name); -+ if(nelems < 0) _ASN_DECODE_STARVED; -+ nelems += ct->lower_bound; -+ } else { -+ nelems = -1; -+ } -+ -+ do { -+ int i; -+ if(nelems < 0) { -+ nelems = aper_get_length(pd, ct ? ct->upper_bound - ct->lower_bound + 1 : -1, -+ ct ? ct->effective_bits : -1, &repeat); -+ ASN_DEBUG("Got to decode %d elements (eff %d)", -+ (int)nelems, (int)ct ? ct->effective_bits : -1); -+ if(nelems < 0) _ASN_DECODE_STARVED; -+ } -+ -+ for(i = 0; i < nelems; i++) { -+ void *ptr = 0; -+ ASN_DEBUG("SET OF %s decoding", elm->type->name); -+ rv = elm->type->aper_decoder(opt_codec_ctx, elm->type, -+ elm->per_constraints, &ptr, pd); -+ ASN_DEBUG("%s SET OF %s decoded %d, %p", -+ td->name, elm->type->name, rv.code, ptr); -+ if(rv.code == RC_OK) { -+ if(ASN_SET_ADD(list, ptr) == 0) -+ continue; -+ ASN_DEBUG("Failed to add element into %s", -+ td->name); -+ /* Fall through */ -+ rv.code = RC_FAIL; -+ } else { -+ ASN_DEBUG("Failed decoding %s of %s (SET OF)", -+ elm->type->name, td->name); -+ } -+ if(ptr) ASN_STRUCT_FREE(*elm->type, ptr); -+ return rv; -+ } -+ -+ nelems = -1; /* Allow uper_get_length() */ -+ } while(repeat); -+ -+ ASN_DEBUG("Decoded %s as SET OF", td->name); -+ -+ rv.code = RC_OK; -+ rv.consumed = 0; -+ return rv; -+} -Index: skeletons/NULL.c -=================================================================== ---- skeletons/NULL.c (revision 1516) -+++ skeletons/NULL.c (working copy) -@@ -25,6 +25,8 @@ - NULL_encode_xer, - NULL_decode_uper, /* Unaligned PER decoder */ - NULL_encode_uper, /* Unaligned PER encoder */ -+ NULL_decode_aper, /* Aligned PER decoder */ -+ NULL_encode_aper, /* Aligned PER encoder */ - 0, /* Use generic outmost tag fetcher */ - asn_DEF_NULL_tags, - sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]), -@@ -135,6 +137,34 @@ - return rv; - } - -+asn_dec_rval_t -+NULL_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { -+ asn_dec_rval_t rv; -+ -+ (void)opt_codec_ctx; -+ (void)td; -+ (void)constraints; -+ (void)pd; -+ -+ if(!*sptr) { -+ *sptr = MALLOC(sizeof(NULL_t)); -+ if(*sptr) { -+ *(NULL_t *)*sptr = 0; -+ } else { -+ _ASN_DECODE_FAILED; -+ } -+ } -+ -+ /* -+ * NULL type does not have content octets. -+ */ -+ -+ rv.code = RC_OK; -+ rv.consumed = 0; -+ return rv; -+} -+ - asn_enc_rval_t - NULL_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, - void *sptr, asn_per_outp_t *po) { -@@ -148,3 +178,17 @@ - er.encoded = 0; - _ASN_ENCODED_OK(er); - } -+ -+asn_enc_rval_t -+NULL_encode_aper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, -+ void *sptr, asn_per_outp_t *po) { -+ asn_enc_rval_t er; -+ -+ (void)td; -+ (void)constraints; -+ (void)sptr; -+ (void)po; -+ -+ er.encoded = 0; -+ _ASN_ENCODED_OK(er); -+} -Index: skeletons/per_decoder.c -=================================================================== ---- skeletons/per_decoder.c (revision 1516) -+++ skeletons/per_decoder.c (working copy) -@@ -37,6 +37,35 @@ - } - - asn_dec_rval_t -+aper_decode_complete(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const void *buffer, size_t size) { -+ asn_dec_rval_t rval; -+ -+ rval = aper_decode(opt_codec_ctx, td, sptr, buffer, size, 0, 0); -+ if(rval.consumed) { -+ /* -+ * We've always given 8-aligned data, -+ * so convert bits to integral bytes. -+ */ -+ rval.consumed += 7; -+ rval.consumed >>= 3; -+ } else if(rval.code == RC_OK) { -+ if(size) { -+ if(((const uint8_t *)buffer)[0] == 0) { -+ rval.consumed = 1; /* 1 byte */ -+ } else { -+ ASN_DEBUG("Expecting single zeroed byte"); -+ rval.code = RC_FAIL; -+ } -+ } else { -+ /* Must contain at least 8 bits. */ -+ rval.code = RC_WMORE; -+ } -+ } -+ -+ return rval; -+} -+ -+asn_dec_rval_t - uper_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const void *buffer, size_t size, int skip_bits, int unused_bits) { - asn_codec_ctx_t s_codec_ctx; - asn_dec_rval_t rval; -@@ -91,3 +120,57 @@ - return rval; - } - -+asn_dec_rval_t -+aper_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const void *buffer, size_t size, int skip_bits, int unused_bits) { -+ asn_codec_ctx_t s_codec_ctx; -+ asn_dec_rval_t rval; -+ asn_per_data_t pd; -+ -+ if(skip_bits < 0 || skip_bits > 7 -+ || unused_bits < 0 || unused_bits > 7 -+ || (unused_bits > 0 && !size)) -+ _ASN_DECODE_FAILED; -+ -+ /* -+ * Stack checker requires that the codec context -+ * must be allocated on the stack. -+ */ -+ if(opt_codec_ctx) { -+ if(opt_codec_ctx->max_stack_size) { -+ s_codec_ctx = *opt_codec_ctx; -+ opt_codec_ctx = &s_codec_ctx; -+ } -+ } else { -+ /* If context is not given, be security-conscious anyway */ -+ memset(&s_codec_ctx, 0, sizeof(s_codec_ctx)); -+ s_codec_ctx.max_stack_size = _ASN_DEFAULT_STACK_MAX; -+ opt_codec_ctx = &s_codec_ctx; -+ } -+ -+ /* Fill in the position indicator */ -+ memset(&pd, 0, sizeof(pd)); -+ pd.buffer = (const uint8_t *)buffer; -+ pd.nboff = skip_bits; -+ pd.nbits = 8 * size - unused_bits; /* 8 is CHAR_BIT from <limits.h> */ -+ if(pd.nboff > pd.nbits) -+ _ASN_DECODE_FAILED; -+ -+ /* -+ * Invoke type-specific decoder. -+ */ -+ if(!td->aper_decoder) -+ _ASN_DECODE_FAILED; /* PER is not compiled in */ -+ rval = td->aper_decoder(opt_codec_ctx, td, 0, sptr, &pd); -+ if(rval.code == RC_OK) { -+ /* Return the number of consumed bits */ -+ rval.consumed = ((pd.buffer - (const uint8_t *)buffer) << 3) -+ + pd.nboff - skip_bits; -+ ASN_DEBUG("PER decoding consumed %d, counted %d", -+ rval.consumed, pd.moved); -+ assert(rval.consumed == pd.moved); -+ } else { -+ /* PER codec is not a restartable */ -+ rval.consumed = 0; -+ } -+ return rval; -+} -Index: skeletons/constr_SET_OF.h -=================================================================== ---- skeletons/constr_SET_OF.h (revision 1516) -+++ skeletons/constr_SET_OF.h (working copy) -@@ -34,6 +34,8 @@ - xer_type_encoder_f SET_OF_encode_xer; - per_type_decoder_f SET_OF_decode_uper; - per_type_encoder_f SET_OF_encode_uper; -+per_type_decoder_f SET_OF_decode_aper; -+per_type_encoder_f SET_OF_encode_aper; - - #ifdef __cplusplus - } -Index: skeletons/NULL.h -=================================================================== ---- skeletons/NULL.h (revision 1516) -+++ skeletons/NULL.h (working copy) -@@ -25,6 +25,8 @@ - xer_type_encoder_f NULL_encode_xer; - per_type_decoder_f NULL_decode_uper; - per_type_encoder_f NULL_encode_uper; -+per_type_decoder_f NULL_decode_aper; -+per_type_encoder_f NULL_encode_aper; - - #ifdef __cplusplus - } -Index: skeletons/per_decoder.h -=================================================================== ---- skeletons/per_decoder.h (revision 1516) -+++ skeletons/per_decoder.h (working copy) -@@ -38,8 +38,30 @@ - int unused_bits /* Number of unused tailing bits, 0..7 */ - ); - -+/* -+ * Aligned PER decoder of a "complete encoding" as per X.691#10.1. -+ * On success, this call always returns (.consumed >= 1), as per X.691#10.1.3. -+ */ -+asn_dec_rval_t aper_decode_complete(struct asn_codec_ctx_s *opt_codec_ctx, -+ struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */ -+ void **struct_ptr, /* Pointer to a target structure's pointer */ -+ const void *buffer, /* Data to be decoded */ -+ size_t size /* Size of data buffer */ -+ ); - - /* -+ * Aligned PER decoder of any ASN.1 type. May be invoked by the application. -+ * WARNING: This call returns the number of BITS read from the stream. Beware. -+ */ -+asn_dec_rval_t aper_decode(struct asn_codec_ctx_s *opt_codec_ctx, -+ struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */ -+ void **struct_ptr, /* Pointer to a target structure's pointer */ -+ const void *buffer, /* Data to be decoded */ -+ size_t size, /* Size of data buffer */ -+ int skip_bits, /* Number of unused leading bits, 0..7 */ -+ int unused_bits /* Number of unused tailing bits, 0..7 */ -+ ); -+/* - * Type of the type-specific PER decoder function. - */ - typedef asn_dec_rval_t (per_type_decoder_f)(asn_codec_ctx_t *opt_codec_ctx, -Index: skeletons/per_support.c -=================================================================== ---- skeletons/per_support.c (revision 1516) -+++ skeletons/per_support.c (working copy) -@@ -31,6 +31,16 @@ - } - } - -+int32_t -+aper_get_align(asn_per_data_t *pd) { -+ -+ if(pd->nboff & 0x7) { -+ ASN_DEBUG("Aligning %d bits", 8 - (pd->nboff & 0x7)); -+ return per_get_few_bits(pd, 8 - (pd->nboff & 0x7)); -+ } -+ return 0; -+} -+ - /* - * Extract a small number of bits (<= 31) from the specified PER data pointer. - */ -@@ -187,6 +197,36 @@ - return (16384 * value); - } - -+ssize_t -+aper_get_length(asn_per_data_t *pd, int range, int ebits, int *repeat) { -+ ssize_t value; -+ -+ *repeat = 0; -+ -+ if (range <= 65536 && range >= 0) -+ return aper_get_nsnnwn(pd, range); -+ -+ if (aper_get_align(pd) < 0) -+ return -1; -+ -+ if(ebits >= 0) return per_get_few_bits(pd, ebits); -+ -+ value = per_get_few_bits(pd, 8); -+ if(value < 0) return -1; -+ if((value & 128) == 0) /* #10.9.3.6 */ -+ return (value & 0x7F); -+ if((value & 64) == 0) { /* #10.9.3.7 */ -+ value = ((value & 63) << 8) | per_get_few_bits(pd, 8); -+ if(value < 0) return -1; -+ return value; -+ } -+ value &= 63; /* this is "m" from X.691, #10.9.3.8 */ -+ if(value < 1 || value > 4) -+ return -1; -+ *repeat = 1; -+ return (16384 * value); -+} -+ - /* - * Get the normally small length "n". - * This procedure used to decode length of extensions bit-maps -@@ -211,6 +251,25 @@ - } - } - -+ssize_t -+aper_get_nslength(asn_per_data_t *pd) { -+ ssize_t length; -+ -+ ASN_DEBUG("Getting normally small length"); -+ -+ if(per_get_few_bits(pd, 1) == 0) { -+ length = per_get_few_bits(pd, 6) + 1; -+ if(length <= 0) return -1; -+ ASN_DEBUG("l=%d", length); -+ return length; -+ } else { -+ int repeat; -+ length = aper_get_length(pd, -1, -1, &repeat); -+ if(length >= 0 && !repeat) return length; -+ return -1; /* Error, or do not support >16K extensions */ -+ } -+} -+ - /* - * Get the normally small non-negative whole number. - * X.691, #10.6 -@@ -237,6 +296,40 @@ - return value; - } - -+ssize_t -+aper_get_nsnnwn(asn_per_data_t *pd, int range) { -+ ssize_t value; -+ int bytes = 0; -+ -+ ASN_DEBUG("getting nsnnwn with range %d", range); -+ -+ if(range <= 255) { -+ if (range < 0) return -1; -+ /* 1 -> 8 bits */ -+ int i; -+ for (i = 1; i <= 8; i++) { -+ int upper = 1 << i; -+ if (upper >= range) -+ break; -+ } -+ value = per_get_few_bits(pd, i); -+ return value; -+ } else if (range == 256){ -+ /* 1 byte */ -+ bytes = 1; -+ return -1; -+ } else if (range <= 65536) { -+ /* 2 bytes */ -+ bytes = 2; -+ } else { -+ return -1; -+ } -+ if (aper_get_align(pd) < 0) -+ return -1; -+ value = per_get_few_bits(pd, 8 * bytes); -+ return value; -+} -+ - /* - * Put the normally small non-negative whole number. - * X.691, #10.6 -@@ -263,7 +356,59 @@ - return per_put_few_bits(po, n, 8 * bytes); - } - -+int -+aper_put_nsnnwn(asn_per_outp_t *po, int range, int number) { -+ int bytes; - -+ /* 10.5.7.1 X.691 */ -+ if(range < 0) { -+ int i; -+ for (i = 1; ; i++) { -+ int bits = 1 << (8 * i); -+ if (number <= bits) -+ break; -+ } -+ bytes = i; -+ assert(i <= 4); -+ } -+ if(range <= 255) { -+ int i; -+ for (i = 1; i <= 8; i++) { -+ int bits = 1 << i; -+ if (range <= bits) -+ break; -+ } -+ return per_put_few_bits(po, number, i); -+ } else if(range == 256) { -+ bytes = 1; -+ } else if(range <= 65536) { -+ bytes = 2; -+ } else { /* Ranges > 64K */ -+ int i; -+ for (i = 1; ; i++) { -+ int bits = 1 << (8 * i); -+ if (range <= bits) -+ break; -+ } -+ assert(i <= 4); -+ bytes = i; -+ } -+ if(aper_put_align(po) < 0) /* Aligning on octet */ -+ return -1; -+ -+ return per_put_few_bits(po, number, 8 * bytes); -+} -+ -+int aper_put_align(asn_per_outp_t *po) { -+ -+ if(po->nboff & 0x7) { -+ ASN_DEBUG("Aligning %d bits", 8 - (po->nboff & 0x7)); -+ if(per_put_few_bits(po, 0x00, (8 - (po->nboff & 0x7)))) -+ return -1; -+ } -+ return 0; -+} -+ - /* - * Put a small number of bits (<= 31). - */ -@@ -392,6 +537,8 @@ - ssize_t - uper_put_length(asn_per_outp_t *po, size_t length) { - -+ ASN_DEBUG("UPER put length %d", length); -+ - if(length <= 127) /* #10.9.3.6 */ - return per_put_few_bits(po, length, 8) - ? -1 : (ssize_t)length; -@@ -406,7 +553,34 @@ - ? -1 : (ssize_t)(length << 14); - } - -+ssize_t -+aper_put_length(asn_per_outp_t *po, int range, size_t length) { - -+ ASN_DEBUG("APER put length %d with range %d", length, range); -+ -+ /* 10.9 X.691 Note 2 */ -+ if (range <= 65536 && range >= 0) -+ return aper_put_nsnnwn(po, range, length); -+ -+ if (aper_put_align(po) < 0) -+ return -1; -+ -+ if(length <= 127) /* #10.9.3.6 */{ -+ return per_put_few_bits(po, length, 8) -+ ? -1 : (ssize_t)length; -+ } -+ else if(length < 16384) /* #10.9.3.7 */ -+ return per_put_few_bits(po, length|0x8000, 16) -+ ? -1 : (ssize_t)length; -+ -+ length >>= 14; -+ if(length > 4) length = 4; -+ -+ return per_put_few_bits(po, 0xC0 | length, 8) -+ ? -1 : (ssize_t)(length << 14); -+} -+ -+ - /* - * Put the normally small length "n" into the stream. - * This procedure used to encode length of extensions bit-maps -@@ -429,3 +603,19 @@ - return 0; - } - -+int -+aper_put_nslength(asn_per_outp_t *po, size_t length) { -+ -+ if(length <= 64) { -+ /* #10.9.3.4 */ -+ if(length == 0) return -1; -+ return per_put_few_bits(po, length-1, 7) ? -1 : 0; -+ } else { -+ if(aper_put_length(po, -1, length) != (ssize_t)length) { -+ /* This might happen in case of >16K extensions */ -+ return -1; -+ } -+ } -+ -+ return 0; -+} -Index: skeletons/constr_SET.c -=================================================================== ---- skeletons/constr_SET.c (revision 1516) -+++ skeletons/constr_SET.c (working copy) -@@ -36,7 +36,7 @@ - #undef ADVANCE - #define ADVANCE(num_bytes) do { \ - size_t num = num_bytes; \ -- ptr = ((const void *)ptr) + num;\ -+ ptr = ((const char *)ptr) + num;\ - size -= num; \ - if(ctx->left >= 0) \ - ctx->left -= num; \ -@@ -132,7 +132,7 @@ - /* - * Restore parsing context. - */ -- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset); -+ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset); - - /* - * Start to parse where left previously -@@ -250,7 +250,7 @@ - - skip = ber_skip_length(opt_codec_ctx, - BER_TLV_CONSTRUCTED(ptr), -- (const void *)ptr + tag_len, LEFT - tag_len); -+ (const char *)ptr + tag_len, LEFT - tag_len); - - switch(skip) { - case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE); -@@ -271,7 +271,7 @@ - * Check for duplications: must not overwrite - * already decoded elements. - */ -- if(ASN_SET_ISPRESENT2((void *)st + specs->pres_offset, edx)) { -+ if(ASN_SET_ISPRESENT2((char *)st + specs->pres_offset, edx)) { - ASN_DEBUG("SET %s: Duplicate element %s (%d)", - td->name, elements[edx].name, edx); - RETURN(RC_FAIL); -@@ -284,13 +284,13 @@ - */ - if(elements[edx].flags & ATF_POINTER) { - /* Member is a pointer to another structure */ -- memb_ptr2 = (void **)((void *)st + elements[edx].memb_offset); -+ memb_ptr2 = (void **)((char *)st + elements[edx].memb_offset); - } else { - /* - * A pointer to a pointer - * holding the start of the structure - */ -- memb_ptr = (void *)st + elements[edx].memb_offset; -+ memb_ptr = (char *)st + elements[edx].memb_offset; - memb_ptr2 = &memb_ptr; - } - /* -@@ -302,7 +302,7 @@ - elements[edx].tag_mode); - switch(rval.code) { - case RC_OK: -- ASN_SET_MKPRESENT((void *)st + specs->pres_offset, edx); -+ ASN_SET_MKPRESENT((char *)st + specs->pres_offset, edx); - break; - case RC_WMORE: /* More data expected */ - if(!SIZE_VIOLATION) { -@@ -369,7 +369,7 @@ - - ll = ber_skip_length(opt_codec_ctx, - BER_TLV_CONSTRUCTED(ptr), -- (const void *)ptr + tl, LEFT - tl); -+ (const char *)ptr + tl, LEFT - tl); - switch(ll) { - case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE); - /* Fall through */ -@@ -404,7 +404,7 @@ - unsigned int midx, pres, must; - - midx = edx/(8 * sizeof(specs->_mandatory_elements[0])); -- pres = ((unsigned int *)((void *)st+specs->pres_offset))[midx]; -+ pres = ((unsigned int *)((char *)st+specs->pres_offset))[midx]; - must = sys_ntohl(specs->_mandatory_elements[midx]); - - if((pres & must) == must) { -@@ -473,7 +473,7 @@ - * Compute the length of the encoding of this member. - */ - if(elm->flags & ATF_POINTER) { -- memb_ptr = *(void **)((void *)sptr + elm->memb_offset); -+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset); - if(!memb_ptr) { - if(!elm->optional) - /* Mandatory elements missing */ -@@ -486,7 +486,7 @@ - continue; - } - } else { -- memb_ptr = (void *)((void *)sptr + elm->memb_offset); -+ memb_ptr = (void *)((char *)sptr + elm->memb_offset); - } - tmper = elm->type->der_encoder(elm->type, memb_ptr, - elm->tag_mode, elm->tag, -@@ -547,10 +547,10 @@ - elm = &td->elements[t2m[edx].el_no]; - - if(elm->flags & ATF_POINTER) { -- memb_ptr = *(void **)((void *)sptr + elm->memb_offset); -+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset); - if(!memb_ptr) continue; - } else { -- memb_ptr = (void *)((void *)sptr + elm->memb_offset); -+ memb_ptr = (void *)((char *)sptr + elm->memb_offset); - } - tmper = elm->type->der_encoder(elm->type, memb_ptr, - elm->tag_mode, elm->tag, -@@ -570,10 +570,185 @@ - _ASN_ENCODED_OK(er); - } - -+asn_enc_rval_t -+SET_encode_uper(asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, -+ void *sptr, -+ asn_per_outp_t *po) { -+} -+ -+asn_dec_rval_t -+SET_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { -+} -+ -+asn_enc_rval_t -+SET_encode_aper(asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, -+ void *sptr, -+ asn_per_outp_t *po) { -+ asn_SET_specifics_t *specs = (asn_SET_specifics_t *)td->specifics; -+ asn_enc_rval_t er; -+ int edx, i; -+ int t2m_build_own = (specs->tag2el_count != td->elements_count); -+ asn_TYPE_tag2member_t *t2m; -+ int t2m_count; -+ -+ (void)constraints; -+ -+ if(!sptr) -+ _ASN_ENCODE_FAILED; -+ -+ er.encoded = 0; -+ -+ ASN_DEBUG("Encoding %s as SET (APER) map %d", td->name, specs->_mandatory_elements[0]); -+ -+ /* -+ * Use existing, or build our own tags map. -+ */ -+ if(t2m_build_own) { -+ t2m = (asn_TYPE_tag2member_t *)alloca( -+ td->elements_count * sizeof(t2m[0])); -+ if(!t2m) _ASN_ENCODE_FAILED; /* There are such platforms */ -+ t2m_count = 0; -+ } else { -+ /* -+ * There is no untagged CHOICE in this SET. -+ * Employ existing table. -+ */ -+ t2m = specs->tag2el; -+ t2m_count = specs->tag2el_count; -+ } -+ -+ /* -+ * Gather the length of the underlying members sequence. -+ */ -+ for(edx = 0; edx < td->elements_count; edx++) { -+ asn_TYPE_member_t *elm = &td->elements[edx]; -+ asn_enc_rval_t tmper; -+ void *memb_ptr; -+ -+ /* -+ * Compute the length of the encoding of this member. -+ */ -+ if(elm->flags & ATF_POINTER) { -+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset); -+ if(!memb_ptr) { -+ if(!elm->optional) -+ /* Mandatory elements missing */ -+ _ASN_ENCODE_FAILED; -+ if(t2m_build_own) { -+ t2m[t2m_count].el_no = edx; -+ t2m[t2m_count].el_tag = 0; -+ t2m_count++; -+ } -+ continue; -+ } -+ } else { -+ memb_ptr = (void *)((char *)sptr + elm->memb_offset); -+ } -+ -+ /* -+ * Remember the outmost tag of this member. -+ */ -+ if(t2m_build_own) { -+ t2m[t2m_count].el_no = edx; -+ t2m[t2m_count].el_tag = asn_TYPE_outmost_tag( -+ elm->type, memb_ptr, elm->tag_mode, elm->tag); -+ t2m_count++; -+ } else { -+ /* -+ * No dynamic sorting is necessary. -+ */ -+ } -+ } -+ -+ /* -+ * Finalize order of the components. -+ */ -+ assert(t2m_count == td->elements_count); -+ if(t2m_build_own) { -+ /* -+ * Sort the underlying members according to their -+ * canonical tags order. DER encoding mandates it. -+ */ -+ qsort(t2m, t2m_count, sizeof(specs->tag2el[0]), _t2e_cmp); -+ } else { -+ /* -+ * Tags are already sorted by the compiler. -+ */ -+ } -+ -+ for(edx = 0; edx < td->elements_count; edx++) { -+ asn_TYPE_member_t *elm = &td->elements[t2m[edx].el_no]; -+ asn_enc_rval_t tmper; -+ void *memb_ptr; /* Pointer to the member */ -+ void **memb_ptr2; /* Pointer to that pointer */ -+ int present; -+ -+ /* Fetch the pointer to this member */ -+ if(elm->flags & ATF_POINTER) { -+ memb_ptr2 = (void **)((char *)sptr + elm->memb_offset); -+ present = (*memb_ptr2 != 0); -+ } else { -+// memb_ptr = (void *)((char *)sptr + elm->memb_offset); -+// memb_ptr2 = &memb_ptr; -+ present = 1; -+ continue; -+ } -+ -+// /* Eliminate default values */ -+// if(present && elm->default_value -+// && elm->default_value(0, memb_ptr2) == 1) -+// present = 0; -+ -+ ASN_DEBUG("Element %s %s %s->%s is %s", -+ elm->flags & ATF_POINTER ? "ptr" : "inline", -+ elm->default_value ? "def" : "wtv", -+ td->name, elm->name, present ? "present" : "absent"); -+ if(per_put_few_bits(po, present << 7, 8)) -+ _ASN_ENCODE_FAILED; -+ } -+ -+ /* -+ * Encode all members. -+ */ -+ for(edx = 0; edx < td->elements_count; edx++) { -+ asn_TYPE_member_t *elm = &td->elements[edx]; -+ asn_enc_rval_t tmper; -+ void *memb_ptr; /* Pointer to the member */ -+ void **memb_ptr2; /* Pointer to that pointer */ -+ -+ /* Encode according to the tag order */ -+// elm = &td->elements[t2m[edx].el_no]; -+ -+ if(elm->flags & ATF_POINTER) { -+ memb_ptr2 = (void **)((char *)sptr + elm->memb_offset); -+ if(!*memb_ptr2) { -+ ASN_DEBUG("Element %s %d not present", -+ elm->name, edx); -+ if(elm->optional) -+ continue; -+ /* Mandatory element is missing */ -+ _ASN_ENCODE_FAILED; -+ } -+ } else { -+ memb_ptr = (void *)((char *)sptr + elm->memb_offset); -+ memb_ptr2 = &memb_ptr; -+ } -+ tmper = elm->type->aper_encoder(elm->type, elm->per_constraints, -+ *memb_ptr2, po); -+ if(tmper.encoded == -1) -+ return tmper; -+ } -+ -+ _ASN_ENCODED_OK(er); -+} -+ - #undef XER_ADVANCE - #define XER_ADVANCE(num_bytes) do { \ - size_t num = num_bytes; \ -- buf_ptr = ((const void *)buf_ptr) + num;\ -+ buf_ptr = ((const char *)buf_ptr) + num;\ - size -= num; \ - consumed_myself += num; \ - } while(0) -@@ -613,7 +788,7 @@ - /* - * Restore parsing context. - */ -- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset); -+ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset); - - /* - * Phases of XER/XML processing: -@@ -637,7 +812,7 @@ - void *memb_ptr; /* Pointer to the member */ - void **memb_ptr2; /* Pointer to that pointer */ - -- if(ASN_SET_ISPRESENT2((void *)st + specs->pres_offset, -+ if(ASN_SET_ISPRESENT2((char *)st + specs->pres_offset, - edx)) { - ASN_DEBUG("SET %s: Duplicate element %s (%d)", - td->name, elements[edx].name, edx); -@@ -648,10 +823,10 @@ - - if(elm->flags & ATF_POINTER) { - /* Member is a pointer to another structure */ -- memb_ptr2 = (void **)((void *)st -+ memb_ptr2 = (void **)((char *)st - + elm->memb_offset); - } else { -- memb_ptr = (void *)st + elm->memb_offset; -+ memb_ptr = (char *)st + elm->memb_offset; - memb_ptr2 = &memb_ptr; - } - -@@ -663,7 +838,7 @@ - if(tmprval.code != RC_OK) - RETURN(tmprval.code); - ctx->phase = 1; /* Back to body processing */ -- ASN_SET_MKPRESENT((void *)st + specs->pres_offset, edx); -+ ASN_SET_MKPRESENT((char *)st + specs->pres_offset, edx); - ASN_DEBUG("XER/SET phase => %d", ctx->phase); - /* Fall through */ - } -@@ -827,7 +1002,7 @@ - mlen = strlen(elm->name); - - if(elm->flags & ATF_POINTER) { -- memb_ptr = *(void **)((void *)sptr + elm->memb_offset); -+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset); - if(!memb_ptr) { - if(elm->optional) - continue; -@@ -835,7 +1010,7 @@ - _ASN_ENCODE_FAILED; - } - } else { -- memb_ptr = (void *)((void *)sptr + elm->memb_offset); -+ memb_ptr = (void *)((char *)sptr + elm->memb_offset); - } - - if(!xcan) -@@ -877,14 +1052,14 @@ - const void *memb_ptr; - - if(elm->flags & ATF_POINTER) { -- memb_ptr = *(const void * const *)((const void *)sptr + elm->memb_offset); -+ memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset); - if(!memb_ptr) { - if(elm->optional) continue; - /* Print <absent> line */ - /* Fall through */ - } - } else { -- memb_ptr = (const void *)((const void *)sptr + elm->memb_offset); -+ memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); - } - - _i_INDENT(1); -@@ -919,11 +1094,11 @@ - asn_TYPE_member_t *elm = &td->elements[edx]; - void *memb_ptr; - if(elm->flags & ATF_POINTER) { -- memb_ptr = *(void **)((void *)ptr + elm->memb_offset); -+ memb_ptr = *(void **)((char *)ptr + elm->memb_offset); - if(memb_ptr) - ASN_STRUCT_FREE(*elm->type, memb_ptr); - } else { -- memb_ptr = (void *)((void *)ptr + elm->memb_offset); -+ memb_ptr = (void *)((char *)ptr + elm->memb_offset); - ASN_STRUCT_FREE_CONTENTS_ONLY(*elm->type, memb_ptr); - } - } -@@ -953,7 +1128,7 @@ - const void *memb_ptr; - - if(elm->flags & ATF_POINTER) { -- memb_ptr = *(const void * const *)((const void *)sptr + elm->memb_offset); -+ memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset); - if(!memb_ptr) { - if(elm->optional) - continue; -@@ -963,7 +1138,7 @@ - return -1; - } - } else { -- memb_ptr = (const void *)((const void *)sptr + elm->memb_offset); -+ memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); - } - - if(elm->memb_constraints) { -Index: skeletons/constr_SEQUENCE_OF.c -=================================================================== ---- skeletons/constr_SEQUENCE_OF.c (revision 1516) -+++ skeletons/constr_SEQUENCE_OF.c (working copy) -@@ -164,7 +164,7 @@ - if(ct) { - int not_in_root = (list->count < ct->lower_bound - || list->count > ct->upper_bound); -- ASN_DEBUG("lb %ld ub %ld %s", -+ ASN_DEBUG("lb %"PRIdMAX" ub %"PRIdMAX" %s", - ct->lower_bound, ct->upper_bound, - ct->flags & APC_EXTENSIBLE ? "ext" : "fix"); - if(ct->flags & APC_EXTENSIBLE) { -@@ -206,3 +206,70 @@ - _ASN_ENCODED_OK(er); - } - -+asn_enc_rval_t -+SEQUENCE_OF_encode_aper(asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -+ asn_anonymous_sequence_ *list; -+ asn_per_constraint_t *ct; -+ asn_enc_rval_t er; -+ asn_TYPE_member_t *elm = td->elements; -+ int seq; -+ -+ if(!sptr) _ASN_ENCODE_FAILED; -+ list = _A_SEQUENCE_FROM_VOID(sptr); -+ -+ er.encoded = 0; -+ -+ ASN_DEBUG("Encoding %s as SEQUENCE OF size (%d) using ALIGNED PER", td->name, list->count); -+ -+ if(constraints) ct = &constraints->size; -+ else if(td->per_constraints) ct = &td->per_constraints->size; -+ else ct = 0; -+ -+ /* If extensible constraint, check if size is in root */ -+ if(ct) { -+ int not_in_root = (list->count < ct->lower_bound -+ || list->count > ct->upper_bound); -+ ASN_DEBUG("lb %"PRIdMAX" ub %"PRIdMAX" %s", -+ ct->lower_bound, ct->upper_bound, -+ ct->flags & APC_EXTENSIBLE ? "ext" : "fix"); -+ if(ct->flags & APC_EXTENSIBLE) { -+ /* Declare whether size is in extension root */ -+ if(per_put_few_bits(po, not_in_root, 1)) -+ _ASN_ENCODE_FAILED; -+ if(not_in_root) ct = 0; -+ } else if(not_in_root && ct->effective_bits >= 0) -+ _ASN_ENCODE_FAILED; -+ } -+ -+ if(ct && ct->effective_bits >= 0) { -+ /* X.691, #19.5: No length determinant */ -+// if(per_put_few_bits(po, list->count - ct->lower_bound, -+// ct->effective_bits)) -+// _ASN_ENCODE_FAILED; -+ if (aper_put_length(po, ct->upper_bound - ct->lower_bound + 1, list->count - ct->lower_bound) < 0) -+ _ASN_ENCODE_FAILED; -+ } -+ -+ for(seq = -1; seq < list->count;) { -+ ssize_t mayEncode; -+ if(seq < 0) seq = 0; -+ if(ct && ct->effective_bits >= 0) { -+ mayEncode = list->count; -+ } else { -+ mayEncode = aper_put_length(po, -1, list->count - seq); -+ if(mayEncode < 0) _ASN_ENCODE_FAILED; -+ } -+ -+ while(mayEncode--) { -+ void *memb_ptr = list->array[seq++]; -+ if(!memb_ptr) _ASN_ENCODE_FAILED; -+ er = elm->type->aper_encoder(elm->type, -+ elm->per_constraints, memb_ptr, po); -+ if(er.encoded == -1) -+ _ASN_ENCODE_FAILED; -+ } -+ } -+ -+ _ASN_ENCODED_OK(er); -+} -Index: skeletons/per_support.h -=================================================================== ---- skeletons/per_support.h (revision 1516) -+++ skeletons/per_support.h (working copy) -@@ -24,8 +24,8 @@ - } flags; - int range_bits; /* Full number of bits in the range */ - int effective_bits; /* Effective bits */ -- long lower_bound; /* "lb" value */ -- long upper_bound; /* "ub" value */ -+ int64_t lower_bound; /* "lb" value */ -+ int64_t upper_bound; /* "ub" value */ - } asn_per_constraint_t; - typedef struct asn_per_constraints_s { - asn_per_constraint_t value; -@@ -39,9 +39,9 @@ - */ - typedef struct asn_per_data_s { - const uint8_t *buffer; /* Pointer to the octet stream */ -- size_t nboff; /* Bit offset to the meaningful bit */ -- size_t nbits; /* Number of bits in the stream */ -- size_t moved; /* Number of bits moved through this bit stream */ -+ size_t nboff; /* Bit offset to the meaningful bit */ -+ size_t nbits; /* Number of bits in the stream */ -+ size_t moved; /* Number of bits moved through this bit stream */ - int (*refill)(struct asn_per_data_s *); - void *refill_key; - } asn_per_data_t; -@@ -71,15 +71,22 @@ - int effective_bound_bits, - int *repeat); - -+ssize_t aper_get_length(asn_per_data_t *pd, -+ int range, -+ int effective_bound_bits, -+ int *repeat); -+ - /* - * Get the normally small length "n". - */ - ssize_t uper_get_nslength(asn_per_data_t *pd); -+ssize_t aper_get_nslength(asn_per_data_t *pd); - - /* - * Get the normally small non-negative whole number. - */ - ssize_t uper_get_nsnnwn(asn_per_data_t *pd); -+ssize_t aper_get_nsnnwn(asn_per_data_t *pd, int range); - - /* Non-thread-safe debugging function, don't use it */ - char *per_data_string(asn_per_data_t *pd); -@@ -103,6 +110,10 @@ - /* Output a large number of bits */ - int per_put_many_bits(asn_per_outp_t *po, const uint8_t *src, int put_nbits); - -+/* Align the current bit position to octet bundary */ -+int aper_put_align(asn_per_outp_t *po); -+int32_t aper_get_align(asn_per_data_t *pd); -+ - /* - * Put the length "n" to the Unaligned PER stream. - * This function returns the number of units which may be flushed -@@ -110,17 +121,23 @@ - */ - ssize_t uper_put_length(asn_per_outp_t *po, size_t whole_length); - -+ssize_t aper_put_length(asn_per_outp_t *po, int range, size_t length); -+ - /* - * Put the normally small length "n" to the Unaligned PER stream. - * Returns 0 or -1. - */ - int uper_put_nslength(asn_per_outp_t *po, size_t length); - -+int aper_put_nslength(asn_per_outp_t *po, size_t length); -+ - /* - * Put the normally small non-negative whole number. - */ - int uper_put_nsnnwn(asn_per_outp_t *po, int n); - -+int aper_put_nsnnwn(asn_per_outp_t *po, int range, int number); -+ - #ifdef __cplusplus - } - #endif -Index: skeletons/constr_SET.h -=================================================================== ---- skeletons/constr_SET.h (revision 1516) -+++ skeletons/constr_SET.h (working copy) -@@ -53,7 +53,9 @@ - xer_type_decoder_f SET_decode_xer; - xer_type_encoder_f SET_encode_xer; - per_type_decoder_f SET_decode_uper; -+per_type_decoder_f SET_decode_aper; - per_type_encoder_f SET_encode_uper; -+per_type_encoder_f SET_encode_aper; - - /*********************** - * Some handy helpers. * -Index: skeletons/constr_SEQUENCE_OF.h -=================================================================== ---- skeletons/constr_SEQUENCE_OF.h (revision 1516) -+++ skeletons/constr_SEQUENCE_OF.h (working copy) -@@ -22,9 +22,11 @@ - #define SEQUENCE_OF_decode_ber SET_OF_decode_ber - #define SEQUENCE_OF_decode_xer SET_OF_decode_xer - #define SEQUENCE_OF_decode_uper SET_OF_decode_uper -+#define SEQUENCE_OF_decode_aper SET_OF_decode_aper - der_type_encoder_f SEQUENCE_OF_encode_der; - xer_type_encoder_f SEQUENCE_OF_encode_xer; - per_type_encoder_f SEQUENCE_OF_encode_uper; -+per_type_encoder_f SEQUENCE_OF_encode_aper; - - #ifdef __cplusplus - } -Index: skeletons/ENUMERATED.c -=================================================================== ---- skeletons/ENUMERATED.c (revision 1516) -+++ skeletons/ENUMERATED.c (working copy) -@@ -26,6 +26,8 @@ - INTEGER_encode_xer, - ENUMERATED_decode_uper, /* Unaligned PER decoder */ - ENUMERATED_encode_uper, /* Unaligned PER encoder */ -+ ENUMERATED_decode_aper, /* Aligned PER decoder */ -+ ENUMERATED_encode_aper, /* Aligned PER encoder */ - 0, /* Use generic outmost tag fetcher */ - asn_DEF_ENUMERATED_tags, - sizeof(asn_DEF_ENUMERATED_tags) / sizeof(asn_DEF_ENUMERATED_tags[0]), -@@ -57,6 +59,27 @@ - return rval; - } - -+asn_dec_rval_t -+ENUMERATED_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { -+ asn_dec_rval_t rval; -+ ENUMERATED_t *st = (ENUMERATED_t *)*sptr; -+ long value; -+ void *vptr = &value; -+ -+ if(!st) { -+ st = (ENUMERATED_t *)(*sptr = CALLOC(1, sizeof(*st))); -+ if(!st) _ASN_DECODE_FAILED; -+ } -+ -+ rval = NativeEnumerated_decode_aper(opt_codec_ctx, td, constraints, -+ (void **)&vptr, pd); -+ if(rval.code == RC_OK) -+ if(asn_long2INTEGER(st, value)) -+ rval.code = RC_FAIL; -+ return rval; -+} -+ - asn_enc_rval_t - ENUMERATED_encode_uper(asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -@@ -69,3 +92,14 @@ - return NativeEnumerated_encode_uper(td, constraints, &value, po); - } - -+asn_enc_rval_t -+ENUMERATED_encode_aper(asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -+ ENUMERATED_t *st = (ENUMERATED_t *)sptr; -+ long value; -+ -+ if(asn_INTEGER2long(st, &value)) -+ _ASN_ENCODE_FAILED; -+ -+ return NativeEnumerated_encode_aper(td, constraints, &value, po); -+} -Index: skeletons/ENUMERATED.h -=================================================================== ---- skeletons/ENUMERATED.h (revision 1516) -+++ skeletons/ENUMERATED.h (working copy) -@@ -17,6 +17,8 @@ - - per_type_decoder_f ENUMERATED_decode_uper; - per_type_encoder_f ENUMERATED_encode_uper; -+per_type_decoder_f ENUMERATED_decode_aper; -+per_type_encoder_f ENUMERATED_encode_aper; - - #ifdef __cplusplus - } -Index: skeletons/NativeEnumerated.c -=================================================================== ---- skeletons/NativeEnumerated.c (revision 1516) -+++ skeletons/NativeEnumerated.c (working copy) -@@ -30,6 +30,8 @@ - NativeEnumerated_encode_xer, - NativeEnumerated_decode_uper, - NativeEnumerated_encode_uper, -+ NativeEnumerated_decode_aper, -+ NativeEnumerated_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_NativeEnumerated_tags, - sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]), -@@ -42,17 +44,17 @@ - - asn_enc_rval_t - NativeEnumerated_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, -- int ilevel, enum xer_encoder_flags_e flags, -- asn_app_consume_bytes_f *cb, void *app_key) { -+ int ilevel, enum xer_encoder_flags_e flags, -+ asn_app_consume_bytes_f *cb, void *app_key) { - asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics; -- asn_enc_rval_t er; -- const long *native = (const long *)sptr; -+ asn_enc_rval_t er; -+ const long *native = (const long *)sptr; - const asn_INTEGER_enum_map_t *el; - -- (void)ilevel; -- (void)flags; -+ (void)ilevel; -+ (void)flags; - -- if(!native) _ASN_ENCODE_FAILED; -+ if(!native) _ASN_ENCODE_FAILED; - - el = INTEGER_map_value2enum(specs, *native); - if(el) { -@@ -125,6 +127,66 @@ - return rval; - } - -+asn_dec_rval_t -+NativeEnumerated_decode_aper(asn_codec_ctx_t *opt_codec_ctx, -+ asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, -+ void **sptr, asn_per_data_t *pd) { -+ asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics; -+ asn_dec_rval_t rval = { RC_OK, 0 }; -+ long *native = (long *)*sptr; -+ asn_per_constraint_t *ct; -+ long value; -+ int freeme = 0; -+ -+ (void)opt_codec_ctx; -+ -+ if(constraints) ct = &constraints->value; -+ else if(td->per_constraints) ct = &td->per_constraints->value; -+ else _ASN_DECODE_FAILED; /* Mandatory! */ -+ if(!specs) _ASN_DECODE_FAILED; -+ -+ if(!native) { -+ native = (long *)(*sptr = CALLOC(1, sizeof(*native))); -+ freeme = 1; -+ if(!native) _ASN_DECODE_FAILED; -+ } -+ -+ ASN_DEBUG("Decoding %s as NativeEnumerated", td->name); -+ -+ if(ct->flags & APC_EXTENSIBLE) { -+ int inext = per_get_few_bits(pd, 1); -+ if(inext < 0) _ASN_DECODE_STARVED; -+ if(inext) ct = 0; -+ } -+ -+ if(ct && ct->range_bits >= 0) { -+ value = per_get_few_bits(pd, ct->range_bits); -+ if(value < 0) _ASN_DECODE_STARVED; -+ if(value >= (specs->extension -+ ? specs->extension - 1 : specs->map_count)) -+ _ASN_DECODE_FAILED; -+ } else { -+ if(!specs->extension) -+ _ASN_DECODE_FAILED; -+ /* -+ * X.691, #10.6: normally small non-negative whole number; -+ */ -+ value = uper_get_nsnnwn(pd); -+ if(value < 0) _ASN_DECODE_STARVED; -+ value += specs->extension - 1; -+ if(value >= specs->map_count) -+ _ASN_DECODE_FAILED; -+ } -+ -+ *native = specs->value2enum[value].nat_value; -+ ASN_DEBUG("Decoded %s = %ld", td->name, *native); -+ -+ if (freeme) -+ free(native); -+ -+ return rval; -+} -+ - static int - NativeEnumerated__compar_value2enum(const void *ap, const void *bp) { - const asn_INTEGER_enum_map_t *a = ap; -@@ -205,3 +267,71 @@ - _ASN_ENCODED_OK(er); - } - -+asn_enc_rval_t -+NativeEnumerated_encode_aper(asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -+ asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics; -+ asn_enc_rval_t er; -+ long native, value; -+ asn_per_constraint_t *ct; -+ int inext = 0; -+ asn_INTEGER_enum_map_t key; -+ asn_INTEGER_enum_map_t *kf; -+ -+ if(!sptr) _ASN_ENCODE_FAILED; -+ if(!specs) _ASN_ENCODE_FAILED; -+ -+ if(constraints) ct = &constraints->value; -+ else if(td->per_constraints) ct = &td->per_constraints->value; -+ else _ASN_ENCODE_FAILED; /* Mandatory! */ -+ -+ ASN_DEBUG("Encoding %s as NativeEnumerated", td->name); -+ -+ er.encoded = 0; -+ -+ native = *(long *)sptr; -+ if(native < 0) _ASN_ENCODE_FAILED; -+ -+ key.nat_value = native; -+ kf = bsearch(&key, specs->value2enum, specs->map_count, -+ sizeof(key), NativeEnumerated__compar_value2enum); -+ if(!kf) { -+ ASN_DEBUG("No element corresponds to %ld", native); -+ _ASN_ENCODE_FAILED; -+ } -+ value = kf - specs->value2enum; -+ -+ if(ct->range_bits >= 0) { -+ int cmpWith = specs->extension -+ ? specs->extension - 1 : specs->map_count; -+ if(value >= cmpWith) -+ inext = 1; -+ } -+ if(ct->flags & APC_EXTENSIBLE) { -+ if(per_put_few_bits(po, inext, 1)) -+ _ASN_ENCODE_FAILED; -+ if(inext) ct = 0; -+ } else if(inext) { -+ _ASN_ENCODE_FAILED; -+ } -+ -+ if(ct && ct->range_bits >= 0) { -+ if(per_put_few_bits(po, value, ct->range_bits)) -+ _ASN_ENCODE_FAILED; -+ _ASN_ENCODED_OK(er); -+ } -+ -+ if(!specs->extension) -+ _ASN_ENCODE_FAILED; -+ -+ /* -+ * X.691, #10.6: normally small non-negative whole number; -+ */ -+ ASN_DEBUG("value = %ld, ext = %d, inext = %d, res = %ld", -+ value, specs->extension, inext, -+ value - (inext ? (specs->extension - 1) : 0)); -+ if(uper_put_nsnnwn(po, value - (inext ? (specs->extension - 1) : 0))) -+ _ASN_ENCODE_FAILED; -+ -+ _ASN_ENCODED_OK(er); -+} -Index: skeletons/GeneralString.c -=================================================================== ---- skeletons/GeneralString.c (revision 1516) -+++ skeletons/GeneralString.c (working copy) -@@ -24,6 +24,8 @@ - OCTET_STRING_encode_xer, - OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_GeneralString_tags, - sizeof(asn_DEF_GeneralString_tags) -Index: skeletons/IA5String.c -=================================================================== ---- skeletons/IA5String.c (revision 1516) -+++ skeletons/IA5String.c (working copy) -@@ -29,6 +29,8 @@ - OCTET_STRING_encode_xer_utf8, - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_IA5String_tags, - sizeof(asn_DEF_IA5String_tags) -Index: skeletons/NativeEnumerated.h -=================================================================== ---- skeletons/NativeEnumerated.h (revision 1516) -+++ skeletons/NativeEnumerated.h (working copy) -@@ -24,6 +24,8 @@ - xer_type_encoder_f NativeEnumerated_encode_xer; - per_type_decoder_f NativeEnumerated_decode_uper; - per_type_encoder_f NativeEnumerated_encode_uper; -+per_type_decoder_f NativeEnumerated_decode_aper; -+per_type_encoder_f NativeEnumerated_encode_aper; - - #ifdef __cplusplus - } -Index: skeletons/OBJECT_IDENTIFIER.c -=================================================================== ---- skeletons/OBJECT_IDENTIFIER.c (revision 1516) -+++ skeletons/OBJECT_IDENTIFIER.c (working copy) -@@ -27,6 +27,8 @@ - OBJECT_IDENTIFIER_encode_xer, - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_OBJECT_IDENTIFIER_tags, - sizeof(asn_DEF_OBJECT_IDENTIFIER_tags) -Index: skeletons/per_opentype.c -=================================================================== ---- skeletons/per_opentype.c (revision 1516) -+++ skeletons/per_opentype.c (working copy) -@@ -53,6 +53,35 @@ - return 0; - } - -+int -+aper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -+ void *buf; -+ void *bptr; -+ ssize_t size; -+ size_t toGo; -+ -+ ASN_DEBUG("Open type put %s ...", td->name); -+ -+ size = aper_encode_to_new_buffer(td, constraints, sptr, &buf); -+ if(size <= 0) return -1; -+ -+ for(bptr = buf, toGo = size; toGo;) { -+ ssize_t maySave = aper_put_length(po, -1, toGo); -+ if(maySave < 0) break; -+ if(per_put_many_bits(po, bptr, maySave * 8)) break; -+ bptr = (char *)bptr + maySave; -+ toGo -= maySave; -+ } -+ -+ FREEMEM(buf); -+ if(toGo) return -1; -+ -+ ASN_DEBUG("Open type put %s of length %ld + overhead (1byte?)", -+ td->name, (long)size); -+ -+ return 0; -+} -+ - static asn_dec_rval_t - uper_open_type_get_simple(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { -Index: skeletons/VideotexString.c -=================================================================== ---- skeletons/VideotexString.c (revision 1516) -+++ skeletons/VideotexString.c (working copy) -@@ -24,6 +24,8 @@ - OCTET_STRING_encode_xer, - OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_VideotexString_tags, - sizeof(asn_DEF_VideotexString_tags) -Index: skeletons/per_opentype.h -=================================================================== ---- skeletons/per_opentype.h (revision 1516) -+++ skeletons/per_opentype.h (working copy) -@@ -15,6 +15,8 @@ - - int uper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po); - -+int aper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po); -+ - #ifdef __cplusplus - } - #endif -Index: skeletons/BOOLEAN.c -=================================================================== ---- skeletons/BOOLEAN.c (revision 1516) -+++ skeletons/BOOLEAN.c (working copy) -@@ -24,6 +24,8 @@ - BOOLEAN_encode_xer, - BOOLEAN_decode_uper, /* Unaligned PER decoder */ - BOOLEAN_encode_uper, /* Unaligned PER encoder */ -+ BOOLEAN_decode_aper, /* Aligned PER decoder */ -+ BOOLEAN_encode_aper, /* Aligned PER encoder */ - 0, /* Use generic outmost tag fetcher */ - asn_DEF_BOOLEAN_tags, - sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]), -@@ -264,7 +266,36 @@ - return rv; - } - -+asn_dec_rval_t -+BOOLEAN_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { -+ asn_dec_rval_t rv; -+ BOOLEAN_t *st = (BOOLEAN_t *)*sptr; - -+ (void)opt_codec_ctx; -+ (void)constraints; -+ -+ if(!st) { -+ st = (BOOLEAN_t *)(*sptr = MALLOC(sizeof(*st))); -+ if(!st) _ASN_DECODE_FAILED; -+ } -+ -+ /* -+ * Extract a single bit -+ */ -+ switch(per_get_few_bits(pd, 1)) { -+ case 1: *st = 1; break; -+ case 0: *st = 0; break; -+ case -1: default: _ASN_DECODE_STARVED; -+ } -+ -+ ASN_DEBUG("%s decoded as %s", td->name, *st ? "TRUE" : "FALSE"); -+ -+ rv.code = RC_OK; -+ rv.consumed = 1; -+ return rv; -+} -+ - asn_enc_rval_t - BOOLEAN_encode_uper(asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -@@ -280,3 +311,18 @@ - - _ASN_ENCODED_OK(er); - } -+ -+asn_enc_rval_t -+BOOLEAN_encode_aper(asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -+ const BOOLEAN_t *st = (const BOOLEAN_t *)sptr; -+ asn_enc_rval_t er; -+ -+ (void)constraints; -+ -+ if(!st) _ASN_ENCODE_FAILED; -+ -+ per_put_few_bits(po, *st ? 1 : 0, 1); -+ -+ _ASN_ENCODED_OK(er); -+} -Index: skeletons/ISO646String.c -=================================================================== ---- skeletons/ISO646String.c (revision 1516) -+++ skeletons/ISO646String.c (working copy) -@@ -29,6 +29,8 @@ - OCTET_STRING_encode_xer_utf8, - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_ISO646String_tags, - sizeof(asn_DEF_ISO646String_tags) -Index: skeletons/constr_CHOICE.c -=================================================================== ---- skeletons/constr_CHOICE.c (revision 1516) -+++ skeletons/constr_CHOICE.c (working copy) -@@ -34,7 +34,7 @@ - #undef ADVANCE - #define ADVANCE(num_bytes) do { \ - size_t num = num_bytes; \ -- ptr = ((const void *)ptr) + num;\ -+ ptr = ((const char *)ptr) + num;\ - size -= num; \ - if(ctx->left >= 0) \ - ctx->left -= num; \ -@@ -133,7 +133,7 @@ - /* - * Restore parsing context. - */ -- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset); -+ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset); - - /* - * Start to parse where left previously -@@ -211,7 +211,7 @@ - - skip = ber_skip_length(opt_codec_ctx, - BER_TLV_CONSTRUCTED(ptr), -- (const void *)ptr + tag_len, -+ (const char *)ptr + tag_len, - LEFT - tag_len); - - switch(skip) { -@@ -244,7 +244,7 @@ - */ - if(elm->flags & ATF_POINTER) { - /* Member is a pointer to another structure */ -- memb_ptr2 = (void **)((void *)st + elm->memb_offset); -+ memb_ptr2 = (void **)((char *)st + elm->memb_offset); - } else { - /* - * A pointer to a pointer -@@ -390,7 +390,7 @@ - */ - elm = &td->elements[present-1]; - if(elm->flags & ATF_POINTER) { -- memb_ptr = *(void **)((void *)sptr + elm->memb_offset); -+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset); - if(memb_ptr == 0) { - if(elm->optional) { - erval.encoded = 0; -@@ -400,7 +400,7 @@ - _ASN_ENCODE_FAILED; - } - } else { -- memb_ptr = (void *)((void *)sptr + elm->memb_offset); -+ memb_ptr = (void *)((char *)sptr + elm->memb_offset); - } - - /* -@@ -463,10 +463,10 @@ - - if(elm->flags & ATF_POINTER) { - memb_ptr = *(const void * const *) -- ((const void *)ptr + elm->memb_offset); -+ ((const char *)ptr + elm->memb_offset); - } else { - memb_ptr = (const void *) -- ((const void *)ptr + elm->memb_offset); -+ ((const char *)ptr + elm->memb_offset); - } - - return asn_TYPE_outmost_tag(elm->type, memb_ptr, -@@ -498,7 +498,7 @@ - const void *memb_ptr; - - if(elm->flags & ATF_POINTER) { -- memb_ptr = *(const void * const *)((const void *)sptr + elm->memb_offset); -+ memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset); - if(!memb_ptr) { - if(elm->optional) - return 0; -@@ -508,7 +508,7 @@ - return -1; - } - } else { -- memb_ptr = (const void *)((const void *)sptr + elm->memb_offset); -+ memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); - } - - if(elm->memb_constraints) { -@@ -535,7 +535,7 @@ - #undef XER_ADVANCE - #define XER_ADVANCE(num_bytes) do { \ - size_t num = num_bytes; \ -- buf_ptr = ((const void *)buf_ptr) + num;\ -+ buf_ptr = ((const char *)buf_ptr) + num;\ - size -= num; \ - consumed_myself += num; \ - } while(0) -@@ -574,7 +574,7 @@ - /* - * Restore parsing context. - */ -- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset); -+ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset); - if(ctx->phase == 0 && !*xml_tag) - ctx->phase = 1; /* Skip the outer tag checking phase */ - -@@ -605,7 +605,7 @@ - - if(elm->flags & ATF_POINTER) { - /* Member is a pointer to another structure */ -- memb_ptr2 = (void **)((void *)st -+ memb_ptr2 = (void **)((char *)st - + elm->memb_offset); - } else { - memb_ptr = (char *)st + elm->memb_offset; -@@ -797,10 +797,10 @@ - unsigned int mlen = strlen(mname); - - if(elm->flags & ATF_POINTER) { -- memb_ptr = *(void **)((void *)sptr + elm->memb_offset); -+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset); - if(!memb_ptr) _ASN_ENCODE_FAILED; - } else { -- memb_ptr = (void *)((void *)sptr + elm->memb_offset); -+ memb_ptr = (void *)((char *)sptr + elm->memb_offset); - } - - er.encoded = 0; -@@ -884,7 +884,7 @@ - elm = &td->elements[value]; - if(elm->flags & ATF_POINTER) { - /* Member is a pointer to another structure */ -- memb_ptr2 = (void **)((void *)st + elm->memb_offset); -+ memb_ptr2 = (void **)((char *)st + elm->memb_offset); - } else { - memb_ptr = (char *)st + elm->memb_offset; - memb_ptr2 = &memb_ptr; -@@ -904,7 +904,88 @@ - elm->name, td->name, rv.code); - return rv; - } -- -+ -+asn_dec_rval_t -+CHOICE_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { -+ asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics; -+ asn_dec_rval_t rv; -+ asn_per_constraint_t *ct; -+ asn_TYPE_member_t *elm; /* CHOICE's element */ -+ void *memb_ptr; -+ void **memb_ptr2; -+ void *st = *sptr; -+ int value; -+ -+ if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx)) -+ _ASN_DECODE_FAILED; -+ -+ /* -+ * Create the target structure if it is not present already. -+ */ -+ if(!st) { -+ st = *sptr = CALLOC(1, specs->struct_size); -+ if(!st) _ASN_DECODE_FAILED; -+ } -+ -+ if(constraints) ct = &constraints->value; -+ else if(td->per_constraints) ct = &td->per_constraints->value; -+ else ct = 0; -+ -+ if(ct && ct->flags & APC_EXTENSIBLE) { -+ value = per_get_few_bits(pd, 1); -+ if(value < 0) _ASN_DECODE_STARVED; -+ if(value) ct = 0; /* Not restricted */ -+ } -+ -+ if(ct && ct->range_bits >= 0) { -+ value = per_get_few_bits(pd, ct->range_bits); -+ if(value < 0) _ASN_DECODE_STARVED; -+ ASN_DEBUG("CHOICE %s got index %d in range %d", -+ td->name, value, ct->range_bits); -+ if(value > ct->upper_bound) -+ _ASN_DECODE_FAILED; -+ } else { -+ if(specs->ext_start == -1) -+ _ASN_DECODE_FAILED; -+ value = uper_get_nsnnwn(pd); -+ if(value < 0) _ASN_DECODE_STARVED; -+ value += specs->ext_start; -+ if(value >= td->elements_count) -+ _ASN_DECODE_FAILED; -+ } -+ -+ /* Adjust if canonical order is different from natural order */ -+ if(specs->canonical_order) -+ value = specs->canonical_order[value]; -+ -+ /* Set presence to be able to free it later */ -+ _set_present_idx(st, specs->pres_offset, specs->pres_size, value + 1); -+ -+ elm = &td->elements[value]; -+ if(elm->flags & ATF_POINTER) { -+ /* Member is a pointer to another structure */ -+ memb_ptr2 = (void **)((char *)st + elm->memb_offset); -+ } else { -+ memb_ptr = (char *)st + elm->memb_offset; -+ memb_ptr2 = &memb_ptr; -+ } -+ ASN_DEBUG("Discovered CHOICE %s encodes %s", td->name, elm->name); -+ -+ if(ct && ct->range_bits >= 0) { -+ rv = elm->type->aper_decoder(opt_codec_ctx, elm->type, -+ elm->per_constraints, memb_ptr2, pd); -+ } else { -+ rv = uper_open_type_get(opt_codec_ctx, elm->type, -+ elm->per_constraints, memb_ptr2, pd); -+ } -+ -+ if(rv.code != RC_OK) -+ ASN_DEBUG("Failed to decode %s in %s (CHOICE) %d", -+ elm->name, td->name, rv.code); -+ return rv; -+} -+ - asn_enc_rval_t - CHOICE_encode_uper(asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -@@ -917,7 +998,7 @@ - - if(!sptr) _ASN_ENCODE_FAILED; - -- ASN_DEBUG("Encoding %s as CHOICE", td->name); -+ ASN_DEBUG("Encoding %s as CHOICE using UPER", td->name); - - if(constraints) ct = &constraints->value; - else if(td->per_constraints) ct = &td->per_constraints->value; -@@ -962,7 +1043,7 @@ - elm = &td->elements[present]; - if(elm->flags & ATF_POINTER) { - /* Member is a pointer to another structure */ -- memb_ptr = *(void **)((void *)sptr + elm->memb_offset); -+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset); - if(!memb_ptr) _ASN_ENCODE_FAILED; - } else { - memb_ptr = (char *)sptr + elm->memb_offset; -@@ -987,8 +1068,88 @@ - _ASN_ENCODED_OK(rval); - } - } -- - -+asn_enc_rval_t -+CHOICE_encode_aper(asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -+ asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics; -+ asn_TYPE_member_t *elm; /* CHOICE's element */ -+ asn_per_constraint_t *ct; -+ void *memb_ptr; -+ int present; -+ -+ if(!sptr) _ASN_ENCODE_FAILED; -+ -+ ASN_DEBUG("Encoding %s as CHOICE using ALIGNED PER", td->name); -+ -+ if(constraints) ct = &constraints->value; -+ else if(td->per_constraints) ct = &td->per_constraints->value; -+ else ct = 0; -+ -+ present = _fetch_present_idx(sptr, -+ specs->pres_offset, specs->pres_size); -+ -+ /* -+ * If the structure was not initialized properly, it cannot be encoded: -+ * can't deduce what to encode in the choice type. -+ */ -+ if(present <= 0 || present > td->elements_count) -+ _ASN_ENCODE_FAILED; -+ else -+ present--; -+ -+ /* Adjust if canonical order is different from natural order */ -+ if(specs->canonical_order) -+ present = specs->canonical_order[present]; -+ -+ ASN_DEBUG("Encoding %s CHOICE element %d", td->name, present); -+ -+ if(ct && ct->range_bits >= 0) { -+ if(present < ct->lower_bound -+ || present > ct->upper_bound) { -+ if(ct->flags & APC_EXTENSIBLE) { -+ if(per_put_few_bits(po, 1, 1)) -+ _ASN_ENCODE_FAILED; -+ } else { -+ _ASN_ENCODE_FAILED; -+ } -+ ct = 0; -+ } -+ } -+ if(ct && ct->flags & APC_EXTENSIBLE) { -+ if(per_put_few_bits(po, 0, 1)) -+ _ASN_ENCODE_FAILED; -+ } -+ -+ elm = &td->elements[present]; -+ if(elm->flags & ATF_POINTER) { -+ /* Member is a pointer to another structure */ -+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset); -+ if(!memb_ptr) _ASN_ENCODE_FAILED; -+ } else { -+ memb_ptr = (char *)sptr + elm->memb_offset; -+ } -+ -+ if(ct && ct->range_bits >= 0) { -+ if(per_put_few_bits(po, present, ct->range_bits)) -+ _ASN_ENCODE_FAILED; -+ -+ return elm->type->aper_encoder(elm->type, elm->per_constraints, -+ memb_ptr, po); -+ } else { -+ asn_enc_rval_t rval; -+ if(specs->ext_start == -1) -+ _ASN_ENCODE_FAILED; -+ if(aper_put_nsnnwn(po, ct->range_bits, present - specs->ext_start)) -+ _ASN_ENCODE_FAILED; -+ if(aper_open_type_put(elm->type, elm->per_constraints, -+ memb_ptr, po)) -+ _ASN_ENCODE_FAILED; -+ rval.encoded = 0; -+ _ASN_ENCODED_OK(rval); -+ } -+} -+ - int - CHOICE_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, - asn_app_consume_bytes_f *cb, void *app_key) { -@@ -1010,10 +1171,10 @@ - const void *memb_ptr; - - if(elm->flags & ATF_POINTER) { -- memb_ptr = *(const void * const *)((const void *)sptr + elm->memb_offset); -+ memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset); - if(!memb_ptr) return (cb("<absent>", 8, app_key) < 0) ? -1 : 0; - } else { -- memb_ptr = (const void *)((const void *)sptr + elm->memb_offset); -+ memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); - } - - /* Print member's name and stuff */ -@@ -1053,11 +1214,11 @@ - void *memb_ptr; - - if(elm->flags & ATF_POINTER) { -- memb_ptr = *(void **)((void *)ptr + elm->memb_offset); -+ memb_ptr = *(void **)((char *)ptr + elm->memb_offset); - if(memb_ptr) - ASN_STRUCT_FREE(*elm->type, memb_ptr); - } else { -- memb_ptr = (void *)((void *)ptr + elm->memb_offset); -+ memb_ptr = (void *)((char *)ptr + elm->memb_offset); - ASN_STRUCT_FREE_CONTENTS_ONLY(*elm->type, memb_ptr); - } - } -@@ -1082,7 +1243,7 @@ - const void *present_ptr; - int present; - -- present_ptr = ((const void *)struct_ptr) + pres_offset; -+ present_ptr = ((const char *)struct_ptr) + pres_offset; - - switch(pres_size) { - case sizeof(int): present = *(const int *)present_ptr; break; -@@ -1100,7 +1261,7 @@ - static void - _set_present_idx(void *struct_ptr, int pres_offset, int pres_size, int present) { - void *present_ptr; -- present_ptr = ((void *)struct_ptr) + pres_offset; -+ present_ptr = ((char *)struct_ptr) + pres_offset; - - switch(pres_size) { - case sizeof(int): *(int *)present_ptr = present; break; -Index: skeletons/asn_internal.h -=================================================================== ---- skeletons/asn_internal.h (revision 1516) -+++ skeletons/asn_internal.h (working copy) -@@ -20,7 +20,7 @@ - #endif - - /* Environment version might be used to avoid running with the old library */ --#define ASN1C_ENVIRONMENT_VERSION 923 /* Compile-time version */ -+#define ASN1C_ENVIRONMENT_VERSION 924 /* Compile-time version */ - int get_asn1c_environment_version(void); /* Run-time version */ - - #define CALLOC(nmemb, size) calloc(nmemb, size) -@@ -48,18 +48,22 @@ - #define ASN_DEBUG_INDENT_ADD(i) do { asn_debug_indent += i; } while(0) - #endif /* ASN_THREAD_SAFE */ - #define ASN_DEBUG(fmt, args...) do { \ -- int adi = asn_debug_indent; \ -- while(adi--) fprintf(stderr, " "); \ -- fprintf(stderr, fmt, ##args); \ -- fprintf(stderr, " (%s:%d)\n", \ -- __FILE__, __LINE__); \ -- } while(0) -+ int adi = asn_debug_indent; \ -+ while(adi--) fprintf(stderr, " "); \ -+ fprintf(stderr, fmt, ##args); \ -+ fprintf(stderr, " (%s:%d)\n", \ -+ __FILE__, __LINE__); \ -+} while(0) - #else /* !__GNUC__ */ - void ASN_DEBUG_f(const char *fmt, ...); - #define ASN_DEBUG ASN_DEBUG_f - #endif /* __GNUC__ */ - #else /* EMIT_ASN_DEBUG != 1 */ -+# ifdef EMIT_ASN_DEBUG_EXTERN -+extern inline void ASN_DEBUG(const char *fmt, ...); -+# else - static inline void ASN_DEBUG(const char *fmt, ...) { (void)fmt; } -+# endif - #endif /* EMIT_ASN_DEBUG */ - #endif /* ASN_DEBUG */ - -Index: skeletons/BOOLEAN.h -=================================================================== ---- skeletons/BOOLEAN.h (revision 1516) -+++ skeletons/BOOLEAN.h (working copy) -@@ -28,6 +28,8 @@ - xer_type_encoder_f BOOLEAN_encode_xer; - per_type_decoder_f BOOLEAN_decode_uper; - per_type_encoder_f BOOLEAN_encode_uper; -+per_type_decoder_f BOOLEAN_decode_aper; -+per_type_encoder_f BOOLEAN_encode_aper; - - #ifdef __cplusplus - } -Index: skeletons/constr_CHOICE.h -=================================================================== ---- skeletons/constr_CHOICE.h (revision 1516) -+++ skeletons/constr_CHOICE.h (working copy) -@@ -48,6 +48,8 @@ - xer_type_encoder_f CHOICE_encode_xer; - per_type_decoder_f CHOICE_decode_uper; - per_type_encoder_f CHOICE_encode_uper; -+per_type_decoder_f CHOICE_decode_aper; -+per_type_encoder_f CHOICE_encode_aper; - asn_outmost_tag_f CHOICE_outmost_tag; - - #ifdef __cplusplus -Index: skeletons/INTEGER.c -=================================================================== ---- skeletons/INTEGER.c (revision 1516) -+++ skeletons/INTEGER.c (working copy) -@@ -27,9 +27,13 @@ - #ifdef ASN_DISABLE_PER_SUPPORT - 0, - 0, -+ 0, -+ 0, - #else - INTEGER_decode_uper, /* Unaligned PER decoder */ - INTEGER_encode_uper, /* Unaligned PER encoder */ -+ INTEGER_decode_aper, -+ INTEGER_encode_aper, - #endif /* ASN_DISABLE_PER_SUPPORT */ - 0, /* Use generic outmost tag fetcher */ - asn_DEF_INTEGER_tags, -@@ -612,7 +616,7 @@ - value = per_get_few_bits(pd, ct->range_bits); - if(value < 0) _ASN_DECODE_STARVED; - } -- ASN_DEBUG("Got value %ld + low %ld", -+ ASN_DEBUG("Got value %ld + low %"PRIdMAX, - value, ct->lower_bound); - value += ct->lower_bound; - if((specs && specs->field_unsigned) -@@ -660,6 +664,158 @@ - return rval; - } - -+asn_dec_rval_t -+INTEGER_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { -+ asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics; -+ asn_dec_rval_t rval = { RC_OK, 0 }; -+ INTEGER_t *st = (INTEGER_t *)*sptr; -+ asn_per_constraint_t *ct; -+ int repeat; -+ -+ (void)opt_codec_ctx; -+ -+ if(!st) { -+ st = (INTEGER_t *)(*sptr = CALLOC(1, sizeof(*st))); -+ if(!st) _ASN_DECODE_FAILED; -+ } -+ -+ if(!constraints) constraints = td->per_constraints; -+ ct = constraints ? &constraints->value : 0; -+ -+ if(ct && ct->flags & APC_EXTENSIBLE) { -+ int inext = per_get_few_bits(pd, 1); -+ if(inext < 0) _ASN_DECODE_STARVED; -+ if(inext) ct = 0; -+ } -+ -+ FREEMEM(st->buf); -+ st->buf = 0; -+ st->size = 0; -+ if(ct) { -+ if(ct->flags & APC_SEMI_CONSTRAINED) { -+ st->buf = (uint8_t *)CALLOC(1, 2); -+ if(!st->buf) _ASN_DECODE_FAILED; -+ st->size = 1; -+ } else if(ct->flags & APC_CONSTRAINED && ct->range_bits >= 0) { -+ size_t size = (ct->range_bits + 7) >> 3; -+ st->buf = (uint8_t *)MALLOC(1 + size + 1); -+ if(!st->buf) _ASN_DECODE_FAILED; -+ st->size = size; -+ } -+ } -+ -+ /* X.691, #12.2.2 */ -+ if(ct && ct->flags != APC_UNCONSTRAINED) { -+ /* #10.5.6 */ -+ ASN_DEBUG("Integer with range %d bits", ct->range_bits); -+ if(ct->range_bits >= 0) { -+ if (ct->range_bits > 16) { -+ int max_range_bytes = (ct->range_bits >> 3) + -+ (((ct->range_bits % 8) > 0) ? 1 : 0); -+ int length = 0, i; -+ int64_t value = 0; -+ -+ for (i = 1; ; i++) { -+ int upper = 1 << i; -+ if (upper >= max_range_bytes) -+ break; -+ } -+ ASN_DEBUG("Can encode %d (%d bytes) in %d bits", ct->range_bits, -+ max_range_bytes, i); -+ -+ if ((length = per_get_few_bits(pd, i)) < 0) -+ _ASN_DECODE_FAILED; -+ -+ /* X.691 #12.2.6 length determinant + lb (1) */ -+ length += 1; -+ ASN_DEBUG("Got length %d", length); -+ -+ if (aper_get_align(pd) != 0) -+ _ASN_DECODE_STARVED; -+ -+ while (length--) { -+ int buf = per_get_few_bits(pd, 8); -+ if (buf < 0) -+ _ASN_DECODE_STARVED; -+ value += (((int64_t)buf) << (8 * length)); -+ } -+ -+ value += ct->lower_bound; -+ if((specs && specs->field_unsigned) -+ ? asn_uint642INTEGER(st, value) -+ : asn_int642INTEGER(st, value)) -+ _ASN_DECODE_FAILED; -+ ASN_DEBUG("Got value %lld + low %lld", -+ value, ct->lower_bound); -+ } else { -+ long value = 0; -+ if (ct->range_bits < 8) { -+ value = per_get_few_bits(pd, ct->range_bits); -+ if(value < 0) _ASN_DECODE_STARVED; -+ } else if (ct->range_bits == 8) { -+ if (aper_get_align(pd) < 0) -+ _ASN_DECODE_FAILED; -+ value = per_get_few_bits(pd, ct->range_bits); -+ if(value < 0) _ASN_DECODE_STARVED; -+ } else { -+ /* Align */ -+ if (aper_get_align(pd) < 0) -+ _ASN_DECODE_FAILED; -+ value = per_get_few_bits(pd, 16); -+ if(value < 0) _ASN_DECODE_STARVED; -+ } -+ value += ct->lower_bound; -+ if((specs && specs->field_unsigned) -+ ? asn_ulong2INTEGER(st, value) -+ : asn_long2INTEGER(st, value)) -+ _ASN_DECODE_FAILED; -+ ASN_DEBUG("Got value %ld + low %lld", -+ value, ct->lower_bound); -+ } -+ return rval; -+ } else { -+ _ASN_DECODE_FAILED; -+ } -+ } else { -+ ASN_DEBUG("Decoding unconstrained integer %s", td->name); -+ } -+ -+ /* X.691, #12.2.3, #12.2.4 */ -+ do { -+ ssize_t len; -+ void *p; -+ int ret; -+ -+ /* Get the PER length */ -+ len = aper_get_length(pd, -1, -1, &repeat); -+ if(len < 0) _ASN_DECODE_STARVED; -+ -+ p = REALLOC(st->buf, st->size + len + 1); -+ if(!p) _ASN_DECODE_FAILED; -+ st->buf = (uint8_t *)p; -+ -+ ret = per_get_many_bits(pd, &st->buf[st->size], 0, 8 * len); -+ if(ret < 0) _ASN_DECODE_STARVED; -+ st->size += len; -+ } while(repeat); -+ st->buf[st->size] = 0; /* JIC */ -+ -+ /* #12.2.3 */ -+ if(ct && ct->lower_bound) { -+ /* -+ * TODO: replace by in-place arithmetics. -+ */ -+ long value; -+ if(asn_INTEGER2long(st, &value)) -+ _ASN_DECODE_FAILED; -+ if(asn_long2INTEGER(st, value + ct->lower_bound)) -+ _ASN_DECODE_FAILED; -+ } -+ -+ return rval; -+} -+ - asn_enc_rval_t - INTEGER_encode_uper(asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -@@ -693,7 +849,7 @@ - || uval > (unsigned long)ct->upper_bound) - inext = 1; - } -- ASN_DEBUG("Value %lu (%02x/%d) lb %lu ub %lu %s", -+ ASN_DEBUG("Value %lu (%02x/%d) lb %"PRIuMAX" ub %"PRIuMAX" %s", - uval, st->buf[0], st->size, - ct->lower_bound, ct->upper_bound, - inext ? "ext" : "fix"); -@@ -710,7 +866,7 @@ - || value > ct->upper_bound) - inext = 1; - } -- ASN_DEBUG("Value %ld (%02x/%d) lb %ld ub %ld %s", -+ ASN_DEBUG("Value %ld (%02x/%d) lb %"PRIdMAX" ub %"PRIdMAX" %s", - value, st->buf[0], st->size, - ct->lower_bound, ct->upper_bound, - inext ? "ext" : "fix"); -@@ -745,7 +901,7 @@ - } - - if(ct && ct->lower_bound) { -- ASN_DEBUG("Adjust lower bound to %ld", ct->lower_bound); -+ ASN_DEBUG("Adjust lower bound to %"PRIdMAX"\n", ct->lower_bound); - /* TODO: adjust lower bound */ - _ASN_ENCODE_FAILED; - } -@@ -762,6 +918,153 @@ - _ASN_ENCODED_OK(er); - } - -+asn_enc_rval_t -+INTEGER_encode_aper(asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -+ asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics; -+ asn_enc_rval_t er; -+ INTEGER_t *st = (INTEGER_t *)sptr; -+ const uint8_t *buf; -+ const uint8_t *end; -+ asn_per_constraint_t *ct; -+ int64_t value = 0; -+ -+ if(!st || st->size == 0) _ASN_ENCODE_FAILED; -+ -+ if(!constraints) constraints = td->per_constraints; -+ ct = constraints ? &constraints->value : 0; -+ -+ er.encoded = 0; -+ -+ if(ct) { -+ int inext = 0; -+ if(specs && specs->field_unsigned) { -+ uint64_t uval; -+ if(asn_INTEGER2uint64(st, &uval)) -+ _ASN_ENCODE_FAILED; -+ /* Check proper range */ -+ if(ct->flags & APC_SEMI_CONSTRAINED) { -+ if(uval < ct->lower_bound) -+ inext = 1; -+ } else if(ct->range_bits >= 0) { -+ if(uval < ct->lower_bound -+ || uval > ct->upper_bound) -+ inext = 1; -+ } -+ ASN_DEBUG("Value %llu (%02x/%d) lb %llu ub %llu %s", -+ uval, st->buf[0], st->size, -+ ct->lower_bound, ct->upper_bound, -+ inext ? "ext" : "fix"); -+ value = uval; -+ } else { -+ if(asn_INTEGER2int64(st, &value)) _ASN_ENCODE_FAILED; -+ /* Check proper range */ -+ if(ct->flags & APC_SEMI_CONSTRAINED) { -+ if(value < ct->lower_bound) -+ inext = 1; -+ } else if(ct->range_bits >= 0) { -+ if(value < ct->lower_bound -+ || value > ct->upper_bound) -+ inext = 1; -+ } -+ ASN_DEBUG("Value %lld (%02x/%d) lb %lld ub %lld %s", -+ value, st->buf[0], st->size, -+ ct->lower_bound, ct->upper_bound, -+ inext ? "ext" : "fix"); -+ } -+ if(ct->flags & APC_EXTENSIBLE) { -+ if(per_put_few_bits(po, inext, 1)) -+ _ASN_ENCODE_FAILED; -+ if(inext) ct = 0; -+ } else if(inext) { -+ _ASN_ENCODE_FAILED; -+ } -+ } -+ -+ /* X.691, #12.2.2 */ -+ if(ct && ct->range_bits >= 0) { -+ /* #10.5.6 */ -+ ASN_DEBUG("Encoding integer with range %d bits", -+ ct->range_bits); -+ -+ value -= ct->lower_bound; -+ -+ /* #12 <= 8 -> alignment ? */ -+ if (ct->range_bits < 8) { -+ /* Bit field case -> no alignment*/ -+ if(per_put_few_bits(po, 0x00 | value, ct->range_bits)) -+ _ASN_ENCODE_FAILED; -+ } else if (ct->range_bits == 8) { -+ if(aper_put_align(po) < 0) -+ _ASN_ENCODE_FAILED; -+ if(per_put_few_bits(po, 0x00 | value, ct->range_bits)) -+ _ASN_ENCODE_FAILED; -+ } else if (ct->range_bits <= 16) { -+ // Consume the bytes to align on octet -+ if(aper_put_align(po) < 0) -+ _ASN_ENCODE_FAILED; -+ if(per_put_few_bits(po, 0x0000 | value, -+ 16)) -+ _ASN_ENCODE_FAILED; -+ } else { -+ /* TODO: extend to >64 bits */ -+ int64_t v = value; -+ int i, j; -+ int max_range_bytes = (ct->range_bits >> 3) + -+ (((ct->range_bits % 8) > 0) ? 1 : 0); -+ -+ for (i = 1; ; i++) { -+ int upper = 1 << i; -+ if (upper >= max_range_bytes) -+ break; -+ } -+ -+ for(j = sizeof(int64_t) - 1; j != 0; j--) { -+ uint8_t val; -+ val = v >> (j * 8); -+ if (val != 0) { -+ break; -+ } -+ } -+ -+ ASN_DEBUG("Putting n - lb (%"PRIdMAX") with range %d bytes (real size - lb (1)) %d in %d bits", -+ v, max_range_bytes, j, i); -+ -+ /* Putting length in the minimum number of bits ex: 5 = 3bits */ -+ if (per_put_few_bits(po, j, i)) -+ _ASN_ENCODE_FAILED; -+ -+ // Consume the bits to align on octet -+ if (aper_put_align(po) < 0) -+ _ASN_ENCODE_FAILED; -+ -+ /* Put the value */ -+ for (i = 0; i <= j; i++) { -+ if(per_put_few_bits(po, (v >> (8 * (j - i))) & 0xff, 8)) -+ _ASN_ENCODE_FAILED; -+ } -+ } -+ _ASN_ENCODED_OK(er); -+ } -+ -+ if(ct && ct->lower_bound) { -+ ASN_DEBUG("Adjust lower bound to %"PRIdMAX, ct->lower_bound); -+ /* TODO: adjust lower bound */ -+ _ASN_ENCODE_FAILED; -+ } -+ -+ for(buf = st->buf, end = st->buf + st->size; buf < end;) { -+ ssize_t mayEncode = aper_put_length(po, -1, end - buf); -+ if(mayEncode < 0) -+ _ASN_ENCODE_FAILED; -+ if(per_put_many_bits(po, buf, 8 * mayEncode)) -+ _ASN_ENCODE_FAILED; -+ buf += mayEncode; -+ } -+ -+ _ASN_ENCODED_OK(er); -+} -+ - #endif /* ASN_DISABLE_PER_SUPPORT */ - - int -@@ -825,6 +1128,66 @@ - } - - int -+asn_INTEGER2int64(const INTEGER_t *iptr, int64_t *lptr) { -+ uint8_t *b, *end; -+ size_t size; -+ int64_t l; -+ -+ /* Sanity checking */ -+ if(!iptr || !iptr->buf || !lptr) { -+ errno = EINVAL; -+ return -1; -+ } -+ -+ /* Cache the begin/end of the buffer */ -+ b = iptr->buf; /* Start of the INTEGER buffer */ -+ size = iptr->size; -+ end = b + size; /* Where to stop */ -+ -+ if(size > sizeof(int64_t)) { -+ uint8_t *end1 = end - 1; -+ /* -+ * Slightly more advanced processing, -+ * able to >sizeof(int64_t) bytes, -+ * when the actual value is small -+ * (0x0000000000abcdef would yield a fine 0x00abcdef) -+ */ -+ /* Skip out the insignificant leading bytes */ -+ for(; b < end1; b++) { -+ switch(*b) { -+ case 0x00: if((b[1] & 0x80) == 0) continue; break; -+ case 0xff: if((b[1] & 0x80) != 0) continue; break; -+ } -+ break; -+ } -+ -+ size = end - b; -+ if(size > sizeof(int64_t)) { -+ /* Still cannot fit the int64_t */ -+ errno = ERANGE; -+ return -1; -+ } -+ } -+ -+ /* Shortcut processing of a corner case */ -+ if(end == b) { -+ *lptr = 0; -+ return 0; -+ } -+ -+ /* Perform the sign initialization */ -+ /* Actually l = -(*b >> 7); gains nothing, yet unreadable! */ -+ if((*b >> 7)) l = -1; else l = 0; -+ -+ /* Conversion engine */ -+ for(; b < end; b++) -+ l = (l << 8) | *b; -+ -+ *lptr = l; -+ return 0; -+} -+ -+int - asn_INTEGER2ulong(const INTEGER_t *iptr, unsigned long *lptr) { - uint8_t *b, *end; - unsigned long l; -@@ -857,6 +1220,38 @@ - } - - int -+asn_INTEGER2uint64(const INTEGER_t *iptr, uint64_t *lptr) { -+ uint8_t *b, *end; -+ uint64_t l; -+ size_t size; -+ -+ if(!iptr || !iptr->buf || !lptr) { -+ errno = EINVAL; -+ return -1; -+ } -+ -+ b = iptr->buf; -+ size = iptr->size; -+ end = b + size; -+ -+ /* If all extra leading bytes are zeroes, ignore them */ -+ for(; size > sizeof(uint64_t); b++, size--) { -+ if(*b) { -+ /* Value won't fit unsigned long */ -+ errno = ERANGE; -+ return -1; -+ } -+ } -+ -+ /* Conversion engine */ -+ for(l = 0; b < end; b++) -+ l = (l << 8) | *b; -+ -+ *lptr = l; -+ return 0; -+} -+ -+int - asn_ulong2INTEGER(INTEGER_t *st, unsigned long value) { - uint8_t *buf; - uint8_t *end; -@@ -871,7 +1266,7 @@ - - end = buf + (sizeof(value) + 1); - buf[0] = 0; -- for(b = buf + 1, shr = (sizeof(long)-1)*8; b < end; shr -= 8, b++) -+ for(b = buf + 1, shr = (sizeof(unsigned long)-1)*8; b < end; shr -= 8, b++) - *b = (uint8_t)(value >> shr); - - if(st->buf) FREEMEM(st->buf); -@@ -882,6 +1277,31 @@ - } - - int -+asn_uint642INTEGER(INTEGER_t *st, uint64_t value) { -+ uint8_t *buf; -+ uint8_t *end; -+ uint8_t *b; -+ int shr; -+ -+ if(value <= INT64_MAX) -+ return asn_int642INTEGER(st, value); -+ -+ buf = (uint8_t *)MALLOC(1 + sizeof(value)); -+ if(!buf) return -1; -+ -+ end = buf + (sizeof(value) + 1); -+ buf[0] = 0; -+ for(b = buf + 1, shr = (sizeof(value)-1)*8; b < end; shr -= 8, b++) -+ *b = (uint8_t)(value >> shr); -+ -+ if(st->buf) FREEMEM(st->buf); -+ st->buf = buf; -+ st->size = 1 + sizeof(value); -+ -+ return 0; -+} -+ -+int - asn_long2INTEGER(INTEGER_t *st, long value) { - uint8_t *buf, *bp; - uint8_t *p; -@@ -1024,3 +1444,60 @@ - return ASN_STRTOL_OK; - } - -+ -+int -+asn_int642INTEGER(INTEGER_t *st, int64_t value) { -+ uint8_t *buf, *bp; -+ uint8_t *p; -+ uint8_t *pstart; -+ uint8_t *pend1; -+ int littleEndian = 1; /* Run-time detection */ -+ int add; -+ -+ if(!st) { -+ errno = EINVAL; -+ return -1; -+ } -+ -+ buf = (uint8_t *)MALLOC(sizeof(value)); -+ if(!buf) return -1; -+ -+ if(*(char *)&littleEndian) { -+ pstart = (uint8_t *)&value + sizeof(value) - 1; -+ pend1 = (uint8_t *)&value; -+ add = -1; -+ } else { -+ pstart = (uint8_t *)&value; -+ pend1 = pstart + sizeof(value) - 1; -+ add = 1; -+ } -+ -+ /* -+ * If the contents octet consists of more than one octet, -+ * then bits of the first octet and bit 8 of the second octet: -+ * a) shall not all be ones; and -+ * b) shall not all be zero. -+ */ -+ for(p = pstart; p != pend1; p += add) { -+ switch(*p) { -+ case 0x00: if((*(p+add) & 0x80) == 0) -+ continue; -+ break; -+ case 0xff: if((*(p+add) & 0x80)) -+ continue; -+ break; -+ } -+ break; -+ } -+ /* Copy the integer body */ -+ for(pstart = p, bp = buf, pend1 += add; p != pend1; p += add) -+ *bp++ = *p; -+ -+ if(st->buf) FREEMEM(st->buf); -+ st->buf = buf; -+ st->size = bp - buf; -+ -+ return 0; -+} -+ -+ -Index: skeletons/constr_SEQUENCE.c -=================================================================== ---- skeletons/constr_SEQUENCE.c (revision 1516) -+++ skeletons/constr_SEQUENCE.c (working copy) -@@ -34,7 +34,7 @@ - #undef ADVANCE - #define ADVANCE(num_bytes) do { \ - size_t num = num_bytes; \ -- ptr = ((const void *)ptr) + num;\ -+ ptr = ((const char *)ptr) + num;\ - size -= num; \ - if(ctx->left >= 0) \ - ctx->left -= num; \ -@@ -144,7 +144,7 @@ - /* - * Restore parsing context. - */ -- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset); -+ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset); - - /* - * Start to parse where left previously -@@ -366,7 +366,7 @@ - ber_tlv_tag_string(tlv_tag), edx); - skip = ber_skip_length(opt_codec_ctx, - BER_TLV_CONSTRUCTED(ptr), -- (const void *)ptr + tag_len, -+ (const char *)ptr + tag_len, - LEFT - tag_len); - ASN_DEBUG("Skip length %d in %s", - (int)skip, td->name); -@@ -397,13 +397,13 @@ - */ - if(elements[edx].flags & ATF_POINTER) { - /* Member is a pointer to another structure */ -- memb_ptr2 = (void **)((void *)st + elements[edx].memb_offset); -+ memb_ptr2 = (void **)((char *)st + elements[edx].memb_offset); - } else { - /* - * A pointer to a pointer - * holding the start of the structure - */ -- memb_ptr = (void *)st + elements[edx].memb_offset; -+ memb_ptr = (char *)st + elements[edx].memb_offset; - memb_ptr2 = &memb_ptr; - } - /* -@@ -489,7 +489,7 @@ - - ll = ber_skip_length(opt_codec_ctx, - BER_TLV_CONSTRUCTED(ptr), -- (const void *)ptr + tl, LEFT - tl); -+ (const char *)ptr + tl, LEFT - tl); - switch(ll) { - case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE); - /* Fall through */ -@@ -528,14 +528,14 @@ - asn_TYPE_member_t *elm = &td->elements[edx]; - void *memb_ptr; - if(elm->flags & ATF_POINTER) { -- memb_ptr = *(void **)((void *)sptr + elm->memb_offset); -+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset); - if(!memb_ptr) { - if(elm->optional) continue; - /* Mandatory element is missing */ - _ASN_ENCODE_FAILED; - } - } else { -- memb_ptr = (void *)((void *)sptr + elm->memb_offset); -+ memb_ptr = (void *)((char *)sptr + elm->memb_offset); - } - erval = elm->type->der_encoder(elm->type, memb_ptr, - elm->tag_mode, elm->tag, -@@ -567,10 +567,10 @@ - void *memb_ptr; - - if(elm->flags & ATF_POINTER) { -- memb_ptr = *(void **)((void *)sptr + elm->memb_offset); -+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset); - if(!memb_ptr) continue; - } else { -- memb_ptr = (void *)((void *)sptr + elm->memb_offset); -+ memb_ptr = (void *)((char *)sptr + elm->memb_offset); - } - tmperval = elm->type->der_encoder(elm->type, memb_ptr, - elm->tag_mode, elm->tag, -@@ -595,7 +595,7 @@ - #undef XER_ADVANCE - #define XER_ADVANCE(num_bytes) do { \ - size_t num = num_bytes; \ -- buf_ptr = ((const void *)buf_ptr) + num;\ -+ buf_ptr = ((const char *)buf_ptr) + num;\ - size -= num; \ - consumed_myself += num; \ - } while(0) -@@ -637,7 +637,7 @@ - /* - * Restore parsing context. - */ -- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset); -+ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset); - - - /* -@@ -667,9 +667,10 @@ - - if(elm->flags & ATF_POINTER) { - /* Member is a pointer to another structure */ -- memb_ptr2 = (void **)((void *)st + elm->memb_offset); -+ memb_ptr2 = (void **)((char *)st -+ + elm->memb_offset); - } else { -- memb_ptr = (void *)st + elm->memb_offset; -+ memb_ptr = (char *)st + elm->memb_offset; - memb_ptr2 = &memb_ptr; - } - -@@ -739,7 +740,7 @@ - if(edx >= td->elements_count - || - /* Explicit OPTIONAL specs reaches the end */ -- (edx + elements[edx].optional -+ (edx + elements[edx].optional - == td->elements_count) - || - /* All extensions are optional */ -@@ -869,7 +870,7 @@ - unsigned int mlen = strlen(mname); - - if(elm->flags & ATF_POINTER) { -- memb_ptr = *(void **)((void *)sptr + elm->memb_offset); -+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset); - if(!memb_ptr) { - if(elm->optional) - continue; -@@ -877,7 +878,7 @@ - _ASN_ENCODE_FAILED; - } - } else { -- memb_ptr = (void *)((void *)sptr + elm->memb_offset); -+ memb_ptr = (void *)((char *)sptr + elm->memb_offset); - } - - if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel); -@@ -917,14 +918,14 @@ - const void *memb_ptr; - - if(elm->flags & ATF_POINTER) { -- memb_ptr = *(const void * const *)((const void *)sptr + elm->memb_offset); -+ memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset); - if(!memb_ptr) { - if(elm->optional) continue; - /* Print <absent> line */ - /* Fall through */ - } - } else { -- memb_ptr = (const void *)((const void *)sptr + elm->memb_offset); -+ memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); - } - - /* Indentation */ -@@ -960,11 +961,11 @@ - asn_TYPE_member_t *elm = &td->elements[edx]; - void *memb_ptr; - if(elm->flags & ATF_POINTER) { -- memb_ptr = *(void **)((void *)sptr + elm->memb_offset); -+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset); - if(memb_ptr) - ASN_STRUCT_FREE(*elm->type, memb_ptr); - } else { -- memb_ptr = (void *)((void *)sptr + elm->memb_offset); -+ memb_ptr = (void *)((char *)sptr + elm->memb_offset); - ASN_STRUCT_FREE_CONTENTS_ONLY(*elm->type, memb_ptr); - } - } -@@ -994,7 +995,7 @@ - const void *memb_ptr; - - if(elm->flags & ATF_POINTER) { -- memb_ptr = *(const void * const *)((const void *)sptr + elm->memb_offset); -+ memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset); - if(!memb_ptr) { - if(elm->optional) - continue; -@@ -1004,7 +1005,7 @@ - return -1; - } - } else { -- memb_ptr = (const void *)((const void *)sptr + elm->memb_offset); -+ memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); - } - - if(elm->memb_constraints) { -@@ -1088,9 +1089,9 @@ - - /* Fetch the pointer to this member */ - if(elm->flags & ATF_POINTER) { -- memb_ptr2 = (void **)((void *)st + elm->memb_offset); -+ memb_ptr2 = (void **)((char *)st + elm->memb_offset); - } else { -- memb_ptr = (void *)st + elm->memb_offset; -+ memb_ptr = (char *)st + elm->memb_offset; - memb_ptr2 = &memb_ptr; - } - -@@ -1154,11 +1155,224 @@ - memset(&epmd, 0, sizeof(epmd)); - epmd.buffer = epres; - epmd.nbits = bmlength; -+ ASN_DEBUG("Read in extensions bitmap for %s of %d bits (%x..)", -+ td->name, bmlength, *epres); -+ -+ /* Go over extensions and read them in */ -+ for(edx = specs->ext_after + 1; edx < td->elements_count; edx++) { -+ asn_TYPE_member_t *elm = &td->elements[edx]; -+ void *memb_ptr; /* Pointer to the member */ -+ void **memb_ptr2; /* Pointer to that pointer */ -+ int present; -+ -+ if(!IN_EXTENSION_GROUP(specs, edx)) { -+ ASN_DEBUG("%d is not extension", edx); -+ continue; -+ } -+ -+ /* Fetch the pointer to this member */ -+ if(elm->flags & ATF_POINTER) { -+ memb_ptr2 = (void **)((char *)st + elm->memb_offset); -+ } else { -+ memb_ptr = (void *)((char *)st + elm->memb_offset); -+ memb_ptr2 = &memb_ptr; -+ } -+ -+ present = per_get_few_bits(&epmd, 1); -+ if(present <= 0) { -+ if(present < 0) break; /* No more extensions */ -+ continue; -+ } -+ -+ ASN_DEBUG("Decoding member %s in %s %p", elm->name, td->name, *memb_ptr2); -+ rv = uper_open_type_get(opt_codec_ctx, elm->type, -+ elm->per_constraints, memb_ptr2, pd); -+ if(rv.code != RC_OK) { -+ FREEMEM(epres); -+ return rv; -+ } -+ } -+ -+ /* Skip over overflow extensions which aren't present -+ * in this system's version of the protocol */ -+ for(;;) { -+ ASN_DEBUG("Getting overflow extensions"); -+ switch(per_get_few_bits(&epmd, 1)) { -+ case -1: break; -+ case 0: continue; -+ default: -+ if(uper_open_type_skip(opt_codec_ctx, pd)) { -+ FREEMEM(epres); -+ _ASN_DECODE_STARVED; -+ } -+ } -+ break; -+ } -+ -+ FREEMEM(epres); -+ } -+ -+ /* Fill DEFAULT members in extensions */ -+ for(edx = specs->roms_count; edx < specs->roms_count -+ + specs->aoms_count; edx++) { -+ asn_TYPE_member_t *elm = &td->elements[edx]; -+ void **memb_ptr2; /* Pointer to member pointer */ -+ -+ if(!elm->default_value) continue; -+ -+ /* Fetch the pointer to this member */ -+ if(elm->flags & ATF_POINTER) { -+ memb_ptr2 = (void **)((char *)st -+ + elm->memb_offset); -+ if(*memb_ptr2) continue; -+ } else { -+ continue; /* Extensions are all optionals */ -+ } -+ -+ /* Set default value */ -+ if(elm->default_value(1, memb_ptr2)) { -+ _ASN_DECODE_FAILED; -+ } -+ } -+ -+ rv.consumed = 0; -+ rv.code = RC_OK; -+ return rv; -+} -+ -+asn_dec_rval_t -+SEQUENCE_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { -+ asn_SEQUENCE_specifics_t *specs = (asn_SEQUENCE_specifics_t *)td->specifics; -+ void *st = *sptr; /* Target structure. */ -+ int extpresent; /* Extension additions are present */ -+ uint8_t *opres; /* Presence of optional root members */ -+ asn_per_data_t opmd; -+ asn_dec_rval_t rv; -+ int edx; -+ -+ (void)constraints; -+ -+ if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx)) -+ _ASN_DECODE_FAILED; -+ -+ if(!st) { -+ st = *sptr = CALLOC(1, specs->struct_size); -+ if(!st) _ASN_DECODE_FAILED; -+ } -+ -+ ASN_DEBUG("Decoding %s as SEQUENCE (APER)", td->name); -+ -+ /* Handle extensions */ -+ if(specs->ext_before >= 0) { -+ extpresent = per_get_few_bits(pd, 1); -+ if(extpresent < 0) _ASN_DECODE_STARVED; -+ } else { -+ extpresent = 0; -+ } -+ -+ /* Prepare a place and read-in the presence bitmap */ -+ memset(&opmd, 0, sizeof(opmd)); -+ if(specs->roms_count) { -+ opres = (uint8_t *)MALLOC(((specs->roms_count + 7) >> 3) + 1); -+ if(!opres) _ASN_DECODE_FAILED; -+ /* Get the presence map */ -+ if(per_get_many_bits(pd, opres, 0, specs->roms_count)) { -+ FREEMEM(opres); -+ _ASN_DECODE_STARVED; -+ } -+ opmd.buffer = opres; -+ opmd.nbits = specs->roms_count; -+ ASN_DEBUG("Read in presence bitmap for %s of %d bits (%x..)", -+ td->name, specs->roms_count, *opres); -+ } else { -+ opres = 0; -+ } -+ -+ /* -+ * Get the sequence ROOT elements. -+ */ -+ for(edx = 0; edx < td->elements_count; edx++) { -+ asn_TYPE_member_t *elm = &td->elements[edx]; -+ void *memb_ptr; /* Pointer to the member */ -+ void **memb_ptr2; /* Pointer to that pointer */ -+ -+ if(IN_EXTENSION_GROUP(specs, edx)) -+ continue; -+ -+ /* Fetch the pointer to this member */ -+ if(elm->flags & ATF_POINTER) { -+ memb_ptr2 = (void **)((char *)st + elm->memb_offset); -+ } else { -+ memb_ptr = (char *)st + elm->memb_offset; -+ memb_ptr2 = &memb_ptr; -+ } -+ -+ /* Deal with optionality */ -+ if(elm->optional) { -+ int present = per_get_few_bits(&opmd, 1); -+ ASN_DEBUG("Member %s->%s is optional, p=%d (%d->%d)", -+ td->name, elm->name, present, -+ (int)opmd.nboff, (int)opmd.nbits); -+ if(present == 0) { -+ /* This element is not present */ -+ if(elm->default_value) { -+ /* Fill-in DEFAULT */ -+ if(elm->default_value(1, memb_ptr2)) { -+ FREEMEM(opres); -+ _ASN_DECODE_FAILED; -+ } -+ ASN_DEBUG("Filled-in default"); -+ } -+ /* The member is just not present */ -+ continue; -+ } -+ /* Fall through */ -+ } -+ -+ /* Fetch the member from the stream */ -+ ASN_DEBUG("Decoding member %s in %s", elm->name, td->name); -+ rv = elm->type->aper_decoder(opt_codec_ctx, elm->type, -+ elm->per_constraints, memb_ptr2, pd); -+ if(rv.code != RC_OK) { -+ ASN_DEBUG("Failed decode %s in %s", -+ elm->name, td->name); -+ FREEMEM(opres); -+ return rv; -+ } -+ } -+ -+ /* Optionality map is not needed anymore */ -+ FREEMEM(opres); -+ -+ /* -+ * Deal with extensions. -+ */ -+ if(extpresent) { -+ ssize_t bmlength; -+ uint8_t *epres; /* Presence of extension members */ -+ asn_per_data_t epmd; -+ -+ bmlength = uper_get_nslength(pd); -+ if(bmlength < 0) _ASN_DECODE_STARVED; -+ -+ ASN_DEBUG("Extensions %d present in %s", bmlength, td->name); -+ -+ epres = (uint8_t *)MALLOC((bmlength + 15) >> 3); -+ if(!epres) _ASN_DECODE_STARVED; -+ -+ /* Get the extensions map */ -+ if(per_get_many_bits(pd, epres, 0, bmlength)) -+ _ASN_DECODE_STARVED; -+ -+ memset(&epmd, 0, sizeof(epmd)); -+ epmd.buffer = epres; -+ epmd.nbits = bmlength; - ASN_DEBUG("Read in extensions bitmap for %s of %ld bits (%x..)", - td->name, (long)bmlength, *epres); - -- /* Go over extensions and read them in */ -- for(edx = specs->ext_after + 1; edx < td->elements_count; edx++) { -+ /* Go over extensions and read them in */ -+ for(edx = specs->ext_after + 1; edx < td->elements_count; edx++) { - asn_TYPE_member_t *elm = &td->elements[edx]; - void *memb_ptr; /* Pointer to the member */ - void **memb_ptr2; /* Pointer to that pointer */ -@@ -1171,9 +1385,9 @@ - - /* Fetch the pointer to this member */ - if(elm->flags & ATF_POINTER) { -- memb_ptr2 = (void **)((void *)st + elm->memb_offset); -+ memb_ptr2 = (void **)((char *)st + elm->memb_offset); - } else { -- memb_ptr = (void *)((void *)st + elm->memb_offset); -+ memb_ptr = (void *)((char *)st + elm->memb_offset); - memb_ptr2 = &memb_ptr; - } - -@@ -1190,7 +1404,7 @@ - FREEMEM(epres); - return rv; - } -- } -+ } - - /* Skip over overflow extensions which aren't present - * in this system's version of the protocol */ -@@ -1221,7 +1435,7 @@ - - /* Fetch the pointer to this member */ - if(elm->flags & ATF_POINTER) { -- memb_ptr2 = (void **)((void *)st -+ memb_ptr2 = (void **)((char *)st - + elm->memb_offset); - if(*memb_ptr2) continue; - } else { -@@ -1265,10 +1479,10 @@ - - /* Fetch the pointer to this member */ - if(elm->flags & ATF_POINTER) { -- memb_ptr2 = (void **)((void *)sptr + elm->memb_offset); -+ memb_ptr2 = (void **)((char *)sptr + elm->memb_offset); - present = (*memb_ptr2 != 0); - } else { -- memb_ptr = (void *)((void *)sptr + elm->memb_offset); -+ memb_ptr = (void *)((char *)sptr + elm->memb_offset); - memb_ptr2 = &memb_ptr; - present = 1; - } -@@ -1334,10 +1548,10 @@ - - /* Fetch the pointer to this member */ - if(elm->flags & ATF_POINTER) { -- memb_ptr2 = (void **)((void *)sptr + elm->memb_offset); -+ memb_ptr2 = (void **)((char *)sptr + elm->memb_offset); - present = (*memb_ptr2 != 0); - } else { -- memb_ptr = (void *)((void *)sptr + elm->memb_offset); -+ memb_ptr = (void *)((char *)sptr + elm->memb_offset); - memb_ptr2 = &memb_ptr; - present = 1; - } -@@ -1373,7 +1587,7 @@ - - /* Fetch the pointer to this member */ - if(elm->flags & ATF_POINTER) { -- memb_ptr2 = (void **)((void *)sptr + elm->memb_offset); -+ memb_ptr2 = (void **)((char *)sptr + elm->memb_offset); - if(!*memb_ptr2) { - ASN_DEBUG("Element %s %d not present", - elm->name, edx); -@@ -1383,7 +1597,7 @@ - _ASN_ENCODE_FAILED; - } - } else { -- memb_ptr = (void *)((void *)sptr + elm->memb_offset); -+ memb_ptr = (void *)((char *)sptr + elm->memb_offset); - memb_ptr2 = &memb_ptr; - } - -@@ -1420,3 +1634,130 @@ - _ASN_ENCODED_OK(er); - } - -+asn_enc_rval_t -+SEQUENCE_encode_aper(asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -+ asn_SEQUENCE_specifics_t *specs -+ = (asn_SEQUENCE_specifics_t *)td->specifics; -+ asn_enc_rval_t er; -+ int n_extensions; -+ int edx; -+ int i; -+ -+ (void)constraints; -+ -+ if(!sptr) -+ _ASN_ENCODE_FAILED; -+ -+ er.encoded = 0; -+ -+ ASN_DEBUG("Encoding %s as SEQUENCE (APER)", td->name); -+ -+ /* -+ * X.691#18.1 Whether structure is extensible -+ * and whether to encode extensions -+ */ -+ if(specs->ext_before >= 0) { -+ n_extensions = SEQUENCE_handle_extensions(td, sptr, 0, 0); -+ per_put_few_bits(po, n_extensions ? 1 : 0, 1); -+ } else { -+ n_extensions = 0; /* There are no extensions to encode */ -+ } -+ -+ /* Encode a presence bitmap */ -+ for(i = 0; i < specs->roms_count; i++) { -+ asn_TYPE_member_t *elm; -+ void *memb_ptr; /* Pointer to the member */ -+ void **memb_ptr2; /* Pointer to that pointer */ -+ int present; -+ -+ edx = specs->oms[i]; -+ elm = &td->elements[edx]; -+ -+ /* Fetch the pointer to this member */ -+ if(elm->flags & ATF_POINTER) { -+ memb_ptr2 = (void **)((char *)sptr + elm->memb_offset); -+ present = (*memb_ptr2 != 0); -+ } else { -+ memb_ptr = (void *)((char *)sptr + elm->memb_offset); -+ memb_ptr2 = &memb_ptr; -+ present = 1; -+ } -+ -+ /* Eliminate default values */ -+ if(present && elm->default_value -+ && elm->default_value(0, memb_ptr2) == 1) -+ present = 0; -+ -+ ASN_DEBUG("Element %s %s %s->%s is %s", -+ elm->flags & ATF_POINTER ? "ptr" : "inline", -+ elm->default_value ? "def" : "wtv", -+ td->name, elm->name, present ? "present" : "absent"); -+ if(per_put_few_bits(po, present, 1)) -+ _ASN_ENCODE_FAILED; -+ } -+ -+ /* -+ * Encode the sequence ROOT elements. -+ */ -+ ASN_DEBUG("ext_after = %d, ec = %d, eb = %d", specs->ext_after, td->elements_count, specs->ext_before); -+ for(edx = 0; edx < ((specs->ext_after < 0) -+ ? td->elements_count : specs->ext_before - 1); edx++) { -+ -+ asn_TYPE_member_t *elm = &td->elements[edx]; -+ void *memb_ptr; /* Pointer to the member */ -+ void **memb_ptr2; /* Pointer to that pointer */ -+ -+ if(IN_EXTENSION_GROUP(specs, edx)) -+ continue; -+ -+ ASN_DEBUG("About to encode %s", elm->type->name); -+ -+ /* Fetch the pointer to this member */ -+ if(elm->flags & ATF_POINTER) { -+ memb_ptr2 = (void **)((char *)sptr + elm->memb_offset); -+ if(!*memb_ptr2) { -+ ASN_DEBUG("Element %s %d not present", -+ elm->name, edx); -+ if(elm->optional) -+ continue; -+ /* Mandatory element is missing */ -+ _ASN_ENCODE_FAILED; -+ } -+ } else { -+ memb_ptr = (void *)((char *)sptr + elm->memb_offset); -+ memb_ptr2 = &memb_ptr; -+ } -+ -+ /* Eliminate default values */ -+ if(elm->default_value && elm->default_value(0, memb_ptr2) == 1) -+ continue; -+ -+ ASN_DEBUG("Encoding %s->%s", td->name, elm->name); -+ er = elm->type->aper_encoder(elm->type, elm->per_constraints, -+ *memb_ptr2, po); -+ if(er.encoded == -1) -+ return er; -+ } -+ -+ /* No extensions to encode */ -+ if(!n_extensions) _ASN_ENCODED_OK(er); -+ -+ ASN_DEBUG("Length of %d bit-map", n_extensions); -+ /* #18.8. Write down the presence bit-map length. */ -+ if(aper_put_nslength(po, n_extensions)) -+ _ASN_ENCODE_FAILED; -+ -+ ASN_DEBUG("Bit-map of %d elements", n_extensions); -+ /* #18.7. Encoding the extensions presence bit-map. */ -+ /* TODO: act upon NOTE in #18.7 for canonical PER */ -+ if(SEQUENCE_handle_extensions(td, sptr, po, 0) != n_extensions) -+ _ASN_ENCODE_FAILED; -+ -+ ASN_DEBUG("Writing %d extensions", n_extensions); -+ /* #18.9. Encode extensions as open type fields. */ -+ if(SEQUENCE_handle_extensions(td, sptr, 0, po) != n_extensions) -+ _ASN_ENCODE_FAILED; -+ -+ _ASN_ENCODED_OK(er); -+} -Index: skeletons/INTEGER.h -=================================================================== ---- skeletons/INTEGER.h (revision 1516) -+++ skeletons/INTEGER.h (working copy) -@@ -41,6 +41,8 @@ - xer_type_encoder_f INTEGER_encode_xer; - per_type_decoder_f INTEGER_decode_uper; - per_type_encoder_f INTEGER_encode_uper; -+per_type_decoder_f INTEGER_decode_aper; -+per_type_encoder_f INTEGER_encode_aper; - - /*********************************** - * Some handy conversion routines. * -@@ -52,8 +54,12 @@ - * -1/ERANGE: Value encoded is out of range for long representation - * -1/ENOMEM: Memory allocation failed (in asn_long2INTEGER()). - */ -+int asn_INTEGER2int64(const INTEGER_t *i, int64_t *l); -+int asn_INTEGER2uint64(const INTEGER_t *i, uint64_t *l); - int asn_INTEGER2long(const INTEGER_t *i, long *l); - int asn_INTEGER2ulong(const INTEGER_t *i, unsigned long *l); -+int asn_int642INTEGER(INTEGER_t *i, int64_t l); -+int asn_uint642INTEGER(INTEGER_t *i, uint64_t l); - int asn_long2INTEGER(INTEGER_t *i, long l); - int asn_ulong2INTEGER(INTEGER_t *i, unsigned long l); - -Index: skeletons/OCTET_STRING.c -=================================================================== ---- skeletons/OCTET_STRING.c (revision 1516) -+++ skeletons/OCTET_STRING.c (working copy) -@@ -36,6 +36,8 @@ - OCTET_STRING_encode_xer, - OCTET_STRING_decode_uper, /* Unaligned PER decoder */ - OCTET_STRING_encode_uper, /* Unaligned PER encoder */ -+ OCTET_STRING_decode_aper, /* Aligned PER decoder */ -+ OCTET_STRING_encode_aper, /* Aligned PER encoder */ - 0, /* Use generic outmost tag fetcher */ - asn_DEF_OCTET_STRING_tags, - sizeof(asn_DEF_OCTET_STRING_tags) -@@ -86,7 +88,7 @@ - void *ptr; \ - /* Be nice and round to the memory allocator */ \ - do { _ns = _ns ? _ns << 1 : 16; } \ -- while(_ns <= _es); \ -+ while(_ns <= _es); \ - /* int is really a typeof(st->size): */ \ - if((int)_ns < 0) RETURN(RC_FAIL); \ - ptr = REALLOC(st->buf, _ns); \ -@@ -195,7 +197,7 @@ - } - - /* Restore parsing context */ -- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset); -+ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset); - - switch(ctx->phase) { - case 0: -@@ -416,7 +418,7 @@ - ASN_DEBUG("Phase 2: Need %ld bytes, size=%ld, alrg=%ld, wn=%d", - (long)sel->left, (long)size, (long)sel->got, - sel->want_nulls); -- { -+ { - ber_tlv_len_t len; - - assert(sel->left >= 0); -@@ -446,7 +448,7 @@ - - PREV_PHASE(ctx); - goto phase1; -- } -+ } - break; - case 3: - phase3: -@@ -1143,7 +1145,7 @@ - } - - /* Restore parsing context */ -- ctx = (asn_struct_ctx_t *)(((void *)*sptr) + specs->ctx_offset); -+ ctx = (asn_struct_ctx_t *)(((char *)*sptr) + specs->ctx_offset); - - return xer_decode_general(opt_codec_ctx, ctx, *sptr, xml_tag, - buf_ptr, size, opt_unexpected_tag_decoder, body_receiver); -@@ -1392,7 +1394,7 @@ - if(!st) RETURN(RC_FAIL); - } - -- ASN_DEBUG("PER Decoding %s size %ld .. %ld bits %d", -+ ASN_DEBUG("PER Decoding %s size %"PRIdMAX" .. %"PRIdMAX" bits %d", - csiz->flags & APC_EXTENSIBLE ? "extensible" : "non-extensible", - csiz->lower_bound, csiz->upper_bound, csiz->effective_bits); - -@@ -1423,17 +1425,17 @@ - if(csiz->effective_bits == 0) { - int ret; - if(bpc) { -- ASN_DEBUG("Encoding OCTET STRING size %ld", -+ ASN_DEBUG("Encoding OCTET STRING size %"PRIdMAX, - csiz->upper_bound); - ret = OCTET_STRING_per_get_characters(pd, st->buf, - csiz->upper_bound, bpc, unit_bits, - cval->lower_bound, cval->upper_bound, pc); - if(ret > 0) RETURN(RC_FAIL); - } else { -- ASN_DEBUG("Encoding BIT STRING size %ld", -+ ASN_DEBUG("Encoding BIT STRING size %"PRIdMAX, - csiz->upper_bound); - ret = per_get_many_bits(pd, st->buf, 0, -- unit_bits * csiz->upper_bound); -+ unit_bits * csiz->upper_bound); - } - if(ret < 0) RETURN(RC_WMORE); - consumed_myself += unit_bits * csiz->upper_bound; -@@ -1492,9 +1494,197 @@ - return rval; - } - -+asn_dec_rval_t -+OCTET_STRING_decode_aper(asn_codec_ctx_t *opt_codec_ctx, -+ asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, -+ void **sptr, asn_per_data_t *pd) { -+ -+ asn_OCTET_STRING_specifics_t *specs = td->specifics -+ ? (asn_OCTET_STRING_specifics_t *)td->specifics -+ : &asn_DEF_OCTET_STRING_specs; -+ asn_per_constraints_t *pc = constraints ? constraints -+ : td->per_constraints; -+ asn_per_constraint_t *cval; -+ asn_per_constraint_t *csiz; -+ asn_dec_rval_t rval = { RC_OK, 0 }; -+ BIT_STRING_t *st = (BIT_STRING_t *)*sptr; -+ ssize_t consumed_myself = 0; -+ int repeat; -+ enum { -+ OS__BPC_BIT = 0, -+ OS__BPC_CHAR = 1, -+ OS__BPC_U16 = 2, -+ OS__BPC_U32 = 4 -+ } bpc; /* Bytes per character */ -+ unsigned int unit_bits; -+ unsigned int canonical_unit_bits; -+ -+ (void)opt_codec_ctx; -+ -+ if(pc) { -+ cval = &pc->value; -+ csiz = &pc->size; -+ } else { -+ cval = &asn_DEF_OCTET_STRING_constraints.value; -+ csiz = &asn_DEF_OCTET_STRING_constraints.size; -+ } -+ -+ switch(specs->subvariant) { -+ default: -+// case ASN_OSUBV_ANY: -+// ASN_DEBUG("Unrecognized subvariant %d", specs->subvariant); -+// RETURN(RC_FAIL); -+ case ASN_OSUBV_BIT: -+ canonical_unit_bits = unit_bits = 1; -+ bpc = OS__BPC_BIT; -+ break; -+ case ASN_OSUBV_ANY: -+ case ASN_OSUBV_STR: -+ canonical_unit_bits = unit_bits = 8; -+// if(cval->flags & APC_CONSTRAINED) -+// unit_bits = cval->range_bits; -+ bpc = OS__BPC_CHAR; -+ break; -+ case ASN_OSUBV_U16: -+ canonical_unit_bits = unit_bits = 16; -+ if(cval->flags & APC_CONSTRAINED) -+ unit_bits = cval->range_bits; -+ bpc = OS__BPC_U16; -+ break; -+ case ASN_OSUBV_U32: -+ canonical_unit_bits = unit_bits = 32; -+ if(cval->flags & APC_CONSTRAINED) -+ unit_bits = cval->range_bits; -+ bpc = OS__BPC_U32; -+ break; -+ } -+ -+ /* -+ * Allocate the string. -+ */ -+ if(!st) { -+ st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size)); -+ if(!st) RETURN(RC_FAIL); -+ } -+ -+ ASN_DEBUG("PER Decoding %s size %"PRIdMAX" .. %"PRIdMAX" bits %d", -+ csiz->flags & APC_EXTENSIBLE ? "extensible" : "non-extensible", -+ csiz->lower_bound, csiz->upper_bound, csiz->effective_bits); -+ -+ if(csiz->flags & APC_EXTENSIBLE) { -+ int inext = per_get_few_bits(pd, 1); -+ if(inext < 0) RETURN(RC_WMORE); -+ if(inext) { -+ csiz = &asn_DEF_OCTET_STRING_constraints.size; -+ cval = &asn_DEF_OCTET_STRING_constraints.value; -+ unit_bits = canonical_unit_bits; -+ } -+ } -+ -+ if(csiz->effective_bits >= 0) { -+ FREEMEM(st->buf); -+ if(bpc) { -+ st->size = csiz->upper_bound * bpc; -+ } else { -+ st->size = (csiz->upper_bound + 7) >> 3; -+ } -+ st->buf = (uint8_t *)MALLOC(st->size + 1); -+ if(!st->buf) { st->size = 0; RETURN(RC_FAIL); } -+ } -+ -+ /* X.691, #16.5: zero-length encoding */ -+ /* X.691, #16.6: short fixed length encoding (up to 2 octets) */ -+ /* X.691, #16.7: long fixed length encoding (up to 64K octets) */ -+ if(csiz->effective_bits == 0) { -+ int ret; -+ if (st->size > 2) { /* X.691 #16 NOTE 1 */ -+ if (aper_get_align(pd) < 0) -+ RETURN(RC_FAIL); -+ } -+ if(bpc) { -+ ASN_DEBUG("Decoding OCTET STRING size %"PRIdMAX, -+ csiz->upper_bound); -+ ret = OCTET_STRING_per_get_characters(pd, st->buf, -+ csiz->upper_bound, bpc, unit_bits, -+ cval->lower_bound, cval->upper_bound, pc); -+ if(ret > 0) RETURN(RC_FAIL); -+ } else { -+ ASN_DEBUG("Decoding BIT STRING size %"PRIdMAX, -+ csiz->upper_bound); -+ ret = per_get_many_bits(pd, st->buf, 0, -+ unit_bits * csiz->upper_bound); -+ } -+ if(ret < 0) RETURN(RC_WMORE); -+ consumed_myself += unit_bits * csiz->upper_bound; -+ st->buf[st->size] = 0; -+ if(bpc == 0) { -+ int ubs = (csiz->upper_bound & 0x7); -+ st->bits_unused = ubs ? 8 - ubs : 0; -+ } -+ RETURN(RC_OK); -+ } -+ -+ st->size = 0; -+ do { -+ ssize_t raw_len; -+ ssize_t len_bytes; -+ ssize_t len_bits; -+ void *p; -+ int ret; -+ -+ /* Get the PER length */ -+ if (csiz->upper_bound - csiz->lower_bound == 0) -+ // Indefinite length case -+ raw_len = aper_get_length(pd, -1, csiz->effective_bits, &repeat); -+ else -+ raw_len = aper_get_length(pd, csiz->upper_bound - csiz->lower_bound + 1, csiz->effective_bits, &repeat); -+ repeat = 0; -+ if(raw_len < 0) RETURN(RC_WMORE); -+ raw_len += csiz->lower_bound; -+ -+ ASN_DEBUG("Got PER length eb %ld, len %ld, %s (%s)", -+ (long)csiz->effective_bits, (long)raw_len, -+ repeat ? "repeat" : "once", td->name); -+ -+ if (raw_len > 2) { /* X.691 #16 NOTE 1 */ -+ if (aper_get_align(pd) < 0) -+ RETURN(RC_FAIL); -+ } -+ -+ if(bpc) { -+ len_bytes = raw_len * bpc; -+ len_bits = len_bytes * unit_bits; -+ } else { -+ len_bits = raw_len; -+ len_bytes = (len_bits + 7) >> 3; -+ if(len_bits & 0x7) -+ st->bits_unused = 8 - (len_bits & 0x7); -+ /* len_bits be multiple of 16K if repeat is set */ -+ } -+ p = REALLOC(st->buf, st->size + len_bytes + 1); -+ if(!p) RETURN(RC_FAIL); -+ st->buf = (uint8_t *)p; -+ -+ if(bpc) { -+ ret = OCTET_STRING_per_get_characters(pd, -+ &st->buf[st->size], raw_len, bpc, unit_bits, -+ cval->lower_bound, cval->upper_bound, pc); -+ if(ret > 0) RETURN(RC_FAIL); -+ } else { -+ ret = per_get_many_bits(pd, &st->buf[st->size], -+ 0, len_bits); -+ } -+ if(ret < 0) RETURN(RC_WMORE); -+ st->size += len_bytes; -+ } while(repeat); -+ st->buf[st->size] = 0; /* nul-terminate */ -+ -+ return rval; -+} -+ - asn_enc_rval_t - OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td, -- asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { - - asn_OCTET_STRING_specifics_t *specs = td->specifics - ? (asn_OCTET_STRING_specifics_t *)td->specifics -@@ -1566,7 +1756,7 @@ - } - - ASN_DEBUG("Encoding %s into %d units of %d bits" -- " (%ld..%ld, effective %d)%s", -+ " (%"PRIdMAX"..%"PRIdMAX", effective %d)%s", - td->name, sizeinunits, unit_bits, - csiz->lower_bound, csiz->upper_bound, - csiz->effective_bits, ct_extensible ? " EXT" : ""); -@@ -1598,7 +1788,7 @@ - /* X.691, #16.6: short fixed length encoding (up to 2 octets) */ - /* X.691, #16.7: long fixed length encoding (up to 64K octets) */ - if(csiz->effective_bits >= 0) { -- ASN_DEBUG("Encoding %d bytes (%ld), length in %d bits", -+ ASN_DEBUG("Encoding %d bytes (%"PRIdMAX"), length in %d bits", - st->size, sizeinunits - csiz->lower_bound, - csiz->effective_bits); - ret = per_put_few_bits(po, sizeinunits - csiz->lower_bound, -@@ -1652,6 +1842,173 @@ - _ASN_ENCODED_OK(er); - } - -+asn_enc_rval_t -+OCTET_STRING_encode_aper(asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -+ -+ asn_OCTET_STRING_specifics_t *specs = td->specifics -+ ? (asn_OCTET_STRING_specifics_t *)td->specifics -+ : &asn_DEF_OCTET_STRING_specs; -+ asn_per_constraints_t *pc = constraints ? constraints -+ : td->per_constraints; -+ asn_per_constraint_t *cval; -+ asn_per_constraint_t *csiz; -+ const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; -+ asn_enc_rval_t er = { 0, 0, 0 }; -+ int inext = 0; /* Lies not within extension root */ -+ unsigned int unit_bits; -+ unsigned int canonical_unit_bits; -+ unsigned int sizeinunits; -+ const uint8_t *buf; -+ int ret; -+ enum { -+ OS__BPC_BIT = 0, -+ OS__BPC_CHAR = 1, -+ OS__BPC_U16 = 2, -+ OS__BPC_U32 = 4 -+ } bpc; /* Bytes per character */ -+ int ct_extensible; -+ -+ if(!st || (!st->buf && st->size)) -+ _ASN_ENCODE_FAILED; -+ -+ if(pc) { -+ cval = &pc->value; -+ csiz = &pc->size; -+ } else { -+ cval = &asn_DEF_OCTET_STRING_constraints.value; -+ csiz = &asn_DEF_OCTET_STRING_constraints.size; -+ } -+ ct_extensible = csiz->flags & APC_EXTENSIBLE; -+ -+ switch(specs->subvariant) { -+ default: -+// case ASN_OSUBV_ANY: -+// _ASN_ENCODE_FAILED; -+ case ASN_OSUBV_BIT: -+ canonical_unit_bits = unit_bits = 1; -+ bpc = OS__BPC_BIT; -+ sizeinunits = st->size * 8 - (st->bits_unused & 0x07); -+ ASN_DEBUG("BIT STRING of %d bits", -+ sizeinunits); -+ break; -+ case ASN_OSUBV_ANY: -+ case ASN_OSUBV_STR: -+ canonical_unit_bits = unit_bits = 8; -+// if(cval->flags & APC_CONSTRAINED) -+// unit_bits = 8; -+ bpc = OS__BPC_CHAR; -+ sizeinunits = st->size; -+ break; -+ case ASN_OSUBV_U16: -+ canonical_unit_bits = unit_bits = 16; -+ if(cval->flags & APC_CONSTRAINED) -+ unit_bits = cval->range_bits; -+ bpc = OS__BPC_U16; -+ sizeinunits = st->size / 2; -+ break; -+ case ASN_OSUBV_U32: -+ canonical_unit_bits = unit_bits = 32; -+ if(cval->flags & APC_CONSTRAINED) -+ unit_bits = cval->range_bits; -+ bpc = OS__BPC_U32; -+ sizeinunits = st->size / 4; -+ break; -+ } -+ -+ ASN_DEBUG("Encoding %s into %d units of %d bits" -+ " (%"PRIdMAX"..%"PRIdMAX", effective %d)%s", -+ td->name, sizeinunits, unit_bits, -+ csiz->lower_bound, csiz->upper_bound, -+ csiz->effective_bits, ct_extensible ? " EXT" : ""); -+ -+ /* Figure out wheter size lies within PER visible constraint */ -+ -+ if(csiz->effective_bits >= 0) { -+ if((int)sizeinunits < csiz->lower_bound -+ || (int)sizeinunits > csiz->upper_bound) { -+ if(ct_extensible) { -+ cval = &asn_DEF_OCTET_STRING_constraints.value; -+ csiz = &asn_DEF_OCTET_STRING_constraints.size; -+ unit_bits = canonical_unit_bits; -+ inext = 1; -+ } else -+ _ASN_ENCODE_FAILED; -+ } -+ } else { -+ inext = 0; -+ } -+ -+ -+ if(ct_extensible) { -+ /* Declare whether length is [not] within extension root */ -+ if(per_put_few_bits(po, inext, 1)) -+ _ASN_ENCODE_FAILED; -+ } -+ -+ /* X.691, #16.5: zero-length encoding */ -+ /* X.691, #16.6: short fixed length encoding (up to 2 octets) */ -+ /* X.691, #16.7: long fixed length encoding (up to 64K octets) */ -+ if(csiz->effective_bits >= 0) { -+ ASN_DEBUG("Encoding %d bytes (%"PRIdMAX"), length in %d bits", -+ st->size, sizeinunits - csiz->lower_bound, -+ csiz->effective_bits); -+ ret = per_put_few_bits(po, sizeinunits - csiz->lower_bound, -+ csiz->effective_bits); -+ if(ret) _ASN_ENCODE_FAILED; -+ if (st->size > 2) { /* X.691 #16 NOTE 1 */ -+ if (aper_put_align(po) < 0) -+ _ASN_ENCODE_FAILED; -+ } -+ if(bpc) { -+ ret = OCTET_STRING_per_put_characters(po, st->buf, -+ sizeinunits, bpc, unit_bits, -+ cval->lower_bound, cval->upper_bound, pc); -+ } else { -+ ret = per_put_many_bits(po, st->buf, -+ sizeinunits * unit_bits); -+ } -+ if(ret) _ASN_ENCODE_FAILED; -+ _ASN_ENCODED_OK(er); -+ } -+ -+ ASN_DEBUG("Encoding %d bytes", st->size); -+ -+ if(sizeinunits == 0) { -+ if(aper_put_length(po, -1, 0)) -+ _ASN_ENCODE_FAILED; -+ _ASN_ENCODED_OK(er); -+ } -+ -+ buf = st->buf; -+ while(sizeinunits) { -+ ssize_t maySave = aper_put_length(po, -1, sizeinunits); -+ -+ if(maySave < 0) _ASN_ENCODE_FAILED; -+ -+ ASN_DEBUG("Encoding %ld of %ld", -+ (long)maySave, (long)sizeinunits); -+ -+ if(bpc) { -+ ret = OCTET_STRING_per_put_characters(po, buf, -+ maySave, bpc, unit_bits, -+ cval->lower_bound, cval->upper_bound, pc); -+ } else { -+ ret = per_put_many_bits(po, buf, maySave * unit_bits); -+ } -+ if(ret) _ASN_ENCODE_FAILED; -+ -+ if(bpc) -+ buf += maySave * bpc; -+ else -+ buf += maySave >> 3; -+ sizeinunits -= maySave; -+ assert(!(maySave & 0x07) || !sizeinunits); -+ } -+ -+ _ASN_ENCODED_OK(er); -+} -+ - int - OCTET_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, - asn_app_consume_bytes_f *cb, void *app_key) { -@@ -1716,7 +2073,7 @@ - ? (asn_OCTET_STRING_specifics_t *)td->specifics - : &asn_DEF_OCTET_STRING_specs; - asn_struct_ctx_t *ctx = (asn_struct_ctx_t *) -- ((void *)st + specs->ctx_offset); -+ ((char *)st + specs->ctx_offset); - struct _stack *stck; - - if(!td || !st) -Index: skeletons/BIT_STRING.c -=================================================================== ---- skeletons/BIT_STRING.c (revision 1516) -+++ skeletons/BIT_STRING.c (working copy) -@@ -29,6 +29,8 @@ - BIT_STRING_encode_xer, - OCTET_STRING_decode_uper, /* Unaligned PER decoder */ - OCTET_STRING_encode_uper, /* Unaligned PER encoder */ -+ OCTET_STRING_decode_aper, /* Aligned PER decoder */ -+ OCTET_STRING_encode_aper, /* Aligned PER encoder */ - 0, /* Use generic outmost tag fetcher */ - asn_DEF_BIT_STRING_tags, - sizeof(asn_DEF_BIT_STRING_tags) -Index: skeletons/NativeInteger.c -=================================================================== ---- skeletons/NativeInteger.c (revision 1516) -+++ skeletons/NativeInteger.c (working copy) -@@ -31,6 +31,8 @@ - NativeInteger_encode_xer, - NativeInteger_decode_uper, /* Unaligned PER decoder */ - NativeInteger_encode_uper, /* Unaligned PER encoder */ -+ NativeInteger_decode_aper, /* Aligned PER decoder */ -+ NativeInteger_encode_aper, /* Aligned PER encoder */ - 0, /* Use generic outmost tag fetcher */ - asn_DEF_NativeInteger_tags, - sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]), -@@ -267,6 +269,46 @@ - return rval; - } - -+asn_dec_rval_t -+NativeInteger_decode_aper(asn_codec_ctx_t *opt_codec_ctx, -+ asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { -+ -+ asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics; -+ asn_dec_rval_t rval; -+ long *native = (long *)*sptr; -+ INTEGER_t tmpint; -+ void *tmpintptr = &tmpint; -+ int dynamic = 0; -+ -+ (void)opt_codec_ctx; -+ ASN_DEBUG("Decoding NativeInteger %s (APER)", td->name); -+ -+ if(!native) { -+ native = (long *)(*sptr = CALLOC(1, sizeof(*native))); -+ dynamic = 1; -+ if(!native) _ASN_DECODE_FAILED; -+ } -+ -+ memset(&tmpint, 0, sizeof tmpint); -+ rval = INTEGER_decode_aper(opt_codec_ctx, td, constraints, -+ &tmpintptr, pd); -+ if(rval.code == RC_OK) { -+ if((specs&&specs->field_unsigned) -+ ? asn_INTEGER2ulong(&tmpint, (unsigned long *)native) -+ : asn_INTEGER2long(&tmpint, native)) -+ rval.code = RC_FAIL; -+ else -+ ASN_DEBUG("NativeInteger %s got value %ld", -+ td->name, *native); -+ } -+ ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint); -+ //if (dynamic) -+ // free(native); -+ -+ return rval; -+} -+ - asn_enc_rval_t - NativeInteger_encode_uper(asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -@@ -291,6 +333,44 @@ - return er; - } - -+asn_enc_rval_t -+NativeInteger_encode_aper( -+ asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -+ -+ asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics; -+ asn_enc_rval_t er; -+ INTEGER_t tmpint; -+ -+ if(!sptr) _ASN_ENCODE_FAILED; -+ memset(&tmpint, 0, sizeof(tmpint)); -+ -+ if(specs&&specs->field_unsigned) { -+ unsigned long native; -+ native = *(unsigned long *)sptr; -+ -+ ASN_DEBUG("Encoding NativeInteger %s %lu (APER) (unsigned)", td->name, native); -+ -+ if(asn_ulong2INTEGER(&tmpint, native)) -+ _ASN_ENCODE_FAILED; -+ } else { -+ long native; -+ native = *(long *)sptr; -+ -+ ASN_DEBUG("Encoding NativeInteger %s %ld (APER) (unsigned)", td->name, native); -+ if(asn_long2INTEGER(&tmpint, native)) -+ _ASN_ENCODE_FAILED; -+ } -+ -+// if((specs&&specs->field_unsigned) -+// ? asn_ulong2INTEGER(&tmpint, native) -+// : asn_long2INTEGER(&tmpint, native)) -+// _ASN_ENCODE_FAILED; -+ er = INTEGER_encode_aper(td, constraints, &tmpint, po); -+ ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint); -+ return er; -+} -+ - /* - * INTEGER specific human-readable output. - */ -Index: skeletons/constr_SEQUENCE.h -=================================================================== ---- skeletons/constr_SEQUENCE.h (revision 1516) -+++ skeletons/constr_SEQUENCE.h (working copy) -@@ -52,6 +52,8 @@ - xer_type_encoder_f SEQUENCE_encode_xer; - per_type_decoder_f SEQUENCE_decode_uper; - per_type_encoder_f SEQUENCE_encode_uper; -+per_type_decoder_f SEQUENCE_decode_aper; -+per_type_encoder_f SEQUENCE_encode_aper; - - #ifdef __cplusplus - } -Index: skeletons/NativeInteger.h -=================================================================== ---- skeletons/NativeInteger.h (revision 1516) -+++ skeletons/NativeInteger.h (working copy) -@@ -29,6 +29,8 @@ - xer_type_encoder_f NativeInteger_encode_xer; - per_type_decoder_f NativeInteger_decode_uper; - per_type_encoder_f NativeInteger_encode_uper; -+per_type_decoder_f NativeInteger_decode_aper; -+per_type_encoder_f NativeInteger_encode_aper; - - #ifdef __cplusplus - } -Index: skeletons/OCTET_STRING.h -=================================================================== ---- skeletons/OCTET_STRING.h (revision 1516) -+++ skeletons/OCTET_STRING.h (working copy) -@@ -32,6 +32,8 @@ - xer_type_encoder_f OCTET_STRING_encode_xer_utf8; - per_type_decoder_f OCTET_STRING_decode_uper; - per_type_encoder_f OCTET_STRING_encode_uper; -+per_type_decoder_f OCTET_STRING_decode_aper; -+per_type_encoder_f OCTET_STRING_encode_aper; - - /****************************** - * Handy conversion routines. * -Index: skeletons/UTCTime.c -=================================================================== ---- skeletons/UTCTime.c (revision 1516) -+++ skeletons/UTCTime.c (working copy) -@@ -40,6 +40,8 @@ - UTCTime_encode_xer, - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_UTCTime_tags, - sizeof(asn_DEF_UTCTime_tags) -Index: skeletons/REAL.c -=================================================================== ---- skeletons/REAL.c (revision 1516) -+++ skeletons/REAL.c (working copy) -@@ -45,6 +45,8 @@ - REAL_encode_xer, - REAL_decode_uper, - REAL_encode_uper, -+ REAL_decode_aper, -+ REAL_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_REAL_tags, - sizeof(asn_DEF_REAL_tags) / sizeof(asn_DEF_REAL_tags[0]), -@@ -361,6 +363,21 @@ - return OCTET_STRING_encode_uper(td, 0, sptr, po); - } - -+asn_dec_rval_t -+REAL_decode_aper(asn_codec_ctx_t *opt_codec_ctx, -+ asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, -+ void **sptr, asn_per_data_t *pd) { -+ (void)constraints; /* No PER visible constraints */ -+ return OCTET_STRING_decode_aper(opt_codec_ctx, td, 0, sptr, pd); -+} -+ -+asn_enc_rval_t -+REAL_encode_aper(asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -+ (void)constraints; /* No PER visible constraints */ -+ return OCTET_STRING_encode_aper(td, 0, sptr, po); -+} -+ - int - asn_REAL2double(const REAL_t *st, double *dbl_value) { - unsigned int octv; -Index: skeletons/VisibleString.c -=================================================================== ---- skeletons/VisibleString.c (revision 1516) -+++ skeletons/VisibleString.c (working copy) -@@ -29,6 +29,8 @@ - OCTET_STRING_encode_xer_utf8, - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_VisibleString_tags, - sizeof(asn_DEF_VisibleString_tags) -Index: skeletons/ANY.c -=================================================================== ---- skeletons/ANY.c (revision 1516) -+++ skeletons/ANY.c (working copy) -@@ -21,7 +21,10 @@ - OCTET_STRING_encode_der, - OCTET_STRING_decode_xer_hex, - ANY_encode_xer, -- 0, 0, -+ OCTET_STRING_decode_uper, -+ OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - 0, 0, 0, 0, - 0, /* No PER visible constraints */ -@@ -87,6 +90,37 @@ - return 0; - } - -+int -+ANY_fromType_aper(ANY_t *st, asn_TYPE_descriptor_t *td, void *sptr) { -+ uint8_t *buffer = NULL; -+ ssize_t erval; -+ -+ if(!st || !td) { -+ errno = EINVAL; -+ return -1; -+ } -+ -+ if(!sptr) { -+ if(st->buf) FREEMEM(st->buf); -+ st->size = 0; -+ return 0; -+ } -+ -+ erval = aper_encode_to_new_buffer(td, td->per_constraints, sptr, (void**)&buffer); -+ -+ if(erval == -1) { -+ if(buffer) FREEMEM(buffer); -+ return -1; -+ } -+ assert((size_t)erval > 0); -+ -+ if(st->buf) FREEMEM(st->buf); -+ st->buf = buffer; -+ st->size = erval; -+ -+ return 0; -+} -+ - ANY_t * - ANY_new_fromType(asn_TYPE_descriptor_t *td, void *sptr) { - ANY_t tmp; -@@ -111,6 +145,30 @@ - } - } - -+ANY_t * -+ANY_new_fromType_aper(asn_TYPE_descriptor_t *td, void *sptr) { -+ ANY_t tmp; -+ ANY_t *st; -+ -+ if(!td || !sptr) { -+ errno = EINVAL; -+ return 0; -+ } -+ -+ memset(&tmp, 0, sizeof(tmp)); -+ -+ if(ANY_fromType_aper(&tmp, td, sptr)) return 0; -+ -+ st = (ANY_t *)CALLOC(1, sizeof(ANY_t)); -+ if(st) { -+ *st = tmp; -+ return st; -+ } else { -+ FREEMEM(tmp.buf); -+ return 0; -+ } -+} -+ - int - ANY_to_type(ANY_t *st, asn_TYPE_descriptor_t *td, void **struct_ptr) { - asn_dec_rval_t rval; -@@ -138,6 +196,33 @@ - } - } - -+int -+ANY_to_type_aper(ANY_t *st, asn_TYPE_descriptor_t *td, void **struct_ptr) { -+ asn_dec_rval_t rval; -+ void *newst = 0; -+ -+ if(!st || !td || !struct_ptr) { -+ errno = EINVAL; -+ return -1; -+ } -+ -+ if(st->buf == 0) { -+ /* Nothing to convert, make it empty. */ -+ *struct_ptr = (void *)0; -+ return 0; -+ } -+ -+ rval = aper_decode(0, td, (void **)&newst, st->buf, st->size, 0, 0); -+ if(rval.code == RC_OK) { -+ *struct_ptr = newst; -+ return 0; -+ } else { -+ /* Remove possibly partially decoded data. */ -+ ASN_STRUCT_FREE(*td, newst); -+ return -1; -+ } -+} -+ - static int ANY__consume_bytes(const void *buffer, size_t size, void *key) { - struct _callback_arg *arg = (struct _callback_arg *)key; - -Index: skeletons/REAL.h -=================================================================== ---- skeletons/REAL.h (revision 1516) -+++ skeletons/REAL.h (working copy) -@@ -21,6 +21,8 @@ - xer_type_encoder_f REAL_encode_xer; - per_type_decoder_f REAL_decode_uper; - per_type_encoder_f REAL_encode_uper; -+per_type_decoder_f REAL_decode_aper; -+per_type_encoder_f REAL_encode_aper; - - /*********************************** - * Some handy conversion routines. * -Index: skeletons/NativeReal.c -=================================================================== ---- skeletons/NativeReal.c (revision 1516) -+++ skeletons/NativeReal.c (working copy) -@@ -32,6 +32,8 @@ - NativeReal_encode_xer, - NativeReal_decode_uper, - NativeReal_encode_uper, -+ NativeReal_decode_aper, -+ NativeReal_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_NativeReal_tags, - sizeof(asn_DEF_NativeReal_tags) / sizeof(asn_DEF_NativeReal_tags[0]), -@@ -123,11 +125,11 @@ - tmp.size = length; - memcpy(tmp.buf, buf_ptr, length); - tmp.buf[tmp.size] = '\0'; -- if(asn_REAL2double(&tmp, &d)) { -- rval.code = RC_FAIL; -- rval.consumed = 0; -- return rval; -- } -+ if(asn_REAL2double(&tmp, &d)) { -+ rval.code = RC_FAIL; -+ rval.consumed = 0; -+ return rval; -+ } - } else { - /* This should probably never happen: impractically long value */ - tmp.buf = CALLOC(1, length + 1); -@@ -228,6 +230,43 @@ - return rval; - } - -+asn_dec_rval_t -+NativeReal_decode_aper(asn_codec_ctx_t *opt_codec_ctx, -+ asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, -+ void **dbl_ptr, asn_per_data_t *pd) { -+ double *Dbl = (double *)*dbl_ptr; -+ asn_dec_rval_t rval; -+ REAL_t tmp; -+ void *ptmp = &tmp; -+ int ret; -+ -+ (void)constraints; -+ -+ /* -+ * If the structure is not there, allocate it. -+ */ -+ if(Dbl == NULL) { -+ *dbl_ptr = CALLOC(1, sizeof(*Dbl)); -+ Dbl = (double *)*dbl_ptr; -+ if(Dbl == NULL) -+ _ASN_DECODE_FAILED; -+ } -+ -+ memset(&tmp, 0, sizeof(tmp)); -+ rval = OCTET_STRING_decode_aper(opt_codec_ctx, td, NULL, -+ &ptmp, pd); -+ if(rval.code != RC_OK) { -+ ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_REAL, &tmp); -+ return rval; -+ } -+ -+ ret = asn_REAL2double(&tmp, Dbl); -+ ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_REAL, &tmp); -+ if(ret) _ASN_DECODE_FAILED; -+ -+ return rval; -+} -+ - /* - * Encode the NativeReal using the OCTET STRING PER encoder. - */ -@@ -257,6 +296,32 @@ - return erval; - } - -+asn_enc_rval_t -+NativeReal_encode_aper(asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -+ double Dbl = *(const double *)sptr; -+ asn_enc_rval_t erval; -+ REAL_t tmp; -+ -+ (void)constraints; -+ -+ /* Prepare a temporary clean structure */ -+ memset(&tmp, 0, sizeof(tmp)); -+ -+ if(asn_double2REAL(&tmp, Dbl)) -+ _ASN_ENCODE_FAILED; -+ -+ /* Encode a DER REAL */ -+ erval = OCTET_STRING_encode_aper(td, NULL, &tmp, po); -+ if(erval.encoded == -1) -+ erval.structure_ptr = sptr; -+ -+ /* Free possibly allocated members of the temporary structure */ -+ ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_REAL, &tmp); -+ -+ return erval; -+} -+ - /* - * Decode the chunk of XML text encoding REAL. - */ -Index: skeletons/asn_system.h -=================================================================== ---- skeletons/asn_system.h (revision 1516) -+++ skeletons/asn_system.h (working copy) -@@ -21,6 +21,11 @@ - #include <stdarg.h> /* For va_start */ - #include <stddef.h> /* for offsetof and ptrdiff_t */ - -+#if HAVE_STDINT_H -+# include <stdint.h> -+# include <inttypes.h> -+#endif -+ - #ifdef _WIN32 - - #include <malloc.h> -Index: skeletons/ANY.h -=================================================================== ---- skeletons/ANY.h (revision 1516) -+++ skeletons/ANY.h (working copy) -@@ -32,10 +32,13 @@ - - /* Convert another ASN.1 type into the ANY. This implies DER encoding. */ - int ANY_fromType(ANY_t *, asn_TYPE_descriptor_t *td, void *struct_ptr); -+int ANY_fromType_aper(ANY_t *st, asn_TYPE_descriptor_t *td, void *sptr); - ANY_t *ANY_new_fromType(asn_TYPE_descriptor_t *td, void *struct_ptr); -+ANY_t *ANY_new_fromType_aper(asn_TYPE_descriptor_t *td, void *sptr); - - /* Convert the contents of the ANY type into the specified type. */ - int ANY_to_type(ANY_t *, asn_TYPE_descriptor_t *td, void **struct_ptr); -+int ANY_to_type_aper(ANY_t *, asn_TYPE_descriptor_t *td, void **struct_ptr); - - #define ANY_fromBuf(s, buf, size) OCTET_STRING_fromBuf((s), (buf), (size)) - #define ANY_new_fromBuf(buf, size) OCTET_STRING_new_fromBuf( \ -Index: skeletons/NativeReal.h -=================================================================== ---- skeletons/NativeReal.h (revision 1516) -+++ skeletons/NativeReal.h (working copy) -@@ -27,6 +27,8 @@ - xer_type_encoder_f NativeReal_encode_xer; - per_type_decoder_f NativeReal_decode_uper; - per_type_encoder_f NativeReal_encode_uper; -+per_type_decoder_f NativeReal_decode_aper; -+per_type_encoder_f NativeReal_encode_aper; - - #ifdef __cplusplus - } -Index: skeletons/UniversalString.c -=================================================================== ---- skeletons/UniversalString.c (revision 1516) -+++ skeletons/UniversalString.c (working copy) -@@ -35,6 +35,8 @@ - UniversalString_encode_xer, /* Convert into UTF-8 */ - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_UniversalString_tags, - sizeof(asn_DEF_UniversalString_tags) -Index: skeletons/GraphicString.c -=================================================================== ---- skeletons/GraphicString.c (revision 1516) -+++ skeletons/GraphicString.c (working copy) -@@ -24,6 +24,8 @@ - OCTET_STRING_encode_xer, /* Can't expect it to be ASCII/UTF8 */ - OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_GraphicString_tags, - sizeof(asn_DEF_GraphicString_tags) -Index: skeletons/GeneralizedTime.c -=================================================================== ---- skeletons/GeneralizedTime.c (revision 1516) -+++ skeletons/GeneralizedTime.c (working copy) -@@ -167,6 +167,8 @@ - GeneralizedTime_encode_xer, - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_GeneralizedTime_tags, - sizeof(asn_DEF_GeneralizedTime_tags) -Index: libasn1compiler/asn1c_out.h -=================================================================== ---- libasn1compiler/asn1c_out.h (revision 1516) -+++ libasn1compiler/asn1c_out.h (working copy) -@@ -117,16 +117,24 @@ - * Format LONG_MIN according to C90 rules. - */ - #define OINT(iv) do { \ -- if(iv == (-2147483647L - 1)) \ -+ if(iv > 4294967295U) \ -+ OUT("%" PRIdASN"ULL", iv); \ -+ else if(iv > 2147483647L) \ -+ OUT("%" PRIdASN"U", iv); \ -+ else if(iv == (-2147483647L - 1)) \ - OUT("(-2147483647L - 1)"); \ -- else \ -+ else \ - OUT("%" PRIdASN, iv); \ - } while(0) - - #define OINTS(iv) do { \ -- if(iv == (-2147483647L - 1)) \ -+ if(iv > 4294967295U) \ -+ OUT("%" PRIdASN"ULL", iv); \ -+ else if(iv > 2147483647L) \ -+ OUT("%" PRIdASN"U", iv); \ -+ else if(iv == (-2147483647L - 1)) \ - OUT("(-2147483647L - 1)"); \ -- else \ -+ else \ - OUT("% " PRIdASN, iv); \ - } while(0) - -Index: libasn1compiler/asn1compiler.h -=================================================================== ---- libasn1compiler/asn1compiler.h (revision 1516) -+++ libasn1compiler/asn1compiler.h (working copy) -@@ -77,7 +77,14 @@ - * -fline-refs - * Include ASN.1 module's line numbers in comments. - */ -- A1C_LINE_REFS = 0x20000 -+ A1C_LINE_REFS = 0x20000, -+ /* -+ * -fhave_native64 -+ * Assume target platform has native 64bits support and generate types using -+ * int64_t or uint64_t whereas possible -+ */ -+ A1C_HAVE_NATIVE_64 = 0x40000 -+ - }; - - /* -Index: libasn1compiler/asn1c_C.c -=================================================================== ---- libasn1compiler/asn1c_C.c (revision 1516) -+++ libasn1compiler/asn1c_C.c (working copy) -@@ -1242,6 +1242,8 @@ - OUT("td->xer_encoder = asn_DEF_%s.xer_encoder;\n", type_name); - OUT("td->uper_decoder = asn_DEF_%s.uper_decoder;\n", type_name); - OUT("td->uper_encoder = asn_DEF_%s.uper_encoder;\n", type_name); -+ OUT("td->aper_decoder = asn_DEF_%s.aper_decoder;\n", type_name); -+ OUT("td->aper_encoder = asn_DEF_%s.aper_encoder;\n", type_name); - if(!terminal && !tags_count) { - OUT("/* The next four lines are here because of -fknown-extern-type */\n"); - OUT("td->tags = asn_DEF_%s.tags;\n", type_name); -@@ -1394,6 +1396,38 @@ - ); - OUT("}\n"); - OUT("\n"); -+ -+ p = MKID(expr); -+ if(HIDE_INNER_DEFS) OUT("static "); -+ OUT("asn_enc_rval_t\n"); -+ OUT("%s", p); -+ if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index); -+ OUT("_encode_aper(asn_TYPE_descriptor_t *td,\n"); -+ INDENTED( -+ OUT("\tasn_per_constraints_t *constraints,\n"); -+ OUT("\tvoid *structure, asn_per_outp_t *per_out) {\n"); -+ OUT("%s_%d_inherit_TYPE_descriptor(td);\n", -+ p, expr->_type_unique_index); -+ OUT("return td->aper_encoder(td, constraints, structure, per_out);\n"); -+ ); -+ OUT("}\n"); -+ OUT("\n"); -+ -+ p = MKID(expr); -+ -+ if(HIDE_INNER_DEFS) OUT("static "); -+ OUT("asn_dec_rval_t\n"); -+ OUT("%s", p); -+ if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index); -+ OUT("_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,\n"); -+ INDENTED( -+ OUT("\tasn_per_constraints_t *constraints, void **structure, asn_per_data_t *per_data) {\n"); -+ OUT("%s_%d_inherit_TYPE_descriptor(td);\n", -+ p, expr->_type_unique_index); -+ OUT("return td->aper_decoder(opt_codec_ctx, td, constraints, structure, per_data);\n"); -+ ); -+ OUT("}\n"); -+ OUT("\n"); - } - - REDIR(OT_FUNC_DECLS); -@@ -1415,6 +1449,8 @@ - if(arg->flags & A1C_GEN_PER) { - OUT("per_type_decoder_f %s_decode_uper;\n", p); - OUT("per_type_encoder_f %s_encode_uper;\n", p); -+ OUT("per_type_decoder_f %s_decode_aper;\n", p); -+ OUT("per_type_encoder_f %s_encode_aper;\n", p); - } - } - -@@ -1670,12 +1706,11 @@ - OUT("%d, ", tag2el[i].el_no); - OUT("%d, ", tag2el[i].toff_first); - OUT("%d ", tag2el[i].toff_last); -- OUT("}%s /* %s", -+ OUT("}%s /* %s at %d */\n", - (i + 1 < tag2el_count) ? "," : "", -- tag2el[i].from_expr->Identifier); -- if(arg->flags & A1C_LINE_REFS) -- OUT("at %d", tag2el[i].from_expr->_lineno); -- OUT(" */\n"); -+ tag2el[i].from_expr->Identifier, -+ tag2el[i].from_expr->_lineno -+ ); - } - OUT("};\n"); - -@@ -2111,19 +2146,22 @@ - try_inline_default(arg_t *arg, asn1p_expr_t *expr, int out) { - int save_target = arg->target->target; - asn1p_expr_type_e etype = expr_get_type(arg, expr); -- int fits_long = 0; -+// int fits_long = 0; -+ enum asn1c_fitslong_e fits = FL_NOTFIT; - - switch(etype) { - case ASN_BASIC_BOOLEAN: -- fits_long = 1; -+// fits_long = 1; -+ fits = FL_FITS_SIGNED; - case ASN_BASIC_INTEGER: - case ASN_BASIC_ENUMERATED: - if(expr->marker.default_value == NULL - || expr->marker.default_value->type != ATV_INTEGER) - break; -- if(!fits_long) -- fits_long = asn1c_type_fits_long(arg, expr)!=FL_NOTFIT; -- if(fits_long && !expr->marker.default_value->value.v_integer) -+ if(fits == FL_NOTFIT) -+// fits_long = asn1c_type_fits_long(arg, expr)!=FL_NOTFIT; -+ fits = asn1c_type_fits_long(arg, expr); -+ if(fits != FL_NOTFIT && !expr->marker.default_value->value.v_integer) - expr->marker.flags &= ~EM_INDIRECT; - if(!out) { - OUT("asn_DFL_%d_set_%" PRIdASN -@@ -2150,7 +2188,7 @@ - INDENT(+1); - OUT("/* Install default value %" PRIdASN " */\n", - expr->marker.default_value->value.v_integer); -- if(fits_long) { -+ if(fits != FL_NOTFIT) { - OUT("*st = "); - OINT(expr->marker.default_value->value.v_integer); - OUT(";\n"); -@@ -2165,7 +2203,7 @@ - INDENT(+1); - OUT("/* Test default value %" PRIdASN " */\n", - expr->marker.default_value->value.v_integer); -- if(fits_long) { -+ if(fits != FL_NOTFIT) { - OUT("return (*st == %" PRIdASN ");\n", - expr->marker.default_value->value.v_integer); - } else { -@@ -2455,9 +2493,13 @@ - if(arg->flags & A1C_GEN_PER) { - FUNCREF(decode_uper); - FUNCREF(encode_uper); -+ FUNCREF(decode_aper); -+ FUNCREF(encode_aper); - } else { -- OUT("0, 0,\t/* No PER support, " -+ OUT("0, 0,\t/* No UPER support, " - "use \"-gen-PER\" to enable */\n"); -+ OUT("0, 0,\t/* No APER support, " -+ "use \"-gen-PER\" to enable */\n"); - } - - if(!terminal || terminal->expr_type == ASN_CONSTR_CHOICE) { -Index: libasn1compiler/asn1c_constraint.c -=================================================================== ---- libasn1compiler/asn1c_constraint.c (revision 1516) -+++ libasn1compiler/asn1c_constraint.c (working copy) -@@ -35,6 +35,7 @@ - int alphabet_table_compiled; - int produce_st = 0; - int ulong_optimize = 0; -+ enum asn1c_fitslong_e fits = FL_NOTFIT; - - ct = expr->combined_constraints; - if(ct == NULL) -@@ -74,7 +75,8 @@ - switch(etype) { - case ASN_BASIC_INTEGER: - case ASN_BASIC_ENUMERATED: -- if(asn1c_type_fits_long(arg, arg->expr) == FL_NOTFIT) -+ fits = asn1c_type_fits_long(arg, arg->expr); -+ if(fits == FL_NOTFIT) - produce_st = 1; - break; - case ASN_BASIC_REAL: -@@ -103,13 +105,19 @@ - switch(etype) { - case ASN_BASIC_INTEGER: - case ASN_BASIC_ENUMERATED: -- if(native_long_sign(r_value) >= 0) { -- ulong_optimize = ulong_optimization(etype, r_size, r_value); -- if(!ulong_optimize) { -- OUT("unsigned long value;\n"); -+ if(fits == FL_FITS_INT64) { -+ OUT("int64_t value;\n"); -+ } else if(fits == FL_FITS_UINT64) { -+ OUT("uint64_t value;\n"); -+ } else { -+ if(native_long_sign(r_value) >= 0) { -+ ulong_optimize = ulong_optimization(etype, r_size, r_value); -+ if(!ulong_optimize) { -+ OUT("unsigned long value;\n"); -+ } -+ } else { -+ OUT("long value;\n"); - } -- } else { -- OUT("long value;\n"); - } - break; - case ASN_BASIC_REAL: -@@ -603,13 +611,19 @@ - - static int - emit_value_determination_code(arg_t *arg, asn1p_expr_type_e etype, asn1cnst_range_t *r_value) { -+ enum asn1c_fitslong_e fits = FL_NOTFIT; - - switch(etype) { - case ASN_BASIC_INTEGER: - case ASN_BASIC_ENUMERATED: -- if(asn1c_type_fits_long(arg, arg->expr) == FL_FITS_UNSIGN) { -+ fits = asn1c_type_fits_long(arg, arg->expr); -+ if(fits == FL_FITS_INT64) { -+ OUT("value = *(const int64_t *)sptr;\n"); -+ } else if(fits == FL_FITS_UINT64) { -+ OUT("value = *(const uint64_t *)sptr;\n"); -+ } else if(fits == FL_FITS_UNSIGN) { - OUT("value = *(const unsigned long *)sptr;\n"); -- } else if(asn1c_type_fits_long(arg, arg->expr) != FL_NOTFIT) { -+ } else if(fits != FL_NOTFIT) { - OUT("value = *(const long *)sptr;\n"); - } else { - /* -Index: libasn1compiler/asn1c_misc.c -=================================================================== ---- libasn1compiler/asn1c_misc.c (revision 1516) -+++ libasn1compiler/asn1c_misc.c (working copy) -@@ -158,6 +158,7 @@ - asn1p_expr_t *terminal; - int stdname = 0; - char *typename; -+ enum asn1c_fitslong_e fits; - - /* Rewind to the topmost parent expression */ - if((top_parent = expr->parent_expr)) -@@ -213,15 +214,20 @@ - case ASN_BASIC_INTEGER: - case ASN_BASIC_ENUMERATED: - case ASN_BASIC_REAL: -+ fits = asn1c_type_fits_long(arg, expr); - if((expr->expr_type == ASN_BASIC_REAL - && !(arg->flags & A1C_USE_WIDE_TYPES)) -- || asn1c_type_fits_long(arg, expr)) { -+ || (fits != FL_NOTFIT)) { - switch(_format) { - case TNF_CTYPE: - case TNF_RSAFE: - if(expr->expr_type == ASN_BASIC_REAL) - return "double"; -- else if(asn1c_type_fits_long(arg, expr) == FL_FITS_UNSIGN) -+ else if (fits == FL_FITS_INT64) -+ return "int64_t"; -+ else if (fits == FL_FITS_UINT64) -+ return "uint64_t"; -+ else if(fits == FL_FITS_UNSIGN) - return "unsigned long"; - else - return "long"; -@@ -377,11 +383,33 @@ - /* Special case for unsigned */ - if(left.type == ARE_VALUE - && left.value >= 0 -- && right.type == ARE_VALUE -+ && right.type == ARE_VALUE - && right.value > 2147483647 - && right.value <= 4294967295UL) - return FL_FITS_UNSIGN; -- -+ /* Special for native 64 bits integer option */ -+ if (arg->flags & A1C_HAVE_NATIVE_64) { -+// printf("left.value %lld right.value %lld\n", left.value, right.value); -+ if(left.type == ARE_VALUE -+ && left.value >= 0 -+ && right.type == ARE_VALUE -+ && right.value > 9223372036854775807LL -+ && right.value <= 18446744073709551615ULL) -+ return FL_FITS_UINT64; -+ if(left.type == ARE_VALUE -+ && left.value < -2147483648 -+ && left.value >= -9223372036854775808LL -+ && right.type == ARE_VALUE -+ && right.value > 2147483647 -+ && right.value <= 9223372036854775807LL) -+ return FL_FITS_INT64; -+ if(left.type == ARE_VALUE -+ && left.value >= 0 -+ && right.type == ARE_VALUE -+ && right.value > 4294967295UL -+ && right.value <= 9223372036854775807LL) -+ return FL_FITS_INT64; -+ } - - /* If some fixed value is outside of target range, not fit */ - if(left.type == ARE_VALUE -Index: libasn1compiler/asn1c_misc.h -=================================================================== ---- libasn1compiler/asn1c_misc.h (revision 1516) -+++ libasn1compiler/asn1c_misc.h (working copy) -@@ -36,6 +36,8 @@ - */ - enum asn1c_fitslong_e { - FL_NOTFIT, -+ FL_FITS_INT64, -+ FL_FITS_UINT64, - FL_FITS_SIGNED, - FL_FITS_UNSIGN, - FL_PRESUMED, diff --git a/openair3/S1AP/MESSAGES/ASN1/asn1cpatch_2.p0 b/openair3/S1AP/MESSAGES/ASN1/asn1cpatch_2.p0 deleted file mode 100644 index 80835b1b86621a62fde0dda589135082c142ed93..0000000000000000000000000000000000000000 --- a/openair3/S1AP/MESSAGES/ASN1/asn1cpatch_2.p0 +++ /dev/null @@ -1,22 +0,0 @@ ---- skeletons/OCTET_STRING.c.orig 2015-04-28 10:40:04.036970492 +0200 -+++ skeletons/OCTET_STRING.c 2015-04-28 10:40:09.619970869 +0200 -@@ -159,7 +159,7 @@ - } - - static struct _stack * --_new_stack() { -+_new_stack(void) { - return (struct _stack *)CALLOC(1, sizeof(struct _stack)); - } - ---- skeletons/converter-sample.c.orig 2015-04-28 10:40:32.164972391 +0200 -+++ skeletons/converter-sample.c 2015-04-28 10:40:37.140972727 +0200 -@@ -353,7 +353,7 @@ - } DynamicBuffer; - - static void --buffer_dump() { -+buffer_dump(void) { - uint8_t *p = DynamicBuffer.data + DynamicBuffer.offset; - uint8_t *e = p + DynamicBuffer.length - (DynamicBuffer.unbits ? 1 : 0); - if(!opt_debug) return; diff --git a/openair3/S1AP/MESSAGES/ASN1/asn1cpatch_3.p0 b/openair3/S1AP/MESSAGES/ASN1/asn1cpatch_3.p0 deleted file mode 100644 index d5a936c1018b9d3bcc96d06d532c3cddbec911d4..0000000000000000000000000000000000000000 --- a/openair3/S1AP/MESSAGES/ASN1/asn1cpatch_3.p0 +++ /dev/null @@ -1,1264 +0,0 @@ ---- asn1c/unber.c 2015-12-08 14:39:33.282543533 +0100 -+++ asn1c/unber.c 2015-12-07 10:46:18.382647000 +0100 -@@ -779,4 +779,6 @@ - - asn_enc_rval_t OCTET_STRING_encode_aper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *cts, void *sptr, asn_per_outp_t *po) { asn_enc_rval_t er = { 0, 0, 0 }; (void)td; (void)cts; (void)sptr; (void)po; return er; } - -+asn_comp_rval_t * OCTET_STRING_compare(asn_TYPE_descriptor_t *td1, const void *sptr1, asn_TYPE_descriptor_t *td2, const void *sptr2) { (void)td1; (void)sptr1; (void)td2; (void)sptr2; return 0; } -+ - size_t xer_whitespace_span(const void *chunk_buf, size_t chunk_size) { (void)chunk_buf; (void)chunk_size; return 0; } ---- libasn1compiler/asn1c_C.c 2015-12-08 14:39:33.366543533 +0100 -+++ libasn1compiler/asn1c_C.c 2015-12-08 08:38:29.002565000 +0100 -@@ -1082,6 +1082,8 @@ - enum tvm_compat tv_mode; - enum etd_spec etd_spec; - char *p; -+ //char tmp_buf[512]; -+ //int i = 0; - - if(arg->embed) { - enum tnfmt tnfmt = TNF_CTYPE; -@@ -1243,7 +1245,8 @@ - OUT("td->uper_decoder = asn_DEF_%s.uper_decoder;\n", type_name); - OUT("td->uper_encoder = asn_DEF_%s.uper_encoder;\n", type_name); - OUT("td->aper_decoder = asn_DEF_%s.aper_decoder;\n", type_name); -- OUT("td->aper_encoder = asn_DEF_%s.aper_encoder;\n", type_name); -+ OUT("td->aper_encoder = asn_DEF_%s.aper_encoder;\n", type_name); -+ OUT("td->compare = asn_DEF_%s.compare;\n", type_name); - if(!terminal && !tags_count) { - OUT("/* The next four lines are here because of -fknown-extern-type */\n"); - OUT("td->tags = asn_DEF_%s.tags;\n", type_name); -@@ -1413,6 +1416,39 @@ - OUT("}\n"); - OUT("\n"); - -+ -+ //i = 0; -+ //while ((p[i] != '_') && (i < sizeof(tmp_buf))) { -+ // tmp_buf[i] = p[i]; -+ // i++; -+ //} -+ //tmp_buf[i] = '\0'; -+ // hack, only for s1ap -+ //if ((strcmp("S1ap", tmp_buf) == 0) || (strcmp("X2ap", tmp_buf) == 0)) -+ // OUT("#include \"%s-ProtocolIE-ID.h\"\n", tmp_buf); -+ -+ -+ p = MKID(expr); -+ if(HIDE_INNER_DEFS) OUT("static "); -+ OUT("asn_comp_rval_t * \n"); -+ OUT("%s", p); -+ if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index); -+ OUT("_compare(asn_TYPE_descriptor_t *td1,\n"); -+ INDENTED( -+ OUT("\tconst void *structure1,\n"); -+ OUT("\tasn_TYPE_descriptor_t *td2,\n"); -+ OUT("\tconst void *structure2) {\n"); -+ OUT("asn_comp_rval_t * res = NULL;\n"); -+ OUT("%s_%d_inherit_TYPE_descriptor(td1);\n", -+ p, expr->_type_unique_index); -+ OUT("%s_%d_inherit_TYPE_descriptor(td2);\n", -+ p, expr->_type_unique_index); -+ OUT("res = td1->compare(td1, structure1, td2, structure2);\n"); -+ OUT("return res;\n"); -+ ); -+ OUT("}\n"); -+ OUT("\n"); -+ - p = MKID(expr); - - if(HIDE_INNER_DEFS) OUT("static "); -@@ -1450,7 +1486,8 @@ - OUT("per_type_decoder_f %s_decode_uper;\n", p); - OUT("per_type_encoder_f %s_encode_uper;\n", p); - OUT("per_type_decoder_f %s_decode_aper;\n", p); -- OUT("per_type_encoder_f %s_encode_aper;\n", p); -+ OUT("per_type_encoder_f %s_encode_aper;\n", p); -+ OUT("type_compare_f %s_compare;\n", p); - } - } - -@@ -2501,6 +2538,7 @@ - OUT("0, 0,\t/* No APER support, " - "use \"-gen-PER\" to enable */\n"); - } -+ FUNCREF(compare); - - if(!terminal || terminal->expr_type == ASN_CONSTR_CHOICE) { - //if(expr->expr_type == ASN_CONSTR_CHOICE) { ---- skeletons/ANY.c 2015-12-08 14:39:33.350543533 +0100 -+++ skeletons/ANY.c 2015-11-26 14:40:56.547616000 +0100 -@@ -24,7 +24,8 @@ - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, - OCTET_STRING_decode_aper, -- OCTET_STRING_encode_aper, -+ OCTET_STRING_encode_aper, -+ OCTET_STRING_compare, - 0, /* Use generic outmost tag fetcher */ - 0, 0, 0, 0, - 0, /* No PER visible constraints */ ---- skeletons/asn_application.h 2015-12-08 14:39:12.674543554 +0100 -+++ skeletons/asn_application.h 2015-12-07 14:36:32.950633000 +0100 -@@ -9,7 +9,8 @@ - #define _ASN_APPLICATION_H_ - - #include "asn_system.h" /* for platform-dependent types */ --#include "asn_codecs.h" /* for ASN.1 codecs specifics */ -+#include "asn_codecs.h" /* for ASN.1 codecs specifics */ -+#include "asn_compare.h" - - #ifdef __cplusplus - extern "C" { ---- skeletons/asn_compare.h 1970-01-01 01:00:00.000000000 +0100 -+++ skeletons/asn_compare.h 2015-12-08 10:34:58.090558000 +0100 -@@ -0,0 +1,78 @@ -+#ifndef _ASN_COMPARE_H_ -+#define _ASN_COMPARE_H_ -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+struct asn_TYPE_descriptor_s; /* Forward declaration */ -+ -+ -+typedef enum COMPARE_ERR_CODE_e { -+ COMPARE_ERR_CODE_START = 0, -+ COMPARE_ERR_CODE_NONE = COMPARE_ERR_CODE_START, -+ COMPARE_ERR_CODE_NO_MATCH, -+ COMPARE_ERR_CODE_TYPE_MISMATCH, -+ COMPARE_ERR_CODE_TYPE_ARG_NULL, -+ COMPARE_ERR_CODE_VALUE_NULL, -+ COMPARE_ERR_CODE_VALUE_ARG_NULL, -+ COMPARE_ERR_CODE_CHOICE_NUM, -+ COMPARE_ERR_CODE_CHOICE_PRESENT, -+ COMPARE_ERR_CODE_CHOICE_MALFORMED, -+ COMPARE_ERR_CODE_SET_MALFORMED, -+ COMPARE_ERR_CODE_COLLECTION_NUM_ELEMENTS, -+ COMPARE_ERR_CODE_END -+} COMPARE_ERR_CODE_t; -+ -+typedef struct asn_comp_rval_s { -+ enum COMPARE_ERR_CODE_e err_code; -+ char *name; // e_S1ap_ProtocolIE_ID not available for all ASN1 use (RRC vs S1AP, X2AP) -+ const void *structure1; -+ const void *structure2; -+ struct asn_comp_rval_s *next; -+} asn_comp_rval_t; -+ -+#define COMPARE_CHECK_ARGS(aRg_tYpE_dEf1, aRg_tYpE_dEf2, aRg_vAl1, aRg_vAl2, rEsUlT) \ -+ do {\ -+ if ((aRg_tYpE_dEf1) && (aRg_tYpE_dEf2)) {\ -+ if ((aRg_tYpE_dEf1->name) && (aRg_tYpE_dEf2->name)) {\ -+ if (strcmp(aRg_tYpE_dEf1->name, aRg_tYpE_dEf2->name)) {\ -+ rEsUlT = (asn_comp_rval_t *)calloc(1, sizeof(asn_comp_rval_t));\ -+ rEsUlT->err_code = COMPARE_ERR_CODE_TYPE_MISMATCH;\ -+ rEsUlT->name = aRg_tYpE_dEf1->name;\ -+ return rEsUlT;\ -+ }\ -+ } else {\ -+ if ((aRg_tYpE_dEf1->xml_tag) && (aRg_tYpE_dEf2->xml_tag)) {\ -+ if (strcmp(aRg_tYpE_dEf1->xml_tag, aRg_tYpE_dEf2->xml_tag)) {\ -+ rEsUlT = (asn_comp_rval_t *)calloc(1, sizeof(asn_comp_rval_t));\ -+ rEsUlT->err_code = COMPARE_ERR_CODE_TYPE_MISMATCH;\ -+ rEsUlT->name = aRg_tYpE_dEf1->xml_tag;\ -+ return rEsUlT;\ -+ }\ -+ }\ -+ }\ -+ } else {\ -+ rEsUlT = (asn_comp_rval_t *)calloc(1, sizeof(asn_comp_rval_t));\ -+ rEsUlT->name = aRg_tYpE_dEf1->name;\ -+ rEsUlT->structure1 = aRg_vAl1;\ -+ rEsUlT->structure2 = aRg_vAl2;\ -+ rEsUlT->err_code = COMPARE_ERR_CODE_TYPE_ARG_NULL;\ -+ return rEsUlT;\ -+ }\ -+ if ((NULL == aRg_vAl1) || (NULL == aRg_vAl2)){\ -+ rEsUlT = (asn_comp_rval_t *)calloc(1, sizeof(asn_comp_rval_t));\ -+ rEsUlT->name = aRg_tYpE_dEf1->name;\ -+ rEsUlT->structure1 = aRg_vAl1;\ -+ rEsUlT->structure2 = aRg_vAl2;\ -+ rEsUlT->err_code = COMPARE_ERR_CODE_VALUE_ARG_NULL;\ -+ return rEsUlT;\ -+ }\ -+ } while (0); -+ -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* _ASN_COMPARE_H_ */ ---- skeletons/BIT_STRING.c 2015-12-08 14:39:33.346543533 +0100 -+++ skeletons/BIT_STRING.c 2015-11-26 14:41:50.159616000 +0100 -@@ -30,7 +30,8 @@ - OCTET_STRING_decode_uper, /* Unaligned PER decoder */ - OCTET_STRING_encode_uper, /* Unaligned PER encoder */ - OCTET_STRING_decode_aper, /* Aligned PER decoder */ -- OCTET_STRING_encode_aper, /* Aligned PER encoder */ -+ OCTET_STRING_encode_aper, /* Aligned PER encoder */ -+ OCTET_STRING_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_BIT_STRING_tags, - sizeof(asn_DEF_BIT_STRING_tags) ---- skeletons/BMPString.c 2015-12-08 14:39:33.338543533 +0100 -+++ skeletons/BMPString.c 2015-11-26 14:42:08.487616000 +0100 -@@ -36,7 +36,8 @@ - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, - OCTET_STRING_decode_aper, /* Aligned PER decoder */ -- OCTET_STRING_encode_aper, /* Aligned PER encoder */ -+ OCTET_STRING_encode_aper, /* Aligned PER encoder */ -+ OCTET_STRING_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_BMPString_tags, - sizeof(asn_DEF_BMPString_tags) ---- skeletons/BOOLEAN.c 2015-12-08 14:39:33.342543533 +0100 -+++ skeletons/BOOLEAN.c 2015-12-08 10:37:11.866558000 +0100 -@@ -25,7 +25,8 @@ - BOOLEAN_decode_uper, /* Unaligned PER decoder */ - BOOLEAN_encode_uper, /* Unaligned PER encoder */ - BOOLEAN_decode_aper, /* Aligned PER decoder */ -- BOOLEAN_encode_aper, /* Aligned PER encoder */ -+ BOOLEAN_encode_aper, /* Aligned PER encoder */ -+ BOOLEAN_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_BOOLEAN_tags, - sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]), -@@ -326,3 +327,22 @@ - - _ASN_ENCODED_OK(er); - } -+ -+asn_comp_rval_t * -+BOOLEAN_compare(asn_TYPE_descriptor_t *td1, -+ const void *sptr1, asn_TYPE_descriptor_t *td2, const void *sptr2) { -+ const BOOLEAN_t *st1 = (const BOOLEAN_t *)sptr1; -+ const BOOLEAN_t *st2 = (const BOOLEAN_t *)sptr2; -+ asn_comp_rval_t *res = NULL; -+ -+ COMPARE_CHECK_ARGS(td1, td2, sptr1, sptr2, res) -+ -+ if (*st1 == *st2) return NULL; -+ res = calloc(1, sizeof(asn_comp_rval_t)); -+ res->name = td1->name; -+ res->structure1 = sptr1; -+ res->structure2 = sptr2; -+ res->err_code = COMPARE_ERR_CODE_NO_MATCH; -+ return res; -+} -+ ---- skeletons/BOOLEAN.h 2015-12-08 14:39:33.342543533 +0100 -+++ skeletons/BOOLEAN.h 2015-11-26 12:46:58.491623000 +0100 -@@ -30,6 +30,7 @@ - per_type_encoder_f BOOLEAN_encode_uper; - per_type_decoder_f BOOLEAN_decode_aper; - per_type_encoder_f BOOLEAN_encode_aper; -+type_compare_f BOOLEAN_compare; - - #ifdef __cplusplus - } ---- skeletons/compare.h 1970-01-01 01:00:00.000000000 +0100 -+++ skeletons/compare.h 2015-12-08 08:23:03.694566000 +0100 -@@ -0,0 +1,28 @@ -+/*- -+ * Eurecom 2015. -+ */ -+#ifndef _COMPARE_H_ -+#define _COMPARE_H_ -+ -+#include <asn_application.h> -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+struct asn_TYPE_descriptor_s; /* Forward declaration */ -+ -+typedef asn_comp_rval_t * (type_compare_f)( -+ struct asn_TYPE_descriptor_s *type_descriptor1, -+ const void *struct_ptr1, -+ struct asn_TYPE_descriptor_s *type_descriptor2, -+ const void *struct_ptr2 -+); -+ -+ -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* _COMPARE_H_ */ ---- skeletons/constr_CHOICE.c 2015-12-08 14:39:33.342543533 +0100 -+++ skeletons/constr_CHOICE.c 2015-12-08 10:39:16.670558000 +0100 -@@ -1272,3 +1272,75 @@ - assert(pres_size != sizeof(int)); - } - } -+ -+asn_comp_rval_t * -+CHOICE_compare(asn_TYPE_descriptor_t *td1, const void *sptr1, asn_TYPE_descriptor_t *td2, const void *sptr2) -+{ -+ asn_CHOICE_specifics_t *specs1 = (asn_CHOICE_specifics_t *)td1->specifics; -+ asn_CHOICE_specifics_t *specs2 = (asn_CHOICE_specifics_t *)td2->specifics; -+ int present1; -+ int present2; -+ asn_comp_rval_t *res = NULL; -+ -+ COMPARE_CHECK_ARGS(td1, td2, sptr1, sptr2, res) -+ -+ /* -+ * Figure out which CHOICE element is encoded. -+ */ -+ present1 = _fetch_present_idx(sptr1, specs1->pres_offset,specs1->pres_size); -+ // same specs -+ present2 = _fetch_present_idx(sptr2, specs2->pres_offset,specs2->pres_size); -+ -+ if (td1->elements_count != td2->elements_count) { -+ res = calloc(1, sizeof(asn_comp_rval_t)); -+ res->name = td1->name; -+ res->structure1 = sptr1; -+ res->structure2 = sptr2; -+ res->err_code = COMPARE_ERR_CODE_CHOICE_NUM; -+ return res; -+ } -+ if (present1 != present2) { -+ res = calloc(1, sizeof(asn_comp_rval_t)); -+ res->name = td1->name; -+ res->structure1 = sptr1; -+ res->structure2 = sptr2; -+ res->err_code = COMPARE_ERR_CODE_CHOICE_PRESENT; -+ return res; -+ } -+ if(present1 > 0 && present1 <= td1->elements_count) { -+ asn_TYPE_member_t *elm1 = &td1->elements[present1-1]; -+ asn_TYPE_member_t *elm2 = &td2->elements[present2-1]; -+ const void *memb_ptr1; -+ const void *memb_ptr2; -+ -+ if((elm1->flags & ATF_POINTER) && (elm1->flags & ATF_POINTER)){ -+ memb_ptr1 = *(const void * const *)((const char *)sptr1 + elm1->memb_offset); -+ memb_ptr2 = *(const void * const *)((const char *)sptr2 + elm2->memb_offset); -+ if((!memb_ptr1) || (!memb_ptr2)) { -+ res = calloc(1, sizeof(asn_comp_rval_t)); -+ res->name = td1->name; -+ res->structure1 = sptr1; -+ res->structure2 = sptr2; -+ res->err_code = COMPARE_ERR_CODE_VALUE_NULL; -+ return res; -+ } -+ } else if (!(elm1->flags & ATF_POINTER) && !(elm1->flags & ATF_POINTER)){ -+ memb_ptr1 = (const void *)((const char *)sptr1 + elm1->memb_offset); -+ memb_ptr2 = (const void *)((const char *)sptr2 + elm2->memb_offset); -+ } else { -+ res = calloc(1, sizeof(asn_comp_rval_t)); -+ res->name = td1->name; -+ res->structure1 = sptr1; -+ res->structure2 = sptr2; -+ res->err_code = COMPARE_ERR_CODE_CHOICE_MALFORMED; -+ return res; -+ } -+ return elm1->type->compare(elm1->type, memb_ptr1, elm2->type, memb_ptr2); -+ } -+ res = calloc(1, sizeof(asn_comp_rval_t)); -+ res->name = td1->name; -+ res->structure1 = sptr1; -+ res->structure2 = sptr2; -+ res->err_code = COMPARE_ERR_CODE_CHOICE_MALFORMED; -+ return res; -+} ---- skeletons/constr_CHOICE.h 2015-12-08 14:39:33.342543533 +0100 -+++ skeletons/constr_CHOICE.h 2015-11-26 14:43:57.647616000 +0100 -@@ -39,7 +39,7 @@ - /* - * A set specialized functions dealing with the CHOICE type. - */ --asn_struct_free_f CHOICE_free; -+asn_struct_free_f CHOICE_free; - asn_struct_print_f CHOICE_print; - asn_constr_check_f CHOICE_constraint; - ber_type_decoder_f CHOICE_decode_ber; -@@ -50,7 +50,8 @@ - per_type_encoder_f CHOICE_encode_uper; - per_type_decoder_f CHOICE_decode_aper; - per_type_encoder_f CHOICE_encode_aper; --asn_outmost_tag_f CHOICE_outmost_tag; -+type_compare_f CHOICE_compare; -+asn_outmost_tag_f CHOICE_outmost_tag; - - #ifdef __cplusplus - } ---- skeletons/constr_SEQUENCE.c 2015-12-08 14:39:33.346543533 +0100 -+++ skeletons/constr_SEQUENCE.c 2015-12-08 10:39:52.442558000 +0100 -@@ -1761,3 +1761,65 @@ - - _ASN_ENCODED_OK(er); - } -+ -+asn_comp_rval_t * SEQUENCE_compare(asn_TYPE_descriptor_t *td1, const void *sptr1, asn_TYPE_descriptor_t *td2, const void *sptr2) { -+ int edx; -+ asn_comp_rval_t *res = NULL; -+ asn_comp_rval_t *res2 = NULL; -+ -+ COMPARE_CHECK_ARGS(td1, td2, sptr1, sptr2, res) -+ -+ if (td1->elements_count != td2->elements_count) { -+ res = calloc(1, sizeof(asn_comp_rval_t)); -+ res->name = td1->name; -+ res->structure1 = sptr1; -+ res->structure2 = sptr2; -+ res->err_code = COMPARE_ERR_CODE_COLLECTION_NUM_ELEMENTS; -+ return res; -+ } -+ -+ for(edx = 0; edx < td1->elements_count; edx++) { -+ asn_TYPE_member_t *elm1 = &td1->elements[edx]; -+ asn_TYPE_member_t *elm2 = &td1->elements[edx]; -+ const void *memb_ptr1; -+ const void *memb_ptr2; -+ -+ if(elm1->flags & ATF_POINTER) { -+ memb_ptr1 = *(const void * const *)((const char *)sptr1 + elm1->memb_offset); -+ memb_ptr2 = *(const void * const *)((const char *)sptr2 + elm2->memb_offset); -+ if((!memb_ptr1) && (!memb_ptr2)) { -+ if(elm1->optional) continue; -+ } -+ if ((!memb_ptr1) || (!memb_ptr2)) { -+ res2 = calloc(1, sizeof(asn_comp_rval_t)); -+ res2->name = elm1->name; -+ res2->structure1 = memb_ptr1; -+ res2->structure2 = memb_ptr2; -+ res->err_code = COMPARE_ERR_CODE_VALUE_NULL; -+ if (NULL == res) { -+ res = res2; -+ } else { -+ res2->next = res; -+ res = res2; -+ } -+ res2 = NULL; -+ } -+ } else { -+ memb_ptr1 = (const void *)((const char *)sptr1 + elm1->memb_offset); -+ memb_ptr2 = (const void *)((const char *)sptr2 + elm2->memb_offset); -+ } -+ -+ /* Compare the member itself */ -+ res2 = elm1->type->compare(elm1->type, memb_ptr1, elm2->type, memb_ptr2); -+ if(res2) { -+ if (NULL == res) { -+ res = res2; -+ } else { -+ res2->next = res; -+ res = res2; -+ } -+ res2 = NULL; -+ } -+ } -+ return res; -+} ---- skeletons/constr_SEQUENCE.h 2015-12-08 14:39:33.346543533 +0100 -+++ skeletons/constr_SEQUENCE.h 2015-11-26 14:48:14.123616000 +0100 -@@ -54,6 +54,7 @@ - per_type_encoder_f SEQUENCE_encode_uper; - per_type_decoder_f SEQUENCE_decode_aper; - per_type_encoder_f SEQUENCE_encode_aper; -+type_compare_f SEQUENCE_compare; - - #ifdef __cplusplus - } ---- skeletons/constr_SEQUENCE_OF.h 2015-12-08 14:39:33.342543533 +0100 -+++ skeletons/constr_SEQUENCE_OF.h 2015-11-26 15:05:25.399615000 +0100 -@@ -22,7 +22,8 @@ - #define SEQUENCE_OF_decode_ber SET_OF_decode_ber - #define SEQUENCE_OF_decode_xer SET_OF_decode_xer - #define SEQUENCE_OF_decode_uper SET_OF_decode_uper --#define SEQUENCE_OF_decode_aper SET_OF_decode_aper -+#define SEQUENCE_OF_decode_aper SET_OF_decode_aper -+#define SEQUENCE_OF_compare SET_OF_compare - der_type_encoder_f SEQUENCE_OF_encode_der; - xer_type_encoder_f SEQUENCE_OF_encode_xer; - per_type_encoder_f SEQUENCE_OF_encode_uper; ---- skeletons/constr_SET.c 2015-12-08 14:39:33.342543533 +0100 -+++ skeletons/constr_SET.c 2015-12-08 10:40:35.066558000 +0100 -@@ -1108,7 +1108,7 @@ - } - } - --int -+long - SET_constraint(asn_TYPE_descriptor_t *td, const void *sptr, - asn_app_constraint_failed_f *ctfailcb, void *app_key) { - int edx; -@@ -1159,3 +1159,58 @@ - - return 0; - } -+ -+asn_comp_rval_t * -+SET_compare(asn_TYPE_descriptor_t *td1, const void *sptr1, asn_TYPE_descriptor_t *td2, const void *sptr2) -+{ -+ int edx; -+ asn_comp_rval_t *res = NULL; -+ asn_comp_rval_t *res2 = NULL; -+ -+ COMPARE_CHECK_ARGS(td1, td2, sptr1, sptr2, res) -+ -+ if (td1->elements_count != td2->elements_count) { -+ res = calloc(1, sizeof(asn_comp_rval_t)); -+ res->name = td1->name; -+ res->structure1 = sptr1; -+ res->structure2 = sptr2; -+ res->err_code = COMPARE_ERR_CODE_COLLECTION_NUM_ELEMENTS; -+ return res; -+ } -+ -+ for(edx = 0; edx < td1->elements_count; edx++) { -+ asn_TYPE_member_t *elm1 = &td1->elements[edx]; -+ asn_TYPE_member_t *elm2 = &td2->elements[edx]; -+ const void *memb_ptr1; -+ const void *memb_ptr2; -+ -+ if(elm1->flags & ATF_POINTER) { -+ memb_ptr1 = *(const void * const *)((const char *)sptr1 + elm1->memb_offset); -+ memb_ptr2 = *(const void * const *)((const char *)sptr2 + elm2->memb_offset); -+ if(!memb_ptr1) { -+ if(elm1->optional) -+ continue; -+ res = calloc(1, sizeof(asn_comp_rval_t)); -+ res->name = td1->name; -+ res->structure1 = sptr1; -+ res->structure2 = sptr2; -+ res->err_code = COMPARE_ERR_CODE_SET_MALFORMED; -+ return res; -+ } -+ } else { -+ memb_ptr1 = (const void *)((const char *)sptr1 + elm1->memb_offset); -+ memb_ptr2 = (const void *)((const char *)sptr2 + elm2->memb_offset); -+ } -+ res2 = elm1->type->compare(elm1->type, memb_ptr1, elm2->type, memb_ptr2); -+ if(res2) { -+ if (NULL == res) { -+ res = res2; -+ } else { -+ res2->next = res; -+ res = res2; -+ } -+ res2 = NULL; -+ } -+ } -+ return res; -+} ---- skeletons/constr_SET.h 2015-12-08 14:39:33.342543533 +0100 -+++ skeletons/constr_SET.h 2015-11-26 14:49:09.243616000 +0100 -@@ -56,6 +56,7 @@ - per_type_decoder_f SET_decode_aper; - per_type_encoder_f SET_encode_uper; - per_type_encoder_f SET_encode_aper; -+type_compare_f SET_compare; - - /*********************** - * Some handy helpers. * ---- skeletons/constr_SET_OF.c 2015-12-08 14:39:33.338543533 +0100 -+++ skeletons/constr_SET_OF.c 2015-12-08 10:45:54.466557000 +0100 -@@ -1039,3 +1039,54 @@ - rv.consumed = 0; - return rv; - } -+ -+asn_comp_rval_t * -+SET_OF_compare(asn_TYPE_descriptor_t *td1, const void *sptr1, asn_TYPE_descriptor_t *td2, const void *sptr2) -+{ -+ asn_TYPE_member_t *elm1 = td1->elements; -+ asn_TYPE_member_t *elm2 = td2->elements; -+ const asn_anonymous_set_ *list1 = _A_CSET_FROM_VOID(sptr1); -+ const asn_anonymous_set_ *list2 = _A_CSET_FROM_VOID(sptr2); -+ int i; -+ asn_comp_rval_t *res = NULL; -+ asn_comp_rval_t *res2 = NULL; -+ -+ COMPARE_CHECK_ARGS(td1, td2, sptr1, sptr2, res) -+ -+ if (td1->elements_count != td2->elements_count) { -+ res = calloc(1, sizeof(asn_comp_rval_t)); -+ res->name = td1->name; -+ res->structure1 = sptr1; -+ res->structure2 = sptr2; -+ res->err_code = COMPARE_ERR_CODE_COLLECTION_NUM_ELEMENTS; -+ return res; -+ } -+ -+ -+ if (list1->count != list2->count ) { -+ res = calloc(1, sizeof(asn_comp_rval_t)); -+ res->name = td1->name; -+ res->structure1 = sptr1; -+ res->structure2 = sptr2; -+ res->err_code = COMPARE_ERR_CODE_COLLECTION_NUM_ELEMENTS; -+ return res; -+ } -+ -+ for(i = 0; i < list1->count; i++) { -+ const void *memb_ptr1 = list1->array[i]; -+ const void *memb_ptr2 = list2->array[i]; -+ if ((!memb_ptr1) & (!memb_ptr2)) continue; -+ -+ res2 = elm1->type->compare(elm1->type, memb_ptr1, elm2->type, memb_ptr2); -+ if(res2) { -+ if (NULL == res) { -+ res = res2; -+ } else { -+ res2->next = res; -+ res = res2; -+ } -+ res2 = NULL; -+ } -+ } -+ return res; -+} ---- skeletons/constr_SET_OF.h 2015-12-08 14:39:33.338543533 +0100 -+++ skeletons/constr_SET_OF.h 2015-11-26 14:48:45.067616000 +0100 -@@ -36,6 +36,7 @@ - per_type_encoder_f SET_OF_encode_uper; - per_type_decoder_f SET_OF_decode_aper; - per_type_encoder_f SET_OF_encode_aper; -+type_compare_f SET_OF_compare; - - #ifdef __cplusplus - } ---- skeletons/constr_TYPE.h 2015-12-08 14:39:33.338543533 +0100 -+++ skeletons/constr_TYPE.h 2015-11-26 15:28:05.495613000 +0100 -@@ -41,7 +41,8 @@ - #include <xer_encoder.h> /* Encoder into XER (XML, text) */ - #include <per_decoder.h> /* Packet Encoding Rules decoder */ - #include <per_encoder.h> /* Packet Encoding Rules encoder */ --#include <constraints.h> /* Subtype constraints support */ -+#include <constraints.h> /* Subtype constraints support */ -+#include <compare.h> /* Comparison */ - - /* - * Free the structure according to its specification. -@@ -101,6 +102,7 @@ - per_type_encoder_f *uper_encoder; /* Unaligned PER encoder */ - per_type_decoder_f *aper_decoder; /* Aligned PER decoder */ - per_type_encoder_f *aper_encoder; /* Aligned PER encoder */ -+ type_compare_f *compare; /* Comparison between 2 instances */ - - /*********************************************************************** - * Internally useful members. Not to be used by applications directly. * ---- skeletons/ENUMERATED.c 2015-12-08 14:39:33.342543533 +0100 -+++ skeletons/ENUMERATED.c 2015-12-08 10:40:55.986558000 +0100 -@@ -27,7 +27,8 @@ - ENUMERATED_decode_uper, /* Unaligned PER decoder */ - ENUMERATED_encode_uper, /* Unaligned PER encoder */ - ENUMERATED_decode_aper, /* Aligned PER decoder */ -- ENUMERATED_encode_aper, /* Aligned PER encoder */ -+ ENUMERATED_encode_aper, /* Aligned PER encoder */ -+ ENUMERATED_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_ENUMERATED_tags, - sizeof(asn_DEF_ENUMERATED_tags) / sizeof(asn_DEF_ENUMERATED_tags[0]), -@@ -103,3 +104,22 @@ - - return NativeEnumerated_encode_aper(td, constraints, &value, po); - } -+ -+asn_comp_rval_t * -+ENUMERATED_compare(asn_TYPE_descriptor_t *td1, const void *sptr1, -+ asn_TYPE_descriptor_t *td2, const void *sptr2) { -+ const ENUMERATED_t *st1 = (const ENUMERATED_t *)sptr1; -+ const ENUMERATED_t *st2 = (const ENUMERATED_t *)sptr2; -+ asn_comp_rval_t *res = NULL; -+ -+ COMPARE_CHECK_ARGS(td1, td2, sptr1, sptr2, res) -+ -+ if (*st1 == *st2) return NULL; -+ res = calloc(1, sizeof(asn_comp_rval_t)); -+ res->name = td1->name; -+ res->structure1 = sptr1; -+ res->structure2 = sptr2; -+ res->err_code = COMPARE_ERR_CODE_NO_MATCH; -+ return res; -+} -+ ---- skeletons/ENUMERATED.h 2015-12-08 14:39:33.342543533 +0100 -+++ skeletons/ENUMERATED.h 2015-11-26 12:46:35.523623000 +0100 -@@ -19,6 +19,7 @@ - per_type_encoder_f ENUMERATED_encode_uper; - per_type_decoder_f ENUMERATED_decode_aper; - per_type_encoder_f ENUMERATED_encode_aper; -+type_compare_f ENUMERATED_compare; - - #ifdef __cplusplus - } ---- skeletons/file-dependencies 2015-12-08 14:39:12.678543554 +0100 -+++ skeletons/file-dependencies 2015-12-07 15:34:40.454629000 +0100 -@@ -39,12 +39,13 @@ - constr_SEQUENCE.h constr_SEQUENCE.c - constr_SEQUENCE_OF.h constr_SEQUENCE_OF.c asn_SEQUENCE_OF.h constr_SET_OF.h - constr_SET.h constr_SET.c --constr_SET_OF.h constr_SET_OF.c asn_SET_OF.h -+constr_SET_OF.h constr_SET_OF.c asn_SET_OF.h compare.h - - COMMON-FILES: # THIS IS A SPECIAL SECTION --asn_application.h # Applications should include this file -+asn_application.h # Applications should include this file - asn_system.h # Platform-dependent types --asn_codecs.h # Return types of encoders and decoders -+asn_codecs.h # Return types of encoders and decoders -+asn_compare.h # Return type of compare - asn_internal.h # Internal stuff - OCTET_STRING.h OCTET_STRING.c # This one is used too widely - BIT_STRING.h BIT_STRING.c # This one is necessary for the above one ---- skeletons/GeneralizedTime.c 2015-12-08 14:39:33.350543533 +0100 -+++ skeletons/GeneralizedTime.c 2015-11-26 15:09:03.899615000 +0100 -@@ -168,7 +168,8 @@ - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, - OCTET_STRING_decode_aper, -- OCTET_STRING_encode_aper, -+ OCTET_STRING_encode_aper, -+ OCTET_STRING_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_GeneralizedTime_tags, - sizeof(asn_DEF_GeneralizedTime_tags) ---- skeletons/GeneralString.c 2015-12-08 14:39:33.342543533 +0100 -+++ skeletons/GeneralString.c 2015-11-26 14:50:11.843616000 +0100 -@@ -25,7 +25,8 @@ - OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ - OCTET_STRING_encode_uper, - OCTET_STRING_decode_aper, -- OCTET_STRING_encode_aper, -+ OCTET_STRING_encode_aper, -+ OCTET_STRING_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_GeneralString_tags, - sizeof(asn_DEF_GeneralString_tags) ---- skeletons/GraphicString.c 2015-12-08 14:39:33.350543533 +0100 -+++ skeletons/GraphicString.c 2015-11-26 15:33:33.255613000 +0100 -@@ -25,7 +25,8 @@ - OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ - OCTET_STRING_encode_uper, - OCTET_STRING_decode_aper, -- OCTET_STRING_encode_aper, -+ OCTET_STRING_encode_aper, -+ OCTET_STRING_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_GraphicString_tags, - sizeof(asn_DEF_GraphicString_tags) ---- skeletons/IA5String.c 2015-12-08 14:39:33.342543533 +0100 -+++ skeletons/IA5String.c 2015-11-26 14:50:44.219616000 +0100 -@@ -31,6 +31,7 @@ - OCTET_STRING_encode_uper, - OCTET_STRING_decode_aper, - OCTET_STRING_encode_aper, -+ OCTET_STRING_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_IA5String_tags, - sizeof(asn_DEF_IA5String_tags) ---- skeletons/INTEGER.c 2015-12-08 14:39:33.346543533 +0100 -+++ skeletons/INTEGER.c 2015-12-08 10:41:08.526558000 +0100 -@@ -35,6 +35,7 @@ - INTEGER_decode_aper, - INTEGER_encode_aper, - #endif /* ASN_DISABLE_PER_SUPPORT */ -+ INTEGER_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_INTEGER_tags, - sizeof(asn_DEF_INTEGER_tags) / sizeof(asn_DEF_INTEGER_tags[0]), -@@ -1501,3 +1502,30 @@ - } - - -+asn_comp_rval_t * -+INTEGER_compare(asn_TYPE_descriptor_t *td1, const void *sptr1, -+ asn_TYPE_descriptor_t *td2, const void *sptr2) { -+ const INTEGER_t *st1 = (const INTEGER_t *)sptr1; -+ const INTEGER_t *st2 = (const INTEGER_t *)sptr2; -+ asn_comp_rval_t *res = NULL; -+ -+ COMPARE_CHECK_ARGS(td1, td2, sptr1, sptr2, res) -+ -+ if (st1->size != st2->size) { -+ res = calloc(1, sizeof(asn_comp_rval_t)); -+ res->name = td1->name; -+ res->structure1 = sptr1; -+ res->structure2 = sptr2; -+ res->err_code = COMPARE_ERR_CODE_NO_MATCH; -+ return res; -+ } -+ if (0 != memcmp(st1->buf, st2->buf, st1->size)) { -+ res = calloc(1, sizeof(asn_comp_rval_t)); -+ res->name = td1->name; -+ res->structure1 = sptr1; -+ res->structure2 = sptr2; -+ res->err_code = COMPARE_ERR_CODE_NO_MATCH; -+ return res; -+ } -+ return NULL; -+} ---- skeletons/INTEGER.h 2015-12-08 14:39:33.346543533 +0100 -+++ skeletons/INTEGER.h 2015-11-26 12:50:41.551623000 +0100 -@@ -43,6 +43,7 @@ - per_type_encoder_f INTEGER_encode_uper; - per_type_decoder_f INTEGER_decode_aper; - per_type_encoder_f INTEGER_encode_aper; -+type_compare_f INTEGER_compare; - - /*********************************** - * Some handy conversion routines. * ---- skeletons/ISO646String.c 2015-12-08 14:39:33.342543533 +0100 -+++ skeletons/ISO646String.c 2015-11-26 12:55:48.327623000 +0100 -@@ -30,7 +30,8 @@ - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, - OCTET_STRING_decode_aper, -- OCTET_STRING_encode_aper, -+ OCTET_STRING_encode_aper, -+ OCTET_STRING_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_ISO646String_tags, - sizeof(asn_DEF_ISO646String_tags) ---- skeletons/Makefile.am 2015-12-08 14:39:12.666543554 +0100 -+++ skeletons/Makefile.am 2015-12-07 15:54:00.150628000 +0100 -@@ -46,11 +46,11 @@ - asn_SET_OF.c asn_SET_OF.h \ - asn_application.h asn_codecs.h \ - asn_codecs_prim.c asn_codecs_prim.h \ -- asn_internal.h asn_system.h \ -+ asn_internal.h asn_system.h asn_compare.h \ - ber_decoder.c ber_decoder.h \ - ber_tlv_length.c ber_tlv_length.h \ -- ber_tlv_tag.c ber_tlv_tag.h \ -- constr_CHOICE.c constr_CHOICE.h \ -+ ber_tlv_tag.c ber_tlv_tag.h compare.h \ -+ comparison.h constr_CHOICE.c constr_CHOICE.h \ - constr_SEQUENCE.c constr_SEQUENCE.h \ - constr_SEQUENCE_OF.c constr_SEQUENCE_OF.h \ - constr_SET.c constr_SET.h \ ---- skeletons/NativeEnumerated.c 2015-12-08 14:39:33.342543533 +0100 -+++ skeletons/NativeEnumerated.c 2015-12-08 10:41:17.662558000 +0100 -@@ -31,7 +31,8 @@ - NativeEnumerated_decode_uper, - NativeEnumerated_encode_uper, - NativeEnumerated_decode_aper, -- NativeEnumerated_encode_aper, -+ NativeEnumerated_encode_aper, -+ NativeEnumerated_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_NativeEnumerated_tags, - sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]), -@@ -335,3 +336,22 @@ - - _ASN_ENCODED_OK(er); - } -+ -+asn_comp_rval_t * -+NativeEnumerated_compare(asn_TYPE_descriptor_t *td1, const void *sptr1, -+ asn_TYPE_descriptor_t *td2, const void *sptr2) { -+ const asn_INTEGER_enum_map_t *a = sptr1; -+ const asn_INTEGER_enum_map_t *b = sptr2; -+ asn_comp_rval_t *res = NULL; -+ -+ COMPARE_CHECK_ARGS(td1, td2, sptr1, sptr2, res) -+ -+ if(a->nat_value == b->nat_value) -+ return NULL; -+ res = calloc(1, sizeof(asn_comp_rval_t)); -+ res->name = td1->name; -+ res->structure1 = sptr1; -+ res->structure2 = sptr2; -+ res->err_code = COMPARE_ERR_CODE_NO_MATCH; -+ return res; -+} ---- skeletons/NativeEnumerated.h 2015-12-08 14:39:33.342543533 +0100 -+++ skeletons/NativeEnumerated.h 2015-11-26 14:51:43.315616000 +0100 -@@ -26,6 +26,7 @@ - per_type_encoder_f NativeEnumerated_encode_uper; - per_type_decoder_f NativeEnumerated_decode_aper; - per_type_encoder_f NativeEnumerated_encode_aper; -+type_compare_f NativeEnumerated_compare; - - #ifdef __cplusplus - } ---- skeletons/NativeInteger.c 2015-12-08 14:39:33.346543533 +0100 -+++ skeletons/NativeInteger.c 2015-12-08 10:41:24.550558000 +0100 -@@ -32,7 +32,8 @@ - NativeInteger_decode_uper, /* Unaligned PER decoder */ - NativeInteger_encode_uper, /* Unaligned PER encoder */ - NativeInteger_decode_aper, /* Aligned PER decoder */ -- NativeInteger_encode_aper, /* Aligned PER encoder */ -+ NativeInteger_encode_aper, /* Aligned PER encoder */ -+ NativeInteger_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_NativeInteger_tags, - sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]), -@@ -410,3 +411,21 @@ - } - } - -+ -+asn_comp_rval_t * -+NativeInteger_compare(asn_TYPE_descriptor_t *td1, const void *sptr1, -+ asn_TYPE_descriptor_t *td2, const void *sptr2) { -+ const long *native1 = (const long *)sptr1; -+ const long *native2 = (const long *)sptr2; -+ asn_comp_rval_t *res = NULL; -+ -+ COMPARE_CHECK_ARGS(td1, td2, sptr1, sptr2, res) -+ -+ if (*native1 == *native2) return NULL; -+ res = calloc(1, sizeof(asn_comp_rval_t)); -+ res->name = td1->name; -+ res->structure1 = sptr1; -+ res->structure2 = sptr2; -+ res->err_code = COMPARE_ERR_CODE_NO_MATCH; -+ return res; -+} ---- skeletons/NativeInteger.h 2015-12-08 14:39:33.346543533 +0100 -+++ skeletons/NativeInteger.h 2015-11-26 14:52:13.931616000 +0100 -@@ -31,6 +31,7 @@ - per_type_encoder_f NativeInteger_encode_uper; - per_type_decoder_f NativeInteger_decode_aper; - per_type_encoder_f NativeInteger_encode_aper; -+type_compare_f NativeInteger_compare; - - #ifdef __cplusplus - } ---- skeletons/NativeReal.c 2015-12-08 14:39:33.350543533 +0100 -+++ skeletons/NativeReal.c 2015-12-08 10:41:32.666558000 +0100 -@@ -33,7 +33,8 @@ - NativeReal_decode_uper, - NativeReal_encode_uper, - NativeReal_decode_aper, -- NativeReal_encode_aper, -+ NativeReal_encode_aper, -+ NativeReal_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_NativeReal_tags, - sizeof(asn_DEF_NativeReal_tags) / sizeof(asn_DEF_NativeReal_tags[0]), -@@ -405,3 +406,30 @@ - } - } - -+asn_comp_rval_t * -+NativeReal_compare(asn_TYPE_descriptor_t *td1, const void *sptr1, -+ asn_TYPE_descriptor_t *td2, const void *sptr2) { -+ const REAL_t *st1 = (const REAL_t *)sptr1; -+ const REAL_t *st2 = (const REAL_t *)sptr2; -+ asn_comp_rval_t *res = NULL; -+ -+ COMPARE_CHECK_ARGS(td1, td2, sptr1, sptr2, res) -+ -+ if (st1->size != st2->size) { -+ res = calloc(1, sizeof(asn_comp_rval_t)); -+ res->name = td1->name; -+ res->structure1 = sptr1; -+ res->structure2 = sptr2; -+ res->err_code = COMPARE_ERR_CODE_NO_MATCH; -+ return res; -+ } -+ if (0 != memcmp(st1->buf, st2->buf, st1->size)) { -+ res = calloc(1, sizeof(asn_comp_rval_t)); -+ res->name = td1->name; -+ res->structure1 = sptr1; -+ res->structure2 = sptr2; -+ res->err_code = COMPARE_ERR_CODE_NO_MATCH; -+ return res; -+ } -+ return NULL; -+} ---- skeletons/NativeReal.h 2015-12-08 14:39:33.350543533 +0100 -+++ skeletons/NativeReal.h 2015-11-26 14:31:12.631617000 +0100 -@@ -29,6 +29,7 @@ - per_type_encoder_f NativeReal_encode_uper; - per_type_decoder_f NativeReal_decode_aper; - per_type_encoder_f NativeReal_encode_aper; -+type_compare_f NativeReal_compare; - - #ifdef __cplusplus - } ---- skeletons/NULL.c 2015-12-08 14:39:33.338543533 +0100 -+++ skeletons/NULL.c 2015-12-07 10:49:05.178647000 +0100 -@@ -26,7 +26,8 @@ - NULL_decode_uper, /* Unaligned PER decoder */ - NULL_encode_uper, /* Unaligned PER encoder */ - NULL_decode_aper, /* Aligned PER decoder */ -- NULL_encode_aper, /* Aligned PER encoder */ -+ NULL_encode_aper, /* Aligned PER encoder */ -+ NULL_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_NULL_tags, - sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]), -@@ -192,3 +193,10 @@ - er.encoded = 0; - _ASN_ENCODED_OK(er); - } -+ -+asn_comp_rval_t * -+NULL_compare(asn_TYPE_descriptor_t *td1, const void *sptr1, -+ asn_TYPE_descriptor_t *td2, const void *sptr2) { -+ -+ return NULL; -+} ---- skeletons/NULL.h 2015-12-08 14:39:33.338543533 +0100 -+++ skeletons/NULL.h 2015-11-26 14:53:03.875616000 +0100 -@@ -27,6 +27,7 @@ - per_type_encoder_f NULL_encode_uper; - per_type_decoder_f NULL_decode_aper; - per_type_encoder_f NULL_encode_aper; -+type_compare_f NULL_compare; - - #ifdef __cplusplus - } ---- skeletons/NumericString.c 2015-12-08 14:39:33.338543533 +0100 -+++ skeletons/NumericString.c 2015-11-26 14:40:39.407616000 +0100 -@@ -50,7 +50,8 @@ - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, - OCTET_STRING_decode_aper, -- OCTET_STRING_encode_aper, -+ OCTET_STRING_encode_aper, -+ OCTET_STRING_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_NumericString_tags, - sizeof(asn_DEF_NumericString_tags) ---- skeletons/ObjectDescriptor.c 2015-12-08 14:39:33.338543533 +0100 -+++ skeletons/ObjectDescriptor.c 2015-11-26 14:55:46.227615000 +0100 -@@ -25,7 +25,8 @@ - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, - OCTET_STRING_decode_aper, -- OCTET_STRING_encode_aper, -+ OCTET_STRING_encode_aper, -+ OCTET_STRING_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_ObjectDescriptor_tags, - sizeof(asn_DEF_ObjectDescriptor_tags) ---- skeletons/OBJECT_IDENTIFIER.c 2015-12-08 14:39:33.342543533 +0100 -+++ skeletons/OBJECT_IDENTIFIER.c 2015-11-26 14:55:13.311615000 +0100 -@@ -28,7 +28,8 @@ - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, - OCTET_STRING_decode_aper, -- OCTET_STRING_encode_aper, -+ OCTET_STRING_encode_aper, -+ OCTET_STRING_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_OBJECT_IDENTIFIER_tags, - sizeof(asn_DEF_OBJECT_IDENTIFIER_tags) ---- skeletons/OCTET_STRING.c 2015-12-08 14:39:44.554543521 +0100 -+++ skeletons/OCTET_STRING.c 2015-12-08 10:41:42.838558000 +0100 -@@ -37,7 +37,8 @@ - OCTET_STRING_decode_uper, /* Unaligned PER decoder */ - OCTET_STRING_encode_uper, /* Unaligned PER encoder */ - OCTET_STRING_decode_aper, /* Aligned PER decoder */ -- OCTET_STRING_encode_aper, /* Aligned PER encoder */ -+ OCTET_STRING_encode_aper, /* Aligned PER encoder */ -+ OCTET_STRING_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_OCTET_STRING_tags, - sizeof(asn_DEF_OCTET_STRING_tags) -@@ -2160,3 +2161,30 @@ - return st; - } - -+asn_comp_rval_t * -+OCTET_STRING_compare(asn_TYPE_descriptor_t *td1, -+ const void *sptr1, asn_TYPE_descriptor_t *td2, const void *sptr2) { -+ const OCTET_STRING_t *st1 = (const OCTET_STRING_t *)sptr1; -+ const OCTET_STRING_t *st2 = (const OCTET_STRING_t *)sptr2; -+ asn_comp_rval_t *res = NULL; -+ -+ COMPARE_CHECK_ARGS(td1, td2, sptr1, sptr2, res) -+ -+ if (st1->size != st2->size) { -+ res = calloc(1, sizeof(asn_comp_rval_t)); -+ res->name = td1->name; -+ res->structure1 = sptr1; -+ res->structure2 = sptr2; -+ res->err_code = COMPARE_ERR_CODE_NO_MATCH; -+ return res; -+ } -+ if (0 != memcmp(st1->buf, st2->buf, st1->size)) { -+ res = calloc(1, sizeof(asn_comp_rval_t)); -+ res->name = td1->name; -+ res->structure1 = sptr1; -+ res->structure2 = sptr2; -+ res->err_code = COMPARE_ERR_CODE_NO_MATCH; -+ return res; -+ } -+ return NULL; -+} ---- skeletons/OCTET_STRING.h 2015-12-08 14:39:33.350543533 +0100 -+++ skeletons/OCTET_STRING.h 2015-11-26 12:56:15.259623000 +0100 -@@ -34,6 +34,7 @@ - per_type_encoder_f OCTET_STRING_encode_uper; - per_type_decoder_f OCTET_STRING_decode_aper; - per_type_encoder_f OCTET_STRING_encode_aper; -+type_compare_f OCTET_STRING_compare; - - /****************************** - * Handy conversion routines. * ---- skeletons/PrintableString.c 2015-12-08 14:39:33.338543533 +0100 -+++ skeletons/PrintableString.c 2015-11-26 14:56:09.787615000 +0100 -@@ -60,7 +60,8 @@ - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, - OCTET_STRING_decode_aper, -- OCTET_STRING_encode_aper, -+ OCTET_STRING_encode_aper, -+ OCTET_STRING_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_PrintableString_tags, - sizeof(asn_DEF_PrintableString_tags) ---- skeletons/REAL.c 2015-12-08 14:39:33.350543533 +0100 -+++ skeletons/REAL.c 2015-12-08 10:41:55.178558000 +0100 -@@ -46,7 +46,8 @@ - REAL_decode_uper, - REAL_encode_uper, - REAL_decode_aper, -- REAL_encode_aper, -+ REAL_encode_aper, -+ REAL_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_REAL_tags, - sizeof(asn_DEF_REAL_tags) / sizeof(asn_DEF_REAL_tags[0]), -@@ -741,3 +742,32 @@ - - return 0; - } -+ -+ -+asn_comp_rval_t * -+REAL_compare(asn_TYPE_descriptor_t *td1, const void *sptr1, -+ asn_TYPE_descriptor_t *td2, const void *sptr2) { -+ const REAL_t *st1 = (const REAL_t *)sptr1; -+ const REAL_t *st2 = (const REAL_t *)sptr2; -+ asn_comp_rval_t *res = NULL; -+ -+ COMPARE_CHECK_ARGS(td1, td2, sptr1, sptr2, res) -+ -+ if (st1->size != st2->size) { -+ res = calloc(1, sizeof(asn_comp_rval_t)); -+ res->name = td1->name; -+ res->structure1 = sptr1; -+ res->structure2 = sptr2; -+ res->err_code = COMPARE_ERR_CODE_NO_MATCH; -+ return res; -+ } -+ if (0 != memcmp(st1->buf, st2->buf, st1->size)) { -+ res = calloc(1, sizeof(asn_comp_rval_t)); -+ res->name = td1->name; -+ res->structure1 = sptr1; -+ res->structure2 = sptr2; -+ res->err_code = COMPARE_ERR_CODE_NO_MATCH; -+ return res; -+ } -+ return NULL; -+} ---- skeletons/REAL.h 2015-12-08 14:39:33.350543533 +0100 -+++ skeletons/REAL.h 2015-11-26 13:00:46.183623000 +0100 -@@ -23,6 +23,7 @@ - per_type_encoder_f REAL_encode_uper; - per_type_decoder_f REAL_decode_aper; - per_type_encoder_f REAL_encode_aper; -+type_compare_f REAL_compare; - - /*********************************** - * Some handy conversion routines. * ---- skeletons/RELATIVE-OID.c 2015-12-08 14:39:33.338543533 +0100 -+++ skeletons/RELATIVE-OID.c 2015-11-26 14:56:31.703615000 +0100 -@@ -29,7 +29,8 @@ - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, - OCTET_STRING_decode_aper, -- OCTET_STRING_encode_aper, -+ OCTET_STRING_encode_aper, -+ OCTET_STRING_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_RELATIVE_OID_tags, - sizeof(asn_DEF_RELATIVE_OID_tags) ---- skeletons/T61String.c 2015-12-08 14:39:33.338543533 +0100 -+++ skeletons/T61String.c 2015-11-26 14:57:07.235615000 +0100 -@@ -25,7 +25,8 @@ - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, - OCTET_STRING_decode_aper, -- OCTET_STRING_encode_aper, -+ OCTET_STRING_encode_aper, -+ OCTET_STRING_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_T61String_tags, - sizeof(asn_DEF_T61String_tags) ---- skeletons/TeletexString.c 2015-12-08 14:39:33.338543533 +0100 -+++ skeletons/TeletexString.c 2015-11-26 14:57:17.643615000 +0100 -@@ -25,7 +25,8 @@ - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, - OCTET_STRING_decode_aper, -- OCTET_STRING_encode_aper, -+ OCTET_STRING_encode_aper, -+ OCTET_STRING_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_TeletexString_tags, - sizeof(asn_DEF_TeletexString_tags) ---- skeletons/UniversalString.c 2015-12-08 14:39:33.350543533 +0100 -+++ skeletons/UniversalString.c 2015-11-26 14:57:29.015615000 +0100 -@@ -36,7 +36,8 @@ - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, - OCTET_STRING_decode_aper, -- OCTET_STRING_encode_aper, -+ OCTET_STRING_encode_aper, -+ OCTET_STRING_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_UniversalString_tags, - sizeof(asn_DEF_UniversalString_tags) ---- skeletons/UTCTime.c 2015-12-08 14:39:33.350543533 +0100 -+++ skeletons/UTCTime.c 2015-11-26 14:57:44.127615000 +0100 -@@ -41,7 +41,8 @@ - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, - OCTET_STRING_decode_aper, -- OCTET_STRING_encode_aper, -+ OCTET_STRING_encode_aper, -+ OCTET_STRING_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_UTCTime_tags, - sizeof(asn_DEF_UTCTime_tags) ---- skeletons/UTF8String.c 2015-12-08 14:39:33.314543533 +0100 -+++ skeletons/UTF8String.c 2015-11-26 14:06:54.563618000 +0100 -@@ -27,6 +27,7 @@ - OCTET_STRING_encode_uper, - OCTET_STRING_decode_aper, - OCTET_STRING_encode_aper, -+ OCTET_STRING_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_UTF8String_tags, - sizeof(asn_DEF_UTF8String_tags) ---- skeletons/VideotexString.c 2015-12-08 14:39:33.342543533 +0100 -+++ skeletons/VideotexString.c 2015-11-26 14:07:06.139618000 +0100 -@@ -25,7 +25,8 @@ - OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ - OCTET_STRING_encode_uper, - OCTET_STRING_decode_aper, -- OCTET_STRING_encode_aper, -+ OCTET_STRING_encode_aper, -+ OCTET_STRING_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_VideotexString_tags, - sizeof(asn_DEF_VideotexString_tags) ---- skeletons/VisibleString.c 2015-12-08 14:39:33.350543533 +0100 -+++ skeletons/VisibleString.c 2015-11-26 14:07:15.283618000 +0100 -@@ -30,7 +30,8 @@ - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, - OCTET_STRING_decode_aper, -- OCTET_STRING_encode_aper, -+ OCTET_STRING_encode_aper, -+ OCTET_STRING_compare, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_VisibleString_tags, - sizeof(asn_DEF_VisibleString_tags) diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.c b/openair3/S1AP/s1ap_eNB_nas_procedures.c index dbe0fef09116f7f61408fc8eab433c44efb15ddf..43f5ad49e53f40edd3d5dd72836ed0df9bfc27ff 100644 --- a/openair3/S1AP/s1ap_eNB_nas_procedures.c +++ b/openair3/S1AP/s1ap_eNB_nas_procedures.c @@ -668,6 +668,8 @@ int s1ap_eNB_ue_capabilities(instance_t instance, return -1; } + free(ue_cap_info_ind_p->ue_radio_cap.buffer); + MSC_LOG_TX_MESSAGE( MSC_S1AP_ENB, MSC_S1AP_MME,