From 1b86363795b0931fc47d78899e9d079df659f408 Mon Sep 17 00:00:00 2001 From: gauthier <lionel.gauthier@eurecom.fr> Date: Tue, 8 Dec 2015 15:08:02 +0100 Subject: [PATCH] Remaining TODO: handle diff MME_UE_S1AP_ID, asn1c compare not tested --- cmake_targets/CMakeLists.txt | 1 + openair3/S1AP/MESSAGES/ASN1/asn1cpatch_3.p0 | 848 +++++++++++------- openair3/S1AP/MESSAGES/ASN1/asn1tostruct.py | 87 +- openair3/TEST/EPC_TEST/play_scenario.c | 34 +- openair3/TEST/EPC_TEST/play_scenario.h | 14 +- openair3/TEST/EPC_TEST/play_scenario_s1ap.c | 394 +++++++- .../EPC_TEST/play_scenario_s1ap_compare_ie.c | 6 +- openair3/TEST/EPC_TEST/play_scenario_sctp.c | 31 +- 8 files changed, 1041 insertions(+), 374 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 9c5bbad0de9..a562a5ebc0a 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1677,6 +1677,7 @@ add_executable(test_epc_play_scenario ${OPENAIR2_DIR}/COMMON/messages_types.h ${OPENAIR_BIN_DIR}/messages_xml.h ) +target_include_directories(test_epc_play_scenario PUBLIC /usr/local/share/asn1c) target_link_libraries (test_epc_play_scenario -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES} ) diff --git a/openair3/S1AP/MESSAGES/ASN1/asn1cpatch_3.p0 b/openair3/S1AP/MESSAGES/ASN1/asn1cpatch_3.p0 index cf3553c362d..3986a6a83b4 100644 --- a/openair3/S1AP/MESSAGES/ASN1/asn1cpatch_3.p0 +++ b/openair3/S1AP/MESSAGES/ASN1/asn1cpatch_3.p0 @@ -1,20 +1,20 @@ ---- ./asn1c/unber.c 2015-12-03 09:43:33.959009150 +0100 -+++ ./asn1c/unber.c 2015-11-30 13:20:40.751264003 +0100 +--- 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; } -+long OCTET_STRING_compare(asn_TYPE_descriptor_t *td1, void *sptr1, asn_TYPE_descriptor_t *td2, void *sptr2) { (void)td1; (void)sptr1; (void)td2; (void)sptr2; return 0; } ++asn_comp_rval_t * OCTET_STRING_compare(asn_TYPE_descriptor_t *td1, void *sptr1, asn_TYPE_descriptor_t *td2, 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-03 09:43:33.971009150 +0100 -+++ ./libasn1compiler/asn1c_C.c 2015-11-30 14:29:33.027259725 +0100 +--- 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; ++ //char tmp_buf[512]; ++ //int i = 0; if(arg->embed) { enum tnfmt tnfmt = TNF_CTYPE; @@ -28,49 +28,39 @@ 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,49 @@ +@@ -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'; ++ //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); ++ //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("long\n"); ++ 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"); -+ i = 0; -+ while ((p[i] != '_') && (i < sizeof(tmp_buf))) { -+ tmp_buf[i] = p[i]; -+ i++; -+ } -+ tmp_buf[i] = '\0'; -+ strcat(tmp_buf,"_ProtocolIE_ID_id_"); -+ strcat(tmp_buf,&p[++i]); + INDENTED( + OUT("\tvoid *structure1,\n"); + OUT("\tasn_TYPE_descriptor_t *td2,\n"); + OUT("\tvoid *structure2) {\n"); -+ OUT("long rv = 0;\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("rv = td1->compare(td1, structure1, td2, structure2);\n"); -+ if ((strcmp("S1ap", tmp_buf) == 0) || (strcmp("X2ap", tmp_buf) == 0)) -+ OUT("if (rv) { rv = (rv << 8); rv |= %s;}\n", tmp_buf); -+ OUT("return rv;\n"); ++ OUT("res = td1->compare(td1, structure1, td2, structure2);\n"); ++ OUT("return res;\n"); + ); + OUT("}\n"); + OUT("\n"); @@ -78,7 +68,7 @@ p = MKID(expr); if(HIDE_INNER_DEFS) OUT("static "); -@@ -1450,7 +1496,8 @@ +@@ -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); @@ -88,7 +78,7 @@ } } -@@ -2501,6 +2548,7 @@ +@@ -2501,6 +2538,7 @@ OUT("0, 0,\t/* No APER support, " "use \"-gen-PER\" to enable */\n"); } @@ -96,8 +86,8 @@ if(!terminal || terminal->expr_type == ASN_CONSTR_CHOICE) { //if(expr->expr_type == ASN_CONSTR_CHOICE) { ---- ./skeletons/ANY.c 2015-12-03 09:43:33.971009150 +0100 -+++ ./skeletons/ANY.c 2015-11-26 14:40:56.547616803 +0100 +--- 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, @@ -108,8 +98,101 @@ 0, /* Use generic outmost tag fetcher */ 0, 0, 0, 0, 0, /* No PER visible constraints */ ---- ./skeletons/BIT_STRING.c 2015-12-03 09:43:33.967009150 +0100 -+++ ./skeletons/BIT_STRING.c 2015-11-26 14:41:50.159616747 +0100 +--- 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) ++ void *structure1; ++ 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 */ @@ -120,8 +203,8 @@ 0, /* Use generic outmost tag fetcher */ asn_DEF_BIT_STRING_tags, sizeof(asn_DEF_BIT_STRING_tags) ---- ./skeletons/BMPString.c 2015-12-03 09:43:33.963009150 +0100 -+++ ./skeletons/BMPString.c 2015-11-26 14:42:08.487616728 +0100 +--- 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, @@ -132,8 +215,8 @@ 0, /* Use generic outmost tag fetcher */ asn_DEF_BMPString_tags, sizeof(asn_DEF_BMPString_tags) ---- ./skeletons/BOOLEAN.c 2015-12-03 09:43:33.967009150 +0100 -+++ ./skeletons/BOOLEAN.c 2015-11-30 13:16:30.275264262 +0100 +--- 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 */ @@ -144,30 +227,31 @@ 0, /* Use generic outmost tag fetcher */ asn_DEF_BOOLEAN_tags, sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]), -@@ -326,3 +327,21 @@ +@@ -326,3 +327,22 @@ _ASN_ENCODED_OK(er); } + -+long ++asn_comp_rval_t * +BOOLEAN_compare(asn_TYPE_descriptor_t *td1, + void *sptr1, asn_TYPE_descriptor_t *td2, void *sptr2) { + const BOOLEAN_t *st1 = (const BOOLEAN_t *)sptr1; + const BOOLEAN_t *st2 = (const BOOLEAN_t *)sptr2; -+ if ((td1) && (td2)) { -+ if ((td1->name) && (td2->name)) { -+ if (strcmp(td1->name, td2->name)) return -1; -+ } else { -+ if ((td1->xml_tag) && (td2->xml_tag)) { -+ if (strcmp(td1->xml_tag, td2->xml_tag)) return -1; -+ } -+ } -+ } -+ return (*st1 != *st2); ++ 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-03 09:43:33.967009150 +0100 -+++ ./skeletons/BOOLEAN.h 2015-11-26 12:46:58.491623882 +0100 +--- 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; @@ -176,9 +260,9 @@ #ifdef __cplusplus } ---- ./skeletons/compare.h 1970-01-01 01:00:00.000000000 +0100 -+++ ./skeletons/compare.h 2015-11-30 13:15:56.415264297 +0100 -@@ -0,0 +1,27 @@ +--- 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. + */ @@ -186,7 +270,6 @@ +#define _COMPARE_H_ + +#include <asn_application.h> -+#include <per_support.h> + +#ifdef __cplusplus +extern "C" { @@ -194,46 +277,37 @@ + +struct asn_TYPE_descriptor_s; /* Forward declaration */ + -+typedef long (type_compare_f)( ++typedef asn_comp_rval_t * (type_compare_f)( + struct asn_TYPE_descriptor_s *type_descriptor1, + void *struct_ptr1, + struct asn_TYPE_descriptor_s *type_descriptor2, + void *struct_ptr2 +); + ++ ++ +#ifdef __cplusplus +} +#endif + +#endif /* _COMPARE_H_ */ ---- ./skeletons/constr_CHOICE.c 2015-12-03 09:43:33.967009150 +0100 -+++ ./skeletons/constr_CHOICE.c 2015-11-30 13:16:49.007264243 +0100 -@@ -1272,3 +1272,57 @@ +--- 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)); } } + -+long ++asn_comp_rval_t * +CHOICE_compare(asn_TYPE_descriptor_t *td1, void *sptr1, asn_TYPE_descriptor_t *td2, 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; + -+ if ((!sptr1) && (!sptr2)) return 0; -+ if (!sptr1) return -1; -+ if (!sptr2) return -1; -+ -+ if ((td1) && (td2)) { -+ if ((td1->name) && (td2->name)) { -+ if (strcmp(td1->name, td2->name)) return -1; -+ } else { -+ if ((td1->xml_tag) && (td2->xml_tag)) { -+ if (strcmp(td1->xml_tag, td2->xml_tag)) return -1; -+ } -+ } -+ } ++ COMPARE_CHECK_ARGS(td1, td2, sptr1, sptr2, res) + + /* + * Figure out which CHOICE element is encoded. @@ -242,8 +316,22 @@ + // same specs + present2 = _fetch_present_idx(sptr2, specs2->pres_offset,specs2->pres_size); + -+ if (td1->elements_count != td2->elements_count) return -1; -+ if (present1 != present2) return -1; ++ 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]; @@ -253,21 +341,36 @@ + 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)) return -1; -+ if (!memb_ptr1) return -1; -+ if (!memb_ptr2) return -1; ++ 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 { -+ return -1; ++ 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); + } -+ return 0; ++ 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-03 09:43:33.967009150 +0100 -+++ ./skeletons/constr_CHOICE.h 2015-11-26 14:43:57.647616615 +0100 +--- 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. @@ -287,34 +390,30 @@ #ifdef __cplusplus } ---- ./skeletons/constr_SEQUENCE.c 2015-12-03 09:43:33.967009150 +0100 -+++ ./skeletons/constr_SEQUENCE.c 2015-11-30 13:17:33.871264196 +0100 -@@ -1761,3 +1761,50 @@ +--- 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,66 @@ _ASN_ENCODED_OK(er); } + -+long -+SEQUENCE_compare(asn_TYPE_descriptor_t *td1, void *sptr1, asn_TYPE_descriptor_t *td2, void *sptr2) { ++asn_comp_rval_t * SEQUENCE_compare(asn_TYPE_descriptor_t *td1, void *sptr1, asn_TYPE_descriptor_t *td2, void *sptr2) { + int edx; + int ret; ++ asn_comp_rval_t *res = NULL; ++ asn_comp_rval_t *res2 = NULL; + -+ if((!sptr1) && (!sptr2)) return -1; -+ if(!sptr1) return -1; -+ if(!sptr2) return -1; ++ COMPARE_CHECK_ARGS(td1, td2, sptr1, sptr2, res) + -+ if ((td1) && (td2)) { -+ if ((td1->name) && (td2->name)) { -+ if (strcmp(td1->name, td2->name)) return -1; -+ } else { -+ if ((td1->xml_tag) && (td2->xml_tag)) { -+ if (strcmp(td1->xml_tag, td2->xml_tag)) return -1; -+ } -+ } ++ 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 (td1->elements_count != td2->elements_count) return -1; -+ + for(edx = 0; edx < td1->elements_count; edx++) { + asn_TYPE_member_t *elm1 = &td1->elements[edx]; + asn_TYPE_member_t *elm2 = &td1->elements[edx]; @@ -327,21 +426,41 @@ + if((!memb_ptr1) && (!memb_ptr2)) { + if(elm1->optional) continue; + } -+ if (!memb_ptr1) return -1; -+ if (!memb_ptr2) return -1; ++ 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 */ -+ ret = elm1->type->compare(elm1->type, memb_ptr1, elm2->type, memb_ptr2); -+ if(ret) return ret; ++ 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 0; ++ return res; +} ---- ./skeletons/constr_SEQUENCE.h 2015-12-03 09:43:33.971009150 +0100 -+++ ./skeletons/constr_SEQUENCE.h 2015-11-26 14:48:14.123616350 +0100 +--- 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; @@ -350,8 +469,8 @@ #ifdef __cplusplus } ---- ./skeletons/constr_SEQUENCE_OF.h 2015-12-03 09:43:33.963009150 +0100 -+++ ./skeletons/constr_SEQUENCE_OF.h 2015-11-26 15:05:25.399615282 +0100 +--- 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 @@ -362,8 +481,8 @@ 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-03 09:43:33.963009150 +0100 -+++ ./skeletons/constr_SET.c 2015-11-30 13:17:49.903264180 +0100 +--- 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 @@ } } @@ -373,8 +492,67 @@ SET_constraint(asn_TYPE_descriptor_t *td, const void *sptr, asn_app_constraint_failed_f *ctfailcb, void *app_key) { int edx; ---- ./skeletons/constr_SET.h 2015-12-03 09:43:33.963009150 +0100 -+++ ./skeletons/constr_SET.h 2015-11-26 14:49:09.243616293 +0100 +@@ -1159,3 +1159,58 @@ + + return 0; + } ++ ++asn_comp_rval_t * ++SET_compare(asn_TYPE_descriptor_t *td1, void *sptr1, asn_TYPE_descriptor_t *td2, 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; @@ -383,14 +561,14 @@ /*********************** * Some handy helpers. * ---- ./skeletons/constr_SET_OF.c 2015-12-03 09:43:33.963009150 +0100 -+++ ./skeletons/constr_SET_OF.c 2015-11-30 13:17:42.099264188 +0100 -@@ -1039,3 +1039,46 @@ +--- 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,55 @@ rv.consumed = 0; return rv; } + -+long ++asn_comp_rval_t * +SET_OF_compare(asn_TYPE_descriptor_t *td1, void *sptr1, asn_TYPE_descriptor_t *td2, void *sptr2) +{ + asn_TYPE_member_t *elm1 = td1->elements; @@ -399,41 +577,50 @@ + const asn_anonymous_set_ *list2 = _A_CSET_FROM_VOID(sptr2); + int ret; + int i; ++ asn_comp_rval_t *res = NULL; ++ asn_comp_rval_t *res2 = NULL; + -+ if((!sptr1) && !(sptr2)) return 0; -+ if(!sptr1) return -1; -+ if(!sptr2) return -1; ++ COMPARE_CHECK_ARGS(td1, td2, sptr1, sptr2, res) + -+ if ((td1) && (td2)) { -+ if ((td1->name) && (td2->name)) { -+ if (strcmp(td1->name, td2->name)) return -1; -+ } else { -+ if ((td1->xml_tag) && (td2->xml_tag)) { -+ if (strcmp(td1->xml_tag, td2->xml_tag)) return -1; -+ } -+ } ++ 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 (td1->elements_count != td2->elements_count) return -1; -+ + -+ if (list1->count != list2->count ) return -1; ++ 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; -+ if(!memb_ptr1) return -1; -+ if(!memb_ptr2) return -1; + -+ ret = elm1->type->compare(elm1->type, memb_ptr1, elm2->type, memb_ptr2); -+ if(ret) return ret; ++ 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 0; ++ return res; +} ---- ./skeletons/constr_SET_OF.h 2015-12-03 09:43:33.963009150 +0100 -+++ ./skeletons/constr_SET_OF.h 2015-11-26 14:48:45.067616318 +0100 +--- 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; @@ -442,8 +629,8 @@ #ifdef __cplusplus } ---- ./skeletons/constr_TYPE.h 2015-12-03 09:43:33.963009150 +0100 -+++ ./skeletons/constr_TYPE.h 2015-11-26 15:28:05.495613874 +0100 +--- 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 */ @@ -462,8 +649,8 @@ /*********************************************************************** * Internally useful members. Not to be used by applications directly. * ---- ./skeletons/ENUMERATED.c 2015-12-03 09:43:33.963009150 +0100 -+++ ./skeletons/ENUMERATED.c 2015-11-30 13:18:05.399264164 +0100 +--- 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 */ @@ -479,26 +666,26 @@ return NativeEnumerated_encode_aper(td, constraints, &value, po); } + -+long ++asn_comp_rval_t * +ENUMERATED_compare(asn_TYPE_descriptor_t *td1, void *sptr1, + asn_TYPE_descriptor_t *td2, void *sptr2) { + ENUMERATED_t *st1 = (ENUMERATED_t *)sptr1; + ENUMERATED_t *st2 = (ENUMERATED_t *)sptr2; ++ asn_comp_rval_t *res = NULL; + -+ if ((td1) && (td2)) { -+ if ((td1->name) && (td2->name)) { -+ if (strcmp(td1->name, td2->name)) return -1; -+ } else { -+ if ((td1->xml_tag) && (td2->xml_tag)) { -+ if (strcmp(td1->xml_tag, td2->xml_tag)) return -1; -+ } -+ } -+ } -+ return (*st1 != *st2); ++ 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/ENUMERATED.h 2015-12-03 09:43:33.963009150 +0100 -+++ ./skeletons/ENUMERATED.h 2015-11-26 12:46:35.523623906 +0100 +--- skeletons/ENUMERATED.h 2015-12-08 14:39:33.342543533 +0100 ++++ skeletons/ENUMERATED.h 2015-11-26 12:46:35.523623000 +0100 @@ -19,6 +19,7 @@ per_type_encoder_f ENUMERATED_encode_uper; per_type_decoder_f ENUMERATED_decode_aper; @@ -507,9 +694,9 @@ #ifdef __cplusplus } ---- ./skeletons/file-dependencies 2015-12-03 09:43:33.731009150 +0100 -+++ ./skeletons/file-dependencies 2015-11-26 16:05:44.923611535 +0100 -@@ -39,7 +39,7 @@ +--- skeletons/file-dependencies 2015-12-08 14:39:12.678543554 +0100 ++++ skeletons/file-dependencies 2015-12-07 15:34:40.454629000 +0100 +@@ -39,12 +39,13 @@ constr_SEQUENCE.h constr_SEQUENCE.c constr_SEQUENCE_OF.h constr_SEQUENCE_OF.c asn_SEQUENCE_OF.h constr_SET_OF.h constr_SET.h constr_SET.c @@ -517,9 +704,17 @@ +constr_SET_OF.h constr_SET_OF.c asn_SET_OF.h compare.h COMMON-FILES: # THIS IS A SPECIAL SECTION - asn_application.h # Applications should include this file ---- ./skeletons/GeneralizedTime.c 2015-12-03 09:43:33.971009150 +0100 -+++ ./skeletons/GeneralizedTime.c 2015-11-26 15:09:03.899615056 +0100 +-asn_application.h # Applications should include this file ++asn_application.h # Applications should include this file + asn_system.h # Platform-dependent types +-asn_codecs.h # Return types of encoders and decoders ++asn_codecs.h # Return types of encoders and decoders ++asn_compare.h # Return type of compare + asn_internal.h # Internal stuff + OCTET_STRING.h OCTET_STRING.c # This one is used too widely + BIT_STRING.h BIT_STRING.c # This one is necessary for the above one +--- skeletons/GeneralizedTime.c 2015-12-08 14:39:33.350543533 +0100 ++++ skeletons/GeneralizedTime.c 2015-11-26 15:09:03.899615000 +0100 @@ -168,7 +168,8 @@ OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, @@ -530,8 +725,8 @@ 0, /* Use generic outmost tag fetcher */ asn_DEF_GeneralizedTime_tags, sizeof(asn_DEF_GeneralizedTime_tags) ---- ./skeletons/GeneralString.c 2015-12-03 09:43:33.967009150 +0100 -+++ ./skeletons/GeneralString.c 2015-11-26 14:50:11.843616228 +0100 +--- skeletons/GeneralString.c 2015-12-08 14:39:33.342543533 +0100 ++++ skeletons/GeneralString.c 2015-11-26 14:50:11.843616000 +0100 @@ -25,7 +25,8 @@ OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_uper, @@ -542,8 +737,8 @@ 0, /* Use generic outmost tag fetcher */ asn_DEF_GeneralString_tags, sizeof(asn_DEF_GeneralString_tags) ---- ./skeletons/GraphicString.c 2015-12-03 09:43:33.971009150 +0100 -+++ ./skeletons/GraphicString.c 2015-11-26 15:33:33.255613535 +0100 +--- skeletons/GraphicString.c 2015-12-08 14:39:33.350543533 +0100 ++++ skeletons/GraphicString.c 2015-11-26 15:33:33.255613000 +0100 @@ -25,7 +25,8 @@ OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_uper, @@ -554,8 +749,8 @@ 0, /* Use generic outmost tag fetcher */ asn_DEF_GraphicString_tags, sizeof(asn_DEF_GraphicString_tags) ---- ./skeletons/IA5String.c 2015-12-03 09:43:33.967009150 +0100 -+++ ./skeletons/IA5String.c 2015-11-26 14:50:44.219616194 +0100 +--- skeletons/IA5String.c 2015-12-08 14:39:33.342543533 +0100 ++++ skeletons/IA5String.c 2015-11-26 14:50:44.219616000 +0100 @@ -31,6 +31,7 @@ OCTET_STRING_encode_uper, OCTET_STRING_decode_aper, @@ -564,8 +759,8 @@ 0, /* Use generic outmost tag fetcher */ asn_DEF_IA5String_tags, sizeof(asn_DEF_IA5String_tags) ---- ./skeletons/INTEGER.c 2015-12-03 09:43:33.967009150 +0100 -+++ ./skeletons/INTEGER.c 2015-11-30 13:18:18.143264151 +0100 +--- skeletons/INTEGER.c 2015-12-08 14:39:33.346543533 +0100 ++++ skeletons/INTEGER.c 2015-12-08 10:41:08.526558000 +0100 @@ -35,6 +35,7 @@ INTEGER_decode_aper, INTEGER_encode_aper, @@ -574,29 +769,39 @@ 0, /* Use generic outmost tag fetcher */ asn_DEF_INTEGER_tags, sizeof(asn_DEF_INTEGER_tags) / sizeof(asn_DEF_INTEGER_tags[0]), -@@ -1501,3 +1502,20 @@ +@@ -1501,3 +1502,30 @@ } -+long ++asn_comp_rval_t * +INTEGER_compare(asn_TYPE_descriptor_t *td1, void *sptr1, + asn_TYPE_descriptor_t *td2, void *sptr2) { + INTEGER_t *st1 = (INTEGER_t *)sptr1; + INTEGER_t *st2 = (INTEGER_t *)sptr2; -+ if ((td1) && (td2)) { -+ if ((td1->name) && (td2->name)) { -+ if (strcmp(td1->name, td2->name)) return -1; -+ } else { -+ if ((td1->xml_tag) && (td2->xml_tag)) { -+ if (strcmp(td1->xml_tag, td2->xml_tag)) return -1; -+ } -+ } ++ asn_comp_rval_t *res = NULL; ++ ++ COMPARE_CHECK_ARGS(td1, td2, sptr1, sptr2, res) ++ ++ if (st1->size != st2->size) { ++ 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; ++ } ++ if (0 != memcmp(st1->buf, st2->buf, st1->size)) { ++ 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; + } -+ if (st1->size != st2->size) return -1; -+ return memcmp(st1->buf, st2->buf, st1->size); ++ return NULL; +} ---- ./skeletons/INTEGER.h 2015-12-03 09:43:33.967009150 +0100 -+++ ./skeletons/INTEGER.h 2015-11-26 12:50:41.551623651 +0100 +--- skeletons/INTEGER.h 2015-12-08 14:39:33.346543533 +0100 ++++ skeletons/INTEGER.h 2015-11-26 12:50:41.551623000 +0100 @@ -43,6 +43,7 @@ per_type_encoder_f INTEGER_encode_uper; per_type_decoder_f INTEGER_decode_aper; @@ -605,8 +810,8 @@ /*********************************** * Some handy conversion routines. * ---- ./skeletons/ISO646String.c 2015-12-03 09:43:33.967009150 +0100 -+++ ./skeletons/ISO646String.c 2015-11-26 12:55:48.327623333 +0100 +--- skeletons/ISO646String.c 2015-12-08 14:39:33.342543533 +0100 ++++ skeletons/ISO646String.c 2015-11-26 12:55:48.327623000 +0100 @@ -30,7 +30,8 @@ OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, @@ -617,19 +822,25 @@ 0, /* Use generic outmost tag fetcher */ asn_DEF_ISO646String_tags, sizeof(asn_DEF_ISO646String_tags) ---- ./skeletons/Makefile.am 2015-12-03 09:43:33.715009150 +0100 -+++ ./skeletons/Makefile.am 2015-11-26 15:28:55.887613822 +0100 -@@ -50,7 +50,7 @@ +--- skeletons/Makefile.am 2015-12-08 14:39:12.666543554 +0100 ++++ skeletons/Makefile.am 2015-12-07 15:54:00.150628000 +0100 +@@ -46,11 +46,11 @@ + asn_SET_OF.c asn_SET_OF.h \ + asn_application.h asn_codecs.h \ + asn_codecs_prim.c asn_codecs_prim.h \ +- asn_internal.h asn_system.h \ ++ asn_internal.h asn_system.h asn_compare.h \ ber_decoder.c ber_decoder.h \ ber_tlv_length.c ber_tlv_length.h \ - ber_tlv_tag.c ber_tlv_tag.h \ +- ber_tlv_tag.c ber_tlv_tag.h \ - constr_CHOICE.c constr_CHOICE.h \ ++ ber_tlv_tag.c ber_tlv_tag.h compare.h \ + comparison.h constr_CHOICE.c constr_CHOICE.h \ constr_SEQUENCE.c constr_SEQUENCE.h \ constr_SEQUENCE_OF.c constr_SEQUENCE_OF.h \ constr_SET.c constr_SET.h \ ---- ./skeletons/NativeEnumerated.c 2015-12-03 09:43:33.967009150 +0100 -+++ ./skeletons/NativeEnumerated.c 2015-11-30 13:18:32.015264136 +0100 +--- skeletons/NativeEnumerated.c 2015-12-08 14:39:33.342543533 +0100 ++++ skeletons/NativeEnumerated.c 2015-12-08 10:41:17.662558000 +0100 @@ -31,7 +31,8 @@ NativeEnumerated_decode_uper, NativeEnumerated_encode_uper, @@ -640,34 +851,31 @@ 0, /* Use generic outmost tag fetcher */ asn_DEF_NativeEnumerated_tags, sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]), -@@ -335,3 +336,25 @@ +@@ -335,3 +336,22 @@ _ASN_ENCODED_OK(er); } + -+long ++asn_comp_rval_t * +NativeEnumerated_compare(asn_TYPE_descriptor_t *td1, void *sptr1, + asn_TYPE_descriptor_t *td2, void *sptr2) { + const asn_INTEGER_enum_map_t *a = sptr1; + const asn_INTEGER_enum_map_t *b = sptr2; -+ if ((td1) && (td2)) { -+ if ((td1->name) && (td2->name)) { -+ if (strcmp(td1->name, td2->name)) return -1; -+ } else { -+ if ((td1->xml_tag) && (td2->xml_tag)) { -+ if (strcmp(td1->xml_tag, td2->xml_tag)) return -1; -+ } -+ } -+ } ++ asn_comp_rval_t *res = NULL; ++ ++ COMPARE_CHECK_ARGS(td1, td2, sptr1, sptr2, res) + + if(a->nat_value == b->nat_value) -+ return 0; -+ if(a->nat_value < b->nat_value) -+ return -1; -+ return 1; ++ 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/NativeEnumerated.h 2015-12-03 09:43:33.967009150 +0100 -+++ ./skeletons/NativeEnumerated.h 2015-11-26 14:51:43.315616133 +0100 +--- skeletons/NativeEnumerated.h 2015-12-08 14:39:33.342543533 +0100 ++++ skeletons/NativeEnumerated.h 2015-11-26 14:51:43.315616000 +0100 @@ -26,6 +26,7 @@ per_type_encoder_f NativeEnumerated_encode_uper; per_type_decoder_f NativeEnumerated_decode_aper; @@ -676,8 +884,8 @@ #ifdef __cplusplus } ---- ./skeletons/NativeInteger.c 2015-12-03 09:43:33.967009150 +0100 -+++ ./skeletons/NativeInteger.c 2015-11-30 13:18:39.887264128 +0100 +--- skeletons/NativeInteger.c 2015-12-08 14:39:33.346543533 +0100 ++++ skeletons/NativeInteger.c 2015-12-08 10:41:24.550558000 +0100 @@ -32,7 +32,8 @@ NativeInteger_decode_uper, /* Unaligned PER decoder */ NativeInteger_encode_uper, /* Unaligned PER encoder */ @@ -688,29 +896,30 @@ 0, /* Use generic outmost tag fetcher */ asn_DEF_NativeInteger_tags, sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]), -@@ -410,3 +411,20 @@ +@@ -410,3 +411,21 @@ } } + -+long ++asn_comp_rval_t * +NativeInteger_compare(asn_TYPE_descriptor_t *td1, void *sptr1, + asn_TYPE_descriptor_t *td2, void *sptr2) { + const long *native1 = (const long *)sptr1; + const long *native2 = (const long *)sptr2; -+ if ((td1) && (td2)) { -+ if ((td1->name) && (td2->name)) { -+ if (strcmp(td1->name, td2->name)) return -1; -+ } else { -+ if ((td1->xml_tag) && (td2->xml_tag)) { -+ if (strcmp(td1->xml_tag, td2->xml_tag)) return -1; -+ } -+ } -+ } -+ return (*native1 != *native2); ++ asn_comp_rval_t *res = NULL; ++ ++ COMPARE_CHECK_ARGS(td1, td2, sptr1, sptr2, res) ++ ++ if (*native1 == *native2) 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/NativeInteger.h 2015-12-03 09:43:33.971009150 +0100 -+++ ./skeletons/NativeInteger.h 2015-11-26 14:52:13.931616101 +0100 +--- skeletons/NativeInteger.h 2015-12-08 14:39:33.346543533 +0100 ++++ skeletons/NativeInteger.h 2015-11-26 14:52:13.931616000 +0100 @@ -31,6 +31,7 @@ per_type_encoder_f NativeInteger_encode_uper; per_type_decoder_f NativeInteger_decode_aper; @@ -719,8 +928,8 @@ #ifdef __cplusplus } ---- ./skeletons/NativeReal.c 2015-12-03 09:43:33.971009150 +0100 -+++ ./skeletons/NativeReal.c 2015-11-30 13:18:46.655264121 +0100 +--- skeletons/NativeReal.c 2015-12-08 14:39:33.350543533 +0100 ++++ skeletons/NativeReal.c 2015-12-08 10:41:32.666558000 +0100 @@ -33,7 +33,8 @@ NativeReal_decode_uper, NativeReal_encode_uper, @@ -731,30 +940,39 @@ 0, /* Use generic outmost tag fetcher */ asn_DEF_NativeReal_tags, sizeof(asn_DEF_NativeReal_tags) / sizeof(asn_DEF_NativeReal_tags[0]), -@@ -405,3 +406,21 @@ +@@ -405,3 +406,30 @@ } } -+long ++asn_comp_rval_t * +NativeReal_compare(asn_TYPE_descriptor_t *td1, void *sptr1, + asn_TYPE_descriptor_t *td2, void *sptr2) { + REAL_t *st1 = (REAL_t *)sptr1; + REAL_t *st2 = (REAL_t *)sptr2; ++ asn_comp_rval_t *res = NULL; + -+ if ((td1) && (td2)) { -+ if ((td1->name) && (td2->name)) { -+ if (strcmp(td1->name, td2->name)) return -1; -+ } else { -+ if ((td1->xml_tag) && (td2->xml_tag)) { -+ if (strcmp(td1->xml_tag, td2->xml_tag)) return -1; -+ } -+ } ++ COMPARE_CHECK_ARGS(td1, td2, sptr1, sptr2, res) ++ ++ if (st1->size != st2->size) { ++ 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; + } -+ if (st1->size != st2->size) return -1; -+ return memcmp(st1->buf, st2->buf, st1->size); ++ if (0 != memcmp(st1->buf, st2->buf, st1->size)) { ++ 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; ++ } ++ return NULL; +} ---- ./skeletons/NativeReal.h 2015-12-03 09:43:33.971009150 +0100 -+++ ./skeletons/NativeReal.h 2015-11-26 14:31:12.631617407 +0100 +--- skeletons/NativeReal.h 2015-12-08 14:39:33.350543533 +0100 ++++ skeletons/NativeReal.h 2015-11-26 14:31:12.631617000 +0100 @@ -29,6 +29,7 @@ per_type_encoder_f NativeReal_encode_uper; per_type_decoder_f NativeReal_decode_aper; @@ -763,8 +981,8 @@ #ifdef __cplusplus } ---- ./skeletons/NULL.c 2015-12-03 09:43:33.963009150 +0100 -+++ ./skeletons/NULL.c 2015-11-30 13:18:53.047264114 +0100 +--- skeletons/NULL.c 2015-12-08 14:39:33.338543533 +0100 ++++ skeletons/NULL.c 2015-12-07 10:49:05.178647000 +0100 @@ -26,7 +26,8 @@ NULL_decode_uper, /* Unaligned PER decoder */ NULL_encode_uper, /* Unaligned PER encoder */ @@ -780,14 +998,14 @@ _ASN_ENCODED_OK(er); } + -+long ++asn_comp_rval_t * +NULL_compare(asn_TYPE_descriptor_t *td1, void *sptr1, + asn_TYPE_descriptor_t *td2, void *sptr2) { + -+ return 0; ++ return NULL; +} ---- ./skeletons/NULL.h 2015-12-03 09:43:33.963009150 +0100 -+++ ./skeletons/NULL.h 2015-11-26 14:53:03.875616050 +0100 +--- skeletons/NULL.h 2015-12-08 14:39:33.338543533 +0100 ++++ skeletons/NULL.h 2015-11-26 14:53:03.875616000 +0100 @@ -27,6 +27,7 @@ per_type_encoder_f NULL_encode_uper; per_type_decoder_f NULL_decode_aper; @@ -796,8 +1014,8 @@ #ifdef __cplusplus } ---- ./skeletons/NumericString.c 2015-12-03 09:43:33.963009150 +0100 -+++ ./skeletons/NumericString.c 2015-11-26 14:40:39.407616820 +0100 +--- skeletons/NumericString.c 2015-12-08 14:39:33.338543533 +0100 ++++ skeletons/NumericString.c 2015-11-26 14:40:39.407616000 +0100 @@ -50,7 +50,8 @@ OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, @@ -808,8 +1026,8 @@ 0, /* Use generic outmost tag fetcher */ asn_DEF_NumericString_tags, sizeof(asn_DEF_NumericString_tags) ---- ./skeletons/ObjectDescriptor.c 2015-12-03 09:43:33.963009150 +0100 -+++ ./skeletons/ObjectDescriptor.c 2015-11-26 14:55:46.227615882 +0100 +--- skeletons/ObjectDescriptor.c 2015-12-08 14:39:33.338543533 +0100 ++++ skeletons/ObjectDescriptor.c 2015-11-26 14:55:46.227615000 +0100 @@ -25,7 +25,8 @@ OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, @@ -820,8 +1038,8 @@ 0, /* Use generic outmost tag fetcher */ asn_DEF_ObjectDescriptor_tags, sizeof(asn_DEF_ObjectDescriptor_tags) ---- ./skeletons/OBJECT_IDENTIFIER.c 2015-12-03 09:43:33.967009150 +0100 -+++ ./skeletons/OBJECT_IDENTIFIER.c 2015-11-26 14:55:13.311615916 +0100 +--- skeletons/OBJECT_IDENTIFIER.c 2015-12-08 14:39:33.342543533 +0100 ++++ skeletons/OBJECT_IDENTIFIER.c 2015-11-26 14:55:13.311615000 +0100 @@ -28,7 +28,8 @@ OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, @@ -832,8 +1050,8 @@ 0, /* Use generic outmost tag fetcher */ asn_DEF_OBJECT_IDENTIFIER_tags, sizeof(asn_DEF_OBJECT_IDENTIFIER_tags) ---- ./skeletons/OCTET_STRING.c 2015-12-03 09:43:33.975009150 +0100 -+++ ./skeletons/OCTET_STRING.c 2015-11-30 13:19:18.271264088 +0100 +--- skeletons/OCTET_STRING.c 2015-12-08 14:39:44.554543521 +0100 ++++ skeletons/OCTET_STRING.c 2015-12-08 10:41:42.838558000 +0100 @@ -37,7 +37,8 @@ OCTET_STRING_decode_uper, /* Unaligned PER decoder */ OCTET_STRING_encode_uper, /* Unaligned PER encoder */ @@ -844,30 +1062,39 @@ 0, /* Use generic outmost tag fetcher */ asn_DEF_OCTET_STRING_tags, sizeof(asn_DEF_OCTET_STRING_tags) -@@ -2160,3 +2161,21 @@ +@@ -2160,3 +2161,30 @@ return st; } -+long ++asn_comp_rval_t * +OCTET_STRING_compare(asn_TYPE_descriptor_t *td1, + void *sptr1, asn_TYPE_descriptor_t *td2, void *sptr2) { + OCTET_STRING_t *st1 = (OCTET_STRING_t *)sptr1; + OCTET_STRING_t *st2 = (OCTET_STRING_t *)sptr2; ++ asn_comp_rval_t *res = NULL; + -+ if ((td1) && (td2)) { -+ if ((td1->name) && (td2->name)) { -+ if (strcmp(td1->name, td2->name)) return -1; -+ } else { -+ if ((td1->xml_tag) && (td2->xml_tag)) { -+ if (strcmp(td1->xml_tag, td2->xml_tag)) return -1; -+ } -+ } ++ COMPARE_CHECK_ARGS(td1, td2, sptr1, sptr2, res) ++ ++ if (st1->size != st2->size) { ++ 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; ++ } ++ if (0 != memcmp(st1->buf, st2->buf, st1->size)) { ++ 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; + } -+ if (st1->size != st2->size) return -1; -+ return memcmp(st1->buf, st2->buf, st1->size); ++ return NULL; +} ---- ./skeletons/OCTET_STRING.h 2015-12-03 09:43:33.971009150 +0100 -+++ ./skeletons/OCTET_STRING.h 2015-11-26 12:56:15.259623305 +0100 +--- skeletons/OCTET_STRING.h 2015-12-08 14:39:33.350543533 +0100 ++++ skeletons/OCTET_STRING.h 2015-11-26 12:56:15.259623000 +0100 @@ -34,6 +34,7 @@ per_type_encoder_f OCTET_STRING_encode_uper; per_type_decoder_f OCTET_STRING_decode_aper; @@ -876,8 +1103,8 @@ /****************************** * Handy conversion routines. * ---- ./skeletons/PrintableString.c 2015-12-03 09:43:33.963009150 +0100 -+++ ./skeletons/PrintableString.c 2015-11-26 14:56:09.787615857 +0100 +--- skeletons/PrintableString.c 2015-12-08 14:39:33.338543533 +0100 ++++ skeletons/PrintableString.c 2015-11-26 14:56:09.787615000 +0100 @@ -60,7 +60,8 @@ OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, @@ -888,8 +1115,8 @@ 0, /* Use generic outmost tag fetcher */ asn_DEF_PrintableString_tags, sizeof(asn_DEF_PrintableString_tags) ---- ./skeletons/REAL.c 2015-12-03 09:43:33.971009150 +0100 -+++ ./skeletons/REAL.c 2015-11-30 13:19:27.671264079 +0100 +--- skeletons/REAL.c 2015-12-08 14:39:33.350543533 +0100 ++++ skeletons/REAL.c 2015-12-08 10:41:55.178558000 +0100 @@ -46,7 +46,8 @@ REAL_decode_uper, REAL_encode_uper, @@ -900,32 +1127,41 @@ 0, /* Use generic outmost tag fetcher */ asn_DEF_REAL_tags, sizeof(asn_DEF_REAL_tags) / sizeof(asn_DEF_REAL_tags[0]), -@@ -741,3 +742,23 @@ +@@ -741,3 +742,32 @@ return 0; } + + -+long ++asn_comp_rval_t * +REAL_compare(asn_TYPE_descriptor_t *td1, void *sptr1, + asn_TYPE_descriptor_t *td2, void *sptr2) { + REAL_t *st1 = (REAL_t *)sptr1; + REAL_t *st2 = (REAL_t *)sptr2; ++ asn_comp_rval_t *res = NULL; + -+ if ((td1) && (td2)) { -+ if ((td1->name) && (td2->name)) { -+ if (strcmp(td1->name, td2->name)) return -1; -+ } else { -+ if ((td1->xml_tag) && (td2->xml_tag)) { -+ if (strcmp(td1->xml_tag, td2->xml_tag)) return -1; -+ } -+ } ++ COMPARE_CHECK_ARGS(td1, td2, sptr1, sptr2, res) ++ ++ if (st1->size != st2->size) { ++ 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; ++ } ++ if (0 != memcmp(st1->buf, st2->buf, st1->size)) { ++ 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; + } -+ if (st1->size != st2->size) return -1; -+ return memcmp(st1->buf, st2->buf, st1->size); ++ return NULL; +} ---- ./skeletons/REAL.h 2015-12-03 09:43:33.971009150 +0100 -+++ ./skeletons/REAL.h 2015-11-26 13:00:46.183623025 +0100 +--- skeletons/REAL.h 2015-12-08 14:39:33.350543533 +0100 ++++ skeletons/REAL.h 2015-11-26 13:00:46.183623000 +0100 @@ -23,6 +23,7 @@ per_type_encoder_f REAL_encode_uper; per_type_decoder_f REAL_decode_aper; @@ -934,8 +1170,8 @@ /*********************************** * Some handy conversion routines. * ---- ./skeletons/RELATIVE-OID.c 2015-12-03 09:43:33.963009150 +0100 -+++ ./skeletons/RELATIVE-OID.c 2015-11-26 14:56:31.703615834 +0100 +--- skeletons/RELATIVE-OID.c 2015-12-08 14:39:33.338543533 +0100 ++++ skeletons/RELATIVE-OID.c 2015-11-26 14:56:31.703615000 +0100 @@ -29,7 +29,8 @@ OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, @@ -946,8 +1182,8 @@ 0, /* Use generic outmost tag fetcher */ asn_DEF_RELATIVE_OID_tags, sizeof(asn_DEF_RELATIVE_OID_tags) ---- ./skeletons/T61String.c 2015-12-03 09:43:33.963009150 +0100 -+++ ./skeletons/T61String.c 2015-11-26 14:57:07.235615798 +0100 +--- skeletons/T61String.c 2015-12-08 14:39:33.338543533 +0100 ++++ skeletons/T61String.c 2015-11-26 14:57:07.235615000 +0100 @@ -25,7 +25,8 @@ OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, @@ -958,8 +1194,8 @@ 0, /* Use generic outmost tag fetcher */ asn_DEF_T61String_tags, sizeof(asn_DEF_T61String_tags) ---- ./skeletons/TeletexString.c 2015-12-03 09:43:33.963009150 +0100 -+++ ./skeletons/TeletexString.c 2015-11-26 14:57:17.643615787 +0100 +--- skeletons/TeletexString.c 2015-12-08 14:39:33.338543533 +0100 ++++ skeletons/TeletexString.c 2015-11-26 14:57:17.643615000 +0100 @@ -25,7 +25,8 @@ OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, @@ -970,8 +1206,8 @@ 0, /* Use generic outmost tag fetcher */ asn_DEF_TeletexString_tags, sizeof(asn_DEF_TeletexString_tags) ---- ./skeletons/UniversalString.c 2015-12-03 09:43:33.971009150 +0100 -+++ ./skeletons/UniversalString.c 2015-11-26 14:57:29.015615775 +0100 +--- skeletons/UniversalString.c 2015-12-08 14:39:33.350543533 +0100 ++++ skeletons/UniversalString.c 2015-11-26 14:57:29.015615000 +0100 @@ -36,7 +36,8 @@ OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, @@ -982,8 +1218,8 @@ 0, /* Use generic outmost tag fetcher */ asn_DEF_UniversalString_tags, sizeof(asn_DEF_UniversalString_tags) ---- ./skeletons/UTCTime.c 2015-12-03 09:43:33.971009150 +0100 -+++ ./skeletons/UTCTime.c 2015-11-26 14:57:44.127615759 +0100 +--- skeletons/UTCTime.c 2015-12-08 14:39:33.350543533 +0100 ++++ skeletons/UTCTime.c 2015-11-26 14:57:44.127615000 +0100 @@ -41,7 +41,8 @@ OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, @@ -994,8 +1230,8 @@ 0, /* Use generic outmost tag fetcher */ asn_DEF_UTCTime_tags, sizeof(asn_DEF_UTCTime_tags) ---- ./skeletons/UTF8String.c 2015-12-03 09:43:33.959009150 +0100 -+++ ./skeletons/UTF8String.c 2015-11-26 14:06:54.563618917 +0100 +--- skeletons/UTF8String.c 2015-12-08 14:39:33.314543533 +0100 ++++ skeletons/UTF8String.c 2015-11-26 14:06:54.563618000 +0100 @@ -27,6 +27,7 @@ OCTET_STRING_encode_uper, OCTET_STRING_decode_aper, @@ -1004,8 +1240,8 @@ 0, /* Use generic outmost tag fetcher */ asn_DEF_UTF8String_tags, sizeof(asn_DEF_UTF8String_tags) ---- ./skeletons/VideotexString.c 2015-12-03 09:43:33.967009150 +0100 -+++ ./skeletons/VideotexString.c 2015-11-26 14:07:06.139618905 +0100 +--- skeletons/VideotexString.c 2015-12-08 14:39:33.342543533 +0100 ++++ skeletons/VideotexString.c 2015-11-26 14:07:06.139618000 +0100 @@ -25,7 +25,8 @@ OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_uper, @@ -1016,8 +1252,8 @@ 0, /* Use generic outmost tag fetcher */ asn_DEF_VideotexString_tags, sizeof(asn_DEF_VideotexString_tags) ---- ./skeletons/VisibleString.c 2015-12-03 09:43:33.971009150 +0100 -+++ ./skeletons/VisibleString.c 2015-11-26 14:07:15.283618895 +0100 +--- skeletons/VisibleString.c 2015-12-08 14:39:33.350543533 +0100 ++++ skeletons/VisibleString.c 2015-11-26 14:07:15.283618000 +0100 @@ -30,7 +30,8 @@ OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, diff --git a/openair3/S1AP/MESSAGES/ASN1/asn1tostruct.py b/openair3/S1AP/MESSAGES/ASN1/asn1tostruct.py index f5daf03c254..446266d6a37 100644 --- a/openair3/S1AP/MESSAGES/ASN1/asn1tostruct.py +++ b/openair3/S1AP/MESSAGES/ASN1/asn1tostruct.py @@ -36,7 +36,7 @@ def outputHeaderToFile(f, filename): f.write("""/******************************************************************************* Eurecom OpenAirInterface - Copyright(c) 1999 - 2013 Eurecom + Copyright(c) 1999 - 2015 Eurecom This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -267,7 +267,7 @@ for key in iesDefs: f.write(" * \\param %s Pointer to the ASN1 structure.\n" % (firstlower)) f.write(" * \\param %s Pointer to the ASN1 structure.\n" % (firstlower)) f.write(" **/\n") - f.write("long %s_compare_%s(\n" % (fileprefix, keylowerunderscore)) + f.write("asn_comp_rval_t * %s_compare_%s(\n" % (fileprefix, keylowerunderscore)) f.write(" %s_t *%s1,\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key)))) f.write(" %s_t *%s2);\n\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key)))) @@ -311,7 +311,7 @@ for key in iesDefs: f.write(" * \\param %s Pointer to the IES structure.\n" % (firstlower)) f.write(" * \\param %s Pointer to the IES structure.\n" % (firstlower)) f.write(" **/\n") - f.write("long %s_compare_%s(\n" % (fileprefix, firstlower.lower())) + f.write("asn_comp_rval_t * %s_compare_%s(\n" % (fileprefix, firstlower.lower())) f.write(" %sIEs_t *%s1,\n" % (asn1cStruct, firstlower)) f.write(" %sIEs_t *%s2);\n\n" % (asn1cStruct, firstlower)) @@ -761,11 +761,12 @@ for key in iesDefs: if len(iesDefs[key]["ies"]) == 0: continue - f.write("long %s_compare_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower()))) + f.write("asn_comp_rval_t * %s_compare_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower()))) f.write(" %s_t *%s1,\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key)))) f.write(" %s_t *%s2) {\n\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key)))) - f.write(" long rv = 0;\n\n") + f.write(" asn_comp_rval_t *rv = NULL;\n\n") + f.write(" asn_comp_rval_t *rv2 = NULL;\n\n") f.write(" assert(%s1 != NULL);\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))); f.write(" assert(%s2 != NULL);\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))); @@ -784,7 +785,7 @@ for key in iesDefs: if loop == 1: #f.write(" %s_IE_t *ie1 = NULL;\n" % (fileprefix_first_upper)) #f.write(" %s_IE_t *ie2 = NULL;\n" % (fileprefix_first_upper)) - f.write(" if (%s1->presenceMask != %s2->presenceMask) return -1;\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), lowerFirstCamelWord(re.sub('-', '_', key)))) + f.write(" if (%s1->presenceMask != %s2->presenceMask) {rv=calloc(1,sizeof(asn_comp_rval_t));rv->name = asn_DEF_%s.name;rv->structure1 = %s1;rv->structure2 = %s2;rv->err_code = COMPARE_ERR_CODE_VALUE_NULL; return rv;}\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), lowerFirstCamelWord(re.sub('-', '_', key)), ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', key)), lowerFirstCamelWord(re.sub('-', '_', key)))) if ie[3] == "optional": f.write(" /* Optional field */\n") @@ -795,25 +796,61 @@ for key in iesDefs: if ie[2] in ieofielist.keys(): f.write(" /* collection field */\n") - f.write(" rv = %s_compare_%s(&%s1->%s, &%s2->%s);\n" % (fileprefix, ietypeunderscore.lower(), lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower )) - f.write(" if (rv != 0) {rv = rv << 8; rv |= %s_ProtocolIE_ID_id_%s; return rv;}\n" % (fileprefix_first_upper, ienameunderscore)) + f.write(" rv2 = %s_compare_%s(&%s1->%s, &%s2->%s);\n" % (fileprefix, ietypeunderscore.lower(), lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower )) + f.write(" if(rv2) {") + f.write(" if (NULL == rv) {") + f.write(" rv = rv2;") + f.write(" } else {") + f.write(" rv2->next = rv;") + f.write(" rv = rv2;") + f.write(" }") + f.write(" rv2 = NULL;") + f.write(" }") else: f.write(" /* simple field */\n") - f.write(" rv = asn_DEF_%s.compare(&asn_DEF_%s, &%s1->%s, &asn_DEF_%s, &%s2->%s); \n" % (ietypeunderscore, ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower, ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower )) - f.write(" if (rv != 0) {rv = rv << 8; rv |= %s_ProtocolIE_ID_id_%s; return rv;}\n" % (fileprefix_first_upper, ienameunderscore)) + f.write(" rv2 = asn_DEF_%s.compare(&asn_DEF_%s, &%s1->%s, &asn_DEF_%s, &%s2->%s); \n" % (ietypeunderscore, ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower, ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower )) + f.write(" if (rv2) {") + f.write(" if (NULL == rv) {") + f.write(" rv = rv2;") + f.write(" } else {") + f.write(" rv2->next = rv;") + f.write(" rv = rv2;") + f.write(" }") + f.write(" rv2 = NULL;") + f.write(" if (!rv->name) rv->name = asn_DEF_%s.name;" % (ietypeunderscore)) + f.write(" }") + f.write(" assert(0);\n"); f.write(" }\n\n") else: if ie[2] in ieofielist.keys(): f.write(" /* Mandatory collection field */\n") - f.write(" rv = %s_compare_%s(&%s1->%s, &%s2->%s);\n" % (fileprefix, ietypeunderscore.lower(), lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower )) - f.write(" if (rv != 0) {rv = rv << 8; rv |= %s_ProtocolIE_ID_id_%s; return rv;}\n" % (fileprefix_first_upper, ienameunderscore)) + f.write(" rv2 = %s_compare_%s(&%s1->%s, &%s2->%s);\n" % (fileprefix, ietypeunderscore.lower(), lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower )) + f.write(" if (rv2) {\n") + f.write(" if (NULL == rv) {\n") + f.write(" rv = rv2;\n") + f.write(" } else {\n") + f.write(" rv2->next = rv;\n") + f.write(" rv = rv2;\n") + f.write(" }\n") + f.write(" rv2 = NULL;\n") + f.write(" }\n") + else: f.write(" /* Mandatory simple field */\n") - f.write(" rv = asn_DEF_%s.compare(&asn_DEF_%s, &%s1->%s, &asn_DEF_%s, &%s2->%s);\n" % (ietypeunderscore, ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower, ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower )) - f.write(" if (rv != 0) {rv = rv << 8; rv |= %s_ProtocolIE_ID_id_%s; return rv;}\n" % (fileprefix_first_upper, ienameunderscore)) - f.write(" return 0;\n") + f.write(" rv2 = asn_DEF_%s.compare(&asn_DEF_%s, &%s1->%s, &asn_DEF_%s, &%s2->%s);\n" % (ietypeunderscore, ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower, ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower )) + f.write(" if(rv2) {\n") + f.write(" if (NULL == rv) {\n") + f.write(" rv = rv2;\n") + f.write(" } else {\n") + f.write(" rv2->next = rv;\n") + f.write(" rv = rv2;\n") + f.write(" }\n") + f.write(" rv2 = NULL;\n") + f.write(" if (!rv->name) rv->name = asn_DEF_%s.name;\n" % (ietypeunderscore)) + f.write(" }\n") + f.write(" return rv;\n") f.write("}\n\n") for (key, value) in iesDefs.items(): @@ -832,19 +869,29 @@ for (key, value) in iesDefs.items(): f.write("extern asn_TYPE_descriptor_t asn_DEF_%s;\n" % (ietypeunderscore)) - f.write("long %s_compare_%s(\n" % (fileprefix, re.sub('-', '_', i).lower())) + f.write("asn_comp_rval_t * %s_compare_%s(\n" % (fileprefix, re.sub('-', '_', i).lower())) f.write(" %sIEs_t *%sIEs1,\n" % (re.sub('-', '_', i), lowerFirstCamelWord(re.sub('-', '_', i)))) f.write(" %sIEs_t *%sIEs2) {\n\n" % (re.sub('-', '_', i), lowerFirstCamelWord(re.sub('-', '_', i)))) f.write(" int i;\n") - f.write(" long rv = 0;\n") + f.write(" asn_comp_rval_t *rv = NULL;\n\n") + f.write(" asn_comp_rval_t *rv2 = NULL;\n\n") + f.write(" assert(%sIEs1 != NULL);\n" % (lowerFirstCamelWord(re.sub('-', '_', i)))); f.write(" assert(%sIEs2 != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', i)))); f.write(" for (i = 0; i < %sIEs1->%s.count; i++) {\n" % (lowerFirstCamelWord(re.sub('-', '_', i)), re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))))) - f.write(" rv = asn_DEF_%s.compare(&asn_DEF_%s, %sIEs1->%s.array[i], &asn_DEF_%s, %sIEs2->%s.array[i]);\n" % (ietypeunderscore, ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', i)), re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))), ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', i)), re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))))) - f.write(" if (rv != 0) return rv;\n") + f.write(" rv2 = asn_DEF_%s.compare(&asn_DEF_%s, %sIEs1->%s.array[i], &asn_DEF_%s, %sIEs2->%s.array[i]);\n" % (ietypeunderscore, ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', i)), re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))), ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', i)), re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))))) + f.write(" if(rv2) {") + f.write(" if (NULL == rv) {") + f.write(" rv = rv2;") + f.write(" } else {") + f.write(" rv2->next = rv;") + f.write(" rv = rv2;") + f.write(" }") + f.write(" rv2 = NULL;") + f.write(" }") f.write(" }\n") - f.write(" return 0;\n") + f.write(" return rv;\n") f.write("}\n\n") diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c index 1aab2164282..133e9adf4bc 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.c +++ b/openair3/TEST/EPC_TEST/play_scenario.c @@ -286,14 +286,26 @@ const char * const et_chunk_type_cid2str(const sctp_cid_t chunk_type) const char * const et_error_match2str(const int err) { switch (err) { - case -ET_ERROR_MATCH_PACKET_SCTP_CHUNK_TYPE: return "SCTP_CHUNK_TYPE"; break; - case -ET_ERROR_MATCH_PACKET_SCTP_PPID: return "SCTP_PPID"; break; - case -ET_ERROR_MATCH_PACKET_SCTP_ASSOC_ID: return "SCTP_ASSOC_ID"; break; - case -ET_ERROR_MATCH_PACKET_SCTP_STREAM_ID: return "SCTP_STREAM_ID"; break; - case -ET_ERROR_MATCH_PACKET_SCTP_SSN: return "SCTP_SSN"; break; - case -ET_ERROR_MATCH_PACKET_S1AP_PRESENT: return "S1AP_PRESENT"; break; - case -ET_ERROR_MATCH_PACKET_S1AP_PROCEDURE_CODE: return "S1AP_PROCEDURE_CODE"; break; - case -ET_ERROR_MATCH_PACKET_S1AP_CRITICALITY: return "S1AP_CRITICALITY"; break; + // from asn_compare.h + case COMPARE_ERR_CODE_NO_MATCH: return "CODE_NO_MATCH"; break; + case COMPARE_ERR_CODE_TYPE_MISMATCH: return "TYPE_MISMATCH"; break; + case COMPARE_ERR_CODE_TYPE_ARG_NULL: return "TYPE_ARG_NULL"; break; + case COMPARE_ERR_CODE_VALUE_NULL: return "VALUE_NULL"; break; + case COMPARE_ERR_CODE_VALUE_ARG_NULL: return "VALUE_ARG_NULL"; break; + case COMPARE_ERR_CODE_CHOICE_NUM: return "CHOICE_NUM"; break; + case COMPARE_ERR_CODE_CHOICE_PRESENT: return "CHOICE_PRESENT"; break; + case COMPARE_ERR_CODE_CHOICE_MALFORMED: return "CHOICE_MALFORMED"; break; + case COMPARE_ERR_CODE_SET_MALFORMED: return "SET_MALFORMED"; break; + case COMPARE_ERR_CODE_COLLECTION_NUM_ELEMENTS: return "COLLECTION_NUM_ELEMENTS"; break; + // from play_scenario.h + case ET_ERROR_MATCH_PACKET_SCTP_CHUNK_TYPE: return "SCTP_CHUNK_TYPE"; break; + case ET_ERROR_MATCH_PACKET_SCTP_PPID: return "SCTP_PPID"; break; + case ET_ERROR_MATCH_PACKET_SCTP_ASSOC_ID: return "SCTP_ASSOC_ID"; break; + case ET_ERROR_MATCH_PACKET_SCTP_STREAM_ID: return "SCTP_STREAM_ID"; break; + case ET_ERROR_MATCH_PACKET_SCTP_SSN: return "SCTP_SSN"; break; + case ET_ERROR_MATCH_PACKET_S1AP_PRESENT: return "S1AP_PRESENT"; break; + case ET_ERROR_MATCH_PACKET_S1AP_PROCEDURE_CODE: return "S1AP_PROCEDURE_CODE"; break; + case ET_ERROR_MATCH_PACKET_S1AP_CRITICALITY: return "S1AP_CRITICALITY"; break; default: AssertFatal (0, "ERROR: Unknown match error %d!(TODO handle an1c error codes)\n", err); } @@ -792,9 +804,9 @@ static void et_usage ( fprintf (stdout, "Please report any bug to: %s\n",PACKAGE_BUGREPORT); fprintf (stdout, "Usage: %s [options]\n\n", argv[0]); fprintf (stdout, "\n"); - fprintf (stdout, "Client options:\n"); - fprintf (stdout, "\t-S | --server <server network @> File name (with no path) of a test scenario that has to be replayed (TODO in future?)\n"); - fprintf (stdout, "Server options:\n"); + //fprintf (stdout, "Client options:\n"); + //fprintf (stdout, "\t-S | --server <server network @> File name (with no path) of a test scenario that has to be replayed (TODO in future?)\n"); + //fprintf (stdout, "Server options:\n"); fprintf (stdout, "\t-d | --test-dir <dir> Directory where a set of files related to a particular test are located\n"); fprintf (stdout, "\t-c | --enb-conf-file <file> Provide an eNB config file, valid for the testbed\n"); fprintf (stdout, "\t-s | --scenario <file> File name (with no path) of a test scenario that has to be replayed ()\n"); diff --git a/openair3/TEST/EPC_TEST/play_scenario.h b/openair3/TEST/EPC_TEST/play_scenario.h index a926ea55e49..f44974dae01 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.h +++ b/openair3/TEST/EPC_TEST/play_scenario.h @@ -46,6 +46,7 @@ #include "s1ap_ies_defs.h" #include "play_scenario_s1ap_eNB_defs.h" #include "hashtable.h" +#include "asn_compare.h" // powers of 2 #define ET_BIT_MASK_MATCH_SCTP_STREAM 1 @@ -179,8 +180,10 @@ typedef enum { ET_FSM_STATE_END } et_fsm_state_t; +enum COMPARE_ERR_CODE_e; + typedef enum { - ET_ERROR_MATCH_START = 1, + ET_ERROR_MATCH_START = COMPARE_ERR_CODE_END, ET_ERROR_MATCH_PACKET_SCTP_CHUNK_TYPE = ET_ERROR_MATCH_START, ET_ERROR_MATCH_PACKET_SCTP_PPID, ET_ERROR_MATCH_PACKET_SCTP_ASSOC_ID, @@ -415,7 +418,8 @@ void et_s1ap_eNB_insert_new_instance(s1ap_eNB_instance_t *new_instance_p); struct s1ap_eNB_mme_data_s *et_s1ap_eNB_get_MME(s1ap_eNB_instance_t *instance_p,int32_t assoc_id, uint16_t cnx_id); s1ap_eNB_instance_t *et_s1ap_eNB_get_instance(instance_t instance); void et_s1ap_eNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,uint32_t buffer_length, uint16_t stream); -long et_s1ap_is_matching(et_s1ap_t * const s1ap1, et_s1ap_t * const s1ap2, const uint32_t constraints); +int et_handle_s1ap_mismatch(et_packet_t * const spacket, et_packet_t * const rx_packet); +asn_comp_rval_t* et_s1ap_is_matching(et_s1ap_t * const s1ap1, et_s1ap_t * const s1ap2, const uint32_t constraints); et_packet_t* et_build_packet_from_s1ap_data_ind(et_event_s1ap_data_ind_t * const s1ap_data_ind); int et_scenario_set_packet_received(et_packet_t * const packet); int et_s1ap_process_rx_packet(et_event_s1ap_data_ind_t * const sctp_data_ind); @@ -451,10 +455,10 @@ void et_parse_sctp(xmlDocPtr doc, const xmlNode const *sctp_node, et_sctp_hdr_t et_packet_t* et_parse_xml_packet(xmlDocPtr doc, xmlNodePtr node); et_scenario_t* et_generate_scenario(const char * const et_scenario_filename ); //------------------------- -long et_s1ap_ies_is_matching(const S1AP_PDU_PR present, s1ap_message * const m1, s1ap_message * const m2, const uint32_t constraints); +asn_comp_rval_t * et_s1ap_ies_is_matching(const S1AP_PDU_PR present, s1ap_message * const m1, s1ap_message * const m2, const uint32_t constraints); //------------------------- -long et_sctp_data_is_matching(sctp_datahdr_t * const sctp1, sctp_datahdr_t * const sctp2, const uint32_t constraints); -long et_sctp_is_matching(et_sctp_hdr_t * const sctp1, et_sctp_hdr_t * const sctp2, const uint32_t constraints); +asn_comp_rval_t * et_sctp_data_is_matching(sctp_datahdr_t * const sctp1, sctp_datahdr_t * const sctp2, const uint32_t constraints); +asn_comp_rval_t * et_sctp_is_matching(et_sctp_hdr_t * const sctp1, et_sctp_hdr_t * const sctp2, const uint32_t constraints); //------------------------------------------------------------------------------ void et_print_hex_octets(const unsigned char * const byte_stream, const unsigned long int num); int et_is_file_exists ( const char const * file_nameP, const char const *file_roleP); diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c index df26de97c2d..d58b16c2d35 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c @@ -189,30 +189,363 @@ void et_s1ap_eNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, itti_send_msg_to_task(TASK_SCTP, instance, message_p); } //------------------------------------------------------------------------------ -long et_s1ap_is_matching(et_s1ap_t * const s1ap1, et_s1ap_t * const s1ap2, const uint32_t constraints) +int et_handle_s1ap_mismatch(et_packet_t * const spacket, et_packet_t * const rx_packet) { - if (s1ap1->pdu.present != s1ap2->pdu.present) return -ET_ERROR_MATCH_PACKET_S1AP_PRESENT; + S1ap_MME_UE_S1AP_ID_t scenario_mme_ue_s1ap_id = 0; + S1ap_MME_UE_S1AP_ID_t rx_mme_ue_s1ap_id = 0; + S1AP_PDU_PR present; + + present = rx_packet->sctp_hdr.u.data_hdr.payload.pdu.present; + + switch (rx_packet->sctp_hdr.u.data_hdr.payload.message.procedureCode) { + case S1ap_ProcedureCode_id_HandoverPreparation: + if (present == S1AP_PDU_PR_initiatingMessage) { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequiredIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequiredIEs.mme_ue_s1ap_id; + } else { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverCommandIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverCommandIEs.mme_ue_s1ap_id; + } + break; + + case S1ap_ProcedureCode_id_HandoverResourceAllocation: + if (present == S1AP_PDU_PR_initiatingMessage) { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequestIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequestIEs.mme_ue_s1ap_id; + } else if (present == S1AP_PDU_PR_successfulOutcome) { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequestAcknowledgeIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequestAcknowledgeIEs.mme_ue_s1ap_id; + } else if (present == S1AP_PDU_PR_unsuccessfulOutcome) { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverFailureIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverFailureIEs.mme_ue_s1ap_id; + } + break; + + case S1ap_ProcedureCode_id_HandoverNotification: + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverNotifyIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverNotifyIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_PathSwitchRequest: + //rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_PathSwitchRequestIEs.mme_ue_s1ap_id; + //scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_PathSwitchRequestIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_HandoverCancel: + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverCancelIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverCancelIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_E_RABSetup: + if (present == S1AP_PDU_PR_initiatingMessage) { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABSetupRequestIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABSetupRequestIEs.mme_ue_s1ap_id; + } else { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABSetupResponseIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABSetupResponseIEs.mme_ue_s1ap_id; + } + break; + + case S1ap_ProcedureCode_id_E_RABModify: + if (present == S1AP_PDU_PR_initiatingMessage) { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABModifyRequestIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABModifyRequestIEs.mme_ue_s1ap_id; + } else { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABModifyResponseIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABModifyResponseIEs.mme_ue_s1ap_id; + } + break; + + case S1ap_ProcedureCode_id_E_RABRelease: + if (present == S1AP_PDU_PR_initiatingMessage) { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABReleaseCommandIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABReleaseCommandIEs.mme_ue_s1ap_id; + } else { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABReleaseResponseIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABReleaseResponseIEs.mme_ue_s1ap_id; + } + break; + + case S1ap_ProcedureCode_id_E_RABReleaseIndication: + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABReleaseIndicationIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABReleaseIndicationIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_InitialContextSetup: + if (present == S1AP_PDU_PR_initiatingMessage) { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_InitialContextSetupRequestIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_InitialContextSetupRequestIEs.mme_ue_s1ap_id; + } else { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_InitialContextSetupResponseIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_InitialContextSetupResponseIEs.mme_ue_s1ap_id; + } + break; + + case S1ap_ProcedureCode_id_Paging: + //rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_PagingIEs.mme_ue_s1ap_id; + //scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_PagingIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_downlinkNASTransport: + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkNASTransportIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkNASTransportIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_initialUEMessage: + //rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_InitialUEMessageIEs.mme_ue_s1ap_id; + //scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_InitialUEMessageIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_uplinkNASTransport: + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkNASTransportIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkNASTransportIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_Reset: + //rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ResetIEs.mme_ue_s1ap_id; + //scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ResetIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_ErrorIndication: + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ErrorIndicationIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ErrorIndicationIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_NASNonDeliveryIndication: + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_NASNonDeliveryIndication_IEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_NASNonDeliveryIndication_IEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_S1Setup: + /*if (present == S1AP_PDU_PR_initiatingMessage) { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_S1SetupRequestIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_S1SetupRequestIEs.mme_ue_s1ap_id; + } else if (present == S1AP_PDU_PR_successfulOutcome) { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_S1SetupResponseIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_S1SetupResponseIEs.mme_ue_s1ap_id; + } else if (present == S1AP_PDU_PR_unsuccessfulOutcome) { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_S1SetupFailureIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_S1SetupFailureIEs.mme_ue_s1ap_id; + }*/ + break; + + case S1ap_ProcedureCode_id_UEContextReleaseRequest: + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextReleaseRequestIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextReleaseRequestIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_DownlinkS1cdma2000tunneling: + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkS1cdma2000tunnelingIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkS1cdma2000tunnelingIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_UplinkS1cdma2000tunneling: + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkS1cdma2000tunnelingIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkS1cdma2000tunnelingIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_UEContextModification: + if (present == S1AP_PDU_PR_initiatingMessage) { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextModificationRequestIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextModificationRequestIEs.mme_ue_s1ap_id; + } else if (present == S1AP_PDU_PR_successfulOutcome) { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextModificationResponseIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextModificationResponseIEs.mme_ue_s1ap_id; + } else if (present == S1AP_PDU_PR_unsuccessfulOutcome) { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextModificationFailureIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextModificationFailureIEs.mme_ue_s1ap_id; + } + break; + + case S1ap_ProcedureCode_id_UECapabilityInfoIndication: + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UECapabilityInfoIndicationIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UECapabilityInfoIndicationIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_UEContextRelease: + if (present == S1AP_PDU_PR_initiatingMessage) { + //rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextReleaseCommandIEs.mme_ue_s1ap_id; + //scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextReleaseCommandIEs.mme_ue_s1ap_id; + } else { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextReleaseCompleteIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextReleaseCompleteIEs.mme_ue_s1ap_id; + } + break; + + case S1ap_ProcedureCode_id_eNBStatusTransfer: + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ENBStatusTransferIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ENBStatusTransferIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_MMEStatusTransfer: + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_MMEStatusTransferIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_MMEStatusTransferIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_DeactivateTrace: + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DeactivateTraceIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DeactivateTraceIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_TraceStart: + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_TraceStartIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_TraceStartIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_TraceFailureIndication: + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_TraceFailureIndicationIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_TraceFailureIndicationIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_ENBConfigurationUpdate: + /*if (present == S1AP_PDU_PR_initiatingMessage) { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ENBConfigurationUpdateIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ENBConfigurationUpdateIEs.mme_ue_s1ap_id; + } else if (present == S1AP_PDU_PR_successfulOutcome) { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ENBConfigurationUpdateAcknowledgeIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ENBConfigurationUpdateAcknowledgeIEs.mme_ue_s1ap_id; + } else { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ENBConfigurationUpdateFailureIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ENBConfigurationUpdateFailureIEs.mme_ue_s1ap_id; + }*/ + break; + + case S1ap_ProcedureCode_id_MMEConfigurationUpdate: + /*if (present == S1AP_PDU_PR_initiatingMessage) { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_MMEConfigurationUpdateIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_MMEConfigurationUpdateIEs.mme_ue_s1ap_id; + } else if (present == S1AP_PDU_PR_successfulOutcome) { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_MMEConfigurationUpdateAcknowledgeIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_MMEConfigurationUpdateAcknowledgeIEs.mme_ue_s1ap_id; + } else { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_MMEConfigurationUpdateFailureIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_MMEConfigurationUpdateFailureIEs.mme_ue_s1ap_id; + }*/ + break; + + case S1ap_ProcedureCode_id_LocationReportingControl: + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_LocationReportingControlIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_LocationReportingControlIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_LocationReportingFailureIndication: + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_LocationReportingFailureIndicationIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_LocationReportingFailureIndicationIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_LocationReport: + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_LocationReportIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_LocationReportIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_OverloadStart: + //rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_OverloadStartIEs.mme_ue_s1ap_id; + //scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_OverloadStartIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_OverloadStop: + //rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_OverloadStopIEs.mme_ue_s1ap_id; + //scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_OverloadStopIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_WriteReplaceWarning: + /*if (present == S1AP_PDU_PR_initiatingMessage) { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_WriteReplaceWarningRequestIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_WriteReplaceWarningRequestIEs.mme_ue_s1ap_id; + } else { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_WriteReplaceWarningResponseIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_WriteReplaceWarningResponseIEs.mme_ue_s1ap_id; + }*/ + break; + + case S1ap_ProcedureCode_id_eNBDirectInformationTransfer: + //rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ENBDirectInformationTransferIEs.mme_ue_s1ap_id; + //scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ENBDirectInformationTransferIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_MMEDirectInformationTransfer: + //rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_MMEDirectInformationTransferIEs.mme_ue_s1ap_id; + //scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_MMEDirectInformationTransferIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_PrivateMessage: + case S1ap_ProcedureCode_id_eNBConfigurationTransfer: + case S1ap_ProcedureCode_id_MMEConfigurationTransfer: + AssertFatal(0, "TODO"); + break; + + case S1ap_ProcedureCode_id_CellTrafficTrace: + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_CellTrafficTraceIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_CellTrafficTraceIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_Kill: + /*if (present == S1AP_PDU_PR_initiatingMessage) { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_KillRequestIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_KillRequestIEs.mme_ue_s1ap_id; + } else { + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_KillResponseIEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_KillResponseIEs.mme_ue_s1ap_id; + }*/ + break; + + case S1ap_ProcedureCode_id_downlinkUEAssociatedLPPaTransport: + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkUEAssociatedLPPaTransport_IEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkUEAssociatedLPPaTransport_IEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_uplinkUEAssociatedLPPaTransport: + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkUEAssociatedLPPaTransport_IEs.mme_ue_s1ap_id; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkUEAssociatedLPPaTransport_IEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_downlinkNonUEAssociatedLPPaTransport: + //rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkNonUEAssociatedLPPaTransport_IEs.mme_ue_s1ap_id; + //scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkNonUEAssociatedLPPaTransport_IEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_uplinkNonUEAssociatedLPPaTransport: + //rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkNonUEAssociatedLPPaTransport_IEs.mme_ue_s1ap_id; + //scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkNonUEAssociatedLPPaTransport_IEs.mme_ue_s1ap_id; + break; + + default: + AssertFatal(0, "Unknown procedure code %ld", rx_packet->sctp_hdr.u.data_hdr.payload.message.procedureCode); + } + return 0; +} +//------------------------------------------------------------------------------ +asn_comp_rval_t * et_s1ap_is_matching(et_s1ap_t * const s1ap1, et_s1ap_t * const s1ap2, const uint32_t constraints) +{ + asn_comp_rval_t *rv = NULL; + if (s1ap1->pdu.present != s1ap2->pdu.present) {rv = calloc(1, sizeof(asn_comp_rval_t)); rv->err_code = ET_ERROR_MATCH_PACKET_S1AP_PRESENT; return rv;} switch (s1ap1->pdu.present) { case S1AP_PDU_PR_NOTHING: break; case S1AP_PDU_PR_initiatingMessage: - if (s1ap1->pdu.choice.initiatingMessage.procedureCode != s1ap2->pdu.choice.initiatingMessage.procedureCode) return -ET_ERROR_MATCH_PACKET_S1AP_PROCEDURE_CODE; - if (s1ap1->pdu.choice.initiatingMessage.criticality != s1ap2->pdu.choice.initiatingMessage.criticality) return -ET_ERROR_MATCH_PACKET_S1AP_CRITICALITY; + if (s1ap1->pdu.choice.initiatingMessage.procedureCode != s1ap2->pdu.choice.initiatingMessage.procedureCode) + {rv = calloc(1, sizeof(asn_comp_rval_t)); rv->err_code = ET_ERROR_MATCH_PACKET_S1AP_PROCEDURE_CODE; return rv;} + if (s1ap1->pdu.choice.initiatingMessage.criticality != s1ap2->pdu.choice.initiatingMessage.criticality) + {rv = calloc(1, sizeof(asn_comp_rval_t)); rv->err_code = ET_ERROR_MATCH_PACKET_S1AP_CRITICALITY; return rv;} break; case S1AP_PDU_PR_successfulOutcome: - if (s1ap1->pdu.choice.successfulOutcome.procedureCode != s1ap2->pdu.choice.successfulOutcome.procedureCode) return -ET_ERROR_MATCH_PACKET_S1AP_PROCEDURE_CODE; - if (s1ap1->pdu.choice.successfulOutcome.criticality != s1ap2->pdu.choice.successfulOutcome.criticality) return -ET_ERROR_MATCH_PACKET_S1AP_CRITICALITY; + if (s1ap1->pdu.choice.successfulOutcome.procedureCode != s1ap2->pdu.choice.successfulOutcome.procedureCode) + {rv = calloc(1, sizeof(asn_comp_rval_t)); rv->err_code = ET_ERROR_MATCH_PACKET_S1AP_PROCEDURE_CODE; return rv;} + if (s1ap1->pdu.choice.successfulOutcome.criticality != s1ap2->pdu.choice.successfulOutcome.criticality) + {rv = calloc(1, sizeof(asn_comp_rval_t)); rv->err_code = ET_ERROR_MATCH_PACKET_S1AP_CRITICALITY; return rv;} break; case S1AP_PDU_PR_unsuccessfulOutcome: - if (s1ap1->pdu.choice.unsuccessfulOutcome.procedureCode != s1ap2->pdu.choice.unsuccessfulOutcome.procedureCode) return -ET_ERROR_MATCH_PACKET_S1AP_PROCEDURE_CODE; - if (s1ap1->pdu.choice.unsuccessfulOutcome.criticality != s1ap2->pdu.choice.unsuccessfulOutcome.criticality) return -ET_ERROR_MATCH_PACKET_S1AP_CRITICALITY; + if (s1ap1->pdu.choice.unsuccessfulOutcome.procedureCode != s1ap2->pdu.choice.unsuccessfulOutcome.procedureCode) + {rv = calloc(1, sizeof(asn_comp_rval_t)); rv->err_code = ET_ERROR_MATCH_PACKET_S1AP_PROCEDURE_CODE; return rv;} + if (s1ap1->pdu.choice.unsuccessfulOutcome.criticality != s1ap2->pdu.choice.unsuccessfulOutcome.criticality) + {rv = calloc(1, sizeof(asn_comp_rval_t)); rv->err_code = ET_ERROR_MATCH_PACKET_S1AP_CRITICALITY; return rv;} break; default: AssertFatal(0, "Unknown pdu.present %d", s1ap1->pdu.present); } if (s1ap1->binary_stream_allocated_size == s1ap2->binary_stream_allocated_size) { - if (memcmp((void*)s1ap1->binary_stream, (void*)s1ap2->binary_stream, s1ap1->binary_stream_allocated_size) == 0) return 0; + if (memcmp((void*)s1ap1->binary_stream, (void*)s1ap2->binary_stream, s1ap1->binary_stream_allocated_size) == 0) return NULL; } // if no matching, may be the scenario need minor corrections (same enb_ue_s1ap_id but need to update mme_ue_s1ap_id) return et_s1ap_ies_is_matching(s1ap1->pdu.present, &s1ap1->message, &s1ap2->message, constraints); @@ -284,10 +617,12 @@ int et_scenario_set_packet_received(et_packet_t * const packet) //------------------------------------------------------------------------------ int et_s1ap_process_rx_packet(et_event_s1ap_data_ind_t * const s1ap_data_ind) { - et_packet_t * packet = NULL; - et_packet_t * rx_packet = NULL; - unsigned long int not_found = 1; - long rv = 0; + et_packet_t *packet = NULL; + et_packet_t *rx_packet = NULL; + unsigned long int not_found = 1; + asn_comp_rval_t *comp_results = NULL; + asn_comp_rval_t *comp_results2 = NULL; + unsigned char error_code = 0; AssertFatal (NULL != s1ap_data_ind, "Bad parameter sctp_data_ind\n"); rx_packet = et_build_packet_from_s1ap_data_ind(s1ap_data_ind); @@ -317,20 +652,35 @@ int et_s1ap_process_rx_packet(et_event_s1ap_data_ind_t * const s1ap_data_ind) // not_found threshold may sure depend on number of mme, may be not sure on number of UE while ((NULL != packet) && (not_found < 5)) { if (packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { - rv = et_sctp_is_matching(&packet->sctp_hdr, &rx_packet->sctp_hdr, g_constraints); - if (0 == rv) { + comp_results = et_sctp_is_matching(&packet->sctp_hdr, &rx_packet->sctp_hdr, g_constraints); + if (NULL == comp_results) { S1AP_DEBUG("Compare RX packet with packet: num %u | original frame number %u \n", packet->packet_number, packet->original_frame_number); packet->timestamp_packet.tv_sec = rx_packet->timestamp_packet.tv_sec; packet->timestamp_packet.tv_usec = rx_packet->timestamp_packet.tv_usec; return et_scenario_set_packet_received(packet); } else { - S1AP_DEBUG("Compare RX packet with packet: num %u | original frame number %u failed:%s\n", - packet->packet_number, packet->original_frame_number, et_error_match2str(rv)); - // asn1 compare no match return code, may not collide with non asn1 error return codes - // (each asn1 rc <= 166 (enum e_S1ap_ProtocolIE_ID, in generated file S1ap_ProtocolIE_ID.h)) - if ((rv > 0) || (rv <= -ET_ERROR_MATCH_END)) { - //TODO MME_UE_S1AP_ID, etc. - AssertFatal(0,"Some work needed there"); + S1AP_DEBUG("Compare RX packet with packet: num %u | original frame number %u failed\n", + packet->packet_number, packet->original_frame_number); + while (comp_results) { + S1AP_DEBUG("Result err code %s(%u) ASN1 struct name %s\n", + et_error_match2str(comp_results->err_code), comp_results->err_code, comp_results->name); + // (each asn1 rc <= 166 (enum e_S1ap_ProtocolIE_ID, in generated file S1ap_ProtocolIE_ID.h)) + if (comp_results->err_code == COMPARE_ERR_CODE_NO_MATCH) { + //TODO MME_UE_S1AP_ID, etc. + // get latest error code + if (strcmp(comp_results->name, "S1ap-MME-UE-S1AP-ID") == 0) { + if (0 == et_handle_s1ap_mismatch((et_packet_t *const)packet, (et_packet_t *const)rx_packet)) { + packet->timestamp_packet.tv_sec = rx_packet->timestamp_packet.tv_sec; + packet->timestamp_packet.tv_usec = rx_packet->timestamp_packet.tv_usec; + return et_scenario_set_packet_received(packet); + } + } else { + AssertFatal(0,"Some work needed there"); + } + } + comp_results2 = comp_results; + comp_results = comp_results2->next; + et_free_pointer(comp_results2); } } } diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c index 5300476e982..213be2b3473 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c @@ -58,9 +58,9 @@ extern et_scenario_t *g_scenario; extern uint32_t g_constraints; //------------------------------------------------------------------------------ -long et_s1ap_ies_is_matching(const S1AP_PDU_PR present, s1ap_message * const m1, s1ap_message * const m2, const uint32_t constraints) +asn_comp_rval_t * et_s1ap_ies_is_matching(const S1AP_PDU_PR present, s1ap_message * const m1, s1ap_message * const m2, const uint32_t constraints) { - long ret = 0; + asn_comp_rval_t *ret = NULL; AssertFatal(m1 != NULL, "bad parameter m1"); AssertFatal(m2 != NULL, "bad parameter m2"); AssertFatal((present == S1AP_PDU_PR_initiatingMessage) || @@ -401,6 +401,8 @@ long et_s1ap_ies_is_matching(const S1AP_PDU_PR present, s1ap_message * const m1, case S1ap_ProcedureCode_id_PrivateMessage: case S1ap_ProcedureCode_id_eNBConfigurationTransfer: case S1ap_ProcedureCode_id_MMEConfigurationTransfer: + AssertFatal(0, "TODO"); + break; case S1ap_ProcedureCode_id_CellTrafficTrace: ret = s1ap_compare_s1ap_celltraffictraceies( diff --git a/openair3/TEST/EPC_TEST/play_scenario_sctp.c b/openair3/TEST/EPC_TEST/play_scenario_sctp.c index 07206f53b81..181009c2c9d 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_sctp.c +++ b/openair3/TEST/EPC_TEST/play_scenario_sctp.c @@ -44,27 +44,36 @@ #include "play_scenario.h" //------------------------------------------------------------------------------ -long et_sctp_data_is_matching(sctp_datahdr_t * const sctp1, sctp_datahdr_t * const sctp2, const uint32_t constraints) +asn_comp_rval_t * et_sctp_data_is_matching(sctp_datahdr_t * const sctp1, sctp_datahdr_t * const sctp2, const uint32_t constraints) { + asn_comp_rval_t *rv = NULL; // no comparison for ports if (sctp1->ppid != sctp2->ppid) { S1AP_WARN("No Matching SCTP PPID %u %u\n", sctp1->ppid, sctp2->ppid); - return -ET_ERROR_MATCH_PACKET_SCTP_PPID; + rv = calloc(1, sizeof(asn_comp_rval_t)); + rv->err_code = ET_ERROR_MATCH_PACKET_SCTP_PPID; + return rv; } if (sctp1->assoc_id != sctp2->assoc_id) { S1AP_WARN("No Matching SCTP assoc id %u %u\n", sctp1->assoc_id, sctp2->assoc_id); - return -ET_ERROR_MATCH_PACKET_SCTP_ASSOC_ID; + rv = calloc(1, sizeof(asn_comp_rval_t)); + rv->err_code = ET_ERROR_MATCH_PACKET_SCTP_ASSOC_ID; + return rv; } if (sctp1->stream != sctp2->stream) { if (constraints & ET_BIT_MASK_MATCH_SCTP_STREAM) { - return -ET_ERROR_MATCH_PACKET_SCTP_STREAM_ID; + rv = calloc(1, sizeof(asn_comp_rval_t)); + rv->err_code = ET_ERROR_MATCH_PACKET_SCTP_STREAM_ID; + return rv; } else { S1AP_WARN("No Matching SCTP stream %u %u\n", sctp1->stream, sctp2->stream); } } if (sctp1->ssn != sctp2->ssn) { if (constraints & ET_BIT_MASK_MATCH_SCTP_SSN) { - return -ET_ERROR_MATCH_PACKET_SCTP_SSN; + rv = calloc(1, sizeof(asn_comp_rval_t)); + rv->err_code = ET_ERROR_MATCH_PACKET_SCTP_SSN; + return rv; } else { S1AP_WARN("No Matching SCTP STREAM SN %u %u\n", sctp1->ssn, sctp2->ssn); } @@ -73,10 +82,16 @@ long et_sctp_data_is_matching(sctp_datahdr_t * const sctp1, sctp_datahdr_t * con } //------------------------------------------------------------------------------ -long et_sctp_is_matching(et_sctp_hdr_t * const sctp1, et_sctp_hdr_t * const sctp2, const uint32_t constraints) +asn_comp_rval_t * et_sctp_is_matching(et_sctp_hdr_t * const sctp1, et_sctp_hdr_t * const sctp2, const uint32_t constraints) { // no comparison for ports - if (sctp1->chunk_type != sctp2->chunk_type) return -ET_ERROR_MATCH_PACKET_SCTP_CHUNK_TYPE; + asn_comp_rval_t *rv = NULL; + if (sctp1->chunk_type != sctp2->chunk_type){ + S1AP_WARN("No Matching chunk_type %u %u\n", sctp1->chunk_type, sctp2->chunk_type); + rv = calloc(1, sizeof(asn_comp_rval_t)); + rv->err_code = ET_ERROR_MATCH_PACKET_SCTP_CHUNK_TYPE; + return rv; + } switch (sctp1->chunk_type) { case SCTP_CID_DATA: return et_sctp_data_is_matching(&sctp1->u.data_hdr, &sctp2->u.data_hdr, constraints); @@ -92,5 +107,5 @@ long et_sctp_is_matching(et_sctp_hdr_t * const sctp1, et_sctp_hdr_t * const sctp AssertFatal(0, "Not needed now cid %d", sctp1->chunk_type); } - return 0; + return NULL; } -- GitLab