Commit 99acedd0 authored by Cedric Roux's avatar Cedric Roux

Merge branch 'enhancement-i18-asn1c-from-gitlab' into 'develop'

download asn1c from oai gitlab

We need to test at least one attach by the UEs of the test setup, to check that the local asn1c is the same as the one from github we used so far.

I don't think we need to do lots of traffic, it's only about control plane (rrc, s1ap).

And of course see if compilation is still ok.

See merge request !40
parents 7abe45d7 f4e97b50
......@@ -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
......
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;
This source diff could not be displayed because it is too large. You can view the blob instead.
--- 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;
--- 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;
+}