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/libasn1parser/asn1p_class.c b/libasn1parser/asn1p_class.c
index c6fbe21..4376089 100644
--- a/libasn1parser/asn1p_class.c
+++ b/libasn1parser/asn1p_class.c
@@ -26,6 +26,16 @@
}
void
+asn1p_ioc_table_append(asn1p_ioc_table_t *it, asn1p_ioc_table_t *src) {
+
+ if(!src) return;
+
+ for(size_t i = 0; i < src->rows; i++) {
+ asn1p_ioc_table_add(it, asn1p_ioc_row_clone(src->row[i]));
+ }
+}
+
+void
asn1p_ioc_table_free(asn1p_ioc_table_t *it) {
if(it) {
for(size_t i = 0; i < it->rows; i++) {
@@ -93,6 +103,29 @@
return row;
}
+asn1p_ioc_row_t *
+asn1p_ioc_row_clone(asn1p_ioc_row_t *src) {
+ asn1p_ioc_row_t *row;
+
+ row = calloc(1, sizeof *row);
+ if(!row) return NULL;
+
+ row->column = calloc(src->columns, sizeof *src->column);
+ if(!row->column) {
+ free(row);
+ return NULL;
+ }
+ row->columns = src->columns;
+
+ for(size_t i = 0; i < src->columns; i++) {
+ row->column[i].field = src->column[i].field;
+ row->column[i].value = src->column[i].value ? asn1p_expr_clone(src->column[i].value, 0) : 0;
+ row->column[i].new_ref = 1;
+ }
+
+ return row;
+}
+
void
asn1p_ioc_row_delete(asn1p_ioc_row_t *row) {
if(row) {