Fix 'Information Object Set XXX contains no objects' when parsing S1AP's ASN.1
The aforementioned error message displayed during processing the following ASN.1 excerpt.
S1AP-ELEMENTARY-PROCEDURES S1AP-ELEMENTARY-PROCEDURE ::= {
S1AP-ELEMENTARY-PROCEDURES-CLASS-1 |
S1AP-ELEMENTARY-PROCEDURES-CLASS-2,
...
}
S1AP-ELEMENTARY-PROCEDURES-CLASS-1 S1AP-ELEMENTARY-PROCEDURE ::= {
handoverPreparation |
...
writeReplaceWarning,
...,
uERadioCapabilityMatch |
....
uEContextResume
}
S1AP-ELEMENTARY-PROCEDURES-CLASS-2 S1AP-ELEMENTARY-PROCEDURE ::= {
handoverNotification |
...
privateMessage,
...,
downlinkUEAssociatedLPPaTransport |
...
mMECPRelocationIndication
}
Because S1AP-ELEMENTARY-PROCEDURES-CLASS-1 and S1AP-ELEMENTARY-PROCEDURES-CLASS-2
are resolved 'after' S1AP-ELEMENTARY-PROCEDURES, so the ioc tables of them are not
available during resolving S1AP-ELEMENTARY-PROCEDURES. So we can not drop the
latter's containedSubtype field at first pass of asn1f_resolve_constraints of fix
process.
We also add second pass of asn1f_resolve_constraints to have a chance to combine
ioc tables of S1AP-ELEMENTARY-PROCEDURES-CLASS-1 and
S1AP-ELEMENTARY-PROCEDURES-CLASS-2.
diff --git a/libasn1fix/asn1fix.c b/libasn1fix/asn1fix.c
index b52406e..127ba8c 100644
--- a/libasn1fix/asn1fix.c
+++ b/libasn1fix/asn1fix.c
@@ -263,6 +263,12 @@
RET2RVAL(ret, rvalue);
/*
+ * Resolve references in constraints (the second pass).
+ */
+ ret = asn1f_recurse_expr(arg, asn1f_resolve_constraints);
+ RET2RVAL(ret, rvalue);
+
+ /*
* Check semantic validity of constraints.
*/
ret = asn1f_recurse_expr(arg, asn1f_check_constraints);
diff --git a/libasn1fix/asn1fix_constraint.c b/libasn1fix/asn1fix_constraint.c
index 46eddaa..cf29a33 100644
--- a/libasn1fix/asn1fix_constraint.c
+++ b/libasn1fix/asn1fix_constraint.c
@@ -21,6 +21,7 @@
switch(expr->meta_type) {
case AMT_TYPE:
case AMT_TYPEREF:
+ case AMT_VALUESET:
break;
default:
return 0; /* Nothing to do */
@@ -273,6 +274,7 @@
constraint_type_resolve(arg_t *arg, asn1p_constraint_t *ct) {
asn1p_constraint_t *ct_expr;
int ret;
+ asn1p_expr_t *rtype = (asn1p_expr_t *)0;
DEBUG("(\"%s\")", asn1f_printable_value(ct->containedSubtype));
@@ -280,7 +282,6 @@
ct_expr = ct->containedSubtype->value.constraint;
DEBUG("Found %s in constraints", "ValueSet");
} else if(get_reference_from(ct)) {
- asn1p_expr_t *rtype;
arg_t tmparg;
rtype = asn1f_lookup_symbol(arg, arg->expr->rhs_pspecs,
@@ -299,6 +300,14 @@
ret = asn1constraint_pullup(&tmparg);
if(ret) return ret;
+ if(rtype->ioc_table) {
+ if(!arg->expr->ioc_table)
+ arg->expr->ioc_table = asn1p_ioc_table_new();
+ asn1p_ioc_table_append(arg->expr->ioc_table, rtype->ioc_table);
+ asn1p_value_free(ct->containedSubtype);
+ ct->containedSubtype = NULL;
+ }
+
ct_expr = rtype->combined_constraints;
if(!ct_expr) return 0;
} else {
@@ -330,6 +339,14 @@
}
ct->type = ACT_CA_SET;
+
+ /* keep constrainedSubtype field for future usage,
+ if valueset has not been resolved yet. */
+ if(rtype &&
+ (rtype->meta_type == AMT_VALUESET) &&
+ (!rtype->ioc_table))
+ return 0;
+
asn1p_value_free(ct->containedSubtype);
ct->containedSubtype = NULL;