Upstreaming version 0.10.7
Change-Id: Ica4c824e3e053be68d2b0ab3d6d467638632f5e1
Signed-off-by: kalnagy <kalman.nagy@nokia.com>
diff --git a/e2ap/lib/constr_CHOICE.c b/e2ap/lib/constr_CHOICE.c
index 613e6ea..86dcbb0 100644
--- a/e2ap/lib/constr_CHOICE.c
+++ b/e2ap/lib/constr_CHOICE.c
@@ -1017,6 +1017,7 @@
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 @@
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 @@
} 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 @@
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 @@
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 @@
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 @@
/* 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 @@
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 @@
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;