E2AP Abstraction Changes
[ric-app/hw.git] / asn1c_defs / constr_CHOICE.c
index 613e6ea..86dcbb0 100644 (file)
@@ -1017,6 +1017,7 @@ CHOICE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
        const asn_CHOICE_specifics_t *specs = (const asn_CHOICE_specifics_t *)td->specifics;
        asn_dec_rval_t rv;
        const asn_per_constraint_t *ct;
+       const asn_per_constraint_t *ext_ct = NULL;
        asn_TYPE_member_t *elm; /* CHOICE's element */
        void *memb_ptr;
        void **memb_ptr2;
@@ -1042,9 +1043,13 @@ CHOICE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
        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(value) {
+                 ext_ct = ct;
+                 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;
@@ -1055,7 +1060,7 @@ CHOICE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
        } else {
                if(specs->ext_start == -1)
                        ASN__DECODE_FAILED;
-               value = uper_get_nsnnwn(pd);
+               value = aper_get_nsnnwn(pd, ext_ct->range_bits);
                if(value < 0) ASN__DECODE_STARVED;
                value += specs->ext_start;
                if((unsigned)value >= td->elements_count)
@@ -1083,7 +1088,7 @@ CHOICE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
                rv = elm->type->op->aper_decoder(opt_codec_ctx, elm->type,
                                                 elm->encoding_constraints.per_constraints, memb_ptr2, pd);
        } else {
-               rv = uper_open_type_get(opt_codec_ctx, elm->type,
+               rv = aper_open_type_get(opt_codec_ctx, elm->type,
                                        elm->encoding_constraints.per_constraints, memb_ptr2, pd);
        }
 
@@ -1099,10 +1104,12 @@ CHOICE_encode_aper(const asn_TYPE_descriptor_t *td,
                    const void *sptr, asn_per_outp_t *po) {
        const asn_CHOICE_specifics_t *specs = (const asn_CHOICE_specifics_t *)td->specifics;
        const asn_TYPE_member_t *elm; /* CHOICE's element */
-       const asn_per_constraint_t *ct;
+       const asn_per_constraint_t *ct = NULL;
+       const asn_per_constraint_t *ext_ct = NULL;
        const void *memb_ptr;
-       int present;
-
+       unsigned present;
+       int present_enc;
+       
        if(!sptr) ASN__ENCODE_FAILED;
 
        ASN_DEBUG("Encoding %s as CHOICE using ALIGNED PER", td->name);
@@ -1110,7 +1117,7 @@ CHOICE_encode_aper(const asn_TYPE_descriptor_t *td,
        if(constraints) ct = &constraints->value;
        else if(td->encoding_constraints.per_constraints)
                ct = &td->encoding_constraints.per_constraints->value;
-       else ct = 0;
+       else ct = NULL;
 
        present = _fetch_present_idx(sptr,
                                     specs->pres_offset, specs->pres_size);
@@ -1126,25 +1133,38 @@ CHOICE_encode_aper(const asn_TYPE_descriptor_t *td,
 
        /* Adjust if canonical order is different from natural order */
        if(specs->to_canonical_order)
-               present = specs->to_canonical_order[present];
-
+               present_enc = specs->to_canonical_order[present];
+       else
+               present_enc = 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->range_bits >= 0)) {
+         // Value is not within the range of the primary values ?
+         if(present < ct->lower_bound || present > ct->upper_bound) {
+           if(ct->flags & APC_EXTENSIBLE) {
+             ASN_DEBUG("CHOICE member %d (enc %d) is an extension (%ld..%ld)",
+                       present, present_enc, ct->lower_bound, ct->upper_bound);
+             // X691/23.5 Extension marker = 1 
+             if(per_put_few_bits(po, 1, 1)) {
+               ASN__ENCODE_FAILED;
+             }
+           } else {
+             ASN__ENCODE_FAILED;
+           }
+           // no more need of constraint.
+           ext_ct = ct;
+           ct = NULL;
+         }
        }
-       if(ct && ct->flags & APC_EXTENSIBLE) {
-               if(per_put_few_bits(po, 0, 1))
-                       ASN__ENCODE_FAILED;
+       
+       if(ct && (ct->flags & APC_EXTENSIBLE)) {
+         ASN_DEBUG("CHOICE member %d (enc %d) is not an extension (%ld..%ld)",
+                   present, present, ct->lower_bound, ct->upper_bound);
+         // X691.23.5 Extension marker = 0
+         if(per_put_few_bits(po, 0, 1)) {
+           ASN__ENCODE_FAILED;
+         }
        }
 
        elm = &td->elements[present];
@@ -1156,8 +1176,10 @@ CHOICE_encode_aper(const asn_TYPE_descriptor_t *td,
                memb_ptr = (const char *)sptr + elm->memb_offset;
        }
 
-       if(ct && ct->range_bits >= 0) {
-               if(per_put_few_bits(po, present, ct->range_bits))
+       if(ct && (ct->range_bits >= 0)) {
+               // By construction (ct != 0), the alternative value is a non extended one.
+               // X691/23.7 X691/23.6 alternative value encoded as a range_bits bits value.
+               if(per_put_few_bits(po, present_enc, ct->range_bits))
                        ASN__ENCODE_FAILED;
 
                return elm->type->op->aper_encoder(elm->type, elm->encoding_constraints.per_constraints,
@@ -1166,10 +1188,10 @@ CHOICE_encode_aper(const asn_TYPE_descriptor_t *td,
                asn_enc_rval_t rval = {0,0,0};
                if(specs->ext_start == -1)
                        ASN__ENCODE_FAILED;
-               if (ct) {
-                 if(aper_put_nsnnwn(po, ct->range_bits, present - specs->ext_start))
+               // X691/23.8 normally encoded as a small non negative whole number
+               
+               if(ext_ct && aper_put_nsnnwn(po, ext_ct->range_bits, present_enc - specs->ext_start))
                        ASN__ENCODE_FAILED;
-               }
                if(aper_open_type_put(elm->type, elm->encoding_constraints.per_constraints,
                                      memb_ptr, po))
                        ASN__ENCODE_FAILED;