From 1f34bfa1a428d996bd4a1b964d6377f1aa2be236 Mon Sep 17 00:00:00 2001 From: gauthier Date: Wed, 7 Oct 2015 18:53:56 +0200 Subject: [PATCH 01/47] TBD: generate scenario --- cmake_targets/CMakeLists.txt | 2 +- cmake_targets/epc_test/CMakeLists.template | 6 +- openair3/TEST/EPC_TEST/generate_scenario.c | 215 +++++++++++---------- openair3/TEST/EPC_TEST/generate_scenario.h | 132 +++++++++++++ 4 files changed, 252 insertions(+), 103 deletions(-) create mode 100755 openair3/TEST/EPC_TEST/generate_scenario.h diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 47a8f3a9b7..6b5c51870c 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1620,7 +1620,7 @@ add_executable(test_epc_generate_scenario ${OPENAIR_BIN_DIR}/messages_xml.h ) target_link_libraries (test_epc_generate_scenario - -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES} + -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES} ) diff --git a/cmake_targets/epc_test/CMakeLists.template b/cmake_targets/epc_test/CMakeLists.template index 25d94ea852..12a745b997 100644 --- a/cmake_targets/epc_test/CMakeLists.template +++ b/cmake_targets/epc_test/CMakeLists.template @@ -47,9 +47,9 @@ set ( OAI_EMU False ) set ( OAISIM False ) set ( OAI_NW_DRIVER_TYPE_ETHERNET False ) set ( OAI_NW_DRIVER_USE_NETLINK True ) -set ( OPENAIR1 False ) -set ( OPENAIR2 False ) -set ( OPENAIR_LTE F ) +set ( OPENAIR1 True ) +set ( OPENAIR2 True ) +set ( OPENAIR_LTE True ) set ( PACKAGE_NAME "epc_test" ) set ( PBS_SIM False ) set ( PDCP_USE_NETLINK True ) diff --git a/openair3/TEST/EPC_TEST/generate_scenario.c b/openair3/TEST/EPC_TEST/generate_scenario.c index bd181ce878..913533218e 100644 --- a/openair3/TEST/EPC_TEST/generate_scenario.c +++ b/openair3/TEST/EPC_TEST/generate_scenario.c @@ -39,15 +39,19 @@ #include #include #include +#include +#include +#include +#include + #include "assertions.h" -#include "enb_config.h" +#include "generate_scenario.h" #include "s1ap_eNB.h" #if defined(ENABLE_ITTI) # include "intertask_interface.h" #endif -#define EPC_TEST_SCENARIO_MAX_ENB 2 #define ENB_CONFIG_STRING_ACTIVE_ENBS "Active_eNBs" @@ -78,30 +82,53 @@ #define ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U "ENB_IPV4_ADDRESS_FOR_S1U" #define ENB_CONFIG_STRING_ENB_PORT_FOR_S1U "ENB_PORT_FOR_S1U" +#define ENB_CONFIG_PROPERTIES_INDEX_OLD 0 +#define ENB_CONFIG_PROPERTIES_INDEX_NEW 1 -Enb_properties_array_t g_enb_properties; +Enb_properties_array_t g_enb_properties[2]; +char *g_test_dir = "."; // default value +char *g_pdml_in_basename = "trace.pdml"; // default value //------------------------------------------------------------------------------ -static void enb_config_display(void) +void generate_scenario(const char const * pdml_in_basenameP) //------------------------------------------------------------------------------ { - int i,j; + int fd_pdml_in; + if (chdir(g_test_dir) == 0) { + printf( "working in %s directory\n", g_test_dir); + fd_pdml_in = open(pdml_in_basenameP, O_RDONLY); + AssertFatal (fd_pdml_in > 0, + "Error while opening %s file in directory %s\n", + pdml_in_basenameP, + g_test_dir); + + } else { + printf("Error: chdir %s returned %s\n", g_test_dir, strerror(errno)); + exit(-1); + } +} + +//------------------------------------------------------------------------------ +static void enb_config_display(const boolean_t new_config_fileP) +//------------------------------------------------------------------------------ +{ + int i; printf( "\n----------------------------------------------------------------------\n"); - printf( " ENB CONFIG FILE CONTENT LOADED (TBC):\n"); + printf( " %s ENB CONFIG FILE CONTENT LOADED:\n", new_config_fileP == ENB_CONFIG_PROPERTIES_INDEX_OLD ? "Old":"New"); printf( "----------------------------------------------------------------------\n"); - for (i = 0; i < g_enb_properties.number; i++) { + for (i = 0; i < g_enb_properties[new_config_fileP].number; i++) { printf( "ENB CONFIG for instance %u:\n\n", i); - printf( "\teNB name: \t%s:\n",g_enb_properties.properties[i]->eNB_name); - printf( "\teNB ID: \t%"PRIu32":\n",g_enb_properties.properties[i]->eNB_id); - printf( "\tCell type: \t%s:\n",g_enb_properties.properties[i]->cell_type == CELL_MACRO_ENB ? "CELL_MACRO_ENB":"CELL_HOME_ENB"); - printf( "\tTAC: \t%"PRIu16":\n",g_enb_properties.properties[i]->tac); - printf( "\tMCC: \t%"PRIu16":\n",g_enb_properties.properties[i]->mcc); + printf( "\teNB name: \t%s\n",g_enb_properties[new_config_fileP].properties[i]->eNB_name); + printf( "\teNB ID: \t%"PRIu32"\n",g_enb_properties[new_config_fileP].properties[i]->eNB_id); + printf( "\tCell type: \t%s\n",g_enb_properties[new_config_fileP].properties[i]->cell_type == CELL_MACRO_ENB ? "CELL_MACRO_ENB":"CELL_HOME_ENB"); + printf( "\tTAC: \t%"PRIu16"\n",g_enb_properties[new_config_fileP].properties[i]->tac); + printf( "\tMCC: \t%"PRIu16"\n",g_enb_properties[new_config_fileP].properties[i]->mcc); - if (g_enb_properties.properties[i]->mnc_digit_length == 3) { - printf( "\tMNC: \t%03"PRIu16":\n",g_enb_properties.properties[i]->mnc); + if (g_enb_properties[new_config_fileP].properties[i]->mnc_digit_length == 3) { + printf( "\tMNC: \t%03"PRIu16"\n",g_enb_properties[new_config_fileP].properties[i]->mnc); } else { - printf( "\tMNC: \t%02"PRIu16":\n",g_enb_properties.properties[i]->mnc); + printf( "\tMNC: \t%02"PRIu16"\n",g_enb_properties[new_config_fileP].properties[i]->mnc); } printf( "\n--------------------------------------------------------\n"); } @@ -114,13 +141,12 @@ static void enb_config_display(void) #define libconfig_int int #endif //------------------------------------------------------------------------------ -const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) +void enb_config_init(const char const * lib_config_file_name_pP, const boolean_t new_config_fileP) //------------------------------------------------------------------------------ { config_t cfg; config_setting_t *setting = NULL; config_setting_t *subsetting = NULL; - config_setting_t *setting_srb1 = NULL; config_setting_t *setting_mme_addresses = NULL; config_setting_t *setting_mme_address = NULL; config_setting_t *setting_enb = NULL; @@ -128,8 +154,6 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) int enb_properties_index = 0; int num_enbs = 0; int num_mme_address = 0; - int num_otg_elements =0; - int num_component_carriers =0; int i = 0; int j = 0; int parse_errors = 0; @@ -139,12 +163,6 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) const char* enb_name = NULL; const char* mcc = 0; const char* mnc = 0; - const char* frame_type = NULL; - const char* prefix_type = NULL; - libconfig_int Nid_cell = 0; - - libconfig_int my_int; - char* ipv4 = NULL; char* ipv6 = NULL; char* active = NULL; @@ -157,21 +175,22 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) char* enb_ipv4_address_for_S1_MME = NULL; char *address = NULL; char *cidr = NULL; - char *astring = NULL; + + AssertFatal ((new_config_fileP == 0) || (new_config_fileP == 1), + "Bad parameter new_config_fileP %d \n", + new_config_fileP); + AssertFatal (lib_config_file_name_pP != NULL, + "Bad parameter lib_config_file_name_pP %s , must reference a valid eNB config file\n", + lib_config_file_name_pP); memset((char*)active_enb, 0 , EPC_TEST_SCENARIO_MAX_ENB * sizeof(char*)); config_init(&cfg); - if (lib_config_file_name_pP != NULL) { - /* Read the file. If there is an error, report it and exit. */ - if (! config_read_file(&cfg, lib_config_file_name_pP)) { - config_destroy(&cfg); - AssertFatal (0, "Failed to parse eNB configuration file %s!\n", lib_config_file_name_pP); - } - } else { + /* Read the file. If there is an error, report it and exit. */ + if (! config_read_file(&cfg, lib_config_file_name_pP)) { config_destroy(&cfg); - AssertFatal (0, "No eNB configuration file provided!\n"); + AssertFatal (0, "Failed to parse eNB configuration file %s!\n", lib_config_file_name_pP); } // Get list of active eNBs, (only these will be configured) @@ -195,7 +214,7 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) setting = config_lookup(&cfg, ENB_CONFIG_STRING_ENB_LIST); if (setting != NULL) { - enb_properties_index = 0; + enb_properties_index = g_enb_properties[new_config_fileP].number; parse_errors = 0; num_enbs = config_setting_length(setting); @@ -232,34 +251,34 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) // search if in active list for (j=0; j < num_enb_properties; j++) { if (strcmp(active_enb[j], enb_name) == 0) { - g_enb_properties.properties[enb_properties_index] = calloc(1, sizeof(Enb_properties_t)); + g_enb_properties[new_config_fileP].properties[enb_properties_index] = calloc(1, sizeof(Enb_properties_t)); - g_enb_properties.properties[enb_properties_index]->eNB_id = enb_id; + g_enb_properties[new_config_fileP].properties[enb_properties_index]->eNB_id = enb_id; if (strcmp(cell_type, "CELL_MACRO_ENB") == 0) { - g_enb_properties.properties[enb_properties_index]->cell_type = CELL_MACRO_ENB; + g_enb_properties[new_config_fileP].properties[enb_properties_index]->cell_type = CELL_MACRO_ENB; } else if (strcmp(cell_type, "CELL_HOME_ENB") == 0) { - g_enb_properties.properties[enb_properties_index]->cell_type = CELL_HOME_ENB; + g_enb_properties[new_config_fileP].properties[enb_properties_index]->cell_type = CELL_HOME_ENB; } else { AssertError (0, parse_errors ++, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n", lib_config_file_name_pP, i, cell_type); } - g_enb_properties.properties[enb_properties_index]->eNB_name = strdup(enb_name); - g_enb_properties.properties[enb_properties_index]->tac = (uint16_t)atoi(tac); - g_enb_properties.properties[enb_properties_index]->mcc = (uint16_t)atoi(mcc); - g_enb_properties.properties[enb_properties_index]->mnc = (uint16_t)atoi(mnc); - g_enb_properties.properties[enb_properties_index]->mnc_digit_length = strlen(mnc); - AssertFatal((g_enb_properties.properties[enb_properties_index]->mnc_digit_length == 2) || - (g_enb_properties.properties[enb_properties_index]->mnc_digit_length == 3), + g_enb_properties[new_config_fileP].properties[enb_properties_index]->eNB_name = strdup(enb_name); + g_enb_properties[new_config_fileP].properties[enb_properties_index]->tac = (uint16_t)atoi(tac); + g_enb_properties[new_config_fileP].properties[enb_properties_index]->mcc = (uint16_t)atoi(mcc); + g_enb_properties[new_config_fileP].properties[enb_properties_index]->mnc = (uint16_t)atoi(mnc); + g_enb_properties[new_config_fileP].properties[enb_properties_index]->mnc_digit_length = strlen(mnc); + AssertFatal((g_enb_properties[new_config_fileP].properties[enb_properties_index]->mnc_digit_length == 2) || + (g_enb_properties[new_config_fileP].properties[enb_properties_index]->mnc_digit_length == 3), "BAD MNC DIGIT LENGTH %d", - g_enb_properties.properties[i]->mnc_digit_length); + g_enb_properties[new_config_fileP].properties[i]->mnc_digit_length); setting_mme_addresses = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_MME_IP_ADDRESS); num_mme_address = config_setting_length(setting_mme_addresses); - g_enb_properties.properties[enb_properties_index]->nb_mme = 0; + g_enb_properties[new_config_fileP].properties[enb_properties_index]->nb_mme = 0; for (j = 0; j < num_mme_address; j++) { setting_mme_address = config_setting_get_elem(setting_mme_addresses, j); @@ -277,22 +296,22 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) continue; // FIXME will prevent segfaults below, not sure what happens at function exit... } - g_enb_properties.properties[enb_properties_index]->nb_mme += 1; + g_enb_properties[new_config_fileP].properties[enb_properties_index]->nb_mme += 1; - g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv4_address = strdup(ipv4); - g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv6_address = strdup(ipv6); + g_enb_properties[new_config_fileP].properties[enb_properties_index]->mme_ip_address[j].ipv4_address = strdup(ipv4); + g_enb_properties[new_config_fileP].properties[enb_properties_index]->mme_ip_address[j].ipv6_address = strdup(ipv6); if (strcmp(active, "yes") == 0) { - g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].active = 1; + g_enb_properties[new_config_fileP].properties[enb_properties_index]->mme_ip_address[j].active = 1; } // else { (calloc) if (strcmp(preference, "ipv4") == 0) { - g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv4 = 1; + g_enb_properties[new_config_fileP].properties[enb_properties_index]->mme_ip_address[j].ipv4 = 1; } else if (strcmp(preference, "ipv6") == 0) { - g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv6 = 1; + g_enb_properties[new_config_fileP].properties[enb_properties_index]->mme_ip_address[j].ipv6 = 1; } else if (strcmp(preference, "no") == 0) { - g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv4 = 1; - g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv6 = 1; + g_enb_properties[new_config_fileP].properties[enb_properties_index]->mme_ip_address[j].ipv4 = 1; + g_enb_properties[new_config_fileP].properties[enb_properties_index]->mme_ip_address[j].ipv6 = 1; } } @@ -314,49 +333,37 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) &enb_port_for_S1U) ) ) { - g_enb_properties.properties[enb_properties_index]->enb_interface_name_for_S1U = strdup(enb_interface_name_for_S1U); + g_enb_properties[new_config_fileP].properties[enb_properties_index]->enb_interface_name_for_S1U = strdup(enb_interface_name_for_S1U); cidr = enb_ipv4_address_for_S1U; address = strtok(cidr, "/"); if (address) { - IPV4_STR_ADDR_TO_INT_NWBO ( address, g_enb_properties.properties[enb_properties_index]->enb_ipv4_address_for_S1U, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" ); + IPV4_STR_ADDR_TO_INT_NWBO ( address, g_enb_properties[new_config_fileP].properties[enb_properties_index]->enb_ipv4_address_for_S1U, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" ); } - g_enb_properties.properties[enb_properties_index]->enb_port_for_S1U = enb_port_for_S1U; + g_enb_properties[new_config_fileP].properties[enb_properties_index]->enb_port_for_S1U = enb_port_for_S1U; - g_enb_properties.properties[enb_properties_index]->enb_interface_name_for_S1_MME = strdup(enb_interface_name_for_S1_MME); + g_enb_properties[new_config_fileP].properties[enb_properties_index]->enb_interface_name_for_S1_MME = strdup(enb_interface_name_for_S1_MME); cidr = enb_ipv4_address_for_S1_MME; address = strtok(cidr, "/"); if (address) { - IPV4_STR_ADDR_TO_INT_NWBO ( address, g_enb_properties.properties[enb_properties_index]->enb_ipv4_address_for_S1_MME, "BAD IP ADDRESS FORMAT FOR eNB S1_MME !\n" ); + IPV4_STR_ADDR_TO_INT_NWBO ( address, g_enb_properties[new_config_fileP].properties[enb_properties_index]->enb_ipv4_address_for_S1_MME, "BAD IP ADDRESS FORMAT FOR eNB S1_MME !\n" ); } } - } - } - } - } - } + } // if (subsetting != NULL) { + enb_properties_index += 1; + } // if (strcmp(active_enb[j], enb_name) == 0) + } // for (j=0; j < num_enb_properties; j++) + } // for (i = 0; i < num_enbs; i++) + } // if (setting != NULL) { - g_enb_properties.number = num_enb_properties; + g_enb_properties[new_config_fileP].number += num_enb_properties; - AssertError (enb_properties_index == num_enb_properties, parse_errors ++, - "Failed to parse eNB configuration file %s, mismatch between %u active eNBs and %u corresponding defined eNBs !\n", - lib_config_file_name_pP, num_enb_properties, enb_properties_index); AssertFatal (parse_errors == 0, "Failed to parse eNB configuration file %s, found %d error%s !\n", lib_config_file_name_pP, parse_errors, parse_errors > 1 ? "s" : ""); - enb_config_display(); - return &g_enb_properties; - -} - -//------------------------------------------------------------------------------ -const Enb_properties_array_t *enb_config_get(void) -//------------------------------------------------------------------------------ -{ - return &g_enb_properties; } @@ -370,12 +377,12 @@ static void usage ( fprintf (stdout, "Usage: %s [options]\n\n", argv[0]); fprintf (stdout, "Available options:\n"); fprintf (stdout, "\t--help, -h Print this help and return\n"); - fprintf (stdout, "\t--test-dir \n"); - fprintf (stdout, " Set the test directory where pdml and original enb(s) config files are located\n"); - fprintf (stdout, " See README in openair3/TEST/EPC_TEST\n"); fprintf (stdout, "\t--new-enb-conf-file \n"); fprintf (stdout, " Provide an updated eNB config file for generating a copy of the original test\n"); - fprintf (stdout, " This option is set as many times as there are some eNB in the original test\n"); + fprintf (stdout, " This option is set as many times as there are some eNB config files in the original test\n"); + fprintf (stdout, "\t--old-enb-conf-file \n"); + fprintf (stdout, " Provide the old eNB config file for generating a copy of the original test\n"); + fprintf (stdout, " This option is set as many times as there are some eNB config files in the original test\n"); } @@ -388,18 +395,19 @@ config_parse_opt_line ( { int option; char *enb_config_file_name = NULL; - char *test_dir = NULL; enum long_option_e { LONG_OPTION_START = 0x100, /* Start after regular single char options */ - LONG_OPTION_TEST_DIR, LONG_OPTION_NEW_ENB_CONF_FILE, + LONG_OPTION_OLD_ENB_CONF_FILE, + LONG_OPTION_PDML_IN_BASENAME, LONG_OPTION_HELP, }; static struct option long_options[] = { - {"test-dir", required_argument, 0, LONG_OPTION_TEST_DIR}, + {"old-enb-conf-file", required_argument, 0, LONG_OPTION_OLD_ENB_CONF_FILE}, {"new-enb-conf-file", required_argument, 0, LONG_OPTION_NEW_ENB_CONF_FILE}, + {"pdml_in_basename", required_argument, 0, LONG_OPTION_PDML_IN_BASENAME}, {"help", required_argument, 0, LONG_OPTION_HELP}, {NULL, 0, NULL, 0} }; @@ -407,31 +415,37 @@ config_parse_opt_line ( /* * Parsing command line */ - while ((option = getopt_long (argc, argv, "h", long_options, NULL)) != -1) { + while ((option = getopt_long (argc, argv, "hp:n:o", long_options, NULL)) != -1) { switch (option) { - case LONG_OPTION_TEST_DIR: + case LONG_OPTION_OLD_ENB_CONF_FILE: + case 'o': if (optarg) { - test_dir = strdup(optarg); - printf("TEST DIRECTORY IS %s\n", test_dir); + enb_config_file_name = optarg; + printf("Old eNB config file name is %s\n", enb_config_file_name); + enb_config_init(enb_config_file_name, ENB_CONFIG_PROPERTIES_INDEX_OLD); + g_test_dir = strdup(dirname(enb_config_file_name)); } break; case LONG_OPTION_NEW_ENB_CONF_FILE: + case 'n': if (optarg) { - enb_config_file_name = strdup(optarg); - printf("eNB config file name is %s\n", enb_config_file_name); - enb_config_init(enb_config_file_name); + enb_config_file_name = optarg; + printf("New eNB config file name is %s\n", enb_config_file_name); + enb_config_init(enb_config_file_name, ENB_CONFIG_PROPERTIES_INDEX_NEW); } break; + case LONG_OPTION_PDML_IN_BASENAME: + case 'p': if (optarg) { - test_dir = strdup(optarg); - printf("TEST DIRECTORY IS %s\n", test_dir); + g_pdml_in_basename = strdup(optarg); + printf("PDML input file name is %s\n", g_pdml_in_basename); } break; case LONG_OPTION_HELP: - case 'h': /* Fall through */ + case 'h': default: usage (argc, argv); exit (0); @@ -444,8 +458,11 @@ config_parse_opt_line ( int main( int argc, char **argv ) //------------------------------------------------------------------------------ { - memset((char*) &g_enb_properties, 0 , sizeof(g_enb_properties)); + memset((char*) &g_enb_properties[ENB_CONFIG_PROPERTIES_INDEX_OLD], 0 , sizeof(g_enb_properties[ENB_CONFIG_PROPERTIES_INDEX_OLD])); + memset((char*) &g_enb_properties[ENB_CONFIG_PROPERTIES_INDEX_NEW], 0 , sizeof(g_enb_properties[ENB_CONFIG_PROPERTIES_INDEX_NEW])); config_parse_opt_line (argc, argv); //Command-line options - + enb_config_display(ENB_CONFIG_PROPERTIES_INDEX_OLD); + enb_config_display(ENB_CONFIG_PROPERTIES_INDEX_NEW); + generate_scenario(g_pdml_in_basename); return 0; } diff --git a/openair3/TEST/EPC_TEST/generate_scenario.h b/openair3/TEST/EPC_TEST/generate_scenario.h new file mode 100755 index 0000000000..c3b42ea253 --- /dev/null +++ b/openair3/TEST/EPC_TEST/generate_scenario.h @@ -0,0 +1,132 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2014 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see . + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE + +*******************************************************************************/ + +/* + generate_scenario.h + ------------------- + AUTHOR : Lionel GAUTHIER + COMPANY : EURECOM + EMAIL : Lionel.Gauthier@eurecom.fr +*/ + +#ifndef GENERATE_SCENARIO_H_ +#define GENERATE_SCENARIO_H_ +#include +#include +#include + +#include "commonDef.h" +#include "platform_types.h" +#include "platform_constants.h" +#include "PHY/impl_defs_lte.h" +#include "s1ap_messages_types.h" +#ifdef CMAKER +#include "SystemInformationBlockType2.h" +#else +#include "RRC/LITE/MESSAGES/SystemInformationBlockType2.h" +#endif + +#define IPV4_STR_ADDR_TO_INT_NWBO(AdDr_StR,NwBo,MeSsAgE ) do {\ + struct in_addr inp;\ + if ( inet_aton(AdDr_StR, &inp ) < 0 ) {\ + AssertFatal (0, MeSsAgE);\ + } else {\ + NwBo = inp.s_addr;\ + }\ + } while (0); + +/** @defgroup _enb_app ENB APP + * @ingroup _oai2 + * @{ + */ + +// Hard to find a defined value for max enb... +#define EPC_TEST_SCENARIO_MAX_ENB 4 + + +typedef struct mme_ip_address_s { + unsigned ipv4:1; + unsigned ipv6:1; + unsigned active:1; + char *ipv4_address; + char *ipv6_address; +} mme_ip_address_t; + +typedef struct Enb_properties_s { + /* Unique eNB_id to identify the eNB within EPC. + * For macro eNB ids this field should be 20 bits long. + * For home eNB ids this field should be 28 bits long. + */ + uint32_t eNB_id; + + /* The type of the cell */ + enum cell_type_e cell_type; + + /* Optional name for the cell + * NOTE: the name can be NULL (i.e no name) and will be cropped to 150 + * characters. + */ + char *eNB_name; + + /* Tracking area code */ + uint16_t tac; + + /* Mobile Country Code + * Mobile Network Code + */ + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + + /* Nb of MME to connect to */ + uint8_t nb_mme; + /* List of MME to connect to */ + mme_ip_address_t mme_ip_address[S1AP_MAX_NB_MME_IP_ADDRESS]; + + int sctp_in_streams; + int sctp_out_streams; + + char *enb_interface_name_for_S1U; + in_addr_t enb_ipv4_address_for_S1U; + tcp_udp_port_t enb_port_for_S1U; + + char *enb_interface_name_for_S1_MME; + in_addr_t enb_ipv4_address_for_S1_MME; + +} Enb_properties_t; + +typedef struct Enb_properties_array_s { + int number; + Enb_properties_t *properties[EPC_TEST_SCENARIO_MAX_ENB]; +} Enb_properties_array_t; + +void enb_config_init(const char const * lib_config_file_name_pP, const boolean_t new_config_fileP); + +#endif /* ENB_CONFIG_H_ */ +/** @} */ From 5d4de8bd2d603d651f6eb797b1bb7a48247e9ef9 Mon Sep 17 00:00:00 2001 From: gauthier Date: Thu, 8 Oct 2015 15:21:56 +0200 Subject: [PATCH 02/47] switch branch --- cmake_targets/CMakeLists.txt | 5 ++- openair3/TEST/EPC_TEST/generate_scenario.c | 46 +++++++++++++++++----- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 6b5c51870c..6b9dae6b04 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1332,6 +1332,9 @@ include(FindPkgConfig) pkg_search_module(LIBXML2 libxml-2.0 REQUIRED) include_directories(${LIBXML2_INCLUDE_DIRS}) +pkg_search_module(LIBXSLT libxslt REQUIRED) +include_directories(${LIBXSLT_INCLUDE_DIRS}) + pkg_search_module(OPENSSL openssl REQUIRED) include_directories(${OPENSSL_INCLUDE_DIRS}) @@ -1620,7 +1623,7 @@ add_executable(test_epc_generate_scenario ${OPENAIR_BIN_DIR}/messages_xml.h ) target_link_libraries (test_epc_generate_scenario - -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES} + -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES} ) diff --git a/openair3/TEST/EPC_TEST/generate_scenario.c b/openair3/TEST/EPC_TEST/generate_scenario.c index 913533218e..6843766f95 100644 --- a/openair3/TEST/EPC_TEST/generate_scenario.c +++ b/openair3/TEST/EPC_TEST/generate_scenario.c @@ -43,15 +43,22 @@ #include #include #include - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "assertions.h" #include "generate_scenario.h" #include "s1ap_eNB.h" -#if defined(ENABLE_ITTI) -# include "intertask_interface.h" -#endif - +#include "intertask_interface.h" #define ENB_CONFIG_STRING_ACTIVE_ENBS "Active_eNBs" @@ -85,23 +92,44 @@ #define ENB_CONFIG_PROPERTIES_INDEX_OLD 0 #define ENB_CONFIG_PROPERTIES_INDEX_NEW 1 +#define ENB_CONFIG_MAX_XSLT_PARAMS 64 + Enb_properties_array_t g_enb_properties[2]; char *g_test_dir = "."; // default value char *g_pdml_in_basename = "trace.pdml"; // default value - +extern int xmlLoadExtDtdDefaultValue; //------------------------------------------------------------------------------ void generate_scenario(const char const * pdml_in_basenameP) //------------------------------------------------------------------------------ { - int fd_pdml_in; + //int fd_pdml_in; + xsltStylesheetPtr cur = NULL; + xmlDocPtr doc, res; + const char *params[ENB_CONFIG_MAX_XSLT_PARAMS]; + int nb_params = 0; + if (chdir(g_test_dir) == 0) { printf( "working in %s directory\n", g_test_dir); - fd_pdml_in = open(pdml_in_basenameP, O_RDONLY); + /*fd_pdml_in = open(pdml_in_basenameP, O_RDONLY); AssertFatal (fd_pdml_in > 0, "Error while opening %s file in directory %s\n", pdml_in_basenameP, - g_test_dir); + g_test_dir);*/ + params[nb_params] = NULL; + xmlSubstituteEntitiesDefault(1); + xmlLoadExtDtdDefaultValue = 1; + cur = xsltParseStylesheetFile("enb_config.xsl"); + doc = xmlParseFile(pdml_in_basenameP); + res = xsltApplyStylesheet(cur, doc, params); + xsltSaveResultToFile(stdout, res, cur); + + xsltFreeStylesheet(cur); + xmlFreeDoc(res); + xmlFreeDoc(doc); + + xsltCleanupGlobals(); + xmlCleanupParser(); } else { printf("Error: chdir %s returned %s\n", g_test_dir, strerror(errno)); exit(-1); From 62009b9a43878ff22bc5f1a5e7d49743560a4743 Mon Sep 17 00:00:00 2001 From: gauthier Date: Fri, 16 Oct 2015 16:56:06 +0200 Subject: [PATCH 03/47] Sync for home --- .../attach_complete.pdml | 4242 +++++++++++++++++ .../enb.band7.tm1.usrpb210.epc.local.conf | 174 + openair3/TEST/EPC_TEST/generate_scenario.c | 339 +- openair3/TEST/EPC_TEST/generic_scenario.xsl | 46 + openair3/TEST/EPC_TEST/mme_test_s1_pcap2pdml | 24 +- 5 files changed, 4766 insertions(+), 59 deletions(-) create mode 100644 openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/attach_complete.pdml create mode 100644 openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb.band7.tm1.usrpb210.epc.local.conf create mode 100644 openair3/TEST/EPC_TEST/generic_scenario.xsl diff --git a/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/attach_complete.pdml b/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/attach_complete.pdml new file mode 100644 index 0000000000..fef45773f9 --- /dev/null +++ b/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/attach_complete.pdml @@ -0,0 +1,4242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb.band7.tm1.usrpb210.epc.local.conf b/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb.band7.tm1.usrpb210.epc.local.conf new file mode 100644 index 0000000000..e864f47edb --- /dev/null +++ b/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb.band7.tm1.usrpb210.epc.local.conf @@ -0,0 +1,174 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + + mobile_network_code = "95"; + + ////////// Physical parameters: + + component_carriers = ( + { + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2660000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 120; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -26; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -90; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -108; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + } + ); + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.188.2.2"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "tun2"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.188.2.2/24"; + + ENB_INTERFACE_NAME_FOR_S1U = "lo"; + ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.1/24"; + ENB_PORT_FOR_S1U = 2153; # Spec 2152 + }; + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + gtpu_log_level ="info"; + gtpu_log_verbosity ="medium"; + udp_log_level ="info"; + udp_log_verbosity ="medium"; + }; + + } +); diff --git a/openair3/TEST/EPC_TEST/generate_scenario.c b/openair3/TEST/EPC_TEST/generate_scenario.c index 6843766f95..eff91ea56f 100644 --- a/openair3/TEST/EPC_TEST/generate_scenario.c +++ b/openair3/TEST/EPC_TEST/generate_scenario.c @@ -43,6 +43,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -95,11 +98,64 @@ #define ENB_CONFIG_MAX_XSLT_PARAMS 64 Enb_properties_array_t g_enb_properties[2]; -char *g_test_dir = "."; // default value -char *g_pdml_in_basename = "trace.pdml"; // default value +char *g_openair_dir = NULL; +char *g_test_dir = NULL; +char *g_pdml_in_origin = NULL; +char *g_generic_scenario = NULL; extern int xmlLoadExtDtdDefaultValue; + +#define GENERATE_PDML_FILE 1 +#define GENERATE_GENERIC_SCENARIO 2 +#define GENERATE_DEDICATED_SCENARIO 4 + +#define GS_IS_FILE 1 +#define GS_IS_DIR 2 + //------------------------------------------------------------------------------ -void generate_scenario(const char const * pdml_in_basenameP) +// test if file exist in current directory +int is_file_exists( const char const * file_nameP, const char const *file_roleP) +{ + struct stat s; + int err = stat(file_nameP, &s); + if(-1 == err) { + if(ENOENT == errno) { + fprintf(stderr, "Please provide a valid %s, %s does not exist\n", file_roleP, file_nameP); + } else { + perror("stat"); + exit(1); + } + } else { + if(S_ISREG(s.st_mode)) { + return GS_IS_FILE; + } else if(S_ISDIR(s.st_mode)) { + return GS_IS_DIR; + } else { + fprintf(stderr, "Please provide a valid test %s, %s exists but is not found valid\n", file_roleP, file_nameP); + } + } + return 0; +} + +//------------------------------------------------------------------------------ +// return number of splitted items +int split_path( char * pathP, char *** resP) +{ + char * saveptr1; + char * p = strtok_r (pathP, "/", &saveptr1); + int n_spaces = 0; + + /// split string and append tokens to 'res' + while (p) { + *resP = realloc (*resP, sizeof (char*) * ++n_spaces); + AssertFatal (*resP, "realloc failed"); + (*resP)[n_spaces-1] = p; + p = strtok_r (NULL, "/", &saveptr1); + } + return n_spaces; +} + +//------------------------------------------------------------------------------ +void generate_generic_scenario(const char const * test_nameP, const char const * pdml_in_basenameP) //------------------------------------------------------------------------------ { //int fd_pdml_in; @@ -107,33 +163,58 @@ void generate_scenario(const char const * pdml_in_basenameP) xmlDocPtr doc, res; const char *params[ENB_CONFIG_MAX_XSLT_PARAMS]; int nb_params = 0; + int i,j; + char astring[1024]; + struct in_addr addr; - if (chdir(g_test_dir) == 0) { - printf( "working in %s directory\n", g_test_dir); - /*fd_pdml_in = open(pdml_in_basenameP, O_RDONLY); - AssertFatal (fd_pdml_in > 0, - "Error while opening %s file in directory %s\n", - pdml_in_basenameP, - g_test_dir);*/ - - params[nb_params] = NULL; - xmlSubstituteEntitiesDefault(1); - xmlLoadExtDtdDefaultValue = 1; - cur = xsltParseStylesheetFile("enb_config.xsl"); - doc = xmlParseFile(pdml_in_basenameP); - res = xsltApplyStylesheet(cur, doc, params); - xsltSaveResultToFile(stdout, res, cur); - - xsltFreeStylesheet(cur); - xmlFreeDoc(res); - xmlFreeDoc(doc); - - xsltCleanupGlobals(); - xmlCleanupParser(); + memset(astring, 0, sizeof(astring)); + if (getcwd(astring, sizeof(astring)) != NULL) { + fprintf(stdout, "working in %s directory\n", astring); } else { - printf("Error: chdir %s returned %s\n", g_test_dir, strerror(errno)); - exit(-1); + perror("getcwd() error"); + exit(1); } + + memset(astring, 0, sizeof(astring)); + strcat(astring, g_openair_dir); + strcat(astring, "/openair3/TEST/EPC_TEST/generic_scenario.xsl"); + + xmlSubstituteEntitiesDefault(1); + xmlLoadExtDtdDefaultValue = 1; + cur = xsltParseStylesheetFile(astring); + doc = xmlParseFile(pdml_in_basenameP); + params[nb_params++] = "test_name"; + sprintf(astring, "\"%s\"", test_nameP); + params[nb_params++] = strdup(astring); + + for (i = 0; i < g_enb_properties[ENB_CONFIG_PROPERTIES_INDEX_OLD].number; i++) { + // eNB S1-C IPv4 address + sprintf(astring, "enb_s1c%d", i); + params[nb_params++] = strdup(astring); + addr.s_addr = g_enb_properties[ENB_CONFIG_PROPERTIES_INDEX_OLD].properties[i]->enb_ipv4_address_for_S1_MME; + sprintf(astring, "\"%s\"", inet_ntoa(addr)); + params[nb_params++] = strdup(astring); + + // MME S1-C IPv4 address + for (j = 0; j < g_enb_properties[ENB_CONFIG_PROPERTIES_INDEX_OLD].properties[i]->nb_mme; j++) { + sprintf(astring, "mme_s1c%d_%d", i, j); + params[nb_params++] = strdup(astring); + AssertFatal (g_enb_properties[ENB_CONFIG_PROPERTIES_INDEX_OLD].properties[i]->mme_ip_address[j].ipv4_address, + "Only support MME IPv4 address\n"); + sprintf(astring, "\"%s\"", g_enb_properties[ENB_CONFIG_PROPERTIES_INDEX_OLD].properties[i]->mme_ip_address[j].ipv4_address); + params[nb_params++] = strdup(astring); + } + } + params[nb_params] = NULL; + res = xsltApplyStylesheet(cur, doc, params); + xsltSaveResultToFile(stdout, res, cur); + + xsltFreeStylesheet(cur); + xmlFreeDoc(res); + xmlFreeDoc(doc); + + xsltCleanupGlobals(); + xmlCleanupParser(); } //------------------------------------------------------------------------------ @@ -403,14 +484,77 @@ static void usage ( { fprintf (stdout, "Please report any bug to: openair4g-devel@lists.eurecom.fr\n\n"); fprintf (stdout, "Usage: %s [options]\n\n", argv[0]); + fprintf (stdout, "Mandatory options:\n"); + fprintf (stdout, "\t-t | --test-dir Directory where a set of files related to a particular test are located\n"); + fprintf (stdout, "\n"); fprintf (stdout, "Available options:\n"); - fprintf (stdout, "\t--help, -h Print this help and return\n"); - fprintf (stdout, "\t--new-enb-conf-file \n"); - fprintf (stdout, " Provide an updated eNB config file for generating a copy of the original test\n"); - fprintf (stdout, " This option is set as many times as there are some eNB config files in the original test\n"); - fprintf (stdout, "\t--old-enb-conf-file \n"); - fprintf (stdout, " Provide the old eNB config file for generating a copy of the original test\n"); - fprintf (stdout, " This option is set as many times as there are some eNB config files in the original test\n"); + fprintf (stdout, "\t-h | --help Print this help and return\n"); + fprintf (stdout, "\t-n | --new-enb-conf-file Provide an updated eNB config file for generating a copy of the original test\n"); + fprintf (stdout, " This option is set as many times as there are some eNB config files in the original test\n"); + fprintf (stdout, "\t-o | --old-enb-conf-file Provide the old eNB config file for generating a copy of the original test\n"); + fprintf (stdout, " This option is set as many times as there are some eNB config files in the original test\n"); + fprintf (stdout, "\t-p | --pdml File name (with no path) of an original scenario that has to be reworked (IP addresses) with new testbed\n"); + fprintf (stdout, "\t-s | --scenario-generic File name (with no path) of a scenario that has to be customized (IP addresses) with new testbed\n"); + fprintf (stdout, "\n"); + fprintf (stdout, "\n"); + fprintf (stdout, "Example of generate_scenario use cases: \n"); + fprintf (stdout, "\n"); + fprintf (stdout, " Case 1: generate a generix xml scenario from a captured pcap file: \n"); + fprintf (stdout, " +---------------------+ \n"); + fprintf (stdout, " |captured pcap-ng file| \n"); + fprintf (stdout, " +----------+----------+ \n"); + fprintf (stdout, " |\n"); + fprintf (stdout, " mme_test_s1_pcap2pdml \n"); + fprintf (stdout, " |\n"); + fprintf (stdout, " +--------V----------+ +------------------------+\n"); + fprintf (stdout, " |'pdml-in-orig' file| |'old-enb-conf-file' file|\n"); + fprintf (stdout, " +--------+----------+ +------------+-----------+\n"); + fprintf (stdout, " | |\n"); + fprintf (stdout, " +----------------------------+\n"); + fprintf (stdout, " |\n"); + fprintf (stdout, " generate_scenario -t -p -o \n"); + fprintf (stdout, " |\n"); + fprintf (stdout, " +------------V--------------+\n"); + fprintf (stdout, " +'xml-scenario-generic' file|\n"); + fprintf (stdout, " +---------------------------+\n"); + fprintf (stdout, "\n"); + fprintf (stdout, "\n"); + fprintf (stdout, " Case 2: generate a dedicated xml scenario from generic xml scenario:\n"); + fprintf (stdout, "\n"); + fprintf (stdout, " +---------------------------+ +------------------------+\n"); + fprintf (stdout, " |'xml-scenario-generic' file| |'new-enb-conf-file' file|\n"); + fprintf (stdout, " +--------+------------------+ +------------+-----------+\n"); + fprintf (stdout, " | |\n"); + fprintf (stdout, " +--------------------+---------------+\n"); + fprintf (stdout, " |\n"); + fprintf (stdout, " generate_scenario -t -s -n \n"); + fprintf (stdout, " |\n"); + fprintf (stdout, " +--------------V--------------+\n"); + fprintf (stdout, " +'xml-scenario-dedicated' file|\n"); + fprintf (stdout, " +-----------------------------+\n"); + fprintf (stdout, "\n"); + fprintf (stdout, "\n"); + fprintf (stdout, " Case 3 = case 1 + case 2: generate a dedicated xml scenario from a captured pcap file:\n"); + fprintf (stdout, "\n"); + fprintf (stdout, " +---------------------+\n"); + fprintf (stdout, " |captured pcap-ng file|\n"); + fprintf (stdout, " +----------+----------+\n"); + fprintf (stdout, " |\n"); + fprintf (stdout, " mme_test_s1_pcap2pdml \n"); + fprintf (stdout, " |\n"); + fprintf (stdout, " +------------------------+ +--------V----------+ +------------------------+\n"); + fprintf (stdout, " |'old-enb-conf-file' file| |'pdml-in-orig' file| |'new-enb-conf-file' file|\n"); + fprintf (stdout, " +------------+-----------+ +--------+----------+ +------------+-----------+\n"); + fprintf (stdout, " | | |\n"); + fprintf (stdout, " +----------------------+-------------------------+\n"); + fprintf (stdout, " |\n"); + fprintf (stdout, " V\n"); + fprintf (stdout, " generate_scenario -t -p -o -n \n"); + fprintf (stdout, " | ^ |\n"); + fprintf (stdout, " | | |\n"); + fprintf (stdout, " +--------------V------------+ +------------V----------------+\n"); + fprintf (stdout, " |'xml-scenario-generic' file| |'xml-scenario-dedicated' file|\n"); + fprintf (stdout, " +---------------------------+ +-----------------------------+\n"); } @@ -422,20 +566,29 @@ config_parse_opt_line ( //------------------------------------------------------------------------------ { int option; - char *enb_config_file_name = NULL; + int rv = 0; + char *new_enb_config_file_name = NULL; + char *old_enb_config_file_name = NULL; + char *pdml_in_file_name = NULL; + char *generic_scenario_file_name = NULL; + char *test_dir_name = NULL; enum long_option_e { LONG_OPTION_START = 0x100, /* Start after regular single char options */ LONG_OPTION_NEW_ENB_CONF_FILE, LONG_OPTION_OLD_ENB_CONF_FILE, - LONG_OPTION_PDML_IN_BASENAME, + LONG_OPTION_PDML, + LONG_OPTION_TEST_DIR, + LONG_OPTION_SCENARIO_GENERIC, LONG_OPTION_HELP, }; static struct option long_options[] = { {"old-enb-conf-file", required_argument, 0, LONG_OPTION_OLD_ENB_CONF_FILE}, {"new-enb-conf-file", required_argument, 0, LONG_OPTION_NEW_ENB_CONF_FILE}, - {"pdml_in_basename", required_argument, 0, LONG_OPTION_PDML_IN_BASENAME}, + {"pdml ", required_argument, 0, LONG_OPTION_PDML}, + {"test-dir", required_argument, 0, LONG_OPTION_TEST_DIR}, + {"scenario-generic", required_argument, 0, LONG_OPTION_SCENARIO_GENERIC}, {"help", required_argument, 0, LONG_OPTION_HELP}, {NULL, 0, NULL, 0} }; @@ -443,32 +596,53 @@ config_parse_opt_line ( /* * Parsing command line */ - while ((option = getopt_long (argc, argv, "hp:n:o", long_options, NULL)) != -1) { + while ((option = getopt_long (argc, argv, "hp:n:o:s:t", long_options, NULL)) != -1) { switch (option) { case LONG_OPTION_OLD_ENB_CONF_FILE: case 'o': if (optarg) { - enb_config_file_name = optarg; - printf("Old eNB config file name is %s\n", enb_config_file_name); - enb_config_init(enb_config_file_name, ENB_CONFIG_PROPERTIES_INDEX_OLD); - g_test_dir = strdup(dirname(enb_config_file_name)); + old_enb_config_file_name = optarg; + printf("Old eNB config file name is %s\n", old_enb_config_file_name); + rv |= GENERATE_GENERIC_SCENARIO; } break; case LONG_OPTION_NEW_ENB_CONF_FILE: case 'n': if (optarg) { - enb_config_file_name = optarg; - printf("New eNB config file name is %s\n", enb_config_file_name); - enb_config_init(enb_config_file_name, ENB_CONFIG_PROPERTIES_INDEX_NEW); + new_enb_config_file_name = optarg; + printf("New eNB config file name is %s\n", new_enb_config_file_name); + rv |= GENERATE_DEDICATED_SCENARIO; } break; - case LONG_OPTION_PDML_IN_BASENAME: + case LONG_OPTION_PDML: case 'p': if (optarg) { - g_pdml_in_basename = strdup(optarg); - printf("PDML input file name is %s\n", g_pdml_in_basename); + pdml_in_file_name = strdup(optarg); + printf("PDML input file name is %s\n", pdml_in_file_name); + rv |= GENERATE_GENERIC_SCENARIO; + } + break; + + case LONG_OPTION_TEST_DIR: + case 't': + if (optarg) { + test_dir_name = strdup(optarg); + if (is_file_exists(test_dir_name, "test dirname") != GS_IS_DIR) { + fprintf(stderr, "Please provide a valid test dirname, %s is not a valid directory name\n", test_dir_name); + exit(1); + } + printf("Test dir name is %s\n", test_dir_name); + } + break; + + case LONG_OPTION_SCENARIO_GENERIC: + case 's': + if (optarg) { + generic_scenario_file_name = strdup(optarg); + printf("Generic XML scenario input file name is %s\n", generic_scenario_file_name); + rv |= GENERATE_DEDICATED_SCENARIO; } break; @@ -479,18 +653,77 @@ config_parse_opt_line ( exit (0); } } - return 0; + if (NULL == test_dir_name) { + fprintf(stderr, "Please provide a valid test dirname\n"); + exit(1); + } + g_test_dir = test_dir_name; test_dir_name = NULL; + if (chdir(g_test_dir) != 0) { + fprintf(stderr, "Error: chdir %s returned %s\n", g_test_dir, strerror(errno)); + exit(1); + } + if (rv & GENERATE_GENERIC_SCENARIO) { + if (NULL == old_enb_config_file_name) { + fprintf(stderr, "Error: please provide the original eNB config file name that should be in %s\n", g_test_dir); + } + if (is_file_exists(old_enb_config_file_name, "Old eNB config file") != GS_IS_FILE) { + fprintf(stderr, "Error: original eNB config file name %s is not found in dir %s\n", old_enb_config_file_name, g_test_dir); + } + enb_config_display(ENB_CONFIG_PROPERTIES_INDEX_OLD); + enb_config_init(old_enb_config_file_name, ENB_CONFIG_PROPERTIES_INDEX_OLD); + + if (NULL == pdml_in_file_name) { + fprintf(stderr, "Error: please provide the PDML file name that should be in %s\n", g_test_dir); + } + if (is_file_exists(pdml_in_file_name, "PDML file") != GS_IS_FILE) { + fprintf(stderr, "Error: PDML file name %s is not found in dir %s\n", pdml_in_file_name, g_test_dir); + } + g_pdml_in_origin = pdml_in_file_name; pdml_in_file_name = NULL; + } + + if (rv & GENERATE_DEDICATED_SCENARIO) { + if (NULL == new_enb_config_file_name) { + fprintf(stderr, "Error: please provide the new eNB config file name that should be in %s\n", g_test_dir); + } + if (is_file_exists(new_enb_config_file_name, "New eNB config file") != GS_IS_FILE) { + fprintf(stderr, "Error: New eNB config file name %s is not found in dir %s\n", new_enb_config_file_name, g_test_dir); + } + enb_config_display(ENB_CONFIG_PROPERTIES_INDEX_NEW); + enb_config_init(new_enb_config_file_name, ENB_CONFIG_PROPERTIES_INDEX_NEW); + + if (NULL == generic_scenario_file_name) { + fprintf(stderr, "Error: please provide the Generic scenario file name that should be in %s\n", g_test_dir); + } + if (is_file_exists(generic_scenario_file_name, "Generic scenario file") != GS_IS_FILE) { + fprintf(stderr, "Error: Generic scenario file name %s is not found in dir %s\n", generic_scenario_file_name, g_test_dir); + } + g_generic_scenario = generic_scenario_file_name; generic_scenario_file_name = NULL; + } + return rv; } //------------------------------------------------------------------------------ int main( int argc, char **argv ) //------------------------------------------------------------------------------ { + int actions = 0; + + g_openair_dir = getenv("OPENAIR_DIR"); + if (NULL == g_openair_dir) { + fprintf(stderr, "Error: Could not get OPENAIR_DIR environment variable\n"); + exit(1); + } + memset((char*) &g_enb_properties[ENB_CONFIG_PROPERTIES_INDEX_OLD], 0 , sizeof(g_enb_properties[ENB_CONFIG_PROPERTIES_INDEX_OLD])); memset((char*) &g_enb_properties[ENB_CONFIG_PROPERTIES_INDEX_NEW], 0 , sizeof(g_enb_properties[ENB_CONFIG_PROPERTIES_INDEX_NEW])); - config_parse_opt_line (argc, argv); //Command-line options - enb_config_display(ENB_CONFIG_PROPERTIES_INDEX_OLD); - enb_config_display(ENB_CONFIG_PROPERTIES_INDEX_NEW); - generate_scenario(g_pdml_in_basename); + + actions = config_parse_opt_line (argc, argv); //Command-line options + if (actions & GENERATE_GENERIC_SCENARIO) { + generate_generic_scenario(g_test_dir, g_pdml_in_origin); + } + /*if (actions & GENERATE_DEDICATED_SCENARIO) { + generate_dedicated_scenario(g_test_dir, g_pdml_in_origin); + }*/ + return 0; } diff --git a/openair3/TEST/EPC_TEST/generic_scenario.xsl b/openair3/TEST/EPC_TEST/generic_scenario.xsl new file mode 100644 index 0000000000..99672a28f0 --- /dev/null +++ b/openair3/TEST/EPC_TEST/generic_scenario.xsl @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/openair3/TEST/EPC_TEST/mme_test_s1_pcap2pdml b/openair3/TEST/EPC_TEST/mme_test_s1_pcap2pdml index b0a77e60f5..796fa9a45b 100755 --- a/openair3/TEST/EPC_TEST/mme_test_s1_pcap2pdml +++ b/openair3/TEST/EPC_TEST/mme_test_s1_pcap2pdml @@ -35,14 +35,25 @@ packets = orig_dom.getElementsByTagName("packet") for packet in packets: found_sctp = False found_s1ap = False + sctp_node = None + frame_node = None + ip_node = None protos = packet.getElementsByTagName("proto") for proto in protos: attrs = proto.attributes urlnode = attrs['name'] - if urlnode.nodeValue == 'sctp': + if urlnode.nodeValue == 'frame': + frame_node = proto + elif urlnode.nodeValue == 'ip': + frame_node.appendChild(proto) + ip_node = proto + elif urlnode.nodeValue == 'sctp': found_sctp = True + ip_node.appendChild(proto) + sctp_node = proto elif urlnode.nodeValue == 's1ap': found_s1ap = True + sctp_node.appendChild(proto) elif urlnode.nodeValue == 'geninfo': packet.removeChild(proto) elif urlnode.nodeValue == 'eth': @@ -54,20 +65,21 @@ for packet in packets: ##################### # dom to xml string ##################### -filtered_pdml_string = orig_dom.toxml() +filtered_pdml_string = orig_dom.toprettyxml(indent=" ") cleaned_pdml_string = "" ##################### # remove blank lines in xml string ##################### lines = filtered_pdml_string.splitlines() for line in lines: - if line[:-1]: - cleaned_pdml_string += line + '\r\n' + if len(line.strip()): + if line[:-1]: + cleaned_pdml_string += line + '\r\n' #print "'%s'" % cleaned_pdml_string ##################### # write pdml string to pdml file ##################### -out_pdml_file_name = os.path.dirname(orig_pcap_file_name) + os.path.splitext(os.path.basename(orig_pcap_file_name))[0] + '.pdml' +out_pdml_file_name = os.path.dirname(orig_pcap_file_name) + '/' + os.path.splitext(os.path.basename(orig_pcap_file_name))[0] + '.pdml' out_file = open(out_pdml_file_name, "w") out_file.write(cleaned_pdml_string) out_file.close() @@ -86,7 +98,7 @@ filtered_html_string = etree.tostring(trans_root) ##################### # write html string to html file ##################### -out_html_file_name = os.path.dirname(orig_pcap_file_name) + os.path.splitext(os.path.basename(orig_pcap_file_name))[0] + '.html' +out_html_file_name = os.path.dirname(orig_pcap_file_name) + '/' +os.path.splitext(os.path.basename(orig_pcap_file_name))[0] + '.html' out_file = open(out_html_file_name, "w") out_file.write(filtered_html_string) out_file.close() From e8c40e78efc35ad3c284c494a718b42cffb68b9f Mon Sep 17 00:00:00 2001 From: gauthier Date: Wed, 4 Nov 2015 10:57:03 +0100 Subject: [PATCH 04/47] generated an initial 'generic' scenario. --- openair3/TEST/EPC_TEST/generate_scenario.c | 69 ++++++- openair3/TEST/EPC_TEST/generic_scenario.xsl | 214 +++++++++++++++++++- 2 files changed, 264 insertions(+), 19 deletions(-) diff --git a/openair3/TEST/EPC_TEST/generate_scenario.c b/openair3/TEST/EPC_TEST/generate_scenario.c index eff91ea56f..c5289142b5 100644 --- a/openair3/TEST/EPC_TEST/generate_scenario.c +++ b/openair3/TEST/EPC_TEST/generate_scenario.c @@ -36,6 +36,7 @@ */ #include +#include #include #include #include @@ -95,7 +96,7 @@ #define ENB_CONFIG_PROPERTIES_INDEX_OLD 0 #define ENB_CONFIG_PROPERTIES_INDEX_NEW 1 -#define ENB_CONFIG_MAX_XSLT_PARAMS 64 +#define ENB_CONFIG_MAX_XSLT_PARAMS 32 Enb_properties_array_t g_enb_properties[2]; char *g_openair_dir = NULL; @@ -136,6 +137,25 @@ int is_file_exists( const char const * file_nameP, const char const *file_roleP) return 0; } + +//------------------------------------------------------------------------------ +int strip_extension(char *in_filename) +{ + static const uint8_t name_min_len = 1; + static const uint8_t max_ext_len = 5; // .pdml ! + fprintf(stdout, "strip_extension %s\n", in_filename); + + if (NULL != in_filename) { + /* Check chars starting at end of string to find last '.' */ + for (ssize_t i = strlen(in_filename); i > (name_min_len + max_ext_len); i--) { + if (in_filename[i] == '.') { + in_filename[i] = '\0'; + return i; + } + } + } + return -1; +} //------------------------------------------------------------------------------ // return number of splitted items int split_path( char * pathP, char *** resP) @@ -155,18 +175,21 @@ int split_path( char * pathP, char *** resP) } //------------------------------------------------------------------------------ -void generate_generic_scenario(const char const * test_nameP, const char const * pdml_in_basenameP) +int generate_generic_scenario(const char const * test_nameP, const char const * pdml_in_basenameP) //------------------------------------------------------------------------------ { //int fd_pdml_in; xsltStylesheetPtr cur = NULL; xmlDocPtr doc, res; - const char *params[ENB_CONFIG_MAX_XSLT_PARAMS]; + FILE *generic_scenario_file = NULL; + const char generic_scenario_filename[NAME_MAX]; + const char *params[2*ENB_CONFIG_MAX_XSLT_PARAMS]; int nb_params = 0; int i,j; char astring[1024]; struct in_addr addr; + memset(generic_scenario_filename, 0, sizeof(generic_scenario_filename)); memset(astring, 0, sizeof(astring)); if (getcwd(astring, sizeof(astring)) != NULL) { fprintf(stdout, "working in %s directory\n", astring); @@ -182,7 +205,18 @@ void generate_generic_scenario(const char const * test_nameP, const char const * xmlSubstituteEntitiesDefault(1); xmlLoadExtDtdDefaultValue = 1; cur = xsltParseStylesheetFile(astring); + if (NULL == cur) { + AssertFatal (0, "Could not parse stylesheet file %s (check OPENAIR_DIR env variable)!\n", astring); + } else { + fprintf(stdout, "XSLT style sheet: %s\n", astring); + } + doc = xmlParseFile(pdml_in_basenameP); + if (NULL == doc) { + AssertFatal (0, "Could not parse pdml file %s!\n", pdml_in_basenameP); + } else { + fprintf(stdout, "pdml file: %s\n", pdml_in_basenameP); + } params[nb_params++] = "test_name"; sprintf(astring, "\"%s\"", test_nameP); params[nb_params++] = strdup(astring); @@ -207,8 +241,25 @@ void generate_generic_scenario(const char const * test_nameP, const char const * } params[nb_params] = NULL; res = xsltApplyStylesheet(cur, doc, params); - xsltSaveResultToFile(stdout, res, cur); - + if (NULL != res) { + // since pdml filename is not relative (no path), just filename in current directory we can safely remove + sprintf(generic_scenario_filename,"%s",pdml_in_basenameP); + if (strip_extension(generic_scenario_filename) > 0) { + strcat(generic_scenario_filename, "_generic_scenario.xml"); + generic_scenario_file = fopen( generic_scenario_filename, "w+"); + if (NULL != generic_scenario_file) { + xsltSaveResultToFile(generic_scenario_file, res, cur); + fclose(generic_scenario_file); + fprintf(stdout, "Wrote generic scenario to %s\n", generic_scenario_filename); + } else { + fprintf(stderr, "Error in fopen(%s)\n", generic_scenario_filename); + } + } else { + fprintf(stderr, "Error in strip_extension()\n"); + } + } else { + fprintf(stderr, "Error in xsltApplyStylesheet()\n"); + } xsltFreeStylesheet(cur); xmlFreeDoc(res); xmlFreeDoc(doc); @@ -494,7 +545,7 @@ static void usage ( fprintf (stdout, "\t-o | --old-enb-conf-file Provide the old eNB config file for generating a copy of the original test\n"); fprintf (stdout, " This option is set as many times as there are some eNB config files in the original test\n"); fprintf (stdout, "\t-p | --pdml File name (with no path) of an original scenario that has to be reworked (IP addresses) with new testbed\n"); - fprintf (stdout, "\t-s | --scenario-generic File name (with no path) of a scenario that has to be customized (IP addresses) with new testbed\n"); + fprintf (stdout, "\t-s | --scenario-generic File name (with no path) of a scenario that has to be customized (IP addresses) with new testbed\n"); fprintf (stdout, "\n"); fprintf (stdout, "\n"); fprintf (stdout, "Example of generate_scenario use cases: \n"); @@ -596,7 +647,7 @@ config_parse_opt_line ( /* * Parsing command line */ - while ((option = getopt_long (argc, argv, "hp:n:o:s:t", long_options, NULL)) != -1) { + while ((option = getopt_long (argc, argv, "hp:n:o:s:t:", long_options, NULL)) != -1) { switch (option) { case LONG_OPTION_OLD_ENB_CONF_FILE: case 'o': @@ -669,8 +720,8 @@ config_parse_opt_line ( if (is_file_exists(old_enb_config_file_name, "Old eNB config file") != GS_IS_FILE) { fprintf(stderr, "Error: original eNB config file name %s is not found in dir %s\n", old_enb_config_file_name, g_test_dir); } - enb_config_display(ENB_CONFIG_PROPERTIES_INDEX_OLD); enb_config_init(old_enb_config_file_name, ENB_CONFIG_PROPERTIES_INDEX_OLD); + enb_config_display(ENB_CONFIG_PROPERTIES_INDEX_OLD); if (NULL == pdml_in_file_name) { fprintf(stderr, "Error: please provide the PDML file name that should be in %s\n", g_test_dir); @@ -688,8 +739,8 @@ config_parse_opt_line ( if (is_file_exists(new_enb_config_file_name, "New eNB config file") != GS_IS_FILE) { fprintf(stderr, "Error: New eNB config file name %s is not found in dir %s\n", new_enb_config_file_name, g_test_dir); } - enb_config_display(ENB_CONFIG_PROPERTIES_INDEX_NEW); enb_config_init(new_enb_config_file_name, ENB_CONFIG_PROPERTIES_INDEX_NEW); + enb_config_display(ENB_CONFIG_PROPERTIES_INDEX_NEW); if (NULL == generic_scenario_file_name) { fprintf(stderr, "Error: please provide the Generic scenario file name that should be in %s\n", g_test_dir); diff --git a/openair3/TEST/EPC_TEST/generic_scenario.xsl b/openair3/TEST/EPC_TEST/generic_scenario.xsl index 99672a28f0..ab0e7f1123 100644 --- a/openair3/TEST/EPC_TEST/generic_scenario.xsl +++ b/openair3/TEST/EPC_TEST/generic_scenario.xsl @@ -8,16 +8,103 @@ encoding="iso-8859-1" /> - + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + enb_s1c0 + enb_s1c1 + enb_s1c2 + enb_s1c3 + enb_s1c4 + enb_s1c5 + mme_s1c0_0 + mme_s1c0_1 + mme_s1c0_2 + mme_s1c0_3 + mme_s1c1_0 + mme_s1c1_1 + mme_s1c1_2" + mme_s1c1_3 + reverse_ip_yourself + + + + + + + DATA + INIT + INIT_ACK + SACK + HEARTBEAT + HEARTBEAT_ACK + ABORT + SHUTDOWN + SHUTDOWN_ACK + ERROR + COOKIE_ECHO + COOKIE_ACK + ECNE + CWR + SHUTDOWN_COMPLETE + UNKNOWN_CHUNK_TYPE + + + + + + + + + + + + + - - - + + + + + + + + + + + @@ -25,22 +112,129 @@ - + + + + + + + + + - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - From 12b871086da60688b7d15aeac269345e533b9c6c Mon Sep 17 00:00:00 2001 From: gauthier Date: Wed, 4 Nov 2015 12:26:41 +0100 Subject: [PATCH 05/47] Removed dedicated scenario option, fixed scenario name(xml attribute) = pdml filename --- openair3/TEST/EPC_TEST/generate_scenario.c | 212 +++++++-------------- openair3/TEST/EPC_TEST/generate_scenario.h | 2 +- 2 files changed, 65 insertions(+), 149 deletions(-) diff --git a/openair3/TEST/EPC_TEST/generate_scenario.c b/openair3/TEST/EPC_TEST/generate_scenario.c index c5289142b5..4cb21f9604 100644 --- a/openair3/TEST/EPC_TEST/generate_scenario.c +++ b/openair3/TEST/EPC_TEST/generate_scenario.c @@ -93,12 +93,10 @@ #define ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U "ENB_IPV4_ADDRESS_FOR_S1U" #define ENB_CONFIG_STRING_ENB_PORT_FOR_S1U "ENB_PORT_FOR_S1U" -#define ENB_CONFIG_PROPERTIES_INDEX_OLD 0 -#define ENB_CONFIG_PROPERTIES_INDEX_NEW 1 #define ENB_CONFIG_MAX_XSLT_PARAMS 32 -Enb_properties_array_t g_enb_properties[2]; +Enb_properties_array_t g_enb_properties; char *g_openair_dir = NULL; char *g_test_dir = NULL; char *g_pdml_in_origin = NULL; @@ -107,7 +105,6 @@ extern int xmlLoadExtDtdDefaultValue; #define GENERATE_PDML_FILE 1 #define GENERATE_GENERIC_SCENARIO 2 -#define GENERATE_DEDICATED_SCENARIO 4 #define GS_IS_FILE 1 #define GS_IS_DIR 2 @@ -187,6 +184,7 @@ int generate_generic_scenario(const char const * test_nameP, const char const * int nb_params = 0; int i,j; char astring[1024]; + char *astring2 = NULL; struct in_addr addr; memset(generic_scenario_filename, 0, sizeof(generic_scenario_filename)); @@ -218,24 +216,32 @@ int generate_generic_scenario(const char const * test_nameP, const char const * fprintf(stdout, "pdml file: %s\n", pdml_in_basenameP); } params[nb_params++] = "test_name"; - sprintf(astring, "\"%s\"", test_nameP); + sprintf(astring, "%s", pdml_in_basenameP); + if (strip_extension(astring) > 0) { + astring2 = strdup(astring); + sprintf(astring, "\"%s\"", astring2); + free(astring2); + astring2 = NULL; + } else { + fprintf(stderr, "Assigning test name failed: %s\n", astring); + } params[nb_params++] = strdup(astring); - for (i = 0; i < g_enb_properties[ENB_CONFIG_PROPERTIES_INDEX_OLD].number; i++) { + for (i = 0; i < g_enb_properties.number; i++) { // eNB S1-C IPv4 address sprintf(astring, "enb_s1c%d", i); params[nb_params++] = strdup(astring); - addr.s_addr = g_enb_properties[ENB_CONFIG_PROPERTIES_INDEX_OLD].properties[i]->enb_ipv4_address_for_S1_MME; + addr.s_addr = g_enb_properties.properties[i]->enb_ipv4_address_for_S1_MME; sprintf(astring, "\"%s\"", inet_ntoa(addr)); params[nb_params++] = strdup(astring); // MME S1-C IPv4 address - for (j = 0; j < g_enb_properties[ENB_CONFIG_PROPERTIES_INDEX_OLD].properties[i]->nb_mme; j++) { + for (j = 0; j < g_enb_properties.properties[i]->nb_mme; j++) { sprintf(astring, "mme_s1c%d_%d", i, j); params[nb_params++] = strdup(astring); - AssertFatal (g_enb_properties[ENB_CONFIG_PROPERTIES_INDEX_OLD].properties[i]->mme_ip_address[j].ipv4_address, + AssertFatal (g_enb_properties.properties[i]->mme_ip_address[j].ipv4_address, "Only support MME IPv4 address\n"); - sprintf(astring, "\"%s\"", g_enb_properties[ENB_CONFIG_PROPERTIES_INDEX_OLD].properties[i]->mme_ip_address[j].ipv4_address); + sprintf(astring, "\"%s\"", g_enb_properties.properties[i]->mme_ip_address[j].ipv4_address); params[nb_params++] = strdup(astring); } } @@ -269,26 +275,26 @@ int generate_generic_scenario(const char const * test_nameP, const char const * } //------------------------------------------------------------------------------ -static void enb_config_display(const boolean_t new_config_fileP) +static void enb_config_display(void) //------------------------------------------------------------------------------ { int i; printf( "\n----------------------------------------------------------------------\n"); - printf( " %s ENB CONFIG FILE CONTENT LOADED:\n", new_config_fileP == ENB_CONFIG_PROPERTIES_INDEX_OLD ? "Old":"New"); + printf( " ENB CONFIG FILE CONTENT LOADED:\n"); printf( "----------------------------------------------------------------------\n"); - for (i = 0; i < g_enb_properties[new_config_fileP].number; i++) { + for (i = 0; i < g_enb_properties.number; i++) { printf( "ENB CONFIG for instance %u:\n\n", i); - printf( "\teNB name: \t%s\n",g_enb_properties[new_config_fileP].properties[i]->eNB_name); - printf( "\teNB ID: \t%"PRIu32"\n",g_enb_properties[new_config_fileP].properties[i]->eNB_id); - printf( "\tCell type: \t%s\n",g_enb_properties[new_config_fileP].properties[i]->cell_type == CELL_MACRO_ENB ? "CELL_MACRO_ENB":"CELL_HOME_ENB"); - printf( "\tTAC: \t%"PRIu16"\n",g_enb_properties[new_config_fileP].properties[i]->tac); - printf( "\tMCC: \t%"PRIu16"\n",g_enb_properties[new_config_fileP].properties[i]->mcc); + printf( "\teNB name: \t%s\n",g_enb_properties.properties[i]->eNB_name); + printf( "\teNB ID: \t%"PRIu32"\n",g_enb_properties.properties[i]->eNB_id); + printf( "\tCell type: \t%s\n",g_enb_properties.properties[i]->cell_type == CELL_MACRO_ENB ? "CELL_MACRO_ENB":"CELL_HOME_ENB"); + printf( "\tTAC: \t%"PRIu16"\n",g_enb_properties.properties[i]->tac); + printf( "\tMCC: \t%"PRIu16"\n",g_enb_properties.properties[i]->mcc); - if (g_enb_properties[new_config_fileP].properties[i]->mnc_digit_length == 3) { - printf( "\tMNC: \t%03"PRIu16"\n",g_enb_properties[new_config_fileP].properties[i]->mnc); + if (g_enb_properties.properties[i]->mnc_digit_length == 3) { + printf( "\tMNC: \t%03"PRIu16"\n",g_enb_properties.properties[i]->mnc); } else { - printf( "\tMNC: \t%02"PRIu16"\n",g_enb_properties[new_config_fileP].properties[i]->mnc); + printf( "\tMNC: \t%02"PRIu16"\n",g_enb_properties.properties[i]->mnc); } printf( "\n--------------------------------------------------------\n"); } @@ -301,7 +307,7 @@ static void enb_config_display(const boolean_t new_config_fileP) #define libconfig_int int #endif //------------------------------------------------------------------------------ -void enb_config_init(const char const * lib_config_file_name_pP, const boolean_t new_config_fileP) +void enb_config_init(const char const * lib_config_file_name_pP) //------------------------------------------------------------------------------ { config_t cfg; @@ -336,9 +342,7 @@ void enb_config_init(const char const * lib_config_file_name_pP, const boolean_ char *address = NULL; char *cidr = NULL; - AssertFatal ((new_config_fileP == 0) || (new_config_fileP == 1), - "Bad parameter new_config_fileP %d \n", - new_config_fileP); + AssertFatal (lib_config_file_name_pP != NULL, "Bad parameter lib_config_file_name_pP %s , must reference a valid eNB config file\n", lib_config_file_name_pP); @@ -374,7 +378,7 @@ void enb_config_init(const char const * lib_config_file_name_pP, const boolean_ setting = config_lookup(&cfg, ENB_CONFIG_STRING_ENB_LIST); if (setting != NULL) { - enb_properties_index = g_enb_properties[new_config_fileP].number; + enb_properties_index = g_enb_properties.number; parse_errors = 0; num_enbs = config_setting_length(setting); @@ -411,34 +415,34 @@ void enb_config_init(const char const * lib_config_file_name_pP, const boolean_ // search if in active list for (j=0; j < num_enb_properties; j++) { if (strcmp(active_enb[j], enb_name) == 0) { - g_enb_properties[new_config_fileP].properties[enb_properties_index] = calloc(1, sizeof(Enb_properties_t)); + g_enb_properties.properties[enb_properties_index] = calloc(1, sizeof(Enb_properties_t)); - g_enb_properties[new_config_fileP].properties[enb_properties_index]->eNB_id = enb_id; + g_enb_properties.properties[enb_properties_index]->eNB_id = enb_id; if (strcmp(cell_type, "CELL_MACRO_ENB") == 0) { - g_enb_properties[new_config_fileP].properties[enb_properties_index]->cell_type = CELL_MACRO_ENB; + g_enb_properties.properties[enb_properties_index]->cell_type = CELL_MACRO_ENB; } else if (strcmp(cell_type, "CELL_HOME_ENB") == 0) { - g_enb_properties[new_config_fileP].properties[enb_properties_index]->cell_type = CELL_HOME_ENB; + g_enb_properties.properties[enb_properties_index]->cell_type = CELL_HOME_ENB; } else { AssertError (0, parse_errors ++, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n", lib_config_file_name_pP, i, cell_type); } - g_enb_properties[new_config_fileP].properties[enb_properties_index]->eNB_name = strdup(enb_name); - g_enb_properties[new_config_fileP].properties[enb_properties_index]->tac = (uint16_t)atoi(tac); - g_enb_properties[new_config_fileP].properties[enb_properties_index]->mcc = (uint16_t)atoi(mcc); - g_enb_properties[new_config_fileP].properties[enb_properties_index]->mnc = (uint16_t)atoi(mnc); - g_enb_properties[new_config_fileP].properties[enb_properties_index]->mnc_digit_length = strlen(mnc); - AssertFatal((g_enb_properties[new_config_fileP].properties[enb_properties_index]->mnc_digit_length == 2) || - (g_enb_properties[new_config_fileP].properties[enb_properties_index]->mnc_digit_length == 3), + g_enb_properties.properties[enb_properties_index]->eNB_name = strdup(enb_name); + g_enb_properties.properties[enb_properties_index]->tac = (uint16_t)atoi(tac); + g_enb_properties.properties[enb_properties_index]->mcc = (uint16_t)atoi(mcc); + g_enb_properties.properties[enb_properties_index]->mnc = (uint16_t)atoi(mnc); + g_enb_properties.properties[enb_properties_index]->mnc_digit_length = strlen(mnc); + AssertFatal((g_enb_properties.properties[enb_properties_index]->mnc_digit_length == 2) || + (g_enb_properties.properties[enb_properties_index]->mnc_digit_length == 3), "BAD MNC DIGIT LENGTH %d", - g_enb_properties[new_config_fileP].properties[i]->mnc_digit_length); + g_enb_properties.properties[i]->mnc_digit_length); setting_mme_addresses = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_MME_IP_ADDRESS); num_mme_address = config_setting_length(setting_mme_addresses); - g_enb_properties[new_config_fileP].properties[enb_properties_index]->nb_mme = 0; + g_enb_properties.properties[enb_properties_index]->nb_mme = 0; for (j = 0; j < num_mme_address; j++) { setting_mme_address = config_setting_get_elem(setting_mme_addresses, j); @@ -456,22 +460,22 @@ void enb_config_init(const char const * lib_config_file_name_pP, const boolean_ continue; // FIXME will prevent segfaults below, not sure what happens at function exit... } - g_enb_properties[new_config_fileP].properties[enb_properties_index]->nb_mme += 1; + g_enb_properties.properties[enb_properties_index]->nb_mme += 1; - g_enb_properties[new_config_fileP].properties[enb_properties_index]->mme_ip_address[j].ipv4_address = strdup(ipv4); - g_enb_properties[new_config_fileP].properties[enb_properties_index]->mme_ip_address[j].ipv6_address = strdup(ipv6); + g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv4_address = strdup(ipv4); + g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv6_address = strdup(ipv6); if (strcmp(active, "yes") == 0) { - g_enb_properties[new_config_fileP].properties[enb_properties_index]->mme_ip_address[j].active = 1; + g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].active = 1; } // else { (calloc) if (strcmp(preference, "ipv4") == 0) { - g_enb_properties[new_config_fileP].properties[enb_properties_index]->mme_ip_address[j].ipv4 = 1; + g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv4 = 1; } else if (strcmp(preference, "ipv6") == 0) { - g_enb_properties[new_config_fileP].properties[enb_properties_index]->mme_ip_address[j].ipv6 = 1; + g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv6 = 1; } else if (strcmp(preference, "no") == 0) { - g_enb_properties[new_config_fileP].properties[enb_properties_index]->mme_ip_address[j].ipv4 = 1; - g_enb_properties[new_config_fileP].properties[enb_properties_index]->mme_ip_address[j].ipv6 = 1; + g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv4 = 1; + g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv6 = 1; } } @@ -493,22 +497,22 @@ void enb_config_init(const char const * lib_config_file_name_pP, const boolean_ &enb_port_for_S1U) ) ) { - g_enb_properties[new_config_fileP].properties[enb_properties_index]->enb_interface_name_for_S1U = strdup(enb_interface_name_for_S1U); + g_enb_properties.properties[enb_properties_index]->enb_interface_name_for_S1U = strdup(enb_interface_name_for_S1U); cidr = enb_ipv4_address_for_S1U; address = strtok(cidr, "/"); if (address) { - IPV4_STR_ADDR_TO_INT_NWBO ( address, g_enb_properties[new_config_fileP].properties[enb_properties_index]->enb_ipv4_address_for_S1U, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" ); + IPV4_STR_ADDR_TO_INT_NWBO ( address, g_enb_properties.properties[enb_properties_index]->enb_ipv4_address_for_S1U, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" ); } - g_enb_properties[new_config_fileP].properties[enb_properties_index]->enb_port_for_S1U = enb_port_for_S1U; + g_enb_properties.properties[enb_properties_index]->enb_port_for_S1U = enb_port_for_S1U; - g_enb_properties[new_config_fileP].properties[enb_properties_index]->enb_interface_name_for_S1_MME = strdup(enb_interface_name_for_S1_MME); + g_enb_properties.properties[enb_properties_index]->enb_interface_name_for_S1_MME = strdup(enb_interface_name_for_S1_MME); cidr = enb_ipv4_address_for_S1_MME; address = strtok(cidr, "/"); if (address) { - IPV4_STR_ADDR_TO_INT_NWBO ( address, g_enb_properties[new_config_fileP].properties[enb_properties_index]->enb_ipv4_address_for_S1_MME, "BAD IP ADDRESS FORMAT FOR eNB S1_MME !\n" ); + IPV4_STR_ADDR_TO_INT_NWBO ( address, g_enb_properties.properties[enb_properties_index]->enb_ipv4_address_for_S1_MME, "BAD IP ADDRESS FORMAT FOR eNB S1_MME !\n" ); } } } // if (subsetting != NULL) { @@ -518,7 +522,7 @@ void enb_config_init(const char const * lib_config_file_name_pP, const boolean_ } // for (i = 0; i < num_enbs; i++) } // if (setting != NULL) { - g_enb_properties[new_config_fileP].number += num_enb_properties; + g_enb_properties.number += num_enb_properties; AssertFatal (parse_errors == 0, @@ -540,22 +544,19 @@ static void usage ( fprintf (stdout, "\n"); fprintf (stdout, "Available options:\n"); fprintf (stdout, "\t-h | --help Print this help and return\n"); - fprintf (stdout, "\t-n | --new-enb-conf-file Provide an updated eNB config file for generating a copy of the original test\n"); - fprintf (stdout, " This option is set as many times as there are some eNB config files in the original test\n"); fprintf (stdout, "\t-o | --old-enb-conf-file Provide the old eNB config file for generating a copy of the original test\n"); fprintf (stdout, " This option is set as many times as there are some eNB config files in the original test\n"); fprintf (stdout, "\t-p | --pdml File name (with no path) of an original scenario that has to be reworked (IP addresses) with new testbed\n"); - fprintf (stdout, "\t-s | --scenario-generic File name (with no path) of a scenario that has to be customized (IP addresses) with new testbed\n"); fprintf (stdout, "\n"); fprintf (stdout, "\n"); - fprintf (stdout, "Example of generate_scenario use cases: \n"); + fprintf (stdout, "Example of generate_scenario use case: \n"); fprintf (stdout, "\n"); - fprintf (stdout, " Case 1: generate a generix xml scenario from a captured pcap file: \n"); + fprintf (stdout, " Generate a generix xml scenario from a captured pcap file: \n"); fprintf (stdout, " +---------------------+ \n"); fprintf (stdout, " |captured pcap-ng file| \n"); fprintf (stdout, " +----------+----------+ \n"); fprintf (stdout, " |\n"); - fprintf (stdout, " mme_test_s1_pcap2pdml \n"); + fprintf (stdout, " mme_test_s1_pcap2pdml --pcap_file <`captured pcap-ng file`>\n"); fprintf (stdout, " |\n"); fprintf (stdout, " +--------V----------+ +------------------------+\n"); fprintf (stdout, " |'pdml-in-orig' file| |'old-enb-conf-file' file|\n"); @@ -563,52 +564,14 @@ static void usage ( fprintf (stdout, " | |\n"); fprintf (stdout, " +----------------------------+\n"); fprintf (stdout, " |\n"); - fprintf (stdout, " generate_scenario -t -p -o \n"); + fprintf (stdout, " generate_scenario -t -p <'pdml-in-orig' file> -o <'old-enb-conf-file' file> \n"); fprintf (stdout, " |\n"); fprintf (stdout, " +------------V--------------+\n"); fprintf (stdout, " +'xml-scenario-generic' file|\n"); fprintf (stdout, " +---------------------------+\n"); fprintf (stdout, "\n"); - fprintf (stdout, "\n"); - fprintf (stdout, " Case 2: generate a dedicated xml scenario from generic xml scenario:\n"); - fprintf (stdout, "\n"); - fprintf (stdout, " +---------------------------+ +------------------------+\n"); - fprintf (stdout, " |'xml-scenario-generic' file| |'new-enb-conf-file' file|\n"); - fprintf (stdout, " +--------+------------------+ +------------+-----------+\n"); - fprintf (stdout, " | |\n"); - fprintf (stdout, " +--------------------+---------------+\n"); - fprintf (stdout, " |\n"); - fprintf (stdout, " generate_scenario -t -s -n \n"); - fprintf (stdout, " |\n"); - fprintf (stdout, " +--------------V--------------+\n"); - fprintf (stdout, " +'xml-scenario-dedicated' file|\n"); - fprintf (stdout, " +-----------------------------+\n"); - fprintf (stdout, "\n"); - fprintf (stdout, "\n"); - fprintf (stdout, " Case 3 = case 1 + case 2: generate a dedicated xml scenario from a captured pcap file:\n"); - fprintf (stdout, "\n"); - fprintf (stdout, " +---------------------+\n"); - fprintf (stdout, " |captured pcap-ng file|\n"); - fprintf (stdout, " +----------+----------+\n"); - fprintf (stdout, " |\n"); - fprintf (stdout, " mme_test_s1_pcap2pdml \n"); - fprintf (stdout, " |\n"); - fprintf (stdout, " +------------------------+ +--------V----------+ +------------------------+\n"); - fprintf (stdout, " |'old-enb-conf-file' file| |'pdml-in-orig' file| |'new-enb-conf-file' file|\n"); - fprintf (stdout, " +------------+-----------+ +--------+----------+ +------------+-----------+\n"); - fprintf (stdout, " | | |\n"); - fprintf (stdout, " +----------------------+-------------------------+\n"); - fprintf (stdout, " |\n"); - fprintf (stdout, " V\n"); - fprintf (stdout, " generate_scenario -t -p -o -n \n"); - fprintf (stdout, " | ^ |\n"); - fprintf (stdout, " | | |\n"); - fprintf (stdout, " +--------------V------------+ +------------V----------------+\n"); - fprintf (stdout, " |'xml-scenario-generic' file| |'xml-scenario-dedicated' file|\n"); - fprintf (stdout, " +---------------------------+ +-----------------------------+\n"); } - //------------------------------------------------------------------------------ int config_parse_opt_line ( @@ -618,28 +581,22 @@ config_parse_opt_line ( { int option; int rv = 0; - char *new_enb_config_file_name = NULL; char *old_enb_config_file_name = NULL; char *pdml_in_file_name = NULL; - char *generic_scenario_file_name = NULL; char *test_dir_name = NULL; enum long_option_e { LONG_OPTION_START = 0x100, /* Start after regular single char options */ - LONG_OPTION_NEW_ENB_CONF_FILE, LONG_OPTION_OLD_ENB_CONF_FILE, LONG_OPTION_PDML, LONG_OPTION_TEST_DIR, - LONG_OPTION_SCENARIO_GENERIC, LONG_OPTION_HELP, }; static struct option long_options[] = { {"old-enb-conf-file", required_argument, 0, LONG_OPTION_OLD_ENB_CONF_FILE}, - {"new-enb-conf-file", required_argument, 0, LONG_OPTION_NEW_ENB_CONF_FILE}, {"pdml ", required_argument, 0, LONG_OPTION_PDML}, {"test-dir", required_argument, 0, LONG_OPTION_TEST_DIR}, - {"scenario-generic", required_argument, 0, LONG_OPTION_SCENARIO_GENERIC}, {"help", required_argument, 0, LONG_OPTION_HELP}, {NULL, 0, NULL, 0} }; @@ -658,15 +615,6 @@ config_parse_opt_line ( } break; - case LONG_OPTION_NEW_ENB_CONF_FILE: - case 'n': - if (optarg) { - new_enb_config_file_name = optarg; - printf("New eNB config file name is %s\n", new_enb_config_file_name); - rv |= GENERATE_DEDICATED_SCENARIO; - } - break; - case LONG_OPTION_PDML: case 'p': if (optarg) { @@ -688,15 +636,6 @@ config_parse_opt_line ( } break; - case LONG_OPTION_SCENARIO_GENERIC: - case 's': - if (optarg) { - generic_scenario_file_name = strdup(optarg); - printf("Generic XML scenario input file name is %s\n", generic_scenario_file_name); - rv |= GENERATE_DEDICATED_SCENARIO; - } - break; - case LONG_OPTION_HELP: case 'h': default: @@ -720,8 +659,8 @@ config_parse_opt_line ( if (is_file_exists(old_enb_config_file_name, "Old eNB config file") != GS_IS_FILE) { fprintf(stderr, "Error: original eNB config file name %s is not found in dir %s\n", old_enb_config_file_name, g_test_dir); } - enb_config_init(old_enb_config_file_name, ENB_CONFIG_PROPERTIES_INDEX_OLD); - enb_config_display(ENB_CONFIG_PROPERTIES_INDEX_OLD); + enb_config_init(old_enb_config_file_name); + enb_config_display(); if (NULL == pdml_in_file_name) { fprintf(stderr, "Error: please provide the PDML file name that should be in %s\n", g_test_dir); @@ -731,25 +670,6 @@ config_parse_opt_line ( } g_pdml_in_origin = pdml_in_file_name; pdml_in_file_name = NULL; } - - if (rv & GENERATE_DEDICATED_SCENARIO) { - if (NULL == new_enb_config_file_name) { - fprintf(stderr, "Error: please provide the new eNB config file name that should be in %s\n", g_test_dir); - } - if (is_file_exists(new_enb_config_file_name, "New eNB config file") != GS_IS_FILE) { - fprintf(stderr, "Error: New eNB config file name %s is not found in dir %s\n", new_enb_config_file_name, g_test_dir); - } - enb_config_init(new_enb_config_file_name, ENB_CONFIG_PROPERTIES_INDEX_NEW); - enb_config_display(ENB_CONFIG_PROPERTIES_INDEX_NEW); - - if (NULL == generic_scenario_file_name) { - fprintf(stderr, "Error: please provide the Generic scenario file name that should be in %s\n", g_test_dir); - } - if (is_file_exists(generic_scenario_file_name, "Generic scenario file") != GS_IS_FILE) { - fprintf(stderr, "Error: Generic scenario file name %s is not found in dir %s\n", generic_scenario_file_name, g_test_dir); - } - g_generic_scenario = generic_scenario_file_name; generic_scenario_file_name = NULL; - } return rv; } @@ -765,16 +685,12 @@ int main( int argc, char **argv ) exit(1); } - memset((char*) &g_enb_properties[ENB_CONFIG_PROPERTIES_INDEX_OLD], 0 , sizeof(g_enb_properties[ENB_CONFIG_PROPERTIES_INDEX_OLD])); - memset((char*) &g_enb_properties[ENB_CONFIG_PROPERTIES_INDEX_NEW], 0 , sizeof(g_enb_properties[ENB_CONFIG_PROPERTIES_INDEX_NEW])); + memset((char*) &g_enb_properties, 0 , sizeof(g_enb_properties)); actions = config_parse_opt_line (argc, argv); //Command-line options if (actions & GENERATE_GENERIC_SCENARIO) { generate_generic_scenario(g_test_dir, g_pdml_in_origin); } - /*if (actions & GENERATE_DEDICATED_SCENARIO) { - generate_dedicated_scenario(g_test_dir, g_pdml_in_origin); - }*/ return 0; } diff --git a/openair3/TEST/EPC_TEST/generate_scenario.h b/openair3/TEST/EPC_TEST/generate_scenario.h index c3b42ea253..88c0d28e17 100755 --- a/openair3/TEST/EPC_TEST/generate_scenario.h +++ b/openair3/TEST/EPC_TEST/generate_scenario.h @@ -126,7 +126,7 @@ typedef struct Enb_properties_array_s { Enb_properties_t *properties[EPC_TEST_SCENARIO_MAX_ENB]; } Enb_properties_array_t; -void enb_config_init(const char const * lib_config_file_name_pP, const boolean_t new_config_fileP); +void enb_config_init(const char const * lib_config_file_name_pP); #endif /* ENB_CONFIG_H_ */ /** @} */ From d03f78a4031bf62d4ea1b43b0a83e899027ec84c Mon Sep 17 00:00:00 2001 From: gauthier Date: Fri, 6 Nov 2015 10:03:26 +0100 Subject: [PATCH 06/47] Cleaned xml output, now a S1C test scenario is generated, ready to be parsed. --- cmake_targets/CMakeLists.txt | 66 ++- cmake_targets/tools/build_test_epc_tools | 4 + openair2/ENB_APP/enb_config.c | 2 +- openair2/ENB_APP/enb_config.h | 1 + openair3/TEST/EPC_TEST/generate_scenario.c | 103 ++--- openair3/TEST/EPC_TEST/generate_scenario.h | 0 openair3/TEST/EPC_TEST/generic_scenario.xsl | 421 ++++++++++---------- openair3/TEST/EPC_TEST/play_scenario.c | 405 +++++++++++++++++++ openair3/TEST/EPC_TEST/play_scenario.h | 49 +++ openair3/TEST/EPC_TEST/play_scenario.xsl | 113 ++++++ 10 files changed, 901 insertions(+), 263 deletions(-) mode change 100755 => 100644 openair3/TEST/EPC_TEST/generate_scenario.h create mode 100644 openair3/TEST/EPC_TEST/play_scenario.c create mode 100644 openair3/TEST/EPC_TEST/play_scenario.h create mode 100644 openair3/TEST/EPC_TEST/play_scenario.xsl diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 6b9dae6b04..42e381dd68 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -162,24 +162,47 @@ add_definitions(-DCMAKER) set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -g -DMALLOC_CHECK_=3") set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -g -DMALLOC_CHECK_=3 -O2") -# Below has been put in comment because does not work with -# SVN authentication. -# -#find_package(Subversion) -#if(SUBVERSION_FOUND) -# Subversion_WC_INFO(${OPENAIR_DIR} openair) -# set (FIRMWARE_VERSION "${openair_WC_REVISION} - ${openair_WC_LAST_CHANGED_DATE}") -# Subversion_WC_LOG(${OPENAIR_DIR} Project) -#else() -# set (FIRMWARE_VERSION "No svn information") -#endif() -#add_definitions("-DFIRMWARE_VERSION=\"${FIRMWARE_VERSION}\"") + + +set(GIT_BRANCH "UNKNOWN") +set(GIT_COMMIT_HASH "UNKNOWN") +set(GIT_COMMIT_DATE "UNKNOWN") + + +find_package(Git) +if(GIT_FOUND) + message("git found: ${GIT_EXECUTABLE}") + # Get the current working branch + execute_process( + COMMAND git rev-parse --abbrev-ref HEAD + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_BRANCH + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + # Get the latest abbreviated commit hash of the working branch + execute_process( + COMMAND git log -1 --format=%h + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_COMMIT_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + # Get the latest commit date of the working branch + execute_process( + COMMAND git log -1 --format=%cd + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_COMMIT_DATE + OUTPUT_STRIP_TRAILING_WHITESPACE + ) +endif() + # Below is a hard-coded info set (FIRMWARE_VERSION "No svn information") add_definitions("-DFIRMWARE_VERSION=\"${FIRMWARE_VERSION}\"") -add_definitions("-DPACKAGE_VERSION=\"${FIRMWARE_VERSION}\"") -add_definitions("-DPACKAGE_BUGREPORT=\"OpenAirInterface web site\"") +add_definitions("-DPACKAGE_VERSION=\"Branch: ${GIT_BRANCH} Abrev. Hash: ${GIT_COMMIT_HASH} Date: ${GIT_COMMIT_DATE}\"") +add_definitions("-DPACKAGE_BUGREPORT=\"openair4g-devel@lists.eurecom.fr\"") @@ -1615,6 +1638,7 @@ endforeach(myExe) add_executable(test_epc_generate_scenario ${OPENAIR3_DIR}/TEST/EPC_TEST/generate_scenario.c + ${OPENAIR3_DIR}/TEST/EPC_TEST/generate_scenario.h ${OPENAIR2_DIR}/ENB_APP/enb_config.h ${OPENAIR2_DIR}/COMMON/commonDef.h ${OPENAIR2_DIR}/COMMON/messages_def.h @@ -1626,6 +1650,20 @@ target_link_libraries (test_epc_generate_scenario -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES} ) +add_executable(test_epc_play_scenario + ${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario.c + ${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario.h + ${OPENAIR2_DIR}/ENB_APP/enb_config.h + ${OPENAIR2_DIR}/COMMON/commonDef.h + ${OPENAIR2_DIR}/COMMON/messages_def.h + ${OPENAIR2_DIR}/COMMON/messages_types.h + ${OPENAIR3_DIR}/S1AP/s1ap_eNB_defs.h + ${OPENAIR_BIN_DIR}/messages_xml.h + ) +target_link_libraries (test_epc_play_scenario + -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES} + ) + #unitary tests for Core NEtwork pieces ################################# diff --git a/cmake_targets/tools/build_test_epc_tools b/cmake_targets/tools/build_test_epc_tools index aff2a26fc0..10dc4fd256 100755 --- a/cmake_targets/tools/build_test_epc_tools +++ b/cmake_targets/tools/build_test_epc_tools @@ -121,6 +121,7 @@ function main() echo "Cleaning TEST_EPC" fi rm -f $OPENAIR_DIR/targets/bin/test_epc_generate_scenario + rm -f $OPENAIR_DIR/targets/bin/test_epc_play_scenario rm -Rf build 2>&1 mkdir -m 777 -p -v build fi @@ -140,6 +141,9 @@ function main() compilations \ epc_test test_epc_generate_scenario \ test_epc_generate_scenario $dbin/test_epc_generate_scenario + compilations \ + epc_test test_epc_play_scenario \ + test_epc_play_scenario $dbin/test_epc_play_scenario } diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 07e0ffa640..ad4dde7faa 100755 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -253,7 +253,7 @@ static const eutra_band_t eutra_bands[] = { Enb_properties_array_t enb_properties; -static void enb_config_display(void) +void enb_config_display(void) { int i,j; diff --git a/openair2/ENB_APP/enb_config.h b/openair2/ENB_APP/enb_config.h index 113681dafe..de837303ea 100755 --- a/openair2/ENB_APP/enb_config.h +++ b/openair2/ENB_APP/enb_config.h @@ -239,6 +239,7 @@ typedef struct Enb_properties_array_s { Enb_properties_t *properties[MAX_ENB]; } Enb_properties_array_t; +void enb_config_display(void); const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP); const Enb_properties_array_t *enb_config_get(void); diff --git a/openair3/TEST/EPC_TEST/generate_scenario.c b/openair3/TEST/EPC_TEST/generate_scenario.c index 4cb21f9604..8f39b9873e 100644 --- a/openair3/TEST/EPC_TEST/generate_scenario.c +++ b/openair3/TEST/EPC_TEST/generate_scenario.c @@ -100,11 +100,10 @@ Enb_properties_array_t g_enb_properties; char *g_openair_dir = NULL; char *g_test_dir = NULL; char *g_pdml_in_origin = NULL; -char *g_generic_scenario = NULL; extern int xmlLoadExtDtdDefaultValue; #define GENERATE_PDML_FILE 1 -#define GENERATE_GENERIC_SCENARIO 2 +#define GENERATE_SCENARIO 2 #define GS_IS_FILE 1 #define GS_IS_DIR 2 @@ -172,14 +171,14 @@ int split_path( char * pathP, char *** resP) } //------------------------------------------------------------------------------ -int generate_generic_scenario(const char const * test_nameP, const char const * pdml_in_basenameP) +int generate_test_scenario(const char const * test_nameP, const char const * pdml_in_basenameP) //------------------------------------------------------------------------------ { //int fd_pdml_in; xsltStylesheetPtr cur = NULL; xmlDocPtr doc, res; - FILE *generic_scenario_file = NULL; - const char generic_scenario_filename[NAME_MAX]; + FILE *test_scenario_file = NULL; + const char test_scenario_filename[NAME_MAX]; const char *params[2*ENB_CONFIG_MAX_XSLT_PARAMS]; int nb_params = 0; int i,j; @@ -187,7 +186,7 @@ int generate_generic_scenario(const char const * test_nameP, const char const * char *astring2 = NULL; struct in_addr addr; - memset(generic_scenario_filename, 0, sizeof(generic_scenario_filename)); + memset(test_scenario_filename, 0, sizeof(test_scenario_filename)); memset(astring, 0, sizeof(astring)); if (getcwd(astring, sizeof(astring)) != NULL) { fprintf(stdout, "working in %s directory\n", astring); @@ -249,16 +248,16 @@ int generate_generic_scenario(const char const * test_nameP, const char const * res = xsltApplyStylesheet(cur, doc, params); if (NULL != res) { // since pdml filename is not relative (no path), just filename in current directory we can safely remove - sprintf(generic_scenario_filename,"%s",pdml_in_basenameP); - if (strip_extension(generic_scenario_filename) > 0) { - strcat(generic_scenario_filename, "_generic_scenario.xml"); - generic_scenario_file = fopen( generic_scenario_filename, "w+"); - if (NULL != generic_scenario_file) { - xsltSaveResultToFile(generic_scenario_file, res, cur); - fclose(generic_scenario_file); - fprintf(stdout, "Wrote generic scenario to %s\n", generic_scenario_filename); + sprintf(test_scenario_filename,"%s",pdml_in_basenameP); + if (strip_extension(test_scenario_filename) > 0) { + strcat(test_scenario_filename, ".xml"); + test_scenario_file = fopen( test_scenario_filename, "w+"); + if (NULL != test_scenario_file) { + xsltSaveResultToFile(test_scenario_file, res, cur); + fclose(test_scenario_file); + fprintf(stdout, "Wrote test scenario to %s\n", test_scenario_filename); } else { - fprintf(stderr, "Error in fopen(%s)\n", generic_scenario_filename); + fprintf(stderr, "Error in fopen(%s)\n", test_scenario_filename); } } else { fprintf(stderr, "Error in strip_extension()\n"); @@ -537,17 +536,17 @@ static void usage ( char *argv[]) //------------------------------------------------------------------------------ { - fprintf (stdout, "Please report any bug to: openair4g-devel@lists.eurecom.fr\n\n"); + 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, "Mandatory options:\n"); - fprintf (stdout, "\t-t | --test-dir Directory where a set of files related to a particular test are located\n"); + fprintf (stdout, "\t-c | --enb-conf-file Provide the old eNB config file for generating a copy of the original test\n"); + fprintf (stdout, "\t-d | --test-dir Directory where a set of files related to a particular test are located\n"); + fprintf (stdout, "\t-p | --pdml File name (with no path) in 'test-dir' directory of an original scenario that has to be reworked (IP addresses) with new testbed\n"); fprintf (stdout, "\n"); - fprintf (stdout, "Available options:\n"); + fprintf (stdout, "Other options:\n"); fprintf (stdout, "\t-h | --help Print this help and return\n"); - fprintf (stdout, "\t-o | --old-enb-conf-file Provide the old eNB config file for generating a copy of the original test\n"); - fprintf (stdout, " This option is set as many times as there are some eNB config files in the original test\n"); - fprintf (stdout, "\t-p | --pdml File name (with no path) of an original scenario that has to be reworked (IP addresses) with new testbed\n"); - fprintf (stdout, "\n"); + fprintf (stdout, "\t-v | --version Print informations about the version of this executable\n"); fprintf (stdout, "\n"); fprintf (stdout, "Example of generate_scenario use case: \n"); fprintf (stdout, "\n"); @@ -558,16 +557,16 @@ static void usage ( fprintf (stdout, " |\n"); fprintf (stdout, " mme_test_s1_pcap2pdml --pcap_file <`captured pcap-ng file`>\n"); fprintf (stdout, " |\n"); - fprintf (stdout, " +--------V----------+ +------------------------+\n"); - fprintf (stdout, " |'pdml-in-orig' file| |'old-enb-conf-file' file|\n"); - fprintf (stdout, " +--------+----------+ +------------+-----------+\n"); + fprintf (stdout, " +--------V----------+ +--------------------+\n"); + fprintf (stdout, " |'pdml-in-orig' file| |'enb-conf-file' file|\n"); + fprintf (stdout, " +--------+----------+ +--------------------+\n"); fprintf (stdout, " | |\n"); fprintf (stdout, " +----------------------------+\n"); fprintf (stdout, " |\n"); - fprintf (stdout, " generate_scenario -t -p <'pdml-in-orig' file> -o <'old-enb-conf-file' file> \n"); + fprintf (stdout, " generate_scenario -d -p <'pdml-in-orig' file> -c <'enb-conf-file' file> \n"); fprintf (stdout, " |\n"); fprintf (stdout, " +------------V--------------+\n"); - fprintf (stdout, " +'xml-scenario-generic' file|\n"); + fprintf (stdout, " +'xml-test-scenario' file |\n"); fprintf (stdout, " +---------------------------+\n"); fprintf (stdout, "\n"); } @@ -581,37 +580,39 @@ config_parse_opt_line ( { int option; int rv = 0; - char *old_enb_config_file_name = NULL; + char *enb_config_file_name = NULL; char *pdml_in_file_name = NULL; char *test_dir_name = NULL; enum long_option_e { LONG_OPTION_START = 0x100, /* Start after regular single char options */ - LONG_OPTION_OLD_ENB_CONF_FILE, + LONG_OPTION_ENB_CONF_FILE, LONG_OPTION_PDML, LONG_OPTION_TEST_DIR, LONG_OPTION_HELP, + LONG_OPTION_VERSION, }; static struct option long_options[] = { - {"old-enb-conf-file", required_argument, 0, LONG_OPTION_OLD_ENB_CONF_FILE}, - {"pdml ", required_argument, 0, LONG_OPTION_PDML}, - {"test-dir", required_argument, 0, LONG_OPTION_TEST_DIR}, - {"help", required_argument, 0, LONG_OPTION_HELP}, + {"enb-conf-file", required_argument, 0, LONG_OPTION_ENB_CONF_FILE}, + {"pdml ", required_argument, 0, LONG_OPTION_PDML}, + {"test-dir", required_argument, 0, LONG_OPTION_TEST_DIR}, + {"help", no_argument, 0, LONG_OPTION_HELP}, + {"version", no_argument, 0, LONG_OPTION_VERSION}, {NULL, 0, NULL, 0} }; /* * Parsing command line */ - while ((option = getopt_long (argc, argv, "hp:n:o:s:t:", long_options, NULL)) != -1) { + while ((option = getopt_long (argc, argv, "vhp:n:c:s:d:", long_options, NULL)) != -1) { switch (option) { - case LONG_OPTION_OLD_ENB_CONF_FILE: - case 'o': + case LONG_OPTION_ENB_CONF_FILE: + case 'c': if (optarg) { - old_enb_config_file_name = optarg; - printf("Old eNB config file name is %s\n", old_enb_config_file_name); - rv |= GENERATE_GENERIC_SCENARIO; + enb_config_file_name = optarg; + printf("eNB config file name is %s\n", enb_config_file_name); + rv |= GENERATE_SCENARIO; } break; @@ -620,12 +621,12 @@ config_parse_opt_line ( if (optarg) { pdml_in_file_name = strdup(optarg); printf("PDML input file name is %s\n", pdml_in_file_name); - rv |= GENERATE_GENERIC_SCENARIO; + rv |= GENERATE_SCENARIO; } break; case LONG_OPTION_TEST_DIR: - case 't': + case 'd': if (optarg) { test_dir_name = strdup(optarg); if (is_file_exists(test_dir_name, "test dirname") != GS_IS_DIR) { @@ -636,6 +637,12 @@ config_parse_opt_line ( } break; + case LONG_OPTION_VERSION: + case 'v': + printf("Version %s\n", PACKAGE_VERSION); + exit (0); + break; + case LONG_OPTION_HELP: case 'h': default: @@ -652,14 +659,14 @@ config_parse_opt_line ( fprintf(stderr, "Error: chdir %s returned %s\n", g_test_dir, strerror(errno)); exit(1); } - if (rv & GENERATE_GENERIC_SCENARIO) { - if (NULL == old_enb_config_file_name) { + if (rv & GENERATE_SCENARIO) { + if (NULL == enb_config_file_name) { fprintf(stderr, "Error: please provide the original eNB config file name that should be in %s\n", g_test_dir); } - if (is_file_exists(old_enb_config_file_name, "Old eNB config file") != GS_IS_FILE) { - fprintf(stderr, "Error: original eNB config file name %s is not found in dir %s\n", old_enb_config_file_name, g_test_dir); + if (is_file_exists(enb_config_file_name, "ENB config file") != GS_IS_FILE) { + fprintf(stderr, "Error: eNB config file name %s is not found in dir %s\n", enb_config_file_name, g_test_dir); } - enb_config_init(old_enb_config_file_name); + enb_config_init(enb_config_file_name); enb_config_display(); if (NULL == pdml_in_file_name) { @@ -688,8 +695,8 @@ int main( int argc, char **argv ) memset((char*) &g_enb_properties, 0 , sizeof(g_enb_properties)); actions = config_parse_opt_line (argc, argv); //Command-line options - if (actions & GENERATE_GENERIC_SCENARIO) { - generate_generic_scenario(g_test_dir, g_pdml_in_origin); + if (actions & GENERATE_SCENARIO) { + generate_test_scenario(g_test_dir, g_pdml_in_origin); } return 0; diff --git a/openair3/TEST/EPC_TEST/generate_scenario.h b/openair3/TEST/EPC_TEST/generate_scenario.h old mode 100755 new mode 100644 diff --git a/openair3/TEST/EPC_TEST/generic_scenario.xsl b/openair3/TEST/EPC_TEST/generic_scenario.xsl index ab0e7f1123..e55bfffd69 100644 --- a/openair3/TEST/EPC_TEST/generic_scenario.xsl +++ b/openair3/TEST/EPC_TEST/generic_scenario.xsl @@ -1,240 +1,261 @@ + xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> - + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + enb_s1c0 enb_s1c1 enb_s1c2 enb_s1c3 enb_s1c4 enb_s1c5 + enb_s1c6 + enb_s1c7 mme_s1c0_0 mme_s1c0_1 mme_s1c0_2 mme_s1c0_3 mme_s1c1_0 mme_s1c1_1 - mme_s1c1_2" + mme_s1c1_2 mme_s1c1_3 - reverse_ip_yourself - - + mme_s1c2_0 + mme_s1c2_1 + mme_s1c2_2 + mme_s1c2_3 + mme_s1c3_0 + mme_s1c3_1 + mme_s1c3_2 + mme_s1c3_3 + + ERROR: Cannot reverse resolv IP ! + + + + - - + + - DATA - INIT - INIT_ACK - SACK - HEARTBEAT - HEARTBEAT_ACK - ABORT - SHUTDOWN - SHUTDOWN_ACK - ERROR - COOKIE_ECHO - COOKIE_ACK - ECNE - CWR - SHUTDOWN_COMPLETE - UNKNOWN_CHUNK_TYPE + DATA + INIT + INIT_ACK + SACK + HEARTBEAT + HEARTBEAT_ACK + ABORT + SHUTDOWN + SHUTDOWN_ACK + ERROR + COOKIE_ECHO + COOKIE_ACK + ECNE + CWR + SHUTDOWN_COMPLETE + + ERROR: UNKNOWN CHUNK TYPE ! + + - + + - - - - + - + - + - + - - - - + + + + - - - - + + + + + + + + SEND + RECEIVE + + ERROR: UNKNOWN ACTION ! + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - + + + - - + + - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c new file mode 100644 index 0000000000..b8252854e4 --- /dev/null +++ b/openair3/TEST/EPC_TEST/play_scenario.c @@ -0,0 +1,405 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2014 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see . + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE + + *******************************************************************************/ + +/* + play_scenario.c + ------------------- + AUTHOR : Lionel GAUTHIER + COMPANY : EURECOM + EMAIL : Lionel.Gauthier@eurecom.fr + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "assertions.h" +#include "play_scenario.h" +#include "s1ap_eNB.h" +#include "intertask_interface.h" +#include "enb_config.h" +//------------------------------------------------------------------------------ +#define ENB_CONFIG_MAX_XSLT_PARAMS 32 +#define PLAY_SCENARIO 1 +#define GS_IS_FILE 1 +#define GS_IS_DIR 2 +//------------------------------------------------------------------------------ +char *g_openair_dir = NULL; +//------------------------------------------------------------------------------ +extern Enb_properties_array_t enb_properties; +extern int xmlLoadExtDtdDefaultValue; + +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// test if file exist in current directory +int is_file_exists( const char const * file_nameP, const char const *file_roleP) +{ + struct stat s; + int err = stat(file_nameP, &s); + if(-1 == err) { + if(ENOENT == errno) { + fprintf(stderr, "Please provide a valid %s, %s does not exist\n", file_roleP, file_nameP); + } else { + perror("stat"); + exit(1); + } + } else { + if(S_ISREG(s.st_mode)) { + return GS_IS_FILE; + } else if(S_ISDIR(s.st_mode)) { + return GS_IS_DIR; + } else { + fprintf(stderr, "Please provide a valid test %s, %s exists but is not found valid\n", file_roleP, file_nameP); + } + } + return 0; +} + + +//------------------------------------------------------------------------------ +int strip_extension(char *in_filename) +{ + static const uint8_t name_min_len = 1; + static const uint8_t max_ext_len = 5; // .pdml ! + fprintf(stdout, "strip_extension %s\n", in_filename); + + if (NULL != in_filename) { + /* Check chars starting at end of string to find last '.' */ + for (ssize_t i = strlen(in_filename); i > (name_min_len + max_ext_len); i--) { + if (in_filename[i] == '.') { + in_filename[i] = '\0'; + return i; + } + } + } + return -1; +} +//------------------------------------------------------------------------------ +// return number of splitted items +int split_path( char * pathP, char *** resP) +{ + char * saveptr1; + char * p = strtok_r (pathP, "/", &saveptr1); + int n_spaces = 0; + + /// split string and append tokens to 'res' + while (p) { + *resP = realloc (*resP, sizeof (char*) * ++n_spaces); + AssertFatal (*resP, "realloc failed"); + (*resP)[n_spaces-1] = p; + p = strtok_r (NULL, "/", &saveptr1); + } + return n_spaces; +} + +//------------------------------------------------------------------------------ +void play_scenario( + const char const * play_scenario_filename ) +{ + +} + +//------------------------------------------------------------------------------ +int generate_play_scenario( + const char const * test_dir_name, + const char const * test_scenario_filename, + const char const * enb_config_filename, + char const * play_scenario_filename /* OUT PARAM*/) +//------------------------------------------------------------------------------ +{ + //int fd_pdml_in; + xsltStylesheetPtr cur = NULL; + xmlDocPtr doc, res; + FILE *play_scenario_file = NULL; + const char *params[2*ENB_CONFIG_MAX_XSLT_PARAMS]; + int nb_params = 0; + int i,j; + char astring[1024]; + char *astring2 = NULL; + struct in_addr addr; + int ret = 0; + + memset(astring, 0, sizeof(astring)); + if (getcwd(astring, sizeof(astring)) != NULL) { + fprintf(stdout, "working in %s directory\n", astring); + } else { + perror("getcwd() error"); + exit(1); + } + + memset(astring, 0, sizeof(astring)); + strcat(astring, g_openair_dir); + strcat(astring, "/openair3/TEST/EPC_TEST/play_scenario.xsl"); + + xmlSubstituteEntitiesDefault(1); + xmlLoadExtDtdDefaultValue = 1; + cur = xsltParseStylesheetFile(astring); + if (NULL == cur) { + AssertFatal (0, "Could not parse stylesheet file %s (check OPENAIR_DIR env variable)!\n", astring); + } else { + fprintf(stdout, "XSLT style sheet: %s\n", astring); + } + + doc = xmlParseFile(test_scenario_filename); + if (NULL == doc) { + AssertFatal (0, "Could not parse scenario xml file %s!\n", test_scenario_filename); + } else { + fprintf(stdout, "Test scenario file: %s\n", test_scenario_filename); + } + + for (i = 0; i < enb_properties.number; i++) { + // eNB S1-C IPv4 address + sprintf(astring, "enb_s1c%d", i); + params[nb_params++] = strdup(astring); + addr.s_addr = enb_properties.properties[i]->enb_ipv4_address_for_S1_MME; + sprintf(astring, "\"%s\"", inet_ntoa(addr)); + params[nb_params++] = strdup(astring); + + // MME S1-C IPv4 address + for (j = 0; j < enb_properties.properties[i]->nb_mme; j++) { + sprintf(astring, "mme_s1c%d_%d", i, j); + params[nb_params++] = strdup(astring); + AssertFatal (enb_properties.properties[i]->mme_ip_address[j].ipv4_address, + "Only support MME IPv4 address\n"); + sprintf(astring, "\"%s\"", enb_properties.properties[i]->mme_ip_address[j].ipv4_address); + params[nb_params++] = strdup(astring); + } + } + params[nb_params] = NULL; + res = xsltApplyStylesheet(cur, doc, params); + if (NULL != res) { + // since pdml filename is not relative (no path), just filename in current directory we can safely remove + sprintf(play_scenario_filename,"%s",test_scenario_filename); + if (strip_extension(play_scenario_filename) > 0) { + strcat(play_scenario_filename, ".tsml"); + play_scenario_file = fopen( play_scenario_filename, "w+"); + if (NULL != play_scenario_file) { + xsltSaveResultToFile(play_scenario_file, res, cur); + fclose(play_scenario_file); + fprintf(stdout, "Wrote test scenario to %s\n", play_scenario_filename); + } else { + fprintf(stderr, "Error in fopen(%s)\n", play_scenario_filename); + ret = -1; + } + } else { + fprintf(stderr, "Error in strip_extension()\n"); + ret = -1; + } + } else { + fprintf(stderr, "Error in xsltApplyStylesheet()\n"); + ret = -1; + } + xsltFreeStylesheet(cur); + xmlFreeDoc(res); + xmlFreeDoc(doc); + + xsltCleanupGlobals(); + xmlCleanupParser(); + return ret; +} + +//------------------------------------------------------------------------------ +static void usage ( + int argc, + char *argv[]) +//------------------------------------------------------------------------------ +{ + 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 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 Directory where a set of files related to a particular test are located\n"); + fprintf (stdout, "\t-c | --enb-conf-file Provide an eNB config file, valid for the testbed\n"); + fprintf (stdout, "\t-s | --scenario File name (with no path) of a test scenario that has to be replayed ()\n"); + fprintf (stdout, "\n"); + fprintf (stdout, "Other options:\n"); + fprintf (stdout, "\t-h | --help Print this help and return\n"); + fprintf (stdout, "\t-v | --version Print informations about the version of this executable\n"); + fprintf (stdout, "\n"); +} + +//------------------------------------------------------------------------------ +int +config_parse_opt_line ( + int argc, + char *argv[], + char **test_dir_name, + char **scenario_file_name, + char **enb_config_file_name) +//------------------------------------------------------------------------------ +{ + int option; + int rv = 0; + const Enb_properties_array_t *enb_properties_p = NULL; + + enum long_option_e { + LONG_OPTION_START = 0x100, /* Start after regular single char options */ + LONG_OPTION_ENB_CONF_FILE, + LONG_OPTION_SCENARIO_FILE, + LONG_OPTION_TEST_DIR, + LONG_OPTION_HELP, + LONG_OPTION_VERSION + }; + + static struct option long_options[] = { + {"enb-conf-file", required_argument, 0, LONG_OPTION_ENB_CONF_FILE}, + {"scenario ", required_argument, 0, LONG_OPTION_SCENARIO_FILE}, + {"test-dir", required_argument, 0, LONG_OPTION_TEST_DIR}, + {"help", no_argument, 0, LONG_OPTION_HELP}, + {"version", no_argument, 0, LONG_OPTION_VERSION}, + {NULL, 0, NULL, 0} + }; + + /* + * Parsing command line + */ + while ((option = getopt_long (argc, argv, "vhc:s:d:", long_options, NULL)) != -1) { + switch (option) { + case LONG_OPTION_ENB_CONF_FILE: + case 'c': + if (optarg) { + *enb_config_file_name = strdup(optarg); + printf("eNB config file name is %s\n", *enb_config_file_name); + rv |= PLAY_SCENARIO; + } + break; + + case LONG_OPTION_SCENARIO_FILE: + case 's': + if (optarg) { + *scenario_file_name = strdup(optarg); + printf("Scenario file name is %s\n", *scenario_file_name); + rv |= PLAY_SCENARIO; + } + break; + + case LONG_OPTION_TEST_DIR: + case 'd': + if (optarg) { + *test_dir_name = strdup(optarg); + if (is_file_exists(*test_dir_name, "test dirname") != GS_IS_DIR) { + fprintf(stderr, "Please provide a valid test dirname, %s is not a valid directory name\n", *test_dir_name); + exit(1); + } + printf("Test dir name is %s\n", *test_dir_name); + } + break; + + case LONG_OPTION_VERSION: + case 'v': + printf("Version %s\n", PACKAGE_VERSION); + exit (0); + break; + + case LONG_OPTION_HELP: + case 'h': + default: + usage (argc, argv); + exit (0); + } + } + if (NULL == *test_dir_name) { + fprintf(stderr, "Please provide a valid test dirname\n"); + exit(1); + } + if (chdir(*test_dir_name) != 0) { + fprintf(stderr, "Error: chdir %s returned %s\n", *test_dir_name, strerror(errno)); + exit(1); + } + if (rv & PLAY_SCENARIO) { + if (NULL == *enb_config_file_name) { + fprintf(stderr, "Error: please provide the original eNB config file name that should be in %s\n", *test_dir_name); + } + if (is_file_exists(*enb_config_file_name, "eNB config file") != GS_IS_FILE) { + fprintf(stderr, "Error: original eNB config file name %s is not found in dir %s\n", *enb_config_file_name, *test_dir_name); + } + enb_properties_p = enb_config_init(*enb_config_file_name); + + if (NULL == *scenario_file_name) { + fprintf(stderr, "Error: please provide the scenario file name that should be in %s\n", *test_dir_name); + } + if (is_file_exists(*scenario_file_name, "Scenario file") != GS_IS_FILE) { + fprintf(stderr, "Error: Scenario file name %s is not found in dir %s\n", *scenario_file_name, *test_dir_name); + } + } + return rv; +} + +//------------------------------------------------------------------------------ +int main( int argc, char **argv ) +//------------------------------------------------------------------------------ +{ + int actions = 0; + char *test_dir_name = NULL; + char *scenario_file_name = NULL; + char *enb_config_file_name = NULL; + char play_scenario_filename[NAME_MAX]; + + memset(play_scenario_filename, 0, sizeof(play_scenario_filename)); + g_openair_dir = getenv("OPENAIR_DIR"); + if (NULL == g_openair_dir) { + fprintf(stderr, "Error: Could not get OPENAIR_DIR environment variable\n"); + exit(1); + } + + actions = config_parse_opt_line (argc, argv, &test_dir_name, &scenario_file_name, &enb_config_file_name); //Command-line options + if (actions & PLAY_SCENARIO) { + if (generate_play_scenario(test_dir_name, scenario_file_name,enb_config_file_name, play_scenario_filename) == 0) { + play_scenario(play_scenario_filename); + } + free_pointer(test_dir_name); + free_pointer(scenario_file_name); + free_pointer(enb_config_file_name); + } + + return 0; +} diff --git a/openair3/TEST/EPC_TEST/play_scenario.h b/openair3/TEST/EPC_TEST/play_scenario.h new file mode 100644 index 0000000000..c6e1087a04 --- /dev/null +++ b/openair3/TEST/EPC_TEST/play_scenario.h @@ -0,0 +1,49 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2014 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see . + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE + +*******************************************************************************/ + +/* + generate_scenario.h + ------------------- + AUTHOR : Lionel GAUTHIER + COMPANY : EURECOM + EMAIL : Lionel.Gauthier@eurecom.fr +*/ + +#ifndef GENERATE_SCENARIO_H_ +#define GENERATE_SCENARIO_H_ + +/** @defgroup _enb_app ENB APP + * @ingroup _oai2 + * @{ + */ + + +inline void free_pointer(void *p) {if (NULL != p) {free(p); p=NULL;}}; +#endif /* ENB_CONFIG_H_ */ +/** @} */ diff --git a/openair3/TEST/EPC_TEST/play_scenario.xsl b/openair3/TEST/EPC_TEST/play_scenario.xsl new file mode 100644 index 0000000000..1a89128005 --- /dev/null +++ b/openair3/TEST/EPC_TEST/play_scenario.xsl @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ERROR: Cannot resolv IP ! + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ERROR: Cannot resolv IP ! + + + + + + + + + + + + + + + + From 34ab7c374fa99bc4e1ac167107c4acae0a8c6817 Mon Sep 17 00:00:00 2001 From: gauthier Date: Fri, 6 Nov 2015 16:51:30 +0100 Subject: [PATCH 07/47] For syncing with origin --- openair3/TEST/EPC_TEST/generic_scenario.xsl | 24 +-- openair3/TEST/EPC_TEST/play_scenario.c | 154 ++++++++++++++++++-- openair3/TEST/EPC_TEST/play_scenario.h | 88 +++++++++++ openair3/TEST/EPC_TEST/play_scenario.xsl | 4 +- 4 files changed, 241 insertions(+), 29 deletions(-) diff --git a/openair3/TEST/EPC_TEST/generic_scenario.xsl b/openair3/TEST/EPC_TEST/generic_scenario.xsl index e55bfffd69..b1cadbcdfa 100644 --- a/openair3/TEST/EPC_TEST/generic_scenario.xsl +++ b/openair3/TEST/EPC_TEST/generic_scenario.xsl @@ -146,7 +146,7 @@ - + @@ -160,14 +160,14 @@ - + - + @@ -181,13 +181,13 @@ - + - + @@ -201,13 +201,13 @@ - + - + @@ -218,10 +218,10 @@ - + - + @@ -232,11 +232,11 @@ - + - + @@ -247,7 +247,7 @@ - + diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c index b8252854e4..e73a41a683 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.c +++ b/openair3/TEST/EPC_TEST/play_scenario.c @@ -49,7 +49,6 @@ #include #include #include -#include #include #include #include @@ -138,16 +137,132 @@ int split_path( char * pathP, char *** resP) } return n_spaces; } - //------------------------------------------------------------------------------ -void play_scenario( +void display_node(xmlNodePtr node) { + if (node->type == XML_ELEMENT_NODE) { + xmlChar *path = xmlGetNodePath(node); + if (node->children != NULL && node->children->type == XML_TEXT_NODE) { + xmlChar *content = xmlNodeGetContent(node); + printf("%s -> %s\n", path, content); + xmlFree(content); + } else { + printf("%s\n", path); + } + xmlFree(path); + } +} +//------------------------------------------------------------------------------ +void free_scenario(test_scenario_t* scenario) +{ + //TODO +} +//------------------------------------------------------------------------------ +sctp_cid_t chunk_type_str2cid(xmlChar *chunk_type_str) +{ + if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"DATA"))) { return SCTP_CID_DATA;} + if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"INIT"))) { return SCTP_CID_INIT;} + if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"INIT_ACK"))) { return SCTP_CID_INIT_ACK;} + if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"SACK"))) { return SCTP_CID_SACK;} + if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"HEARTBEAT"))) { return SCTP_CID_HEARTBEAT;} + if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"HEARTBEAT_ACK"))) { return SCTP_CID_HEARTBEAT_ACK;} + if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"ABORT"))) { return SCTP_CID_ABORT;} + if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"SHUTDOWN"))) { return SCTP_CID_SHUTDOWN;} + if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"SHUTDOWN_ACK"))) { return SCTP_CID_SHUTDOWN_ACK;} + if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"ERROR"))) { return SCTP_CID_ERROR;} + if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"COOKIE_ECHO"))) { return SCTP_CID_COOKIE_ECHO;} + if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"COOKIE_ACK"))) { return SCTP_CID_COOKIE_ACK;} + if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"ECN_ECNE"))) { return SCTP_CID_ECN_ECNE;} + if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"ECN_CWR"))) { return SCTP_CID_ECN_CWR;} + if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"SHUTDOWN_COMPLETE"))) { return SCTP_CID_SHUTDOWN_COMPLETE;} + if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"AUTH"))) { return SCTP_CID_AUTH;} + if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"FWD_TSN"))) { return SCTP_CID_FWD_TSN;} + if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"ASCONF"))) { return SCTP_CID_ASCONF;} + if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"ASCONF_ACK"))) { return SCTP_CID_ASCONF_ACK;} + fprintf(stderr, "ERROR: Could not convert: %s\n", chunk_type_str); + exit(-1); +} +//------------------------------------------------------------------------------ +test_packet_t* parse_xml_packet(xmlNodePtr node) { + + test_packet_t *packet = NULL; + xmlNode *cur_node = NULL; + xmlChar *xml_char = NULL; + + if (NULL != node) { + packet = calloc(1, sizeof(*packet)); + + for (cur_node = node->children; cur_node; cur_node = cur_node->next) { + if (cur_node->type == XML_ELEMENT_NODE) { + printf("node type: Element, name: %s\n", cur_node->name); + if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"frame.time_relative"))) { + } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"ip.src"))) { + } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"ip.dst"))) { + } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"sctp.chunk_type_str"))) { + xml_char = xmlGetProp(cur_node, (const xmlChar *)"value"); + packet->sctp_hdr.chunk_type = chunk_type_str2cid(xml_char); + fprintf(stdout, "chunk_type_str2cid: %s\n", xml_char); + } + } + } + } + return packet; +} +//------------------------------------------------------------------------------ +int play_scenario(test_scenario_t* scenario) { + //TODO + return 0; +} +//------------------------------------------------------------------------------ +test_scenario_t* generate_scenario( const char const * play_scenario_filename ) { + xmlDocPtr doc = NULL; + xmlNodePtr root = NULL; + xmlNodePtr node = NULL; + xmlChar *xml_char = NULL; + test_scenario_t *scenario = NULL; + test_packet_t *packet = NULL; + test_packet_t **next_packet = NULL; + doc = xmlParseFile(play_scenario_filename); + if (NULL == doc) { + AssertFatal (0, "Could not parse scenario xml file %s!\n", play_scenario_filename); + } else { + fprintf(stdout, "Test scenario file to play: %s\n", play_scenario_filename); + } + + // Get root + root = xmlDocGetRootElement(doc); + if (NULL != root) { + if ((!xmlStrcmp(root->name, (const xmlChar *)"scenario"))) { + xml_char = xmlGetProp(root, (const xmlChar *)"name"); + printf("scenario name: %s\n", xml_char); + scenario = calloc(1, sizeof(*scenario)); + scenario->name = xml_char; // nodup nofree + next_packet = &scenario->list_packet; + for (node = root->children; node != NULL; node = node->next) { + if ((!xmlStrcmp(node->name, (const xmlChar *)"packet"))) { + packet = parse_xml_packet(node); + if (NULL != packet) { + *next_packet = packet; + next_packet = &packet->next; + } else { + fprintf(stdout, "WARNING omitted packet:\n"); + display_node(node); + } + } + } + } + } else { + fprintf(stderr, "Empty xml document\n"); + } + xmlFreeDoc(doc); + xmlCleanupParser(); + return scenario; } //------------------------------------------------------------------------------ -int generate_play_scenario( +int generate_xml_scenario( const char const * test_dir_name, const char const * test_scenario_filename, const char const * enb_config_filename, @@ -180,7 +295,7 @@ int generate_play_scenario( xmlSubstituteEntitiesDefault(1); xmlLoadExtDtdDefaultValue = 1; - cur = xsltParseStylesheetFile(astring); + cur = xsltParseStylesheetFile((const xmlChar *)astring); if (NULL == cur) { AssertFatal (0, "Could not parse stylesheet file %s (check OPENAIR_DIR env variable)!\n", astring); } else { @@ -215,7 +330,6 @@ int generate_play_scenario( params[nb_params] = NULL; res = xsltApplyStylesheet(cur, doc, params); if (NULL != res) { - // since pdml filename is not relative (no path), just filename in current directory we can safely remove sprintf(play_scenario_filename,"%s",test_scenario_filename); if (strip_extension(play_scenario_filename) > 0) { strcat(play_scenario_filename, ".tsml"); @@ -237,8 +351,8 @@ int generate_play_scenario( ret = -1; } xsltFreeStylesheet(cur); - xmlFreeDoc(res); xmlFreeDoc(doc); + xmlFreeDoc(res); xsltCleanupGlobals(); xmlCleanupParser(); @@ -378,11 +492,13 @@ config_parse_opt_line ( int main( int argc, char **argv ) //------------------------------------------------------------------------------ { - int actions = 0; - char *test_dir_name = NULL; - char *scenario_file_name = NULL; - char *enb_config_file_name = NULL; - char play_scenario_filename[NAME_MAX]; + int actions = 0; + char *test_dir_name = NULL; + char *scenario_file_name = NULL; + char *enb_config_file_name = NULL; + char play_scenario_filename[NAME_MAX]; + int ret = 0; + test_scenario_t *scenario = NULL; memset(play_scenario_filename, 0, sizeof(play_scenario_filename)); g_openair_dir = getenv("OPENAIR_DIR"); @@ -393,13 +509,21 @@ int main( int argc, char **argv ) actions = config_parse_opt_line (argc, argv, &test_dir_name, &scenario_file_name, &enb_config_file_name); //Command-line options if (actions & PLAY_SCENARIO) { - if (generate_play_scenario(test_dir_name, scenario_file_name,enb_config_file_name, play_scenario_filename) == 0) { - play_scenario(play_scenario_filename); + if (generate_xml_scenario(test_dir_name, scenario_file_name,enb_config_file_name, play_scenario_filename) == 0) { + if (NULL != (scenario = generate_scenario(play_scenario_filename))) { + ret = play_scenario(scenario); + } else { + fprintf(stderr, "Error: Could not generate scenario from tsml file\n"); + ret = -1; + } + } else { + fprintf(stderr, "Error: Could not generate tsml scenario from xml file\n"); + ret = -1; } free_pointer(test_dir_name); free_pointer(scenario_file_name); free_pointer(enb_config_file_name); } - return 0; + return ret; } diff --git a/openair3/TEST/EPC_TEST/play_scenario.h b/openair3/TEST/EPC_TEST/play_scenario.h index c6e1087a04..4916950783 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.h +++ b/openair3/TEST/EPC_TEST/play_scenario.h @@ -37,12 +37,100 @@ #ifndef GENERATE_SCENARIO_H_ #define GENERATE_SCENARIO_H_ +# include +# include +#include /** @defgroup _enb_app ENB APP * @ingroup _oai2 * @{ */ +typedef enum { + ACTION_S1C_START = 0, + ACTION_S1C_NULL = ACTION_S1C_START, + ACTION_S1C_SEND, + ACTION_S1C_RECEIVE, + ACTION_S1C_END +} test_action_t; + +// from kernel source file 3.19/include/linux/sctp.h +typedef enum { + SCTP_CID_DATA = 0, + SCTP_CID_INIT = 1, + SCTP_CID_INIT_ACK = 2, + SCTP_CID_SACK = 3, + SCTP_CID_HEARTBEAT = 4, + SCTP_CID_HEARTBEAT_ACK = 5, + SCTP_CID_ABORT = 6, + SCTP_CID_SHUTDOWN = 7, + SCTP_CID_SHUTDOWN_ACK = 8, + SCTP_CID_ERROR = 9, + SCTP_CID_COOKIE_ECHO = 10, + SCTP_CID_COOKIE_ACK = 11, + SCTP_CID_ECN_ECNE = 12, + SCTP_CID_ECN_CWR = 13, + SCTP_CID_SHUTDOWN_COMPLETE = 14, + + /* AUTH Extension Section 4.1 */ + SCTP_CID_AUTH = 0x0F, + + /* PR-SCTP Sec 3.2 */ + SCTP_CID_FWD_TSN = 0xC0, + + /* Use hex, as defined in ADDIP sec. 3.1 */ + SCTP_CID_ASCONF = 0xC1, + SCTP_CID_ASCONF_ACK = 0x80, +} sctp_cid_t; /* enum */ + +// from kernel source file 3.19/include/linux/sctp.h, Big Endians +typedef struct sctp_datahdr_s { + uint32_t tsn; + uint16_t stream; + uint16_t ssn; + uint32_t ppid; + uint8_t payload[0]; +} sctp_datahdr_t; + +// from kernel source file 3.19/include/linux/sctp.h, Big Endians +typedef struct sctp_inithdr { + uint32_t init_tag; + uint32_t a_rwnd; + uint16_t num_outbound_streams; + uint16_t num_inbound_streams; + uint32_t initial_tsn; + uint8_t params[0]; +} sctp_inithdr_t; + +typedef sctp_inithdr_t sctp_initackhdr_t; + +typedef struct test_sctp_hdr_s { + unsigned int src_port; + unsigned int dst_port; + sctp_cid_t chunk_type; + union { + sctp_datahdr_t data_hdr; + sctp_inithdr_t init_hdr; + sctp_initackhdr_t init_ack_hdr; + } u; +} test_sctp_hdr_t; + +typedef struct test_packet_s { + test_action_t action; + struct timeval time_relative_to_first_packet; + struct timeval time_relative_to_last_packet; + test_sctp_hdr_t sctp_hdr; + uint16_t s1ap_byte_stream_count; + uint8_t *s1ap_byte_stream; + xmlNodePtr *s1ap_node; + + struct test_packet_s *next; +}test_packet_t; + +typedef struct test_scenario_s { + xmlChar *name; + test_packet_t *list_packet; +}test_scenario_t; inline void free_pointer(void *p) {if (NULL != p) {free(p); p=NULL;}}; #endif /* ENB_CONFIG_H_ */ diff --git a/openair3/TEST/EPC_TEST/play_scenario.xsl b/openair3/TEST/EPC_TEST/play_scenario.xsl index 1a89128005..6b1c36cc3d 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.xsl +++ b/openair3/TEST/EPC_TEST/play_scenario.xsl @@ -34,7 +34,7 @@ - + @@ -67,7 +67,7 @@ - + From 757b1940ace4f35888b5c0968c0fb0217b498aa1 Mon Sep 17 00:00:00 2001 From: gauthier Date: Fri, 13 Nov 2015 14:04:00 +0100 Subject: [PATCH 08/47] Problem decoding S1AP --- cmake_targets/epc_test/CMakeLists.template | 2 + .../attach_complete.pdml | 2 +- openair3/TEST/EPC_TEST/generic_scenario.xsl | 91 +- openair3/TEST/EPC_TEST/play_scenario.c | 965 +++++++++++++++++- openair3/TEST/EPC_TEST/play_scenario.h | 68 +- 5 files changed, 1035 insertions(+), 93 deletions(-) diff --git a/cmake_targets/epc_test/CMakeLists.template b/cmake_targets/epc_test/CMakeLists.template index 12a745b997..5789c3eb5c 100644 --- a/cmake_targets/epc_test/CMakeLists.template +++ b/cmake_targets/epc_test/CMakeLists.template @@ -1,11 +1,13 @@ cmake_minimum_required(VERSION 2.8) set ( CMAKE_BUILD_TYPE "RelWithDebInfo" ) +set ( ASN_DEBUG False) set ( ADDR_CONF False ) set ( DEBUG_OMG False ) set ( DISABLE_XER_PRINT False ) set ( DRIVER2013 True ) set ( EMOS False ) +set ( EMIT_ASN_DEBUG True ) set ( ENABLE_FXP True ) set ( ENABLE_ITTI True ) set ( ENABLE_NAS_UE_LOGGING True ) diff --git a/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/attach_complete.pdml b/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/attach_complete.pdml index fef45773f9..f7c27272aa 100644 --- a/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/attach_complete.pdml +++ b/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/attach_complete.pdml @@ -1,7 +1,7 @@ - + diff --git a/openair3/TEST/EPC_TEST/generic_scenario.xsl b/openair3/TEST/EPC_TEST/generic_scenario.xsl index b1cadbcdfa..1d49b4942e 100644 --- a/openair3/TEST/EPC_TEST/generic_scenario.xsl +++ b/openair3/TEST/EPC_TEST/generic_scenario.xsl @@ -106,6 +106,7 @@ + @@ -131,16 +132,17 @@ - - - - + + + + + @@ -148,59 +150,61 @@ + - - - - - + + + + + - + - - - + + + + - - - - - - + + + + + - + - - - + + + + - - - - - - + + + + + + - + @@ -209,44 +213,47 @@ + - - - + + + - + + - - - + + + - + + - - - + + + - + diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c index e73a41a683..a32947c439 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.c +++ b/openair3/TEST/EPC_TEST/play_scenario.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -53,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -60,9 +62,13 @@ #include "assertions.h" #include "play_scenario.h" -#include "s1ap_eNB.h" +//#include "s1ap_eNB.h" +#include "s1ap_common.h" +#include "s1ap_ies_defs.h" +#include "s1ap_eNB_decoder.h" #include "intertask_interface.h" #include "enb_config.h" +#include "log.h" //------------------------------------------------------------------------------ #define ENB_CONFIG_MAX_XSLT_PARAMS 32 #define PLAY_SCENARIO 1 @@ -73,8 +79,100 @@ char *g_openair_dir = NULL; //------------------------------------------------------------------------------ extern Enb_properties_array_t enb_properties; extern int xmlLoadExtDtdDefaultValue; - +extern int asn_debug; +extern int asn1_xer_print; //------------------------------------------------------------------------------ +void test_print_hex_octets(const unsigned char * const byte_stream, const unsigned long int num); +int is_file_exists ( const char const * file_nameP, const char const *file_roleP); +int strip_extension( char *in_filename); +int split_path ( char * pathP, char *** resP); +void display_node ( xmlNodePtr node, unsigned int indent); +void display_tree ( xmlNodePtr node, unsigned int indent); +//------------------------- +void free_packet(test_packet_t* packet); +void free_scenario(test_scenario_t* scenario); +//------------------------- +void display_packet_sctp_init(const sctp_inithdr_t * const sctp); +void display_packet_sctp_initack(const sctp_initackhdr_t * const sctp); +void display_packet_sctp_data(const sctp_datahdr_t * const sctp); +void display_packet_sctp(const test_sctp_hdr_t * const sctp); +void display_packet_ip(const test_ip_hdr_t * const ip); +void display_packet(const test_packet_t * const packet); +void display_scenario(const test_scenario_t * const scenario); +//------------------------- +char * test_ip2ip_str(const test_ip_t * const ip); +int hex2data(unsigned char * const data, const unsigned char * const hexstring, const unsigned int len); +sctp_cid_t chunk_type_str2cid(const xmlChar * const chunk_type_str); +const char * const chunk_type_cid2str(const sctp_cid_t chunk_type); +test_action_t action_str2test_action_t(const xmlChar * const action); +void ip_str2test_ip(const xmlChar * const ip_str, test_ip_t * const ip); +//------------------------- +int test_s1ap_decode_initiating_message(s1ap_message *message, S1ap_InitiatingMessage_t *initiating_p); +int test_s1ap_decode_successful_outcome(s1ap_message *message, S1ap_SuccessfulOutcome_t *successfullOutcome_p); +int test_s1ap_decode_unsuccessful_outcome(s1ap_message *message, S1ap_UnsuccessfulOutcome_t *unSuccessfullOutcome_p); +int test_s1ap_decode_pdu(s1ap_message *message, const uint8_t * const buffer,const uint32_t length); +void test_decode_s1ap(test_s1ap_t * const s1ap); +//------------------------- +void parse_s1ap(xmlDocPtr doc, const xmlNode const *s1ap_node, test_s1ap_t * const s1ap); +void parse_sctp_data_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_datahdr_t * const sctp_hdr); +void parse_sctp_init_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_inithdr_t * const sctp_hdr); +void parse_sctp_init_ack_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_initackhdr_t * const sctp_hdr); +void parse_sctp(xmlDocPtr doc, const xmlNode const *sctp_node, test_sctp_hdr_t * const sctp_hdr); +test_packet_t* parse_xml_packet(xmlDocPtr doc, xmlNodePtr node); +//------------------------- +int play_scenario(test_scenario_t* scenario); +int generate_xml_scenario( + const char const * test_dir_name, + const char const * test_scenario_filename, + const char const * enb_config_filename, + char const * play_scenario_filename /* OUT PARAM*/); + +//----------------------------------------------------------------------------- +void test_print_hex_octets(const unsigned char * const byte_stream, const unsigned long int num) +//----------------------------------------------------------------------------- +{ + unsigned long octet_index = 0; + + if (byte_stream == NULL) { + return; + } + + + + + fprintf(stdout, "+-----+-------------------------------------------------+\n"); + fprintf(stdout, "| | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n"); + fprintf(stdout, "+-----+-------------------------------------------------+\n"); + + for (octet_index = 0; octet_index < num; octet_index++) { + if ((octet_index % 16) == 0) { + if (octet_index != 0) { + fprintf(stdout, " |\n"); + } + + fprintf(stdout, " %04ld |", octet_index); + } + + /* + * Print every single octet in hexadecimal form + */ + fprintf(stdout, " %02x", byte_stream[octet_index]); + /* + * Align newline and pipes according to the octets in groups of 2 + */ + } + + /* + * Append enough spaces and put final pipe + */ + unsigned char index; + + for (index = octet_index; index < 16; ++index) { + fprintf(stdout, " "); + } + + fprintf(stdout, " |\n"); +} //------------------------------------------------------------------------------ // test if file exist in current directory @@ -138,9 +236,14 @@ int split_path( char * pathP, char *** resP) return n_spaces; } //------------------------------------------------------------------------------ -void display_node(xmlNodePtr node) { +void display_node(xmlNodePtr node, unsigned int indent) +{ + int i = 0; if (node->type == XML_ELEMENT_NODE) { xmlChar *path = xmlGetNodePath(node); + for (i=0; ichildren != NULL && node->children->type == XML_TEXT_NODE) { xmlChar *content = xmlNodeGetContent(node); printf("%s -> %s\n", path, content); @@ -151,13 +254,229 @@ void display_node(xmlNodePtr node) { xmlFree(path); } } +/** + * print_element_names: + * @node: the initial xml node to consider. + * @indent: indentation level. + * + * Prints the names of the all the xml elements + * that are siblings or children of a given xml node. + */ +//------------------------------------------------------------------------------ +void display_tree(xmlNodePtr node, unsigned int indent) +{ + xmlNode *cur_node = NULL; + + for (cur_node = node; cur_node; cur_node = cur_node->next) { + if (cur_node->type == XML_ELEMENT_NODE) { + display_node(cur_node, indent); + } + display_tree(cur_node->children, indent++); + } +} +//------------------------------------------------------------------------------ +void free_packet(test_packet_t* packet) +{ + if (packet) { + switch (packet->sctp_hdr.chunk_type) { + case SCTP_CID_DATA: + free_pointer(packet->sctp_hdr.u.data_hdr.payload.binary_stream); + break; + default: + ; + } + free_pointer(packet); + } +} + //------------------------------------------------------------------------------ void free_scenario(test_scenario_t* scenario) { - //TODO + test_packet_t *packet = NULL; + test_packet_t *next_packet = NULL; + if (scenario) { + packet = scenario->list_packet; + while (packet) { + next_packet = packet->next; + free_packet(packet); + packet = next_packet->next; + } + free_pointer(scenario); + } +} + + +//------------------------------------------------------------------------------ +void display_packet_sctp_init(const sctp_inithdr_t * const sctp) +{ + + if (sctp) { + fprintf(stdout, "\t\tSCTP.init.init_tag : %u\n", sctp->init_tag); + fprintf(stdout, "\t\tSCTP.init.a_rwnd : %u\n", sctp->a_rwnd); + fprintf(stdout, "\t\tSCTP.init.num_inbound_streams : %u\n", sctp->num_inbound_streams); + fprintf(stdout, "\t\tSCTP.init.num_outbound_streams : %u\n", sctp->num_outbound_streams); + fprintf(stdout, "\t\tSCTP.init.initial_tsn : %u\n", sctp->initial_tsn); + } } //------------------------------------------------------------------------------ -sctp_cid_t chunk_type_str2cid(xmlChar *chunk_type_str) +void display_packet_sctp_initack(const sctp_initackhdr_t * const sctp) +{ + + if (sctp) { + fprintf(stdout, "\t\tSCTP.initack.init_tag : %u\n", sctp->init_tag); + fprintf(stdout, "\t\tSCTP.initack.a_rwnd : %u\n", sctp->a_rwnd); + fprintf(stdout, "\t\tSCTP.initack.num_inbound_streams : %u\n", sctp->num_inbound_streams); + fprintf(stdout, "\t\tSCTP.initack.num_outbound_streams : %u\n", sctp->num_outbound_streams); + fprintf(stdout, "\t\tSCTP.initack.initial_tsn : %u\n", sctp->initial_tsn); + } +} +//------------------------------------------------------------------------------ +void display_packet_sctp_data(const sctp_datahdr_t * const sctp) +{ + if (sctp) { + fprintf(stdout, "\t\tSCTP.data.tsn : %u\n", sctp->tsn); + fprintf(stdout, "\t\tSCTP.data.stream : %u\n", sctp->stream); + fprintf(stdout, "\t\tSCTP.data.ssn : %u\n", sctp->ssn); + fprintf(stdout, "\t\tSCTP.data.ppid : %u\n", sctp->ppid); + //fprintf(stdout, "\t\tSCTP.data.pdu_type : %u\n", sctp->payload.pdu_type); + //fprintf(stdout, "\t\tSCTP.data.procedure_code : %u\n", sctp->payload.procedure_code); + fprintf(stdout, "\t\tSCTP.data.binary_stream_allocated_size : %u\n", sctp->payload.binary_stream_allocated_size); + if (NULL != sctp->payload.binary_stream) { + fprintf(stdout, "\t\tSCTP.data.binary_stream :\n"); + test_print_hex_octets(sctp->payload.binary_stream, sctp->payload.binary_stream_allocated_size); + } else { + fprintf(stdout, "\t\tSCTP.data.binary_stream : NULL\n"); + } + } +} + +//------------------------------------------------------------------------------ +void display_packet_sctp(const test_sctp_hdr_t * const sctp) +{ + if (sctp) { + fprintf(stdout, "\t\tSCTP.src_port : %u\n", sctp->src_port); + fprintf(stdout, "\t\tSCTP.dst_port : %u\n", sctp->dst_port); + fprintf(stdout, "\t\tSCTP.chunk_type : %s\n", chunk_type_cid2str(sctp->chunk_type)); + switch (sctp->chunk_type) { + case SCTP_CID_DATA: + display_packet_sctp_data(&sctp->u.data_hdr); + break; + case SCTP_CID_INIT: + display_packet_sctp_initack(&sctp->u.init_hdr); + break; + case SCTP_CID_INIT_ACK: + display_packet_sctp_initack(&sctp->u.init_ack_hdr); + break; + default: + ; + } + } +} +//------------------------------------------------------------------------------ +void display_packet_ip(const test_ip_hdr_t * const ip) +{ + if (ip) { + fprintf(stdout, "\t\tSource address : %s\n", test_ip2ip_str(&ip->src)); + fprintf(stdout, "\t\tDestination address : %s\n", test_ip2ip_str(&ip->dst)); + } +} + +//------------------------------------------------------------------------------ +void display_packet(const test_packet_t * const packet) +{ + if (packet) { + fprintf(stdout, "\tPacket:\tnum %u | original frame number %u \n", packet->packet_number, packet->original_frame_number); + fprintf(stdout, "\tPacket:\ttime relative to 1st packet %ld.%06lu\n", + packet->time_relative_to_first_packet.tv_sec, packet->time_relative_to_first_packet.tv_usec); + fprintf(stdout, "\tPacket:\ttime relative to last tx packet %ld.%06lu\n", + packet->time_relative_to_last_sent_packet.tv_sec, packet->time_relative_to_last_sent_packet.tv_usec); + fprintf(stdout, "\tPacket:\ttime relative to last_received packet %ld.%06lu\n", + packet->time_relative_to_last_received_packet.tv_sec, packet->time_relative_to_last_received_packet.tv_usec); + + switch(packet->action) { + case ACTION_S1C_SEND: + fprintf(stdout, "\tPacket:\tAction SEND\n"); + break; + case ACTION_S1C_RECEIVE: + fprintf(stdout, "\tPacket:\tAction RECEIVE\n"); + break; + default: + fprintf(stdout, "\tPacket:\tAction UNKNOWN\n"); + } + display_packet_ip(&packet->ip_hdr); + display_packet_sctp(&packet->sctp_hdr); + } +} +//------------------------------------------------------------------------------ +void display_scenario(const test_scenario_t * const scenario) +{ + test_packet_t *packet = NULL; + if (scenario) { + fprintf(stdout, "Scenario: %s\n", (scenario->name != NULL) ? (char*)scenario->name:"UNKNOWN NAME"); + packet = scenario->list_packet; + while (packet) { + display_packet(packet); + packet = packet->next; + } + } +} + +//------------------------------------------------------------------------------ +char * test_ip2ip_str(const test_ip_t * const ip) +{ + static char str[INET6_ADDRSTRLEN]; + + sprintf(str, "ERROR"); + switch (ip->address_family) { + case AF_INET6: + inet_ntop(AF_INET6, &(ip->address.ipv6), str, INET6_ADDRSTRLEN); + break; + case AF_INET: + inet_ntop(AF_INET, &(ip->address.ipv4), str, INET_ADDRSTRLEN); + break; + default: + ; + } + return str; +} +//------------------------------------------------------------------------------ +//convert hexstring to len bytes of data +//returns 0 on success, negative on error +//data is a buffer of at least len bytes +//hexstring is upper or lower case hexadecimal, NOT prepended with "0x" +int hex2data(unsigned char * const data, const unsigned char * const hexstring, const unsigned int len) +{ + unsigned const char *pos = hexstring; + char *endptr = NULL; + size_t count = 0; + + fprintf(stdout, "%s(%s,%d)\n", __FUNCTION__, hexstring, len); + + if ((len > 1) && (strlen((const char*)hexstring) % 2)) { + //or hexstring has an odd length + return -3; + } + + if (len == 1) { + char buf[5] = {'0', 'x', 0, pos[0], '\0'}; + data[0] = strtol(buf, &endptr, 16); + /* Check for various possible errors */ + AssertFatal ((errno == 0) || (data[0] != 0), "ERROR %s() strtol: %s\n", __FUNCTION__, strerror(errno)); + AssertFatal (endptr != buf, "ERROR %s() No digits were found\n", __FUNCTION__); + return 0; + } + + for(count = 0; count < len/2; count++) { + char buf[5] = {'0', 'x', pos[0], pos[1], 0}; + data[count] = strtol(buf, &endptr, 16); + pos += 2 * sizeof(char); + AssertFatal (endptr[0] == '\0', "ERROR %s() non-hexadecimal character encountered buf %p endptr %p buf %s count %d pos %p\n", __FUNCTION__, buf, endptr, buf, count, pos); + AssertFatal (endptr != buf, "ERROR %s() No digits were found\n", __FUNCTION__); + } + return 0; +} +//------------------------------------------------------------------------------ +sctp_cid_t chunk_type_str2cid(const xmlChar * const chunk_type_str) { if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"DATA"))) { return SCTP_CID_DATA;} if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"INIT"))) { return SCTP_CID_INIT;} @@ -178,31 +497,599 @@ sctp_cid_t chunk_type_str2cid(xmlChar *chunk_type_str) if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"FWD_TSN"))) { return SCTP_CID_FWD_TSN;} if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"ASCONF"))) { return SCTP_CID_ASCONF;} if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"ASCONF_ACK"))) { return SCTP_CID_ASCONF_ACK;} - fprintf(stderr, "ERROR: Could not convert: %s\n", chunk_type_str); - exit(-1); + AssertFatal (0, "ERROR: %s() cannot convert: %s\n", __FUNCTION__, chunk_type_str); } //------------------------------------------------------------------------------ -test_packet_t* parse_xml_packet(xmlNodePtr node) { +const char * const chunk_type_cid2str(const sctp_cid_t chunk_type) +{ + switch (chunk_type) { + case SCTP_CID_DATA: return "DATA"; break; + case SCTP_CID_INIT: return "INIT"; break; + case SCTP_CID_INIT_ACK: return "INIT_ACK"; break; + case SCTP_CID_SACK: return "SACK"; break; + case SCTP_CID_HEARTBEAT: return "HEARTBEAT"; break; + case SCTP_CID_HEARTBEAT_ACK: return "HEARTBEAT_ACK"; break; + case SCTP_CID_ABORT: return "ABORT"; break; + case SCTP_CID_SHUTDOWN: return "SHUTDOWN"; break; + case SCTP_CID_SHUTDOWN_ACK: return "SHUTDOWN_ACK"; break; + case SCTP_CID_ERROR: return "ERROR"; break; + case SCTP_CID_COOKIE_ECHO: return "COOKIE_ECHO"; break; + case SCTP_CID_COOKIE_ACK: return "COOKIE_ACK"; break; + case SCTP_CID_ECN_ECNE: return "ECN_ECNE"; break; + case SCTP_CID_ECN_CWR: return "ECN_CWR"; break; + case SCTP_CID_SHUTDOWN_COMPLETE: return "SHUTDOWN_COMPLETE"; break; + case SCTP_CID_AUTH: return "AUTH"; break; + case SCTP_CID_FWD_TSN: return "FWD_TSN"; break; + case SCTP_CID_ASCONF: return "ASCONF"; break; + case SCTP_CID_ASCONF_ACK: return "ASCONF_ACK"; break; + default: + AssertFatal (0, "ERROR %s(): Unknown chunk_type %d!\n", __FUNCTION__, chunk_type); + } +} +//------------------------------------------------------------------------------ +test_action_t action_str2test_action_t(const xmlChar * const action) +{ + if ((!xmlStrcmp(action, (const xmlChar *)"SEND"))) { return ACTION_S1C_SEND;} + if ((!xmlStrcmp(action, (const xmlChar *)"RECEIVE"))) { return ACTION_S1C_RECEIVE;} + AssertFatal (0, "ERROR: %s cannot convert: %s\n", __FUNCTION__, action); + //if (NULL == action) {return ACTION_S1C_NULL;} +} +//------------------------------------------------------------------------------ +void ip_str2test_ip(const xmlChar * const ip_str, test_ip_t * const ip) +{ + AssertFatal (NULL != ip_str, "ERROR %s() Cannot convert null string to ip address!\n", __FUNCTION__); + AssertFatal (NULL != ip, "ERROR %s() out parameter pointer is NULL!\n", __FUNCTION__); + // store this IP address in sa: + if (inet_pton(AF_INET, (const char*)ip_str, (void*)&(ip->address.ipv4)) > 0) { + ip->address_family = AF_INET; + } else if (inet_pton(AF_INET6, (const char*)ip_str, (void*)&(ip->address.ipv6)) > 0) { + ip->address_family = AF_INET6; + } else { + ip->address_family = AF_UNSPEC; + AssertFatal (0, "ERROR %s() Could not parse ip address %s!\n", __FUNCTION__, ip_str); + } +} +//------------------------------------------------------------------------------ +int test_s1ap_decode_initiating_message(s1ap_message *message, + S1ap_InitiatingMessage_t *initiating_p) +{ + int ret = -1; - test_packet_t *packet = NULL; - xmlNode *cur_node = NULL; - xmlChar *xml_char = NULL; + DevAssert(initiating_p != NULL); + + message->procedureCode = initiating_p->procedureCode; + message->criticality = initiating_p->criticality; + + switch(initiating_p->procedureCode) { + case S1ap_ProcedureCode_id_downlinkNASTransport: + ret = s1ap_decode_s1ap_downlinknastransporties( + &message->msg.s1ap_DownlinkNASTransportIEs, + &initiating_p->value); + break; + + case S1ap_ProcedureCode_id_InitialContextSetup: + ret = s1ap_decode_s1ap_initialcontextsetuprequesties( + &message->msg.s1ap_InitialContextSetupRequestIEs, &initiating_p->value); + break; + + case S1ap_ProcedureCode_id_UEContextRelease: + ret = s1ap_decode_s1ap_uecontextreleasecommandies( + &message->msg.s1ap_UEContextReleaseCommandIEs, &initiating_p->value); + break; + + case S1ap_ProcedureCode_id_Paging: + ret = s1ap_decode_s1ap_pagingies( + &message->msg.s1ap_PagingIEs, &initiating_p->value); + break; + + case S1ap_ProcedureCode_id_uplinkNASTransport: { + ret = s1ap_decode_s1ap_uplinknastransporties (&message->msg.s1ap_UplinkNASTransportIEs, &initiating_p->value); + } + break; + + case S1ap_ProcedureCode_id_S1Setup: { + ret = s1ap_decode_s1ap_s1setuprequesties (&message->msg.s1ap_S1SetupRequestIEs, &initiating_p->value); + } + break; + + case S1ap_ProcedureCode_id_initialUEMessage: { + ret = s1ap_decode_s1ap_initialuemessageies (&message->msg.s1ap_InitialUEMessageIEs, &initiating_p->value); + } + break; + + case S1ap_ProcedureCode_id_UEContextReleaseRequest: { + ret = s1ap_decode_s1ap_uecontextreleaserequesties (&message->msg.s1ap_UEContextReleaseRequestIEs, &initiating_p->value); + } + break; + + case S1ap_ProcedureCode_id_UECapabilityInfoIndication: { + ret = s1ap_decode_s1ap_uecapabilityinfoindicationies (&message->msg.s1ap_UECapabilityInfoIndicationIEs, &initiating_p->value); + } + break; + + case S1ap_ProcedureCode_id_NASNonDeliveryIndication: { + ret = s1ap_decode_s1ap_nasnondeliveryindication_ies (&message->msg.s1ap_NASNonDeliveryIndication_IEs, &initiating_p->value); + } + break; + + default: + AssertFatal( 0 , "Unknown procedure ID (%d) for initiating message\n", + (int)initiating_p->procedureCode); + return -1; + } + return ret; +} + +//------------------------------------------------------------------------------ +int test_s1ap_decode_successful_outcome(s1ap_message *message, + S1ap_SuccessfulOutcome_t *successfullOutcome_p) +{ + int ret = -1; + + DevAssert(successfullOutcome_p != NULL); + + message->procedureCode = successfullOutcome_p->procedureCode; + message->criticality = successfullOutcome_p->criticality; + + switch(successfullOutcome_p->procedureCode) { + case S1ap_ProcedureCode_id_S1Setup: + ret = s1ap_decode_s1ap_s1setupresponseies( + &message->msg.s1ap_S1SetupResponseIEs, &successfullOutcome_p->value); + break; + + case S1ap_ProcedureCode_id_InitialContextSetup: { + ret = s1ap_decode_s1ap_initialcontextsetupresponseies (&message->msg.s1ap_InitialContextSetupResponseIEs, &successfullOutcome_p->value); + } + break; + + case S1ap_ProcedureCode_id_UEContextRelease: { + ret = s1ap_decode_s1ap_uecontextreleasecompleteies (&message->msg.s1ap_UEContextReleaseCompleteIEs, &successfullOutcome_p->value); + } + break; + + default: + AssertFatal(0, "Unknown procedure ID (%d) for successfull outcome message\n", + (int)successfullOutcome_p->procedureCode); + return -1; + } + return ret; +} + +//------------------------------------------------------------------------------ +int test_s1ap_decode_unsuccessful_outcome(s1ap_message *message, + S1ap_UnsuccessfulOutcome_t *unSuccessfullOutcome_p) +{ + int ret = -1; + DevAssert(unSuccessfullOutcome_p != NULL); + + message->procedureCode = unSuccessfullOutcome_p->procedureCode; + message->criticality = unSuccessfullOutcome_p->criticality; + + switch(unSuccessfullOutcome_p->procedureCode) { + case S1ap_ProcedureCode_id_S1Setup: + return s1ap_decode_s1ap_s1setupfailureies( + &message->msg.s1ap_S1SetupFailureIEs, &unSuccessfullOutcome_p->value); + + case S1ap_ProcedureCode_id_InitialContextSetup: { + ret = s1ap_decode_s1ap_initialcontextsetupfailureies (&message->msg.s1ap_InitialContextSetupFailureIEs, &unSuccessfullOutcome_p->value); + } + break; + + + default: + AssertFatal(0,"Unknown procedure ID (%d) for unsuccessfull outcome message\n", + (int)unSuccessfullOutcome_p->procedureCode); + break; + } + + return ret; +} + +//------------------------------------------------------------------------------ +int test_s1ap_decode_pdu(s1ap_message *message, const uint8_t * const buffer, + const uint32_t length) +{ + S1AP_PDU_t pdu; + S1AP_PDU_t *pdu_p = &pdu; + asn_dec_rval_t dec_ret; + + DevAssert(buffer != NULL); + + memset((void *)pdu_p, 0, sizeof(S1AP_PDU_t)); + + dec_ret = aper_decode(NULL, + &asn_DEF_S1AP_PDU, + (void **)&pdu_p, + buffer, + length, + 0, + 0); + + if (dec_ret.code != RC_OK) { + S1AP_ERROR("Failed to decode pdu\n"); + return -1; + } + + message->direction = pdu_p->present; + + switch(pdu_p->present) { + case S1AP_PDU_PR_initiatingMessage: + return test_s1ap_decode_initiating_message(message, + &pdu_p->choice.initiatingMessage); + + case S1AP_PDU_PR_successfulOutcome: + return test_s1ap_decode_successful_outcome(message, + &pdu_p->choice.successfulOutcome); + + case S1AP_PDU_PR_unsuccessfulOutcome: + return test_s1ap_decode_unsuccessful_outcome(message, + &pdu_p->choice.unsuccessfulOutcome); + + default: + AssertFatal(0, "Unknown presence (%d) or not implemented\n", (int)pdu_p->present); + break; + } + return -1; +} +//------------------------------------------------------------------------------ +void test_decode_s1ap(test_s1ap_t * const s1ap) +{ + if (NULL != s1ap) { + if (test_s1ap_decode_pdu(&s1ap->message, s1ap->binary_stream, s1ap->binary_stream_allocated_size) < 0) { + AssertFatal (0, "ERROR %s() Cannot decode S1AP message!\n", __FUNCTION__); + } + } +} +//------------------------------------------------------------------------------ +void parse_s1ap(xmlDocPtr doc, const xmlNode const *s1ap_node, test_s1ap_t * const s1ap) +{ + xmlNode *cur_node = NULL; + xmlChar *xml_char = NULL; + xmlChar *xml_char2 = NULL; + unsigned int size = 0; + int rc = 0; + unsigned int go_deeper_in_tree = 1; + + if ((NULL != s1ap_node) && (NULL != s1ap)) { + for (cur_node = (xmlNode *)s1ap_node; cur_node; cur_node = cur_node->next) { + go_deeper_in_tree = 1; + if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"field"))) { + // do not get hidden fields + xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"hide"); + if (NULL != xml_char) { + if ((!xmlStrcmp(xml_char, (const xmlChar *)"yes"))) { + xmlFree(xml_char); + return; + } + xmlFree(xml_char); + } + // first get size + xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"size"); + if (NULL != xml_char) { + size = strtoul((const char *)xml_char, NULL, 0); + xmlFree(xml_char); + // second: try to get value (always hex) + xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"value"); + if (NULL != xml_char) { + xml_char2 = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"name"); + fprintf(stdout, "s1ap %p field %s size %d value %s\n",s1ap, xml_char2, size, xml_char); + xmlFree(xml_char2); + // if success to get value, do not parse children + //AssertFatal ((xmlStrlen(xml_char) == size), "ERROR %s() mismatch in size %d and strlen %d\n", __FUNCTION__, size, xmlStrlen(xml_char)); + //if (xmlStrlen(xml_char) == size) { + AssertFatal ((s1ap->binary_stream_pos+xmlStrlen(xml_char)/2) <= s1ap->binary_stream_allocated_size, + "ERROR %s() in buffer size: binary_stream_pos %d xmlStrlen(xml_char)/2=%d\n", __FUNCTION__, s1ap->binary_stream_pos, xmlStrlen(xml_char)/2); + rc = hex2data( &s1ap->binary_stream[s1ap->binary_stream_pos], xml_char, xmlStrlen(xml_char)); + s1ap->binary_stream_pos += xmlStrlen(xml_char)/2; + display_node(cur_node, 0); + AssertFatal (rc >= 0, "ERROR %s() in converting hex string %s len %d size %d rc %d\n", __FUNCTION__, xml_char, xmlStrlen(xml_char), size, rc); + go_deeper_in_tree = 0; + //} + xmlFree(xml_char); + } + } + } + if (0 < go_deeper_in_tree) { + parse_s1ap(doc, cur_node->children, s1ap); + } + } + } +} + +//------------------------------------------------------------------------------ +void parse_sctp_data_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_datahdr_t * const sctp_hdr) +{ + xmlNode *cur_node = NULL; + xmlChar *xml_char = NULL; + xmlChar *xml_char2 = NULL; + + if ((NULL != sctp_node) && (NULL != sctp_hdr)) { + xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"name"); + if (NULL != xml_char) { + if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.data_payload_proto_id"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); + if (NULL != xml_char2) { + sctp_hdr->ppid = strtoul((const char *)xml_char2, NULL, 0); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.data_sid"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); + if (NULL != xml_char2) { + sctp_hdr->stream = strtoul((const char *)xml_char2, NULL, 16); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.data_tsn"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); + if (NULL != xml_char2) { + sctp_hdr->tsn = strtoul((const char *)xml_char2, NULL, 0); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.data_ssn"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); + if (NULL != xml_char2) { + sctp_hdr->ssn = strtoul((const char *)xml_char2, NULL, 0); + xmlFree(xml_char2); + } + } + xmlFree(xml_char); + } + for (cur_node = sctp_node->children; cur_node; cur_node = cur_node->next) { + parse_sctp_data_chunk(doc, cur_node, sctp_hdr); + } + } + +} +//------------------------------------------------------------------------------ +void parse_sctp_init_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_inithdr_t * const sctp_hdr) +{ + xmlNode *cur_node = NULL; + xmlChar *xml_char = NULL; + xmlChar *xml_char2 = NULL; + + if ((NULL != sctp_node) && (NULL != sctp_hdr)) { + xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"name"); + if (NULL != xml_char) { + if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.init_nr_out_streams"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); + if (NULL != xml_char2) { + sctp_hdr->num_outbound_streams = strtoul((const char *)xml_char2, NULL, 0); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.init_nr_in_streams"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); + if (NULL != xml_char2) { + sctp_hdr->num_inbound_streams = strtoul((const char *)xml_char2, NULL, 0); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.init_credit"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); + if (NULL != xml_char2) { + sctp_hdr->a_rwnd = strtoul((const char *)xml_char2, NULL, 0); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.init_initial_tsn"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); + if (NULL != xml_char2) { + sctp_hdr->initial_tsn = strtoul((const char *)xml_char2, NULL, 0); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.init_initiate_tag"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); + if (NULL != xml_char2) { + sctp_hdr->init_tag = strtoul((const char *)xml_char2, NULL, 16); + xmlFree(xml_char2); + } + } + xmlFree(xml_char); + } + for (cur_node = sctp_node->children; cur_node; cur_node = cur_node->next) { + parse_sctp_init_chunk(doc, cur_node, sctp_hdr); + } + } +} +//------------------------------------------------------------------------------ +void parse_sctp_init_ack_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_initackhdr_t * const sctp_hdr) +{ + xmlNode *cur_node = NULL; + xmlChar *xml_char = NULL; + xmlChar *xml_char2 = NULL; + + if ((NULL != sctp_node) && (NULL != sctp_hdr)) { + xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"name"); + if (NULL != xml_char) { + if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.initack_nr_out_streams"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); + if (NULL != xml_char2) { + sctp_hdr->num_outbound_streams = strtoul((const char *)xml_char2, NULL, 0); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.initack_nr_in_streams"))) { + xml_char2 = xmlGetProp((xmlNode *)(xmlNode *)sctp_node, (const xmlChar *)"value"); + if (NULL != xml_char2) { + sctp_hdr->num_inbound_streams = strtoul((const char *)xml_char2, NULL, 0); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.initack_credit"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); + if (NULL != xml_char2) { + sctp_hdr->a_rwnd = strtoul((const char *)xml_char2, NULL, 0); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.initack_initial_tsn"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); + if (NULL != xml_char2) { + sctp_hdr->initial_tsn = strtoul((const char *)xml_char2, NULL, 0); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.initack_initiate_tag"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); + if (NULL != xml_char2) { + sctp_hdr->init_tag = strtoul((const char *)xml_char2, NULL, 16); + xmlFree(xml_char2); + } + } + xmlFree(xml_char); + } + for (cur_node = sctp_node->children; cur_node; cur_node = cur_node->next) { + parse_sctp_init_ack_chunk(doc, cur_node, sctp_hdr); + } + } +} +//------------------------------------------------------------------------------ +void parse_sctp(xmlDocPtr doc, const xmlNode const *sctp_node, test_sctp_hdr_t * const sctp_hdr) +{ + xmlNode *cur_node = NULL; + xmlChar *xml_char = NULL; + xmlChar *xml_char2 = NULL; + + if ((NULL != sctp_node) && (NULL != sctp_hdr)) { + if ((!xmlStrcmp(sctp_node->name, (const xmlChar *)"proto"))) { + xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"name"); + if (NULL != xml_char) { + if ((!xmlStrcmp(xml_char, (const xmlChar *)"s1ap"))) { + xmlFree(xml_char); + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"size"); + if (NULL != xml_char2) { + sctp_hdr->u.data_hdr.payload.binary_stream_allocated_size = strtoul((const char *)xml_char2, NULL, 0); + sctp_hdr->u.data_hdr.payload.binary_stream = calloc(1, sctp_hdr->u.data_hdr.payload.binary_stream_allocated_size); + xmlFree(xml_char2); + } + parse_s1ap(doc, sctp_node, &sctp_hdr->u.data_hdr.payload); + test_decode_s1ap(&sctp_hdr->u.data_hdr.payload); + return; + } + xmlFree(xml_char); + } + } + //if ((cur_node->type == XML_ATTRIBUTE_NODE) || (cur_node->type == XML_ELEMENT_NODE)) { + xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"name"); + if (NULL != xml_char) { + if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.srcport"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); + if (NULL != xml_char2) { + sctp_hdr->src_port = strtoul((const char *)xml_char2, NULL, 16); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.dstport"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); + if (NULL != xml_char2) { + sctp_hdr->dst_port = strtoul((const char *)xml_char2, NULL, 16); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.chunk_type"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); + if (NULL != xml_char2) { + sctp_hdr->chunk_type = strtoul((const char *)xml_char2, NULL, 0); + xmlFree(xml_char2); + switch (sctp_hdr->chunk_type) { + case SCTP_CID_DATA: + parse_sctp_data_chunk(doc, sctp_node->parent, &sctp_hdr->u.data_hdr); + break; + case SCTP_CID_INIT: + parse_sctp_init_chunk(doc, sctp_node->parent, &sctp_hdr->u.init_hdr); + break; + case SCTP_CID_INIT_ACK: + parse_sctp_init_ack_chunk(doc, sctp_node->parent, &sctp_hdr->u.init_ack_hdr); + break; + default: + ; + } + } + } + } + for (cur_node = sctp_node->children; cur_node; cur_node = cur_node->next) { + parse_sctp(doc, cur_node, sctp_hdr); + } + } +} +//------------------------------------------------------------------------------ +test_packet_t* parse_xml_packet(xmlDocPtr doc, xmlNodePtr node) { + + test_packet_t *packet = NULL; + xmlNode *cur_node = NULL; + xmlChar *xml_char = NULL; + float afloat = (float)0.0; + static struct timeval initial_time = { .tv_sec = 0, .tv_usec = 0 }; + static struct timeval relative_last_sent_packet = { .tv_sec = 0, .tv_usec = 0 }; + static struct timeval relative_last_received_packet = { .tv_sec = 0, .tv_usec = 0 }; + static char first_packet = 1; + static char first_sent_packet = 1; + static char first_received_packet = 1; + static unsigned int packet_number = 1; if (NULL != node) { packet = calloc(1, sizeof(*packet)); + xml_char = xmlGetProp(node, (const xmlChar *)"action"); + packet->action = action_str2test_action_t(xml_char); + xmlFree(xml_char); + packet->packet_number = packet_number++; + for (cur_node = node->children; cur_node; cur_node = cur_node->next) { - if (cur_node->type == XML_ELEMENT_NODE) { - printf("node type: Element, name: %s\n", cur_node->name); + //if (cur_node->type == XML_ELEMENT_NODE) { if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"frame.time_relative"))) { + xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"value"); + afloat = atof((const char*)xml_char); + xmlFree(xml_char); + packet->time_relative_to_first_packet.tv_sec = (int)afloat; + packet->time_relative_to_first_packet.tv_usec = (int)((afloat - packet->time_relative_to_first_packet.tv_sec)*1000000); + + if (first_packet > 0) { + initial_time = packet->time_relative_to_first_packet; + packet->time_relative_to_first_packet.tv_sec = 0; + packet->time_relative_to_first_packet.tv_usec = 0; + first_packet = 0; + } else { + timersub(&packet->time_relative_to_first_packet, &initial_time, + &packet->time_relative_to_first_packet); + } + if (packet->action == ACTION_S1C_SEND) { + if (first_sent_packet > 0) { + relative_last_sent_packet = packet->time_relative_to_first_packet; + packet->time_relative_to_last_sent_packet.tv_sec = 0; + packet->time_relative_to_last_sent_packet.tv_usec = 0; + first_sent_packet = 0; + } else { + timersub(&packet->time_relative_to_first_packet, &relative_last_sent_packet, + &packet->time_relative_to_last_sent_packet); + relative_last_sent_packet = packet->time_relative_to_first_packet; + } + } else if (packet->action == ACTION_S1C_RECEIVE) { + if (first_received_packet > 0) { + relative_last_received_packet.tv_sec = packet->time_relative_to_first_packet.tv_sec; + relative_last_received_packet.tv_usec = packet->time_relative_to_first_packet.tv_usec; + packet->time_relative_to_last_received_packet.tv_sec = 0; + packet->time_relative_to_last_received_packet.tv_usec = 0; + first_received_packet = 0; + } else { + timersub(&packet->time_relative_to_first_packet, &relative_last_received_packet, + &packet->time_relative_to_last_received_packet); + relative_last_received_packet = packet->time_relative_to_first_packet; + } + } + + } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"frame.number"))) { + xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"value"); + packet->original_frame_number = strtoul((const char *)xml_char, NULL, 0); + xmlFree(xml_char); } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"ip.src"))) { + xml_char = xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1); + ip_str2test_ip(xml_char, &packet->ip_hdr.src); + xmlFree(xml_char); } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"ip.dst"))) { - } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"sctp.chunk_type_str"))) { - xml_char = xmlGetProp(cur_node, (const xmlChar *)"value"); - packet->sctp_hdr.chunk_type = chunk_type_str2cid(xml_char); - fprintf(stdout, "chunk_type_str2cid: %s\n", xml_char); + xml_char = xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1); + ip_str2test_ip(xml_char, &packet->ip_hdr.dst); + xmlFree(xml_char); + } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"proto"))) { + xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"name"); + if (NULL != xml_char) { + if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp"))) { + parse_sctp(doc, cur_node, &packet->sctp_hdr); + } + xmlFree(xml_char); + } } - } + //} } } return packet; @@ -210,11 +1097,12 @@ test_packet_t* parse_xml_packet(xmlNodePtr node) { //------------------------------------------------------------------------------ int play_scenario(test_scenario_t* scenario) { //TODO + display_scenario(scenario); return 0; } //------------------------------------------------------------------------------ test_scenario_t* generate_scenario( - const char const * play_scenario_filename ) + const char * const play_scenario_filename ) { xmlDocPtr doc = NULL; xmlNodePtr root = NULL; @@ -229,6 +1117,7 @@ test_scenario_t* generate_scenario( AssertFatal (0, "Could not parse scenario xml file %s!\n", play_scenario_filename); } else { fprintf(stdout, "Test scenario file to play: %s\n", play_scenario_filename); + //xmlDebugDumpDocument(NULL, doc); } // Get root @@ -242,13 +1131,13 @@ test_scenario_t* generate_scenario( next_packet = &scenario->list_packet; for (node = root->children; node != NULL; node = node->next) { if ((!xmlStrcmp(node->name, (const xmlChar *)"packet"))) { - packet = parse_xml_packet(node); + packet = parse_xml_packet(doc, node); if (NULL != packet) { *next_packet = packet; next_packet = &packet->next; } else { fprintf(stdout, "WARNING omitted packet:\n"); - display_node(node); + display_node(node, 0); } } } @@ -285,7 +1174,7 @@ int generate_xml_scenario( if (getcwd(astring, sizeof(astring)) != NULL) { fprintf(stdout, "working in %s directory\n", astring); } else { - perror("getcwd() error"); + perror("getcwd() ERROR"); exit(1); } @@ -332,22 +1221,22 @@ int generate_xml_scenario( if (NULL != res) { sprintf(play_scenario_filename,"%s",test_scenario_filename); if (strip_extension(play_scenario_filename) > 0) { - strcat(play_scenario_filename, ".tsml"); + strcat((char *)play_scenario_filename, ".tsml"); play_scenario_file = fopen( play_scenario_filename, "w+"); if (NULL != play_scenario_file) { xsltSaveResultToFile(play_scenario_file, res, cur); fclose(play_scenario_file); fprintf(stdout, "Wrote test scenario to %s\n", play_scenario_filename); } else { - fprintf(stderr, "Error in fopen(%s)\n", play_scenario_filename); + fprintf(stderr, "ERROR in fopen(%s)\n", play_scenario_filename); ret = -1; } } else { - fprintf(stderr, "Error in strip_extension()\n"); + fprintf(stderr, "ERROR in strip_extension()\n"); ret = -1; } } else { - fprintf(stderr, "Error in xsltApplyStylesheet()\n"); + fprintf(stderr, "ERROR in xsltApplyStylesheet()\n"); ret = -1; } xsltFreeStylesheet(cur); @@ -466,23 +1355,23 @@ config_parse_opt_line ( exit(1); } if (chdir(*test_dir_name) != 0) { - fprintf(stderr, "Error: chdir %s returned %s\n", *test_dir_name, strerror(errno)); + fprintf(stderr, "ERROR: chdir %s returned %s\n", *test_dir_name, strerror(errno)); exit(1); } if (rv & PLAY_SCENARIO) { if (NULL == *enb_config_file_name) { - fprintf(stderr, "Error: please provide the original eNB config file name that should be in %s\n", *test_dir_name); + fprintf(stderr, "ERROR: please provide the original eNB config file name that should be in %s\n", *test_dir_name); } if (is_file_exists(*enb_config_file_name, "eNB config file") != GS_IS_FILE) { - fprintf(stderr, "Error: original eNB config file name %s is not found in dir %s\n", *enb_config_file_name, *test_dir_name); + fprintf(stderr, "ERROR: original eNB config file name %s is not found in dir %s\n", *enb_config_file_name, *test_dir_name); } enb_properties_p = enb_config_init(*enb_config_file_name); if (NULL == *scenario_file_name) { - fprintf(stderr, "Error: please provide the scenario file name that should be in %s\n", *test_dir_name); + fprintf(stderr, "ERROR: please provide the scenario file name that should be in %s\n", *test_dir_name); } if (is_file_exists(*scenario_file_name, "Scenario file") != GS_IS_FILE) { - fprintf(stderr, "Error: Scenario file name %s is not found in dir %s\n", *scenario_file_name, *test_dir_name); + fprintf(stderr, "ERROR: Scenario file name %s is not found in dir %s\n", *scenario_file_name, *test_dir_name); } } return rv; @@ -503,21 +1392,29 @@ int main( int argc, char **argv ) memset(play_scenario_filename, 0, sizeof(play_scenario_filename)); g_openair_dir = getenv("OPENAIR_DIR"); if (NULL == g_openair_dir) { - fprintf(stderr, "Error: Could not get OPENAIR_DIR environment variable\n"); + fprintf(stderr, "ERROR: Could not get OPENAIR_DIR environment variable\n"); exit(1); } + // logging + logInit(); + set_comp_log(S1AP, LOG_TRACE, LOG_MED,1); + set_comp_log(SCTP, LOG_TRACE, LOG_MED,1); + asn_debug = 1; + asn1_xer_print = 1; + + //parameters actions = config_parse_opt_line (argc, argv, &test_dir_name, &scenario_file_name, &enb_config_file_name); //Command-line options if (actions & PLAY_SCENARIO) { if (generate_xml_scenario(test_dir_name, scenario_file_name,enb_config_file_name, play_scenario_filename) == 0) { if (NULL != (scenario = generate_scenario(play_scenario_filename))) { ret = play_scenario(scenario); } else { - fprintf(stderr, "Error: Could not generate scenario from tsml file\n"); + fprintf(stderr, "ERROR: Could not generate scenario from tsml file\n"); ret = -1; } } else { - fprintf(stderr, "Error: Could not generate tsml scenario from xml file\n"); + fprintf(stderr, "ERROR: Could not generate tsml scenario from xml file\n"); ret = -1; } free_pointer(test_dir_name); diff --git a/openair3/TEST/EPC_TEST/play_scenario.h b/openair3/TEST/EPC_TEST/play_scenario.h index 4916950783..2bf6cc4ccf 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.h +++ b/openair3/TEST/EPC_TEST/play_scenario.h @@ -28,18 +28,22 @@ *******************************************************************************/ /* - generate_scenario.h + play_scenario.h ------------------- AUTHOR : Lionel GAUTHIER COMPANY : EURECOM EMAIL : Lionel.Gauthier@eurecom.fr */ -#ifndef GENERATE_SCENARIO_H_ -#define GENERATE_SCENARIO_H_ -# include -# include -#include +#ifndef PLAY_SCENARIO_H_ +#define PLAY_SCENARIO_H_ +# include +# include +# include +# include + +#include "s1ap_ies_defs.h" + /** @defgroup _enb_app ENB APP * @ingroup _oai2 @@ -83,13 +87,32 @@ typedef enum { SCTP_CID_ASCONF_ACK = 0x80, } sctp_cid_t; /* enum */ +typedef enum { + TEST_S1AP_PDU_TYPE_START = 0, + TEST_S1AP_PDU_TYPE_UNKNOWN = TEST_S1AP_PDU_TYPE_START, + TEST_S1AP_PDU_TYPE_INITIATING, + TEST_S1AP_PDU_TYPE_SUCCESSFUL_OUTCOME, + TEST_S1AP_PDU_TYPE_UNSUCCESSFUL_OUTCOME, + TEST_S1AP_PDU_TYPE_END +} test_s1ap_pdu_type_t; + + +typedef struct test_s1ap_s { + //test_s1ap_pdu_type_t pdu_type; + uint16_t binary_stream_pos; + uint16_t binary_stream_allocated_size; + uint8_t *binary_stream; + s1ap_message message; +} test_s1ap_t; + + // from kernel source file 3.19/include/linux/sctp.h, Big Endians typedef struct sctp_datahdr_s { - uint32_t tsn; - uint16_t stream; - uint16_t ssn; - uint32_t ppid; - uint8_t payload[0]; + uint32_t tsn; + uint16_t stream; + uint16_t ssn; + uint32_t ppid; + test_s1ap_t payload; } sctp_datahdr_t; // from kernel source file 3.19/include/linux/sctp.h, Big Endians @@ -115,15 +138,28 @@ typedef struct test_sctp_hdr_s { } u; } test_sctp_hdr_t; +typedef struct test_ip_s { + unsigned int address_family; // AF_INET, AF_INET6 + union { + struct in6_addr ipv6; + in_addr_t ipv4; + }address; +}test_ip_t; + +typedef struct test_ip_hdr_s { + test_ip_t src; + test_ip_t dst; +} test_ip_hdr_t; + typedef struct test_packet_s { test_action_t action; struct timeval time_relative_to_first_packet; - struct timeval time_relative_to_last_packet; + struct timeval time_relative_to_last_sent_packet; + struct timeval time_relative_to_last_received_packet; + unsigned int original_frame_number; + unsigned int packet_number; + test_ip_hdr_t ip_hdr; test_sctp_hdr_t sctp_hdr; - uint16_t s1ap_byte_stream_count; - uint8_t *s1ap_byte_stream; - xmlNodePtr *s1ap_node; - struct test_packet_s *next; }test_packet_t; From 7c28ae7360e846c035db6f906d5f45d570ca0d62 Mon Sep 17 00:00:00 2001 From: gauthier Date: Fri, 13 Nov 2015 16:54:17 +0100 Subject: [PATCH 09/47] Still ASN1 display bug --- openair3/TEST/EPC_TEST/play_scenario.c | 144 +++++++++++++++---------- 1 file changed, 86 insertions(+), 58 deletions(-) diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c index a32947c439..982c1ffb40 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.c +++ b/openair3/TEST/EPC_TEST/play_scenario.c @@ -60,6 +60,7 @@ #include #include +#include "intertask_interface_init.h" #include "assertions.h" #include "play_scenario.h" //#include "s1ap_eNB.h" @@ -470,7 +471,7 @@ int hex2data(unsigned char * const data, const unsigned char * const hexstring, char buf[5] = {'0', 'x', pos[0], pos[1], 0}; data[count] = strtol(buf, &endptr, 16); pos += 2 * sizeof(char); - AssertFatal (endptr[0] == '\0', "ERROR %s() non-hexadecimal character encountered buf %p endptr %p buf %s count %d pos %p\n", __FUNCTION__, buf, endptr, buf, count, pos); + AssertFatal (endptr[0] == '\0', "ERROR %s() non-hexadecimal character encountered buf %p endptr %p buf %s count %zu pos %p\n", __FUNCTION__, buf, endptr, buf, count, pos); AssertFatal (endptr != buf, "ERROR %s() No digits were found\n", __FUNCTION__); } return 0; @@ -553,10 +554,13 @@ void ip_str2test_ip(const xmlChar * const ip_str, test_ip_t * const ip) int test_s1ap_decode_initiating_message(s1ap_message *message, S1ap_InitiatingMessage_t *initiating_p) { + char *message_string = NULL; int ret = -1; DevAssert(initiating_p != NULL); + message_string = calloc(20000, sizeof(char)); + AssertFatal (NULL != message_string, "ERROR malloc()failed!\n"); message->procedureCode = initiating_p->procedureCode; message->criticality = initiating_p->criticality; @@ -565,58 +569,65 @@ int test_s1ap_decode_initiating_message(s1ap_message *message, ret = s1ap_decode_s1ap_downlinknastransporties( &message->msg.s1ap_DownlinkNASTransportIEs, &initiating_p->value); + s1ap_xer_print_s1ap_downlinknastransport(s1ap_xer__print2sp, message_string, message); break; case S1ap_ProcedureCode_id_InitialContextSetup: ret = s1ap_decode_s1ap_initialcontextsetuprequesties( &message->msg.s1ap_InitialContextSetupRequestIEs, &initiating_p->value); + s1ap_xer_print_s1ap_initialcontextsetuprequest(s1ap_xer__print2sp, message_string, message); break; case S1ap_ProcedureCode_id_UEContextRelease: ret = s1ap_decode_s1ap_uecontextreleasecommandies( &message->msg.s1ap_UEContextReleaseCommandIEs, &initiating_p->value); + s1ap_xer_print_s1ap_uecontextreleasecommand(s1ap_xer__print2sp, message_string, message); break; case S1ap_ProcedureCode_id_Paging: ret = s1ap_decode_s1ap_pagingies( &message->msg.s1ap_PagingIEs, &initiating_p->value); + s1ap_xer_print_s1ap_paging(s1ap_xer__print2sp, message_string, message); break; - case S1ap_ProcedureCode_id_uplinkNASTransport: { - ret = s1ap_decode_s1ap_uplinknastransporties (&message->msg.s1ap_UplinkNASTransportIEs, &initiating_p->value); - } + case S1ap_ProcedureCode_id_uplinkNASTransport: + ret = s1ap_decode_s1ap_uplinknastransporties (&message->msg.s1ap_UplinkNASTransportIEs, &initiating_p->value); + s1ap_xer_print_s1ap_uplinknastransport(s1ap_xer__print2sp, message_string, message); break; - case S1ap_ProcedureCode_id_S1Setup: { - ret = s1ap_decode_s1ap_s1setuprequesties (&message->msg.s1ap_S1SetupRequestIEs, &initiating_p->value); - } + case S1ap_ProcedureCode_id_S1Setup: + ret = s1ap_decode_s1ap_s1setuprequesties (&message->msg.s1ap_S1SetupRequestIEs, &initiating_p->value); + s1ap_xer_print_s1ap_s1setuprequest(s1ap_xer__print2sp, message_string, message); break; - case S1ap_ProcedureCode_id_initialUEMessage: { - ret = s1ap_decode_s1ap_initialuemessageies (&message->msg.s1ap_InitialUEMessageIEs, &initiating_p->value); - } + case S1ap_ProcedureCode_id_initialUEMessage: + ret = s1ap_decode_s1ap_initialuemessageies (&message->msg.s1ap_InitialUEMessageIEs, &initiating_p->value); + s1ap_xer_print_s1ap_initialuemessage(s1ap_xer__print2sp, message_string, message); break; - case S1ap_ProcedureCode_id_UEContextReleaseRequest: { - ret = s1ap_decode_s1ap_uecontextreleaserequesties (&message->msg.s1ap_UEContextReleaseRequestIEs, &initiating_p->value); - } + case S1ap_ProcedureCode_id_UEContextReleaseRequest: + ret = s1ap_decode_s1ap_uecontextreleaserequesties (&message->msg.s1ap_UEContextReleaseRequestIEs, &initiating_p->value); + s1ap_xer_print_s1ap_uecontextreleaserequest(s1ap_xer__print2sp, message_string, message); break; - case S1ap_ProcedureCode_id_UECapabilityInfoIndication: { - ret = s1ap_decode_s1ap_uecapabilityinfoindicationies (&message->msg.s1ap_UECapabilityInfoIndicationIEs, &initiating_p->value); - } + case S1ap_ProcedureCode_id_UECapabilityInfoIndication: + ret = s1ap_decode_s1ap_uecapabilityinfoindicationies (&message->msg.s1ap_UECapabilityInfoIndicationIEs, &initiating_p->value); + //s1ap_xer_print_s1ap_uecapabilityinfoindication(s1ap_xer__print2sp, message_string, message); break; - case S1ap_ProcedureCode_id_NASNonDeliveryIndication: { - ret = s1ap_decode_s1ap_nasnondeliveryindication_ies (&message->msg.s1ap_NASNonDeliveryIndication_IEs, &initiating_p->value); - } + case S1ap_ProcedureCode_id_NASNonDeliveryIndication: + ret = s1ap_decode_s1ap_nasnondeliveryindication_ies (&message->msg.s1ap_NASNonDeliveryIndication_IEs, &initiating_p->value); + s1ap_xer_print_s1ap_nasnondeliveryindication_(s1ap_xer__print2sp, message_string, message); break; default: + free(message_string); AssertFatal( 0 , "Unknown procedure ID (%d) for initiating message\n", (int)initiating_p->procedureCode); return -1; } + fprintf(stdout, "s1ap_xer_print:\n%s\n", message_string); + free(message_string); return ret; } @@ -624,9 +635,12 @@ int test_s1ap_decode_initiating_message(s1ap_message *message, int test_s1ap_decode_successful_outcome(s1ap_message *message, S1ap_SuccessfulOutcome_t *successfullOutcome_p) { - int ret = -1; + char *message_string = NULL; + int ret = -1; DevAssert(successfullOutcome_p != NULL); + message_string = calloc(20000, sizeof(char)); + AssertFatal (NULL != message_string, "ERROR malloc()failed!\n"); message->procedureCode = successfullOutcome_p->procedureCode; message->criticality = successfullOutcome_p->criticality; @@ -635,23 +649,27 @@ int test_s1ap_decode_successful_outcome(s1ap_message *message, case S1ap_ProcedureCode_id_S1Setup: ret = s1ap_decode_s1ap_s1setupresponseies( &message->msg.s1ap_S1SetupResponseIEs, &successfullOutcome_p->value); + s1ap_xer_print_s1ap_s1setupresponse(s1ap_xer__print2sp, message_string, message); break; - case S1ap_ProcedureCode_id_InitialContextSetup: { - ret = s1ap_decode_s1ap_initialcontextsetupresponseies (&message->msg.s1ap_InitialContextSetupResponseIEs, &successfullOutcome_p->value); - } + case S1ap_ProcedureCode_id_InitialContextSetup: + ret = s1ap_decode_s1ap_initialcontextsetupresponseies (&message->msg.s1ap_InitialContextSetupResponseIEs, &successfullOutcome_p->value); + s1ap_xer_print_s1ap_initialcontextsetupresponse(s1ap_xer__print2sp, message_string, message); break; - case S1ap_ProcedureCode_id_UEContextRelease: { + case S1ap_ProcedureCode_id_UEContextRelease: ret = s1ap_decode_s1ap_uecontextreleasecompleteies (&message->msg.s1ap_UEContextReleaseCompleteIEs, &successfullOutcome_p->value); - } + s1ap_xer_print_s1ap_uecontextreleasecomplete(s1ap_xer__print2sp, message_string, message); break; default: + free(message_string); AssertFatal(0, "Unknown procedure ID (%d) for successfull outcome message\n", (int)successfullOutcome_p->procedureCode); return -1; } + fprintf(stdout, "s1ap_xer_print:\n%s\n", message_string); + free(message_string); return ret; } @@ -659,29 +677,37 @@ int test_s1ap_decode_successful_outcome(s1ap_message *message, int test_s1ap_decode_unsuccessful_outcome(s1ap_message *message, S1ap_UnsuccessfulOutcome_t *unSuccessfullOutcome_p) { + char *message_string = NULL; int ret = -1; + DevAssert(unSuccessfullOutcome_p != NULL); + message_string = calloc(20000, sizeof(char)); + AssertFatal (NULL != message_string, "ERROR malloc()failed!\n"); message->procedureCode = unSuccessfullOutcome_p->procedureCode; message->criticality = unSuccessfullOutcome_p->criticality; switch(unSuccessfullOutcome_p->procedureCode) { case S1ap_ProcedureCode_id_S1Setup: - return s1ap_decode_s1ap_s1setupfailureies( + ret = s1ap_decode_s1ap_s1setupfailureies( &message->msg.s1ap_S1SetupFailureIEs, &unSuccessfullOutcome_p->value); + s1ap_xer_print_s1ap_s1setupfailure(s1ap_xer__print2sp, message_string, message); + break; - case S1ap_ProcedureCode_id_InitialContextSetup: { - ret = s1ap_decode_s1ap_initialcontextsetupfailureies (&message->msg.s1ap_InitialContextSetupFailureIEs, &unSuccessfullOutcome_p->value); - } + case S1ap_ProcedureCode_id_InitialContextSetup: + ret = s1ap_decode_s1ap_initialcontextsetupfailureies (&message->msg.s1ap_InitialContextSetupFailureIEs, &unSuccessfullOutcome_p->value); + s1ap_xer_print_s1ap_initialcontextsetupfailure(s1ap_xer__print2sp, message_string, message); break; default: + free(message_string); AssertFatal(0,"Unknown procedure ID (%d) for unsuccessfull outcome message\n", (int)unSuccessfullOutcome_p->procedureCode); break; } - + fprintf(stdout, "s1ap_xer_print:\n%s\n", message_string); + free(message_string); return ret; } @@ -758,34 +784,35 @@ void parse_s1ap(xmlDocPtr doc, const xmlNode const *s1ap_node, test_s1ap_t * con xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"hide"); if (NULL != xml_char) { if ((!xmlStrcmp(xml_char, (const xmlChar *)"yes"))) { - xmlFree(xml_char); - return; + go_deeper_in_tree = 0; } xmlFree(xml_char); } - // first get size - xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"size"); - if (NULL != xml_char) { - size = strtoul((const char *)xml_char, NULL, 0); - xmlFree(xml_char); - // second: try to get value (always hex) - xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"value"); + if (0 < go_deeper_in_tree) { + // first get size + xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"size"); if (NULL != xml_char) { - xml_char2 = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"name"); - fprintf(stdout, "s1ap %p field %s size %d value %s\n",s1ap, xml_char2, size, xml_char); - xmlFree(xml_char2); - // if success to get value, do not parse children - //AssertFatal ((xmlStrlen(xml_char) == size), "ERROR %s() mismatch in size %d and strlen %d\n", __FUNCTION__, size, xmlStrlen(xml_char)); - //if (xmlStrlen(xml_char) == size) { - AssertFatal ((s1ap->binary_stream_pos+xmlStrlen(xml_char)/2) <= s1ap->binary_stream_allocated_size, - "ERROR %s() in buffer size: binary_stream_pos %d xmlStrlen(xml_char)/2=%d\n", __FUNCTION__, s1ap->binary_stream_pos, xmlStrlen(xml_char)/2); - rc = hex2data( &s1ap->binary_stream[s1ap->binary_stream_pos], xml_char, xmlStrlen(xml_char)); - s1ap->binary_stream_pos += xmlStrlen(xml_char)/2; - display_node(cur_node, 0); - AssertFatal (rc >= 0, "ERROR %s() in converting hex string %s len %d size %d rc %d\n", __FUNCTION__, xml_char, xmlStrlen(xml_char), size, rc); - go_deeper_in_tree = 0; - //} + size = strtoul((const char *)xml_char, NULL, 0); xmlFree(xml_char); + // second: try to get value (always hex) + xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"value"); + if (NULL != xml_char) { + xml_char2 = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"name"); + fprintf(stdout, "s1ap %p field %s size %d value %s\n",s1ap, xml_char2, size, xml_char); + xmlFree(xml_char2); + // if success to get value, do not parse children + //AssertFatal ((xmlStrlen(xml_char) == size), "ERROR %s() mismatch in size %d and strlen %d\n", __FUNCTION__, size, xmlStrlen(xml_char)); + //if (xmlStrlen(xml_char) == size) { + AssertFatal ((s1ap->binary_stream_pos+xmlStrlen(xml_char)/2) <= s1ap->binary_stream_allocated_size, + "ERROR %s() in buffer size: binary_stream_pos %d xmlStrlen(xml_char)/2=%d\n", __FUNCTION__, s1ap->binary_stream_pos, xmlStrlen(xml_char)/2); + rc = hex2data( &s1ap->binary_stream[s1ap->binary_stream_pos], xml_char, xmlStrlen(xml_char)); + s1ap->binary_stream_pos += xmlStrlen(xml_char)/2; + display_node(cur_node, 0); + AssertFatal (rc >= 0, "ERROR %s() in converting hex string %s len %d size %d rc %d\n", __FUNCTION__, xml_char, xmlStrlen(xml_char), size, rc); + go_deeper_in_tree = 0; + //} + xmlFree(xml_char); + } } } } @@ -1166,7 +1193,6 @@ int generate_xml_scenario( int nb_params = 0; int i,j; char astring[1024]; - char *astring2 = NULL; struct in_addr addr; int ret = 0; @@ -1219,8 +1245,8 @@ int generate_xml_scenario( params[nb_params] = NULL; res = xsltApplyStylesheet(cur, doc, params); if (NULL != res) { - sprintf(play_scenario_filename,"%s",test_scenario_filename); - if (strip_extension(play_scenario_filename) > 0) { + sprintf((char *)play_scenario_filename,"%s",test_scenario_filename); + if (strip_extension((char *)play_scenario_filename) > 0) { strcat((char *)play_scenario_filename, ".tsml"); play_scenario_file = fopen( play_scenario_filename, "w+"); if (NULL != play_scenario_file) { @@ -1398,8 +1424,10 @@ int main( int argc, char **argv ) // logging logInit(); - set_comp_log(S1AP, LOG_TRACE, LOG_MED,1); - set_comp_log(SCTP, LOG_TRACE, LOG_MED,1); + itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, NULL); + + set_comp_log(S1AP, LOG_TRACE, LOG_MED, 1); + set_comp_log(SCTP, LOG_TRACE, LOG_MED, 1); asn_debug = 1; asn1_xer_print = 1; From d27641a443113d3af55e05df7f433b54fd0a6bc5 Mon Sep 17 00:00:00 2001 From: gauthier Date: Tue, 17 Nov 2015 16:56:24 +0100 Subject: [PATCH 10/47] Begin to begin sending packets (many things to do hash assoc id, mme_ue_id, nas security, etc) --- cmake_targets/CMakeLists.txt | 30 +- cmake_targets/epc_test/CMakeLists.template | 4 +- cmake_targets/tools/build_test_epc_tools | 2 +- openair3/S1AP/s1ap_eNB.c | 7 +- openair3/TEST/EPC_TEST/play_scenario.c | 1215 +++-------------- openair3/TEST/EPC_TEST/play_scenario.h | 215 ++- openair3/TEST/EPC_TEST/play_scenario_decode.c | 214 +++ .../TEST/EPC_TEST/play_scenario_display.c | 292 ++++ openair3/TEST/EPC_TEST/play_scenario_fsm.c | 127 ++ openair3/TEST/EPC_TEST/play_scenario_parse.c | 561 ++++++++ openair3/TEST/EPC_TEST/play_scenario_s1ap.c | 162 +++ openair3/TEST/EPC_TEST/play_scenario_sctp.c | 45 + openair3/UTILS/conversions.h | 1 - 13 files changed, 1814 insertions(+), 1061 deletions(-) create mode 100644 openair3/TEST/EPC_TEST/play_scenario_decode.c create mode 100644 openair3/TEST/EPC_TEST/play_scenario_display.c create mode 100644 openair3/TEST/EPC_TEST/play_scenario_fsm.c create mode 100644 openair3/TEST/EPC_TEST/play_scenario_parse.c create mode 100644 openair3/TEST/EPC_TEST/play_scenario_s1ap.c create mode 100644 openair3/TEST/EPC_TEST/play_scenario_sctp.c diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 5fb722ee9d..148aae2419 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -216,18 +216,20 @@ add_definitions("-DPACKAGE_BUGREPORT=\"openair4g-devel@lists.eurecom.fr\"") # Debug related options ######################################### -add_boolean_option(MSG_PRINT False "print debug messages") -add_boolean_option(DISABLE_XER_PRINT False "print XER Format") -add_boolean_option(XER_PRINT False "print XER Format") -add_boolean_option(RRC_MSG_PRINT False "print RRC messages") -add_boolean_option(PDCP_MSG_PRINT False "print PDCP messages to /tmp/pdcp.log") -add_boolean_option(DEBUG_PDCP_PAYLOAD False "print PDCP PDU to stdout") # if true, make sure that global and PDCP log levels are trace +add_boolean_option(ASN_DEBUG False "ASN1 coder/decoder Debug") +add_boolean_option(EMIT_ASN_DEBUG False "ASN1 coder/decoder Debug") +add_boolean_option(MSG_PRINT False "print debug messages") +add_boolean_option(DISABLE_XER_PRINT False "print XER Format") +add_boolean_option(XER_PRINT False "print XER Format") +add_boolean_option(RRC_MSG_PRINT False "print RRC messages") +add_boolean_option(PDCP_MSG_PRINT False "print PDCP messages to /tmp/pdcp.log") +add_boolean_option(DEBUG_PDCP_PAYLOAD False "print PDCP PDU to stdout") # if true, make sure that global and PDCP log levels are trace add_boolean_option(DEBUG_MAC_INTERFACE False "print MAC-RLC PDU exchange to stdout") # if true, make sure that global and PDCP log levels are trace -add_boolean_option(TRACE_RLC_PAYLOAD False "print RLC PDU to stdout") # if true, make sure that global and PDCP log levels are trace -add_boolean_option(TEST_OMG False "???") -add_boolean_option(DEBUG_OMG False "???") -add_boolean_option(XFORMS False "This adds the possibility to see the signal oscilloscope") -add_boolean_option(PRINT_STATS False "This adds the possibility to see the status") +add_boolean_option(TRACE_RLC_PAYLOAD False "print RLC PDU to stdout") # if true, make sure that global and PDCP log levels are trace +add_boolean_option(TEST_OMG False "???") +add_boolean_option(DEBUG_OMG False "???") +add_boolean_option(XFORMS False "This adds the possibility to see the signal oscilloscope") +add_boolean_option(PRINT_STATS False "This adds the possibility to see the status") add_boolean_option(DEBUG_CONSOLE False "makes debugging easier, disables stdout/stderr buffering") @@ -1660,6 +1662,12 @@ target_link_libraries (test_epc_generate_scenario add_executable(test_epc_play_scenario ${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario.c + ${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario_decode.c + ${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario_display.c + ${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario_fsm.c + ${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario_parse.c + ${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario_s1ap.c + ${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario_sctp.c ${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario.h ${OPENAIR2_DIR}/ENB_APP/enb_config.h ${OPENAIR2_DIR}/COMMON/commonDef.h diff --git a/cmake_targets/epc_test/CMakeLists.template b/cmake_targets/epc_test/CMakeLists.template index 5789c3eb5c..8a8223e4ae 100644 --- a/cmake_targets/epc_test/CMakeLists.template +++ b/cmake_targets/epc_test/CMakeLists.template @@ -7,7 +7,7 @@ set ( DEBUG_OMG False ) set ( DISABLE_XER_PRINT False ) set ( DRIVER2013 True ) set ( EMOS False ) -set ( EMIT_ASN_DEBUG True ) +set ( EMIT_ASN_DEBUG False ) set ( ENABLE_FXP True ) set ( ENABLE_ITTI True ) set ( ENABLE_NAS_UE_LOGGING True ) @@ -76,4 +76,4 @@ set ( SMBV False ) set ( TEST_OMG False ) set ( USE_MME "R10" ) set ( USER_MODE True ) -set ( XER_PRINT False ) +set ( XER_PRINT True ) diff --git a/cmake_targets/tools/build_test_epc_tools b/cmake_targets/tools/build_test_epc_tools index 10dc4fd256..db49fa017b 100755 --- a/cmake_targets/tools/build_test_epc_tools +++ b/cmake_targets/tools/build_test_epc_tools @@ -22,7 +22,7 @@ # Contact Information # OpenAirInterface Admin: openair_admin@eurecom.fr # OpenAirInterface Tech : openair_tech@eurecom.fr -# OpenAirInterface Dev : openair4g-devel@eurecom.fr +# OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr # # Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE # diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index c880c3f3b4..1b683d4aa3 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -72,9 +72,9 @@ s1ap_eNB_config_t s1ap_config; static int s1ap_eNB_generate_s1_setup_request( s1ap_eNB_instance_t *instance_p, s1ap_eNB_mme_data_t *s1ap_mme_data_p); -static + void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *s1ap_register_eNB); -static + void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp); uint32_t s1ap_generate_eNB_id(void) @@ -150,7 +150,7 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p); } -static + void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *s1ap_register_eNB) { s1ap_eNB_instance_t *new_instance; @@ -210,7 +210,6 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * } } -static void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) { s1ap_eNB_instance_t *instance_p; diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c index 982c1ffb40..fda38dbcb8 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.c +++ b/openair3/TEST/EPC_TEST/play_scenario.c @@ -48,132 +48,27 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include + #include "intertask_interface_init.h" +#include "timer.h" #include "assertions.h" -#include "play_scenario.h" -//#include "s1ap_eNB.h" #include "s1ap_common.h" -#include "s1ap_ies_defs.h" -#include "s1ap_eNB_decoder.h" #include "intertask_interface.h" -#include "enb_config.h" +#include "play_scenario.h" +#include "sctp_eNB_task.h" #include "log.h" //------------------------------------------------------------------------------ -#define ENB_CONFIG_MAX_XSLT_PARAMS 32 #define PLAY_SCENARIO 1 #define GS_IS_FILE 1 #define GS_IS_DIR 2 //------------------------------------------------------------------------------ char *g_openair_dir = NULL; //------------------------------------------------------------------------------ -extern Enb_properties_array_t enb_properties; extern int xmlLoadExtDtdDefaultValue; extern int asn_debug; extern int asn1_xer_print; -//------------------------------------------------------------------------------ -void test_print_hex_octets(const unsigned char * const byte_stream, const unsigned long int num); -int is_file_exists ( const char const * file_nameP, const char const *file_roleP); -int strip_extension( char *in_filename); -int split_path ( char * pathP, char *** resP); -void display_node ( xmlNodePtr node, unsigned int indent); -void display_tree ( xmlNodePtr node, unsigned int indent); -//------------------------- -void free_packet(test_packet_t* packet); -void free_scenario(test_scenario_t* scenario); -//------------------------- -void display_packet_sctp_init(const sctp_inithdr_t * const sctp); -void display_packet_sctp_initack(const sctp_initackhdr_t * const sctp); -void display_packet_sctp_data(const sctp_datahdr_t * const sctp); -void display_packet_sctp(const test_sctp_hdr_t * const sctp); -void display_packet_ip(const test_ip_hdr_t * const ip); -void display_packet(const test_packet_t * const packet); -void display_scenario(const test_scenario_t * const scenario); -//------------------------- -char * test_ip2ip_str(const test_ip_t * const ip); -int hex2data(unsigned char * const data, const unsigned char * const hexstring, const unsigned int len); -sctp_cid_t chunk_type_str2cid(const xmlChar * const chunk_type_str); -const char * const chunk_type_cid2str(const sctp_cid_t chunk_type); -test_action_t action_str2test_action_t(const xmlChar * const action); -void ip_str2test_ip(const xmlChar * const ip_str, test_ip_t * const ip); -//------------------------- -int test_s1ap_decode_initiating_message(s1ap_message *message, S1ap_InitiatingMessage_t *initiating_p); -int test_s1ap_decode_successful_outcome(s1ap_message *message, S1ap_SuccessfulOutcome_t *successfullOutcome_p); -int test_s1ap_decode_unsuccessful_outcome(s1ap_message *message, S1ap_UnsuccessfulOutcome_t *unSuccessfullOutcome_p); -int test_s1ap_decode_pdu(s1ap_message *message, const uint8_t * const buffer,const uint32_t length); -void test_decode_s1ap(test_s1ap_t * const s1ap); -//------------------------- -void parse_s1ap(xmlDocPtr doc, const xmlNode const *s1ap_node, test_s1ap_t * const s1ap); -void parse_sctp_data_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_datahdr_t * const sctp_hdr); -void parse_sctp_init_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_inithdr_t * const sctp_hdr); -void parse_sctp_init_ack_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_initackhdr_t * const sctp_hdr); -void parse_sctp(xmlDocPtr doc, const xmlNode const *sctp_node, test_sctp_hdr_t * const sctp_hdr); -test_packet_t* parse_xml_packet(xmlDocPtr doc, xmlNodePtr node); -//------------------------- -int play_scenario(test_scenario_t* scenario); -int generate_xml_scenario( - const char const * test_dir_name, - const char const * test_scenario_filename, - const char const * enb_config_filename, - char const * play_scenario_filename /* OUT PARAM*/); -//----------------------------------------------------------------------------- -void test_print_hex_octets(const unsigned char * const byte_stream, const unsigned long int num) -//----------------------------------------------------------------------------- -{ - unsigned long octet_index = 0; - - if (byte_stream == NULL) { - return; - } - - - - - fprintf(stdout, "+-----+-------------------------------------------------+\n"); - fprintf(stdout, "| | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n"); - fprintf(stdout, "+-----+-------------------------------------------------+\n"); - - for (octet_index = 0; octet_index < num; octet_index++) { - if ((octet_index % 16) == 0) { - if (octet_index != 0) { - fprintf(stdout, " |\n"); - } - - fprintf(stdout, " %04ld |", octet_index); - } - - /* - * Print every single octet in hexadecimal form - */ - fprintf(stdout, " %02x", byte_stream[octet_index]); - /* - * Align newline and pipes according to the octets in groups of 2 - */ - } - - /* - * Append enough spaces and put final pipe - */ - unsigned char index; - - for (index = octet_index; index < 16; ++index) { - fprintf(stdout, " "); - } - - fprintf(stdout, " |\n"); -} //------------------------------------------------------------------------------ // test if file exist in current directory @@ -202,7 +97,7 @@ int is_file_exists( const char const * file_nameP, const char const *file_roleP) //------------------------------------------------------------------------------ -int strip_extension(char *in_filename) +int et_strip_extension(char *in_filename) { static const uint8_t name_min_len = 1; static const uint8_t max_ext_len = 5; // .pdml ! @@ -237,193 +132,38 @@ int split_path( char * pathP, char *** resP) return n_spaces; } //------------------------------------------------------------------------------ -void display_node(xmlNodePtr node, unsigned int indent) -{ - int i = 0; - if (node->type == XML_ELEMENT_NODE) { - xmlChar *path = xmlGetNodePath(node); - for (i=0; ichildren != NULL && node->children->type == XML_TEXT_NODE) { - xmlChar *content = xmlNodeGetContent(node); - printf("%s -> %s\n", path, content); - xmlFree(content); - } else { - printf("%s\n", path); - } - xmlFree(path); - } -} -/** - * print_element_names: - * @node: the initial xml node to consider. - * @indent: indentation level. - * - * Prints the names of the all the xml elements - * that are siblings or children of a given xml node. - */ -//------------------------------------------------------------------------------ -void display_tree(xmlNodePtr node, unsigned int indent) -{ - xmlNode *cur_node = NULL; - - for (cur_node = node; cur_node; cur_node = cur_node->next) { - if (cur_node->type == XML_ELEMENT_NODE) { - display_node(cur_node, indent); - } - display_tree(cur_node->children, indent++); - } -} -//------------------------------------------------------------------------------ -void free_packet(test_packet_t* packet) +void et_free_packet(et_packet_t* packet) { if (packet) { switch (packet->sctp_hdr.chunk_type) { case SCTP_CID_DATA: - free_pointer(packet->sctp_hdr.u.data_hdr.payload.binary_stream); + et_free_pointer(packet->sctp_hdr.u.data_hdr.payload.binary_stream); break; default: ; } - free_pointer(packet); + et_free_pointer(packet); } } //------------------------------------------------------------------------------ -void free_scenario(test_scenario_t* scenario) +void et_free_scenario(et_scenario_t* scenario) { - test_packet_t *packet = NULL; - test_packet_t *next_packet = NULL; + et_packet_t *packet = NULL; + et_packet_t *next_packet = NULL; if (scenario) { packet = scenario->list_packet; while (packet) { next_packet = packet->next; - free_packet(packet); + et_free_packet(packet); packet = next_packet->next; } - free_pointer(scenario); - } -} - - -//------------------------------------------------------------------------------ -void display_packet_sctp_init(const sctp_inithdr_t * const sctp) -{ - - if (sctp) { - fprintf(stdout, "\t\tSCTP.init.init_tag : %u\n", sctp->init_tag); - fprintf(stdout, "\t\tSCTP.init.a_rwnd : %u\n", sctp->a_rwnd); - fprintf(stdout, "\t\tSCTP.init.num_inbound_streams : %u\n", sctp->num_inbound_streams); - fprintf(stdout, "\t\tSCTP.init.num_outbound_streams : %u\n", sctp->num_outbound_streams); - fprintf(stdout, "\t\tSCTP.init.initial_tsn : %u\n", sctp->initial_tsn); - } -} -//------------------------------------------------------------------------------ -void display_packet_sctp_initack(const sctp_initackhdr_t * const sctp) -{ - - if (sctp) { - fprintf(stdout, "\t\tSCTP.initack.init_tag : %u\n", sctp->init_tag); - fprintf(stdout, "\t\tSCTP.initack.a_rwnd : %u\n", sctp->a_rwnd); - fprintf(stdout, "\t\tSCTP.initack.num_inbound_streams : %u\n", sctp->num_inbound_streams); - fprintf(stdout, "\t\tSCTP.initack.num_outbound_streams : %u\n", sctp->num_outbound_streams); - fprintf(stdout, "\t\tSCTP.initack.initial_tsn : %u\n", sctp->initial_tsn); - } -} -//------------------------------------------------------------------------------ -void display_packet_sctp_data(const sctp_datahdr_t * const sctp) -{ - if (sctp) { - fprintf(stdout, "\t\tSCTP.data.tsn : %u\n", sctp->tsn); - fprintf(stdout, "\t\tSCTP.data.stream : %u\n", sctp->stream); - fprintf(stdout, "\t\tSCTP.data.ssn : %u\n", sctp->ssn); - fprintf(stdout, "\t\tSCTP.data.ppid : %u\n", sctp->ppid); - //fprintf(stdout, "\t\tSCTP.data.pdu_type : %u\n", sctp->payload.pdu_type); - //fprintf(stdout, "\t\tSCTP.data.procedure_code : %u\n", sctp->payload.procedure_code); - fprintf(stdout, "\t\tSCTP.data.binary_stream_allocated_size : %u\n", sctp->payload.binary_stream_allocated_size); - if (NULL != sctp->payload.binary_stream) { - fprintf(stdout, "\t\tSCTP.data.binary_stream :\n"); - test_print_hex_octets(sctp->payload.binary_stream, sctp->payload.binary_stream_allocated_size); - } else { - fprintf(stdout, "\t\tSCTP.data.binary_stream : NULL\n"); - } + et_free_pointer(scenario); } } //------------------------------------------------------------------------------ -void display_packet_sctp(const test_sctp_hdr_t * const sctp) -{ - if (sctp) { - fprintf(stdout, "\t\tSCTP.src_port : %u\n", sctp->src_port); - fprintf(stdout, "\t\tSCTP.dst_port : %u\n", sctp->dst_port); - fprintf(stdout, "\t\tSCTP.chunk_type : %s\n", chunk_type_cid2str(sctp->chunk_type)); - switch (sctp->chunk_type) { - case SCTP_CID_DATA: - display_packet_sctp_data(&sctp->u.data_hdr); - break; - case SCTP_CID_INIT: - display_packet_sctp_initack(&sctp->u.init_hdr); - break; - case SCTP_CID_INIT_ACK: - display_packet_sctp_initack(&sctp->u.init_ack_hdr); - break; - default: - ; - } - } -} -//------------------------------------------------------------------------------ -void display_packet_ip(const test_ip_hdr_t * const ip) -{ - if (ip) { - fprintf(stdout, "\t\tSource address : %s\n", test_ip2ip_str(&ip->src)); - fprintf(stdout, "\t\tDestination address : %s\n", test_ip2ip_str(&ip->dst)); - } -} - -//------------------------------------------------------------------------------ -void display_packet(const test_packet_t * const packet) -{ - if (packet) { - fprintf(stdout, "\tPacket:\tnum %u | original frame number %u \n", packet->packet_number, packet->original_frame_number); - fprintf(stdout, "\tPacket:\ttime relative to 1st packet %ld.%06lu\n", - packet->time_relative_to_first_packet.tv_sec, packet->time_relative_to_first_packet.tv_usec); - fprintf(stdout, "\tPacket:\ttime relative to last tx packet %ld.%06lu\n", - packet->time_relative_to_last_sent_packet.tv_sec, packet->time_relative_to_last_sent_packet.tv_usec); - fprintf(stdout, "\tPacket:\ttime relative to last_received packet %ld.%06lu\n", - packet->time_relative_to_last_received_packet.tv_sec, packet->time_relative_to_last_received_packet.tv_usec); - - switch(packet->action) { - case ACTION_S1C_SEND: - fprintf(stdout, "\tPacket:\tAction SEND\n"); - break; - case ACTION_S1C_RECEIVE: - fprintf(stdout, "\tPacket:\tAction RECEIVE\n"); - break; - default: - fprintf(stdout, "\tPacket:\tAction UNKNOWN\n"); - } - display_packet_ip(&packet->ip_hdr); - display_packet_sctp(&packet->sctp_hdr); - } -} -//------------------------------------------------------------------------------ -void display_scenario(const test_scenario_t * const scenario) -{ - test_packet_t *packet = NULL; - if (scenario) { - fprintf(stdout, "Scenario: %s\n", (scenario->name != NULL) ? (char*)scenario->name:"UNKNOWN NAME"); - packet = scenario->list_packet; - while (packet) { - display_packet(packet); - packet = packet->next; - } - } -} - -//------------------------------------------------------------------------------ -char * test_ip2ip_str(const test_ip_t * const ip) +char * et_ip2ip_str(const et_ip_t * const ip) { static char str[INET6_ADDRSTRLEN]; @@ -445,7 +185,7 @@ char * test_ip2ip_str(const test_ip_t * const ip) //returns 0 on success, negative on error //data is a buffer of at least len bytes //hexstring is upper or lower case hexadecimal, NOT prepended with "0x" -int hex2data(unsigned char * const data, const unsigned char * const hexstring, const unsigned int len) +int et_hex2data(unsigned char * const data, const unsigned char * const hexstring, const unsigned int len) { unsigned const char *pos = hexstring; char *endptr = NULL; @@ -477,7 +217,7 @@ int hex2data(unsigned char * const data, const unsigned char * const hexstring, return 0; } //------------------------------------------------------------------------------ -sctp_cid_t chunk_type_str2cid(const xmlChar * const chunk_type_str) +sctp_cid_t et_chunk_type_str2cid(const xmlChar * const chunk_type_str) { if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"DATA"))) { return SCTP_CID_DATA;} if ((!xmlStrcmp(chunk_type_str, (const xmlChar *)"INIT"))) { return SCTP_CID_INIT;} @@ -501,7 +241,7 @@ sctp_cid_t chunk_type_str2cid(const xmlChar * const chunk_type_str) AssertFatal (0, "ERROR: %s() cannot convert: %s\n", __FUNCTION__, chunk_type_str); } //------------------------------------------------------------------------------ -const char * const chunk_type_cid2str(const sctp_cid_t chunk_type) +const char * const et_chunk_type_cid2str(const sctp_cid_t chunk_type) { switch (chunk_type) { case SCTP_CID_DATA: return "DATA"; break; @@ -528,15 +268,15 @@ const char * const chunk_type_cid2str(const sctp_cid_t chunk_type) } } //------------------------------------------------------------------------------ -test_action_t action_str2test_action_t(const xmlChar * const action) +et_packet_action_t et_action_str2et_action_t(const xmlChar * const action) { - if ((!xmlStrcmp(action, (const xmlChar *)"SEND"))) { return ACTION_S1C_SEND;} - if ((!xmlStrcmp(action, (const xmlChar *)"RECEIVE"))) { return ACTION_S1C_RECEIVE;} + if ((!xmlStrcmp(action, (const xmlChar *)"SEND"))) { return ET_PACKET_ACTION_S1C_SEND;} + if ((!xmlStrcmp(action, (const xmlChar *)"RECEIVE"))) { return ET_PACKET_ACTION_S1C_RECEIVE;} AssertFatal (0, "ERROR: %s cannot convert: %s\n", __FUNCTION__, action); //if (NULL == action) {return ACTION_S1C_NULL;} } //------------------------------------------------------------------------------ -void ip_str2test_ip(const xmlChar * const ip_str, test_ip_t * const ip) +void et_ip_str2et_ip(const xmlChar * const ip_str, et_ip_t * const ip) { AssertFatal (NULL != ip_str, "ERROR %s() Cannot convert null string to ip address!\n", __FUNCTION__); AssertFatal (NULL != ip, "ERROR %s() out parameter pointer is NULL!\n", __FUNCTION__); @@ -550,732 +290,207 @@ void ip_str2test_ip(const xmlChar * const ip_str, test_ip_t * const ip) AssertFatal (0, "ERROR %s() Could not parse ip address %s!\n", __FUNCTION__, ip_str); } } -//------------------------------------------------------------------------------ -int test_s1ap_decode_initiating_message(s1ap_message *message, - S1ap_InitiatingMessage_t *initiating_p) +/*------------------------------------------------------------------------------*/ +uint32_t et_eNB_app_register(const Enb_properties_array_t *enb_properties) { - char *message_string = NULL; - int ret = -1; + uint32_t enb_id; + uint32_t mme_id; + MessageDef *msg_p; + uint32_t register_enb_pending = 0; + char *str = NULL; + struct in_addr addr; - DevAssert(initiating_p != NULL); - message_string = calloc(20000, sizeof(char)); - AssertFatal (NULL != message_string, "ERROR malloc()failed!\n"); - message->procedureCode = initiating_p->procedureCode; - message->criticality = initiating_p->criticality; + for (enb_id = 0; (enb_id < enb_properties->number) ; enb_id++) { + { + s1ap_register_enb_req_t *s1ap_register_eNB; - switch(initiating_p->procedureCode) { - case S1ap_ProcedureCode_id_downlinkNASTransport: - ret = s1ap_decode_s1ap_downlinknastransporties( - &message->msg.s1ap_DownlinkNASTransportIEs, - &initiating_p->value); - s1ap_xer_print_s1ap_downlinknastransport(s1ap_xer__print2sp, message_string, message); - break; + /* note: there is an implicit relationship between the data structure and the message name */ + msg_p = itti_alloc_new_message (TASK_ENB_APP, S1AP_REGISTER_ENB_REQ); - case S1ap_ProcedureCode_id_InitialContextSetup: - ret = s1ap_decode_s1ap_initialcontextsetuprequesties( - &message->msg.s1ap_InitialContextSetupRequestIEs, &initiating_p->value); - s1ap_xer_print_s1ap_initialcontextsetuprequest(s1ap_xer__print2sp, message_string, message); - break; + s1ap_register_eNB = &S1AP_REGISTER_ENB_REQ(msg_p); - case S1ap_ProcedureCode_id_UEContextRelease: - ret = s1ap_decode_s1ap_uecontextreleasecommandies( - &message->msg.s1ap_UEContextReleaseCommandIEs, &initiating_p->value); - s1ap_xer_print_s1ap_uecontextreleasecommand(s1ap_xer__print2sp, message_string, message); - break; + /* Some default/random parameters */ + s1ap_register_eNB->eNB_id = enb_properties->properties[enb_id]->eNB_id; + s1ap_register_eNB->cell_type = enb_properties->properties[enb_id]->cell_type; + s1ap_register_eNB->eNB_name = enb_properties->properties[enb_id]->eNB_name; + s1ap_register_eNB->tac = enb_properties->properties[enb_id]->tac; + s1ap_register_eNB->mcc = enb_properties->properties[enb_id]->mcc; + s1ap_register_eNB->mnc = enb_properties->properties[enb_id]->mnc; + s1ap_register_eNB->mnc_digit_length = enb_properties->properties[enb_id]->mnc_digit_length; + s1ap_register_eNB->default_drx = enb_properties->properties[enb_id]->pcch_defaultPagingCycle[0]; - case S1ap_ProcedureCode_id_Paging: - ret = s1ap_decode_s1ap_pagingies( - &message->msg.s1ap_PagingIEs, &initiating_p->value); - s1ap_xer_print_s1ap_paging(s1ap_xer__print2sp, message_string, message); - break; + s1ap_register_eNB->nb_mme = enb_properties->properties[enb_id]->nb_mme; + AssertFatal (s1ap_register_eNB->nb_mme <= S1AP_MAX_NB_MME_IP_ADDRESS, "Too many MME for eNB %d (%d/%d)!", enb_id, s1ap_register_eNB->nb_mme, + S1AP_MAX_NB_MME_IP_ADDRESS); - case S1ap_ProcedureCode_id_uplinkNASTransport: - ret = s1ap_decode_s1ap_uplinknastransporties (&message->msg.s1ap_UplinkNASTransportIEs, &initiating_p->value); - s1ap_xer_print_s1ap_uplinknastransport(s1ap_xer__print2sp, message_string, message); - break; + for (mme_id = 0; mme_id < s1ap_register_eNB->nb_mme; mme_id++) { + s1ap_register_eNB->mme_ip_address[mme_id].ipv4 = enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv4; + s1ap_register_eNB->mme_ip_address[mme_id].ipv6 = enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv6; + strncpy (s1ap_register_eNB->mme_ip_address[mme_id].ipv4_address, + enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv4_address, + sizeof(s1ap_register_eNB->mme_ip_address[0].ipv4_address)); + strncpy (s1ap_register_eNB->mme_ip_address[mme_id].ipv6_address, + enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv6_address, + sizeof(s1ap_register_eNB->mme_ip_address[0].ipv6_address)); + } - case S1ap_ProcedureCode_id_S1Setup: - ret = s1ap_decode_s1ap_s1setuprequesties (&message->msg.s1ap_S1SetupRequestIEs, &initiating_p->value); - s1ap_xer_print_s1ap_s1setuprequest(s1ap_xer__print2sp, message_string, message); - break; + s1ap_register_eNB->sctp_in_streams = enb_properties->properties[enb_id]->sctp_in_streams; + s1ap_register_eNB->sctp_out_streams = enb_properties->properties[enb_id]->sctp_out_streams; - case S1ap_ProcedureCode_id_initialUEMessage: - ret = s1ap_decode_s1ap_initialuemessageies (&message->msg.s1ap_InitialUEMessageIEs, &initiating_p->value); - s1ap_xer_print_s1ap_initialuemessage(s1ap_xer__print2sp, message_string, message); - break; - case S1ap_ProcedureCode_id_UEContextReleaseRequest: - ret = s1ap_decode_s1ap_uecontextreleaserequesties (&message->msg.s1ap_UEContextReleaseRequestIEs, &initiating_p->value); - s1ap_xer_print_s1ap_uecontextreleaserequest(s1ap_xer__print2sp, message_string, message); - break; + s1ap_register_eNB->enb_ip_address.ipv6 = 0; + s1ap_register_eNB->enb_ip_address.ipv4 = 1; + addr.s_addr = enb_properties->properties[enb_id]->enb_ipv4_address_for_S1_MME; + str = inet_ntoa(addr); + strcpy(s1ap_register_eNB->enb_ip_address.ipv4_address, str); - case S1ap_ProcedureCode_id_UECapabilityInfoIndication: - ret = s1ap_decode_s1ap_uecapabilityinfoindicationies (&message->msg.s1ap_UECapabilityInfoIndicationIEs, &initiating_p->value); - //s1ap_xer_print_s1ap_uecapabilityinfoindication(s1ap_xer__print2sp, message_string, message); - break; + itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); - case S1ap_ProcedureCode_id_NASNonDeliveryIndication: - ret = s1ap_decode_s1ap_nasnondeliveryindication_ies (&message->msg.s1ap_NASNonDeliveryIndication_IEs, &initiating_p->value); - s1ap_xer_print_s1ap_nasnondeliveryindication_(s1ap_xer__print2sp, message_string, message); - break; - - default: - free(message_string); - AssertFatal( 0 , "Unknown procedure ID (%d) for initiating message\n", - (int)initiating_p->procedureCode); - return -1; + register_enb_pending++; + } } - fprintf(stdout, "s1ap_xer_print:\n%s\n", message_string); - free(message_string); - return ret; + + return register_enb_pending; +} +/*------------------------------------------------------------------------------*/ +void *et_eNB_app_task(void *args_p) +{ + const Enb_properties_array_t *enb_properties_p = NULL; + uint32_t register_enb_pending; + uint32_t registered_enb; + long enb_register_retry_timer_id; + uint32_t enb_id; + MessageDef *msg_p = NULL; + const char *msg_name = NULL; + instance_t instance; + int result; + + itti_mark_task_ready (TASK_ENB_APP); + + + enb_properties_p = enb_config_get(); + + + /* Try to register each eNB */ + registered_enb = 0; + register_enb_pending = et_eNB_app_register (enb_properties_p); + + + do { + // Wait for a message + itti_receive_msg (TASK_ENB_APP, &msg_p); + + msg_name = ITTI_MSG_NAME (msg_p); + instance = ITTI_MSG_INSTANCE (msg_p); + + switch (ITTI_MSG_ID(msg_p)) { + case TERMINATE_MESSAGE: + itti_exit_task (); + break; + + + + case S1AP_REGISTER_ENB_CNF: + LOG_I(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, msg_name, + S1AP_REGISTER_ENB_CNF(msg_p).nb_mme); + + DevAssert(register_enb_pending > 0); + register_enb_pending--; + + /* Check if at least eNB is registered with one MME */ + if (S1AP_REGISTER_ENB_CNF(msg_p).nb_mme > 0) { + registered_enb++; + } + + /* Check if all register eNB requests have been processed */ + if (register_enb_pending == 0) { + if (registered_enb == enb_properties_p->number) { + /* If all eNB are registered, start scenario */ + + } else { + uint32_t not_associated = enb_properties_p->number - registered_enb; + + LOG_W(ENB_APP, " %d eNB %s not associated with a MME, retrying registration in %d seconds ...\n", + not_associated, not_associated > 1 ? "are" : "is", ET_ENB_REGISTER_RETRY_DELAY); + + /* Restart the eNB registration process in ENB_REGISTER_RETRY_DELAY seconds */ + if (timer_setup (ET_ENB_REGISTER_RETRY_DELAY, 0, TASK_ENB_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT, + NULL, &enb_register_retry_timer_id) < 0) { + LOG_E(ENB_APP, " Can not start eNB register retry timer, use \"sleep\" instead!\n"); + + sleep(ET_ENB_REGISTER_RETRY_DELAY); + /* Restart the registration process */ + registered_enb = 0; + register_enb_pending = et_eNB_app_register (enb_properties_p); + } + } + } + + break; + + case S1AP_DEREGISTERED_ENB_IND: + LOG_W(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, msg_name, + S1AP_DEREGISTERED_ENB_IND(msg_p).nb_mme); + + /* TODO handle recovering of registration */ + break; + + case TIMER_HAS_EXPIRED: + LOG_I(ENB_APP, " Received %s: timer_id %d\n", msg_name, TIMER_HAS_EXPIRED(msg_p).timer_id); + + if (TIMER_HAS_EXPIRED (msg_p).timer_id == enb_register_retry_timer_id) { + /* Restart the registration process */ + registered_enb = 0; + register_enb_pending = et_eNB_app_register (enb_properties_p); + } + break; + + default: + LOG_E(ENB_APP, "Received unexpected message %s\n", msg_name); + break; + } + + result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + } while (1); + return NULL; } //------------------------------------------------------------------------------ -int test_s1ap_decode_successful_outcome(s1ap_message *message, - S1ap_SuccessfulOutcome_t *successfullOutcome_p) +int et_play_scenario(et_scenario_t* const scenario) { - char *message_string = NULL; - int ret = -1; + et_event_t event; + et_display_scenario(scenario); - DevAssert(successfullOutcome_p != NULL); - message_string = calloc(20000, sizeof(char)); - AssertFatal (NULL != message_string, "ERROR malloc()failed!\n"); - - message->procedureCode = successfullOutcome_p->procedureCode; - message->criticality = successfullOutcome_p->criticality; - - switch(successfullOutcome_p->procedureCode) { - case S1ap_ProcedureCode_id_S1Setup: - ret = s1ap_decode_s1ap_s1setupresponseies( - &message->msg.s1ap_S1SetupResponseIEs, &successfullOutcome_p->value); - s1ap_xer_print_s1ap_s1setupresponse(s1ap_xer__print2sp, message_string, message); - break; - - case S1ap_ProcedureCode_id_InitialContextSetup: - ret = s1ap_decode_s1ap_initialcontextsetupresponseies (&message->msg.s1ap_InitialContextSetupResponseIEs, &successfullOutcome_p->value); - s1ap_xer_print_s1ap_initialcontextsetupresponse(s1ap_xer__print2sp, message_string, message); - break; - - case S1ap_ProcedureCode_id_UEContextRelease: - ret = s1ap_decode_s1ap_uecontextreleasecompleteies (&message->msg.s1ap_UEContextReleaseCompleteIEs, &successfullOutcome_p->value); - s1ap_xer_print_s1ap_uecontextreleasecomplete(s1ap_xer__print2sp, message_string, message); - break; - - default: - free(message_string); - AssertFatal(0, "Unknown procedure ID (%d) for successfull outcome message\n", - (int)successfullOutcome_p->procedureCode); - return -1; - } - fprintf(stdout, "s1ap_xer_print:\n%s\n", message_string); - free(message_string); - return ret; -} - -//------------------------------------------------------------------------------ -int test_s1ap_decode_unsuccessful_outcome(s1ap_message *message, - S1ap_UnsuccessfulOutcome_t *unSuccessfullOutcome_p) -{ - char *message_string = NULL; - int ret = -1; - - DevAssert(unSuccessfullOutcome_p != NULL); - message_string = calloc(20000, sizeof(char)); - AssertFatal (NULL != message_string, "ERROR malloc()failed!\n"); - - message->procedureCode = unSuccessfullOutcome_p->procedureCode; - message->criticality = unSuccessfullOutcome_p->criticality; - - switch(unSuccessfullOutcome_p->procedureCode) { - case S1ap_ProcedureCode_id_S1Setup: - ret = s1ap_decode_s1ap_s1setupfailureies( - &message->msg.s1ap_S1SetupFailureIEs, &unSuccessfullOutcome_p->value); - s1ap_xer_print_s1ap_s1setupfailure(s1ap_xer__print2sp, message_string, message); - break; - - case S1ap_ProcedureCode_id_InitialContextSetup: - ret = s1ap_decode_s1ap_initialcontextsetupfailureies (&message->msg.s1ap_InitialContextSetupFailureIEs, &unSuccessfullOutcome_p->value); - s1ap_xer_print_s1ap_initialcontextsetupfailure(s1ap_xer__print2sp, message_string, message); - break; - - - default: - free(message_string); - AssertFatal(0,"Unknown procedure ID (%d) for unsuccessfull outcome message\n", - (int)unSuccessfullOutcome_p->procedureCode); - break; - } - fprintf(stdout, "s1ap_xer_print:\n%s\n", message_string); - free(message_string); - return ret; -} - -//------------------------------------------------------------------------------ -int test_s1ap_decode_pdu(s1ap_message *message, const uint8_t * const buffer, - const uint32_t length) -{ - S1AP_PDU_t pdu; - S1AP_PDU_t *pdu_p = &pdu; - asn_dec_rval_t dec_ret; - - DevAssert(buffer != NULL); - - memset((void *)pdu_p, 0, sizeof(S1AP_PDU_t)); - - dec_ret = aper_decode(NULL, - &asn_DEF_S1AP_PDU, - (void **)&pdu_p, - buffer, - length, - 0, - 0); - - if (dec_ret.code != RC_OK) { - S1AP_ERROR("Failed to decode pdu\n"); + // create SCTP ITTI task: same as eNB code + if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) { + LOG_E(SCTP, "Create task for SCTP failed\n"); return -1; } - message->direction = pdu_p->present; - - switch(pdu_p->present) { - case S1AP_PDU_PR_initiatingMessage: - return test_s1ap_decode_initiating_message(message, - &pdu_p->choice.initiatingMessage); - - case S1AP_PDU_PR_successfulOutcome: - return test_s1ap_decode_successful_outcome(message, - &pdu_p->choice.successfulOutcome); - - case S1AP_PDU_PR_unsuccessfulOutcome: - return test_s1ap_decode_unsuccessful_outcome(message, - &pdu_p->choice.unsuccessfulOutcome); - - default: - AssertFatal(0, "Unknown presence (%d) or not implemented\n", (int)pdu_p->present); - break; - } - return -1; -} -//------------------------------------------------------------------------------ -void test_decode_s1ap(test_s1ap_t * const s1ap) -{ - if (NULL != s1ap) { - if (test_s1ap_decode_pdu(&s1ap->message, s1ap->binary_stream, s1ap->binary_stream_allocated_size) < 0) { - AssertFatal (0, "ERROR %s() Cannot decode S1AP message!\n", __FUNCTION__); - } - } -} -//------------------------------------------------------------------------------ -void parse_s1ap(xmlDocPtr doc, const xmlNode const *s1ap_node, test_s1ap_t * const s1ap) -{ - xmlNode *cur_node = NULL; - xmlChar *xml_char = NULL; - xmlChar *xml_char2 = NULL; - unsigned int size = 0; - int rc = 0; - unsigned int go_deeper_in_tree = 1; - - if ((NULL != s1ap_node) && (NULL != s1ap)) { - for (cur_node = (xmlNode *)s1ap_node; cur_node; cur_node = cur_node->next) { - go_deeper_in_tree = 1; - if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"field"))) { - // do not get hidden fields - xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"hide"); - if (NULL != xml_char) { - if ((!xmlStrcmp(xml_char, (const xmlChar *)"yes"))) { - go_deeper_in_tree = 0; - } - xmlFree(xml_char); - } - if (0 < go_deeper_in_tree) { - // first get size - xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"size"); - if (NULL != xml_char) { - size = strtoul((const char *)xml_char, NULL, 0); - xmlFree(xml_char); - // second: try to get value (always hex) - xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"value"); - if (NULL != xml_char) { - xml_char2 = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"name"); - fprintf(stdout, "s1ap %p field %s size %d value %s\n",s1ap, xml_char2, size, xml_char); - xmlFree(xml_char2); - // if success to get value, do not parse children - //AssertFatal ((xmlStrlen(xml_char) == size), "ERROR %s() mismatch in size %d and strlen %d\n", __FUNCTION__, size, xmlStrlen(xml_char)); - //if (xmlStrlen(xml_char) == size) { - AssertFatal ((s1ap->binary_stream_pos+xmlStrlen(xml_char)/2) <= s1ap->binary_stream_allocated_size, - "ERROR %s() in buffer size: binary_stream_pos %d xmlStrlen(xml_char)/2=%d\n", __FUNCTION__, s1ap->binary_stream_pos, xmlStrlen(xml_char)/2); - rc = hex2data( &s1ap->binary_stream[s1ap->binary_stream_pos], xml_char, xmlStrlen(xml_char)); - s1ap->binary_stream_pos += xmlStrlen(xml_char)/2; - display_node(cur_node, 0); - AssertFatal (rc >= 0, "ERROR %s() in converting hex string %s len %d size %d rc %d\n", __FUNCTION__, xml_char, xmlStrlen(xml_char), size, rc); - go_deeper_in_tree = 0; - //} - xmlFree(xml_char); - } - } - } - } - if (0 < go_deeper_in_tree) { - parse_s1ap(doc, cur_node->children, s1ap); - } - } - } -} - -//------------------------------------------------------------------------------ -void parse_sctp_data_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_datahdr_t * const sctp_hdr) -{ - xmlNode *cur_node = NULL; - xmlChar *xml_char = NULL; - xmlChar *xml_char2 = NULL; - - if ((NULL != sctp_node) && (NULL != sctp_hdr)) { - xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"name"); - if (NULL != xml_char) { - if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.data_payload_proto_id"))) { - xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); - if (NULL != xml_char2) { - sctp_hdr->ppid = strtoul((const char *)xml_char2, NULL, 0); - xmlFree(xml_char2); - } - } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.data_sid"))) { - xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); - if (NULL != xml_char2) { - sctp_hdr->stream = strtoul((const char *)xml_char2, NULL, 16); - xmlFree(xml_char2); - } - } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.data_tsn"))) { - xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); - if (NULL != xml_char2) { - sctp_hdr->tsn = strtoul((const char *)xml_char2, NULL, 0); - xmlFree(xml_char2); - } - } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.data_ssn"))) { - xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); - if (NULL != xml_char2) { - sctp_hdr->ssn = strtoul((const char *)xml_char2, NULL, 0); - xmlFree(xml_char2); - } - } - xmlFree(xml_char); - } - for (cur_node = sctp_node->children; cur_node; cur_node = cur_node->next) { - parse_sctp_data_chunk(doc, cur_node, sctp_hdr); - } + // create S1AP ITTI task: not as same as eNB code + if (itti_create_task (TASK_S1AP, et_s1ap_eNB_task, NULL) < 0) { + LOG_E(S1AP, "Create task for S1AP failed\n"); + return -1; } -} -//------------------------------------------------------------------------------ -void parse_sctp_init_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_inithdr_t * const sctp_hdr) -{ - xmlNode *cur_node = NULL; - xmlChar *xml_char = NULL; - xmlChar *xml_char2 = NULL; - - if ((NULL != sctp_node) && (NULL != sctp_hdr)) { - xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"name"); - if (NULL != xml_char) { - if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.init_nr_out_streams"))) { - xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); - if (NULL != xml_char2) { - sctp_hdr->num_outbound_streams = strtoul((const char *)xml_char2, NULL, 0); - xmlFree(xml_char2); - } - } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.init_nr_in_streams"))) { - xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); - if (NULL != xml_char2) { - sctp_hdr->num_inbound_streams = strtoul((const char *)xml_char2, NULL, 0); - xmlFree(xml_char2); - } - } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.init_credit"))) { - xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); - if (NULL != xml_char2) { - sctp_hdr->a_rwnd = strtoul((const char *)xml_char2, NULL, 0); - xmlFree(xml_char2); - } - } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.init_initial_tsn"))) { - xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); - if (NULL != xml_char2) { - sctp_hdr->initial_tsn = strtoul((const char *)xml_char2, NULL, 0); - xmlFree(xml_char2); - } - } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.init_initiate_tag"))) { - xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); - if (NULL != xml_char2) { - sctp_hdr->init_tag = strtoul((const char *)xml_char2, NULL, 16); - xmlFree(xml_char2); - } - } - xmlFree(xml_char); - } - for (cur_node = sctp_node->children; cur_node; cur_node = cur_node->next) { - parse_sctp_init_chunk(doc, cur_node, sctp_hdr); - } + // create ENB_APP ITTI task: not as same as eNB code + if (itti_create_task (TASK_ENB_APP, et_eNB_app_task, NULL) < 0) { + LOG_E(ENB_APP, "Create task for ENB_APP failed\n"); + return -1; } -} -//------------------------------------------------------------------------------ -void parse_sctp_init_ack_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_initackhdr_t * const sctp_hdr) -{ - xmlNode *cur_node = NULL; - xmlChar *xml_char = NULL; - xmlChar *xml_char2 = NULL; - if ((NULL != sctp_node) && (NULL != sctp_hdr)) { - xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"name"); - if (NULL != xml_char) { - if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.initack_nr_out_streams"))) { - xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); - if (NULL != xml_char2) { - sctp_hdr->num_outbound_streams = strtoul((const char *)xml_char2, NULL, 0); - xmlFree(xml_char2); - } - } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.initack_nr_in_streams"))) { - xml_char2 = xmlGetProp((xmlNode *)(xmlNode *)sctp_node, (const xmlChar *)"value"); - if (NULL != xml_char2) { - sctp_hdr->num_inbound_streams = strtoul((const char *)xml_char2, NULL, 0); - xmlFree(xml_char2); - } - } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.initack_credit"))) { - xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); - if (NULL != xml_char2) { - sctp_hdr->a_rwnd = strtoul((const char *)xml_char2, NULL, 0); - xmlFree(xml_char2); - } - } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.initack_initial_tsn"))) { - xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); - if (NULL != xml_char2) { - sctp_hdr->initial_tsn = strtoul((const char *)xml_char2, NULL, 0); - xmlFree(xml_char2); - } - } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.initack_initiate_tag"))) { - xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); - if (NULL != xml_char2) { - sctp_hdr->init_tag = strtoul((const char *)xml_char2, NULL, 16); - xmlFree(xml_char2); - } - } - xmlFree(xml_char); - } - for (cur_node = sctp_node->children; cur_node; cur_node = cur_node->next) { - parse_sctp_init_ack_chunk(doc, cur_node, sctp_hdr); - } - } -} -//------------------------------------------------------------------------------ -void parse_sctp(xmlDocPtr doc, const xmlNode const *sctp_node, test_sctp_hdr_t * const sctp_hdr) -{ - xmlNode *cur_node = NULL; - xmlChar *xml_char = NULL; - xmlChar *xml_char2 = NULL; + event.code = ET_EVENT_INIT; + event.u.init.scenario = scenario; + et_scenario_fsm_notify_event(event); - if ((NULL != sctp_node) && (NULL != sctp_hdr)) { - if ((!xmlStrcmp(sctp_node->name, (const xmlChar *)"proto"))) { - xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"name"); - if (NULL != xml_char) { - if ((!xmlStrcmp(xml_char, (const xmlChar *)"s1ap"))) { - xmlFree(xml_char); - xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"size"); - if (NULL != xml_char2) { - sctp_hdr->u.data_hdr.payload.binary_stream_allocated_size = strtoul((const char *)xml_char2, NULL, 0); - sctp_hdr->u.data_hdr.payload.binary_stream = calloc(1, sctp_hdr->u.data_hdr.payload.binary_stream_allocated_size); - xmlFree(xml_char2); - } - parse_s1ap(doc, sctp_node, &sctp_hdr->u.data_hdr.payload); - test_decode_s1ap(&sctp_hdr->u.data_hdr.payload); - return; - } - xmlFree(xml_char); - } - } - //if ((cur_node->type == XML_ATTRIBUTE_NODE) || (cur_node->type == XML_ELEMENT_NODE)) { - xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"name"); - if (NULL != xml_char) { - if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.srcport"))) { - xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); - if (NULL != xml_char2) { - sctp_hdr->src_port = strtoul((const char *)xml_char2, NULL, 16); - xmlFree(xml_char2); - } - } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.dstport"))) { - xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); - if (NULL != xml_char2) { - sctp_hdr->dst_port = strtoul((const char *)xml_char2, NULL, 16); - xmlFree(xml_char2); - } - } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.chunk_type"))) { - xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); - if (NULL != xml_char2) { - sctp_hdr->chunk_type = strtoul((const char *)xml_char2, NULL, 0); - xmlFree(xml_char2); - switch (sctp_hdr->chunk_type) { - case SCTP_CID_DATA: - parse_sctp_data_chunk(doc, sctp_node->parent, &sctp_hdr->u.data_hdr); - break; - case SCTP_CID_INIT: - parse_sctp_init_chunk(doc, sctp_node->parent, &sctp_hdr->u.init_hdr); - break; - case SCTP_CID_INIT_ACK: - parse_sctp_init_ack_chunk(doc, sctp_node->parent, &sctp_hdr->u.init_ack_hdr); - break; - default: - ; - } - } - } - } - for (cur_node = sctp_node->children; cur_node; cur_node = cur_node->next) { - parse_sctp(doc, cur_node, sctp_hdr); - } - } -} -//------------------------------------------------------------------------------ -test_packet_t* parse_xml_packet(xmlDocPtr doc, xmlNodePtr node) { - test_packet_t *packet = NULL; - xmlNode *cur_node = NULL; - xmlChar *xml_char = NULL; - float afloat = (float)0.0; - static struct timeval initial_time = { .tv_sec = 0, .tv_usec = 0 }; - static struct timeval relative_last_sent_packet = { .tv_sec = 0, .tv_usec = 0 }; - static struct timeval relative_last_received_packet = { .tv_sec = 0, .tv_usec = 0 }; - static char first_packet = 1; - static char first_sent_packet = 1; - static char first_received_packet = 1; - static unsigned int packet_number = 1; - - if (NULL != node) { - packet = calloc(1, sizeof(*packet)); - - xml_char = xmlGetProp(node, (const xmlChar *)"action"); - packet->action = action_str2test_action_t(xml_char); - xmlFree(xml_char); - packet->packet_number = packet_number++; - - for (cur_node = node->children; cur_node; cur_node = cur_node->next) { - //if (cur_node->type == XML_ELEMENT_NODE) { - if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"frame.time_relative"))) { - xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"value"); - afloat = atof((const char*)xml_char); - xmlFree(xml_char); - packet->time_relative_to_first_packet.tv_sec = (int)afloat; - packet->time_relative_to_first_packet.tv_usec = (int)((afloat - packet->time_relative_to_first_packet.tv_sec)*1000000); - - if (first_packet > 0) { - initial_time = packet->time_relative_to_first_packet; - packet->time_relative_to_first_packet.tv_sec = 0; - packet->time_relative_to_first_packet.tv_usec = 0; - first_packet = 0; - } else { - timersub(&packet->time_relative_to_first_packet, &initial_time, - &packet->time_relative_to_first_packet); - } - if (packet->action == ACTION_S1C_SEND) { - if (first_sent_packet > 0) { - relative_last_sent_packet = packet->time_relative_to_first_packet; - packet->time_relative_to_last_sent_packet.tv_sec = 0; - packet->time_relative_to_last_sent_packet.tv_usec = 0; - first_sent_packet = 0; - } else { - timersub(&packet->time_relative_to_first_packet, &relative_last_sent_packet, - &packet->time_relative_to_last_sent_packet); - relative_last_sent_packet = packet->time_relative_to_first_packet; - } - } else if (packet->action == ACTION_S1C_RECEIVE) { - if (first_received_packet > 0) { - relative_last_received_packet.tv_sec = packet->time_relative_to_first_packet.tv_sec; - relative_last_received_packet.tv_usec = packet->time_relative_to_first_packet.tv_usec; - packet->time_relative_to_last_received_packet.tv_sec = 0; - packet->time_relative_to_last_received_packet.tv_usec = 0; - first_received_packet = 0; - } else { - timersub(&packet->time_relative_to_first_packet, &relative_last_received_packet, - &packet->time_relative_to_last_received_packet); - relative_last_received_packet = packet->time_relative_to_first_packet; - } - } - - } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"frame.number"))) { - xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"value"); - packet->original_frame_number = strtoul((const char *)xml_char, NULL, 0); - xmlFree(xml_char); - } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"ip.src"))) { - xml_char = xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1); - ip_str2test_ip(xml_char, &packet->ip_hdr.src); - xmlFree(xml_char); - } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"ip.dst"))) { - xml_char = xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1); - ip_str2test_ip(xml_char, &packet->ip_hdr.dst); - xmlFree(xml_char); - } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"proto"))) { - xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"name"); - if (NULL != xml_char) { - if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp"))) { - parse_sctp(doc, cur_node, &packet->sctp_hdr); - } - xmlFree(xml_char); - } - } - //} - } - } - return packet; -} -//------------------------------------------------------------------------------ -int play_scenario(test_scenario_t* scenario) { - //TODO - display_scenario(scenario); return 0; } -//------------------------------------------------------------------------------ -test_scenario_t* generate_scenario( - const char * const play_scenario_filename ) -{ - xmlDocPtr doc = NULL; - xmlNodePtr root = NULL; - xmlNodePtr node = NULL; - xmlChar *xml_char = NULL; - test_scenario_t *scenario = NULL; - test_packet_t *packet = NULL; - test_packet_t **next_packet = NULL; - - doc = xmlParseFile(play_scenario_filename); - if (NULL == doc) { - AssertFatal (0, "Could not parse scenario xml file %s!\n", play_scenario_filename); - } else { - fprintf(stdout, "Test scenario file to play: %s\n", play_scenario_filename); - //xmlDebugDumpDocument(NULL, doc); - } - - // Get root - root = xmlDocGetRootElement(doc); - if (NULL != root) { - if ((!xmlStrcmp(root->name, (const xmlChar *)"scenario"))) { - xml_char = xmlGetProp(root, (const xmlChar *)"name"); - printf("scenario name: %s\n", xml_char); - scenario = calloc(1, sizeof(*scenario)); - scenario->name = xml_char; // nodup nofree - next_packet = &scenario->list_packet; - for (node = root->children; node != NULL; node = node->next) { - if ((!xmlStrcmp(node->name, (const xmlChar *)"packet"))) { - packet = parse_xml_packet(doc, node); - if (NULL != packet) { - *next_packet = packet; - next_packet = &packet->next; - } else { - fprintf(stdout, "WARNING omitted packet:\n"); - display_node(node, 0); - } - } - } - } - } else { - fprintf(stderr, "Empty xml document\n"); - } - xmlFreeDoc(doc); - xmlCleanupParser(); - return scenario; -} //------------------------------------------------------------------------------ -int generate_xml_scenario( - const char const * test_dir_name, - const char const * test_scenario_filename, - const char const * enb_config_filename, - char const * play_scenario_filename /* OUT PARAM*/) -//------------------------------------------------------------------------------ -{ - //int fd_pdml_in; - xsltStylesheetPtr cur = NULL; - xmlDocPtr doc, res; - FILE *play_scenario_file = NULL; - const char *params[2*ENB_CONFIG_MAX_XSLT_PARAMS]; - int nb_params = 0; - int i,j; - char astring[1024]; - struct in_addr addr; - int ret = 0; - - memset(astring, 0, sizeof(astring)); - if (getcwd(astring, sizeof(astring)) != NULL) { - fprintf(stdout, "working in %s directory\n", astring); - } else { - perror("getcwd() ERROR"); - exit(1); - } - - memset(astring, 0, sizeof(astring)); - strcat(astring, g_openair_dir); - strcat(astring, "/openair3/TEST/EPC_TEST/play_scenario.xsl"); - - xmlSubstituteEntitiesDefault(1); - xmlLoadExtDtdDefaultValue = 1; - cur = xsltParseStylesheetFile((const xmlChar *)astring); - if (NULL == cur) { - AssertFatal (0, "Could not parse stylesheet file %s (check OPENAIR_DIR env variable)!\n", astring); - } else { - fprintf(stdout, "XSLT style sheet: %s\n", astring); - } - - doc = xmlParseFile(test_scenario_filename); - if (NULL == doc) { - AssertFatal (0, "Could not parse scenario xml file %s!\n", test_scenario_filename); - } else { - fprintf(stdout, "Test scenario file: %s\n", test_scenario_filename); - } - - for (i = 0; i < enb_properties.number; i++) { - // eNB S1-C IPv4 address - sprintf(astring, "enb_s1c%d", i); - params[nb_params++] = strdup(astring); - addr.s_addr = enb_properties.properties[i]->enb_ipv4_address_for_S1_MME; - sprintf(astring, "\"%s\"", inet_ntoa(addr)); - params[nb_params++] = strdup(astring); - - // MME S1-C IPv4 address - for (j = 0; j < enb_properties.properties[i]->nb_mme; j++) { - sprintf(astring, "mme_s1c%d_%d", i, j); - params[nb_params++] = strdup(astring); - AssertFatal (enb_properties.properties[i]->mme_ip_address[j].ipv4_address, - "Only support MME IPv4 address\n"); - sprintf(astring, "\"%s\"", enb_properties.properties[i]->mme_ip_address[j].ipv4_address); - params[nb_params++] = strdup(astring); - } - } - params[nb_params] = NULL; - res = xsltApplyStylesheet(cur, doc, params); - if (NULL != res) { - sprintf((char *)play_scenario_filename,"%s",test_scenario_filename); - if (strip_extension((char *)play_scenario_filename) > 0) { - strcat((char *)play_scenario_filename, ".tsml"); - play_scenario_file = fopen( play_scenario_filename, "w+"); - if (NULL != play_scenario_file) { - xsltSaveResultToFile(play_scenario_file, res, cur); - fclose(play_scenario_file); - fprintf(stdout, "Wrote test scenario to %s\n", play_scenario_filename); - } else { - fprintf(stderr, "ERROR in fopen(%s)\n", play_scenario_filename); - ret = -1; - } - } else { - fprintf(stderr, "ERROR in strip_extension()\n"); - ret = -1; - } - } else { - fprintf(stderr, "ERROR in xsltApplyStylesheet()\n"); - ret = -1; - } - xsltFreeStylesheet(cur); - xmlFreeDoc(doc); - xmlFreeDoc(res); - - xsltCleanupGlobals(); - xmlCleanupParser(); - return ret; -} - -//------------------------------------------------------------------------------ -static void usage ( +static void et_usage ( int argc, char *argv[]) //------------------------------------------------------------------------------ @@ -1298,10 +513,10 @@ static void usage ( //------------------------------------------------------------------------------ int -config_parse_opt_line ( +et_config_parse_opt_line ( int argc, char *argv[], - char **test_dir_name, + char **et_dir_name, char **scenario_file_name, char **enb_config_file_name) //------------------------------------------------------------------------------ @@ -1354,12 +569,12 @@ config_parse_opt_line ( case LONG_OPTION_TEST_DIR: case 'd': if (optarg) { - *test_dir_name = strdup(optarg); - if (is_file_exists(*test_dir_name, "test dirname") != GS_IS_DIR) { - fprintf(stderr, "Please provide a valid test dirname, %s is not a valid directory name\n", *test_dir_name); + *et_dir_name = strdup(optarg); + if (is_file_exists(*et_dir_name, "test dirname") != GS_IS_DIR) { + fprintf(stderr, "Please provide a valid test dirname, %s is not a valid directory name\n", *et_dir_name); exit(1); } - printf("Test dir name is %s\n", *test_dir_name); + printf("Test dir name is %s\n", *et_dir_name); } break; @@ -1372,32 +587,32 @@ config_parse_opt_line ( case LONG_OPTION_HELP: case 'h': default: - usage (argc, argv); + et_usage (argc, argv); exit (0); } } - if (NULL == *test_dir_name) { + if (NULL == *et_dir_name) { fprintf(stderr, "Please provide a valid test dirname\n"); exit(1); } - if (chdir(*test_dir_name) != 0) { - fprintf(stderr, "ERROR: chdir %s returned %s\n", *test_dir_name, strerror(errno)); + if (chdir(*et_dir_name) != 0) { + fprintf(stderr, "ERROR: chdir %s returned %s\n", *et_dir_name, strerror(errno)); exit(1); } if (rv & PLAY_SCENARIO) { if (NULL == *enb_config_file_name) { - fprintf(stderr, "ERROR: please provide the original eNB config file name that should be in %s\n", *test_dir_name); + fprintf(stderr, "ERROR: please provide the original eNB config file name that should be in %s\n", *et_dir_name); } if (is_file_exists(*enb_config_file_name, "eNB config file") != GS_IS_FILE) { - fprintf(stderr, "ERROR: original eNB config file name %s is not found in dir %s\n", *enb_config_file_name, *test_dir_name); + fprintf(stderr, "ERROR: original eNB config file name %s is not found in dir %s\n", *enb_config_file_name, *et_dir_name); } enb_properties_p = enb_config_init(*enb_config_file_name); if (NULL == *scenario_file_name) { - fprintf(stderr, "ERROR: please provide the scenario file name that should be in %s\n", *test_dir_name); + fprintf(stderr, "ERROR: please provide the scenario file name that should be in %s\n", *et_dir_name); } if (is_file_exists(*scenario_file_name, "Scenario file") != GS_IS_FILE) { - fprintf(stderr, "ERROR: Scenario file name %s is not found in dir %s\n", *scenario_file_name, *test_dir_name); + fprintf(stderr, "ERROR: Scenario file name %s is not found in dir %s\n", *scenario_file_name, *et_dir_name); } } return rv; @@ -1408,12 +623,12 @@ int main( int argc, char **argv ) //------------------------------------------------------------------------------ { int actions = 0; - char *test_dir_name = NULL; + char *et_dir_name = NULL; char *scenario_file_name = NULL; char *enb_config_file_name = NULL; - char play_scenario_filename[NAME_MAX]; int ret = 0; - test_scenario_t *scenario = NULL; + et_scenario_t *scenario = NULL; + char play_scenario_filename[NAME_MAX]; memset(play_scenario_filename, 0, sizeof(play_scenario_filename)); g_openair_dir = getenv("OPENAIR_DIR"); @@ -1428,15 +643,15 @@ int main( int argc, char **argv ) set_comp_log(S1AP, LOG_TRACE, LOG_MED, 1); set_comp_log(SCTP, LOG_TRACE, LOG_MED, 1); - asn_debug = 1; + asn_debug = 0; asn1_xer_print = 1; //parameters - actions = config_parse_opt_line (argc, argv, &test_dir_name, &scenario_file_name, &enb_config_file_name); //Command-line options + actions = et_config_parse_opt_line (argc, argv, &et_dir_name, &scenario_file_name, &enb_config_file_name); //Command-line options if (actions & PLAY_SCENARIO) { - if (generate_xml_scenario(test_dir_name, scenario_file_name,enb_config_file_name, play_scenario_filename) == 0) { - if (NULL != (scenario = generate_scenario(play_scenario_filename))) { - ret = play_scenario(scenario); + if (et_generate_xml_scenario(et_dir_name, scenario_file_name,enb_config_file_name, play_scenario_filename) == 0) { + if (NULL != (scenario = et_generate_scenario(play_scenario_filename))) { + ret = et_play_scenario(scenario); } else { fprintf(stderr, "ERROR: Could not generate scenario from tsml file\n"); ret = -1; @@ -1445,9 +660,9 @@ int main( int argc, char **argv ) fprintf(stderr, "ERROR: Could not generate tsml scenario from xml file\n"); ret = -1; } - free_pointer(test_dir_name); - free_pointer(scenario_file_name); - free_pointer(enb_config_file_name); + et_free_pointer(et_dir_name); + et_free_pointer(scenario_file_name); + et_free_pointer(enb_config_file_name); } return ret; diff --git a/openair3/TEST/EPC_TEST/play_scenario.h b/openair3/TEST/EPC_TEST/play_scenario.h index 2bf6cc4ccf..725b5abc0e 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.h +++ b/openair3/TEST/EPC_TEST/play_scenario.h @@ -28,7 +28,7 @@ *******************************************************************************/ /* - play_scenario.h + et_scenario.h ------------------- AUTHOR : Lionel GAUTHIER COMPANY : EURECOM @@ -42,21 +42,44 @@ # include # include +#include "enb_config.h" #include "s1ap_ies_defs.h" +# define ET_ENB_REGISTER_RETRY_DELAY 3 -/** @defgroup _enb_app ENB APP - * @ingroup _oai2 - * @{ - */ typedef enum { - ACTION_S1C_START = 0, - ACTION_S1C_NULL = ACTION_S1C_START, - ACTION_S1C_SEND, - ACTION_S1C_RECEIVE, - ACTION_S1C_END -} test_action_t; + ET_PACKET_STATUS_START = 0, + ET_PACKET_STATUS_NONE = ET_PACKET_STATUS_START, + ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT, + ET_PACKET_STATUS_SCHEDULED_FOR_SENDING, + ET_PACKET_STATUS_SENT, + ET_PACKET_STATUS_SENT_WITH_ERRORS, + ET_PACKET_STATUS_SCHEDULED_FOR_RECEIVING, + ET_PACKET_STATUS_RECEIVED, + ET_PACKET_STATUS_RECEIVED_WITH_ERRORS, + ET_PACKET_STATUS_END +} et_packet_status_t; + +typedef enum { + ET_FSM_STATE_START = 0, + ET_FSM_STATE_NULL = ET_FSM_STATE_START, + ET_FSM_STATE_CONNECTING_SCTP, + ET_FSM_STATE_WAITING_TX_EVENT, + ET_FSM_STATE_WAITING_RX_EVENT, + ET_FSM_STATE_END +} et_fsm_state_t; + + + + +typedef enum { + ET_PACKET_ACTION_S1C_START = 0, + ET_PACKET_ACTION_S1C_NULL = ET_PACKET_ACTION_S1C_START, + ET_PACKET_ACTION_S1C_SEND, + ET_PACKET_ACTION_S1C_RECEIVE, + ET_PACKET_ACTION_S1C_END +} et_packet_action_t; // from kernel source file 3.19/include/linux/sctp.h typedef enum { @@ -94,16 +117,17 @@ typedef enum { TEST_S1AP_PDU_TYPE_SUCCESSFUL_OUTCOME, TEST_S1AP_PDU_TYPE_UNSUCCESSFUL_OUTCOME, TEST_S1AP_PDU_TYPE_END -} test_s1ap_pdu_type_t; +} et_s1ap_pdu_type_t; -typedef struct test_s1ap_s { - //test_s1ap_pdu_type_t pdu_type; +typedef struct et_s1ap_s { + //et_s1ap_pdu_type_t pdu_type; + S1AP_PDU_t pdu; // decoded ASN1 C type: choice of initiatingMessage, successfulOutcome, unsuccessfulOutcome uint16_t binary_stream_pos; uint16_t binary_stream_allocated_size; uint8_t *binary_stream; - s1ap_message message; -} test_s1ap_t; + s1ap_message message; // decoded message: information elements +} et_s1ap_t; // from kernel source file 3.19/include/linux/sctp.h, Big Endians @@ -112,7 +136,7 @@ typedef struct sctp_datahdr_s { uint16_t stream; uint16_t ssn; uint32_t ppid; - test_s1ap_t payload; + et_s1ap_t payload; } sctp_datahdr_t; // from kernel source file 3.19/include/linux/sctp.h, Big Endians @@ -127,7 +151,7 @@ typedef struct sctp_inithdr { typedef sctp_inithdr_t sctp_initackhdr_t; -typedef struct test_sctp_hdr_s { +typedef struct et_sctp_hdr_s { unsigned int src_port; unsigned int dst_port; sctp_cid_t chunk_type; @@ -136,38 +160,145 @@ typedef struct test_sctp_hdr_s { sctp_inithdr_t init_hdr; sctp_initackhdr_t init_ack_hdr; } u; -} test_sctp_hdr_t; +} et_sctp_hdr_t; -typedef struct test_ip_s { +typedef struct et_ip_s { unsigned int address_family; // AF_INET, AF_INET6 union { struct in6_addr ipv6; in_addr_t ipv4; }address; -}test_ip_t; +}et_ip_t; -typedef struct test_ip_hdr_s { - test_ip_t src; - test_ip_t dst; -} test_ip_hdr_t; +typedef struct et_ip_hdr_s { + et_ip_t src; + et_ip_t dst; +} et_ip_hdr_t; -typedef struct test_packet_s { - test_action_t action; - struct timeval time_relative_to_first_packet; - struct timeval time_relative_to_last_sent_packet; - struct timeval time_relative_to_last_received_packet; - unsigned int original_frame_number; - unsigned int packet_number; - test_ip_hdr_t ip_hdr; - test_sctp_hdr_t sctp_hdr; - struct test_packet_s *next; -}test_packet_t; +typedef struct et_packet_s { + et_packet_action_t action; + struct timeval time_relative_to_first_packet; + struct timeval time_relative_to_last_sent_packet; + struct timeval time_relative_to_last_received_packet; + unsigned int original_frame_number; + unsigned int packet_number; + et_ip_hdr_t ip_hdr; + et_sctp_hdr_t sctp_hdr; + struct et_packet_s *next; + //scenario running vars + et_packet_status_t status; +}et_packet_t; -typedef struct test_scenario_s { + +typedef struct sctp_epoll_s { + /* Array of events monitored by the task. + * By default only one fd is monitored (the one used to received messages + * from other tasks). + * More events can be suscribed later by the task itself. + */ + struct epoll_event *events; + + int epoll_nb_events; + +} thread_desc_t; + +typedef struct et_scenario_s { xmlChar *name; - test_packet_t *list_packet; -}test_scenario_t; + et_packet_t *list_packet; -inline void free_pointer(void *p) {if (NULL != p) {free(p); p=NULL;}}; -#endif /* ENB_CONFIG_H_ */ -/** @} */ + // playing scenario + et_packet_t *waited_packet; + et_packet_t *current_packet; +} et_scenario_t; + + +typedef enum { + ET_EVENT_START = 0, + ET_EVENT_INIT = ET_EVENT_START, + ET_EVENT_RX_SCTP_EVENT, + ET_EVENT_RX_S1AP, + ET_EVENT_RX_X2AP, + ET_EVENT_RX_PACKET_TIME_OUT, + ET_EVENT_TX_PACKET, + ET_EVENT_STOP, + ET_EVENT_END +} et_event_code_t; + +typedef struct et_event_init_s { + et_scenario_t *scenario; +} et_event_init_t; + +typedef struct et_event_s1ap_data_ind_s { + sctp_datahdr_t sctp_datahdr; +} et_event_s1ap_data_ind_t; + +typedef struct et_event_s1ap_data_req_s { + +} et_event_s1ap_data_req_t; + +typedef struct et_event_s { + et_event_code_t code; + union { + et_event_init_t init; + et_event_s1ap_data_ind_t s1ap_data_ind; + et_event_s1ap_data_req_t s1ap_data_req; + } u; +} et_event_t; + +inline void et_free_pointer(void *p) {if (NULL != p) {free(p); p=NULL;}}; + +//------------------------- +void et_free_packet(et_packet_t* packet); +void et_free_scenario(et_scenario_t* scenario); +//------------------------- +void et_display_packet_s1ap_data(const et_s1ap_t * const s1ap); +void et_display_packet_sctp_init(const sctp_inithdr_t * const sctp); +void et_display_packet_sctp_initack(const sctp_initackhdr_t * const sctp); +void et_display_packet_sctp_data(const sctp_datahdr_t * const sctp); +void et_display_packet_sctp(const et_sctp_hdr_t * const sctp); +void et_display_packet_ip(const et_ip_hdr_t * const ip); +void et_display_packet(const et_packet_t * const packet); +void et_display_scenario(const et_scenario_t * const scenario); +//------------------------- +int et_s1ap_decode_initiating_message(s1ap_message *message, S1ap_InitiatingMessage_t *initiating_p); +int et_s1ap_decode_successful_outcome(s1ap_message *message, S1ap_SuccessfulOutcome_t *successfullOutcome_p); +int et_s1ap_decode_unsuccessful_outcome(s1ap_message *message, S1ap_UnsuccessfulOutcome_t *unSuccessfullOutcome_p); +int et_s1ap_decode_pdu(S1AP_PDU_t * const pdu, s1ap_message * const message, const uint8_t * const buffer, const uint32_t length); +void et_decode_s1ap(et_s1ap_t * const s1ap); +//------------------------- +void et_s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind); +void * et_s1ap_eNB_task(void *arg); +int et_generate_xml_scenario( + const char const * xml_in_dir_name, + const char const * xml_in_scenario_filename, + const char const * enb_config_filename, + char const * tsml_out_scenario_filename); +//------------------------- +int et_scenario_fsm_notify_event_state_null(et_event_t event); +int et_scenario_fsm_notify_event(et_event_t event); +//------------------------- +void et_parse_s1ap(xmlDocPtr doc, const xmlNode const *s1ap_node, et_s1ap_t * const s1ap); +void et_parse_sctp_data_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_datahdr_t * const sctp_hdr); +void et_parse_sctp_init_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_inithdr_t * const sctp_hdr); +void et_parse_sctp_init_ack_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_initackhdr_t * const sctp_hdr); +void et_parse_sctp(xmlDocPtr doc, const xmlNode const *sctp_node, et_sctp_hdr_t * const sctp_hdr); +et_packet_t* et_parse_xml_packet(xmlDocPtr doc, xmlNodePtr node); +et_scenario_t* et_generate_scenario(const char * const et_scenario_filename ); +//------------------------- +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); +int et_strip_extension( char *in_filename); +int et_split_path ( char * pathP, char *** resP); +void et_display_node ( xmlNodePtr node, unsigned int indent); +void et_display_tree ( xmlNodePtr node, unsigned int indent); +char * et_ip2ip_str(const et_ip_t * const ip); +int et_hex2data(unsigned char * const data, const unsigned char * const hexstring, const unsigned int len); +sctp_cid_t et_chunk_type_str2cid(const xmlChar * const chunk_type_str); +const char * const et_chunk_type_cid2str(const sctp_cid_t chunk_type); +et_packet_action_t et_action_str2et_action_t(const xmlChar * const action); +void et_ip_str2et_ip(const xmlChar * const ip_str, et_ip_t * const ip); +uint32_t et_eNB_app_register(const Enb_properties_array_t *enb_properties); +void *et_eNB_app_task(void *args_p); +int et_play_scenario(et_scenario_t* const scenario); + +#endif /* PLAY_SCENARIO_H_ */ diff --git a/openair3/TEST/EPC_TEST/play_scenario_decode.c b/openair3/TEST/EPC_TEST/play_scenario_decode.c new file mode 100644 index 0000000000..aba1703eb3 --- /dev/null +++ b/openair3/TEST/EPC_TEST/play_scenario_decode.c @@ -0,0 +1,214 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2014 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see . + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE + + *******************************************************************************/ + +/* + play_scenario_decode.c + ------------------- + AUTHOR : Lionel GAUTHIER + COMPANY : EURECOM + EMAIL : Lionel.Gauthier@eurecom.fr + */ + +#include "intertask_interface.h" +#include "platform_types.h" +#include "s1ap_ies_defs.h" +#include "s1ap_eNB_decoder.h" +#include "assertions.h" +#include "play_scenario.h" + +//------------------------------------------------------------------------------ +int et_s1ap_decode_initiating_message(s1ap_message *message, S1ap_InitiatingMessage_t *initiating_p) +{ + int ret = -1; + + DevAssert(initiating_p != NULL); + + message->procedureCode = initiating_p->procedureCode; + message->criticality = initiating_p->criticality; + + switch(initiating_p->procedureCode) { + case S1ap_ProcedureCode_id_downlinkNASTransport: + ret = s1ap_decode_s1ap_downlinknastransporties(&message->msg.s1ap_DownlinkNASTransportIEs,&initiating_p->value); + break; + + case S1ap_ProcedureCode_id_InitialContextSetup: + ret = s1ap_decode_s1ap_initialcontextsetuprequesties(&message->msg.s1ap_InitialContextSetupRequestIEs, &initiating_p->value); + break; + + case S1ap_ProcedureCode_id_UEContextRelease: + ret = s1ap_decode_s1ap_uecontextreleasecommandies(&message->msg.s1ap_UEContextReleaseCommandIEs, &initiating_p->value); + break; + + case S1ap_ProcedureCode_id_Paging: + ret = s1ap_decode_s1ap_pagingies(&message->msg.s1ap_PagingIEs, &initiating_p->value); + break; + + case S1ap_ProcedureCode_id_uplinkNASTransport: + ret = s1ap_decode_s1ap_uplinknastransporties (&message->msg.s1ap_UplinkNASTransportIEs, &initiating_p->value); + break; + + case S1ap_ProcedureCode_id_S1Setup: + ret = s1ap_decode_s1ap_s1setuprequesties (&message->msg.s1ap_S1SetupRequestIEs, &initiating_p->value); + break; + + case S1ap_ProcedureCode_id_initialUEMessage: + ret = s1ap_decode_s1ap_initialuemessageies (&message->msg.s1ap_InitialUEMessageIEs, &initiating_p->value); + break; + + case S1ap_ProcedureCode_id_UEContextReleaseRequest: + ret = s1ap_decode_s1ap_uecontextreleaserequesties (&message->msg.s1ap_UEContextReleaseRequestIEs, &initiating_p->value); + break; + + case S1ap_ProcedureCode_id_UECapabilityInfoIndication: + ret = s1ap_decode_s1ap_uecapabilityinfoindicationies (&message->msg.s1ap_UECapabilityInfoIndicationIEs, &initiating_p->value); + break; + + case S1ap_ProcedureCode_id_NASNonDeliveryIndication: + ret = s1ap_decode_s1ap_nasnondeliveryindication_ies (&message->msg.s1ap_NASNonDeliveryIndication_IEs, &initiating_p->value); + break; + + default: + AssertFatal( 0 , "Unknown procedure ID (%d) for initiating message\n", + (int)initiating_p->procedureCode); + return -1; + } + return ret; +} + +//------------------------------------------------------------------------------ +int et_s1ap_decode_successful_outcome(s1ap_message *message, S1ap_SuccessfulOutcome_t *successfullOutcome_p) +{ + int ret = -1; + + DevAssert(successfullOutcome_p != NULL); + + message->procedureCode = successfullOutcome_p->procedureCode; + message->criticality = successfullOutcome_p->criticality; + + switch(successfullOutcome_p->procedureCode) { + case S1ap_ProcedureCode_id_S1Setup: + ret = s1ap_decode_s1ap_s1setupresponseies( + &message->msg.s1ap_S1SetupResponseIEs, &successfullOutcome_p->value); + break; + + case S1ap_ProcedureCode_id_InitialContextSetup: + ret = s1ap_decode_s1ap_initialcontextsetupresponseies (&message->msg.s1ap_InitialContextSetupResponseIEs, &successfullOutcome_p->value); + break; + + case S1ap_ProcedureCode_id_UEContextRelease: + ret = s1ap_decode_s1ap_uecontextreleasecompleteies (&message->msg.s1ap_UEContextReleaseCompleteIEs, &successfullOutcome_p->value); + break; + + default: + AssertFatal(0, "Unknown procedure ID (%d) for successfull outcome message\n", + (int)successfullOutcome_p->procedureCode); + return -1; + } + return ret; +} + +//------------------------------------------------------------------------------ +int et_s1ap_decode_unsuccessful_outcome(s1ap_message *message, S1ap_UnsuccessfulOutcome_t *unSuccessfullOutcome_p) +{ + int ret = -1; + + DevAssert(unSuccessfullOutcome_p != NULL); + + message->procedureCode = unSuccessfullOutcome_p->procedureCode; + message->criticality = unSuccessfullOutcome_p->criticality; + + switch(unSuccessfullOutcome_p->procedureCode) { + case S1ap_ProcedureCode_id_S1Setup: + ret = s1ap_decode_s1ap_s1setupfailureies(&message->msg.s1ap_S1SetupFailureIEs, &unSuccessfullOutcome_p->value); + break; + + case S1ap_ProcedureCode_id_InitialContextSetup: + ret = s1ap_decode_s1ap_initialcontextsetupfailureies (&message->msg.s1ap_InitialContextSetupFailureIEs, &unSuccessfullOutcome_p->value); + break; + + default: + AssertFatal(0,"Unknown procedure ID (%d) for unsuccessfull outcome message\n", + (int)unSuccessfullOutcome_p->procedureCode); + break; + } + return ret; +} + +//------------------------------------------------------------------------------ +int et_s1ap_decode_pdu(S1AP_PDU_t * const pdu, s1ap_message * const message, const uint8_t * const buffer, const uint32_t length) +{ + asn_dec_rval_t dec_ret; + + DevAssert(buffer != NULL); + + memset((void *)pdu, 0, sizeof(S1AP_PDU_t)); + + dec_ret = aper_decode(NULL, + &asn_DEF_S1AP_PDU, + (void **)&pdu, + buffer, + length, + 0, + 0); + + if (dec_ret.code != RC_OK) { + S1AP_ERROR("Failed to decode pdu\n"); + return -1; + } + + message->direction = pdu->present; + + switch(pdu->present) { + case S1AP_PDU_PR_initiatingMessage: + return et_s1ap_decode_initiating_message(message, + &pdu->choice.initiatingMessage); + + case S1AP_PDU_PR_successfulOutcome: + return et_s1ap_decode_successful_outcome(message, + &pdu->choice.successfulOutcome); + + case S1AP_PDU_PR_unsuccessfulOutcome: + return et_s1ap_decode_unsuccessful_outcome(message, + &pdu->choice.unsuccessfulOutcome); + + default: + AssertFatal(0, "Unknown presence (%d) or not implemented\n", (int)pdu->present); + break; + } + return -1; +} +//------------------------------------------------------------------------------ +void et_decode_s1ap(et_s1ap_t * const s1ap) +{ + if (NULL != s1ap) { + if (et_s1ap_decode_pdu(&s1ap->pdu, &s1ap->message, s1ap->binary_stream, s1ap->binary_stream_allocated_size) < 0) { + AssertFatal (0, "ERROR %s() Cannot decode S1AP message!\n", __FUNCTION__); + } + } +} diff --git a/openair3/TEST/EPC_TEST/play_scenario_display.c b/openair3/TEST/EPC_TEST/play_scenario_display.c new file mode 100644 index 0000000000..406c69c858 --- /dev/null +++ b/openair3/TEST/EPC_TEST/play_scenario_display.c @@ -0,0 +1,292 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2014 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see . + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE + + *******************************************************************************/ + +/* + play_scenario_display.c + ------------------- + AUTHOR : Lionel GAUTHIER + COMPANY : EURECOM + EMAIL : Lionel.Gauthier@eurecom.fr + */ +#include +#include + +#include "intertask_interface.h" +#include "platform_types.h" +#include "assertions.h" +#include "s1ap_ies_defs.h" +#include "s1ap_eNB_decoder.h" +#include "play_scenario.h" +//----------------------------------------------------------------------------- +void et_print_hex_octets(const unsigned char * const byte_stream, const unsigned long int num) +{ + unsigned long octet_index = 0; + + if (byte_stream == NULL) { + return; + } + + fprintf(stdout, "+-----+-------------------------------------------------+\n"); + fprintf(stdout, "| | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n"); + fprintf(stdout, "+-----+-------------------------------------------------+\n"); + + for (octet_index = 0; octet_index < num; octet_index++) { + if ((octet_index % 16) == 0) { + if (octet_index != 0) { + fprintf(stdout, " |\n"); + } + + fprintf(stdout, " %04ld |", octet_index); + } + + /* + * Print every single octet in hexadecimal form + */ + fprintf(stdout, " %02x", byte_stream[octet_index]); + /* + * Align newline and pipes according to the octets in groups of 2 + */ + } + + /* + * Append enough spaces and put final pipe + */ + unsigned char index; + + for (index = octet_index; index < 16; ++index) { + fprintf(stdout, " "); + } + + fprintf(stdout, " |\n"); +} + +//------------------------------------------------------------------------------ +void et_display_node(xmlNodePtr node, unsigned int indent) +{ + int i = 0; + if (node->type == XML_ELEMENT_NODE) { + xmlChar *path = xmlGetNodePath(node); + for (i=0; ichildren != NULL && node->children->type == XML_TEXT_NODE) { + xmlChar *content = xmlNodeGetContent(node); + printf("%s -> %s\n", path, content); + xmlFree(content); + } else { + printf("%s\n", path); + } + xmlFree(path); + } +} +//------------------------------------------------------------------------------ +void et_display_tree(xmlNodePtr node, unsigned int indent) +{ + xmlNode *cur_node = NULL; + + for (cur_node = node; cur_node; cur_node = cur_node->next) { + if (cur_node->type == XML_ELEMENT_NODE) { + et_display_node(cur_node, indent); + } + et_display_tree(cur_node->children, indent++); + } +} +//------------------------------------------------------------------------------ +void et_display_packet_s1ap_data(const et_s1ap_t * const s1ap) +{ + char *message_string = NULL; + + if (s1ap) { + message_string = calloc(20000, sizeof(char)); + AssertFatal (NULL != message_string, "ERROR malloc()failed!\n"); + s1ap_string_total_size = 0; + switch(s1ap->pdu.present) { + case S1AP_PDU_PR_initiatingMessage: + switch(s1ap->pdu.choice.initiatingMessage.procedureCode) { + case S1ap_ProcedureCode_id_downlinkNASTransport: s1ap_xer_print_s1ap_downlinknastransport(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; + case S1ap_ProcedureCode_id_InitialContextSetup: s1ap_xer_print_s1ap_initialcontextsetuprequest(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; + case S1ap_ProcedureCode_id_UEContextRelease: s1ap_xer_print_s1ap_uecontextreleasecommand(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; + case S1ap_ProcedureCode_id_Paging: s1ap_xer_print_s1ap_paging(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; + case S1ap_ProcedureCode_id_uplinkNASTransport: s1ap_xer_print_s1ap_uplinknastransport(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; + case S1ap_ProcedureCode_id_S1Setup: s1ap_xer_print_s1ap_s1setuprequest(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; + case S1ap_ProcedureCode_id_initialUEMessage: s1ap_xer_print_s1ap_initialuemessage(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; + case S1ap_ProcedureCode_id_UEContextReleaseRequest: s1ap_xer_print_s1ap_uecontextreleaserequest(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; + case S1ap_ProcedureCode_id_UECapabilityInfoIndication:s1ap_xer_print_s1ap_uecapabilityinfoindication(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; + case S1ap_ProcedureCode_id_NASNonDeliveryIndication: s1ap_xer_print_s1ap_nasnondeliveryindication_(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; + default: + AssertFatal( 0 , "Unknown procedure ID (%d) for initiating message\n", + (int)s1ap->pdu.choice.initiatingMessage.procedureCode); + } + break; + case S1AP_PDU_PR_successfulOutcome: + switch(s1ap->pdu.choice.successfulOutcome.procedureCode) { + case S1ap_ProcedureCode_id_S1Setup: s1ap_xer_print_s1ap_s1setupresponse(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; + case S1ap_ProcedureCode_id_InitialContextSetup: s1ap_xer_print_s1ap_initialcontextsetupresponse(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; + case S1ap_ProcedureCode_id_UEContextRelease: s1ap_xer_print_s1ap_uecontextreleasecomplete(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; + default: + AssertFatal(0, "Unknown procedure ID (%d) for successfull outcome message\n", + (int)s1ap->pdu.choice.successfulOutcome.procedureCode); + } + break; + + case S1AP_PDU_PR_unsuccessfulOutcome: + switch(s1ap->pdu.choice.unsuccessfulOutcome.procedureCode) { + case S1ap_ProcedureCode_id_S1Setup: s1ap_xer_print_s1ap_s1setupfailure(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; + case S1ap_ProcedureCode_id_InitialContextSetup: s1ap_xer_print_s1ap_initialcontextsetupfailure(s1ap_xer__print2sp, message_string, (s1ap_message *)&s1ap->message);break; + default: + et_free_pointer(message_string); + AssertFatal(0,"Unknown procedure ID (%d) for unsuccessfull outcome message\n", + (int)s1ap->pdu.choice.unsuccessfulOutcome.procedureCode); + break; + } + break; + default: + AssertFatal(0, "Unknown presence (%d) or not implemented\n", (int)s1ap->pdu.present); + break; + } + fprintf(stdout, "\t\tSCTP.data XML dump:\n%s\n", message_string); + et_free_pointer(message_string); + } +} +//------------------------------------------------------------------------------ +void et_display_packet_sctp_init(const sctp_inithdr_t * const sctp) +{ + + if (sctp) { + fprintf(stdout, "\t\tSCTP.init.init_tag : %u\n", sctp->init_tag); + fprintf(stdout, "\t\tSCTP.init.a_rwnd : %u\n", sctp->a_rwnd); + fprintf(stdout, "\t\tSCTP.init.num_inbound_streams : %u\n", sctp->num_inbound_streams); + fprintf(stdout, "\t\tSCTP.init.num_outbound_streams : %u\n", sctp->num_outbound_streams); + fprintf(stdout, "\t\tSCTP.init.initial_tsn : %u\n", sctp->initial_tsn); + } +} +//------------------------------------------------------------------------------ +void et_display_packet_sctp_initack(const sctp_initackhdr_t * const sctp) +{ + + if (sctp) { + fprintf(stdout, "\t\tSCTP.initack.init_tag : %u\n", sctp->init_tag); + fprintf(stdout, "\t\tSCTP.initack.a_rwnd : %u\n", sctp->a_rwnd); + fprintf(stdout, "\t\tSCTP.initack.num_inbound_streams : %u\n", sctp->num_inbound_streams); + fprintf(stdout, "\t\tSCTP.initack.num_outbound_streams : %u\n", sctp->num_outbound_streams); + fprintf(stdout, "\t\tSCTP.initack.initial_tsn : %u\n", sctp->initial_tsn); + } +} +//------------------------------------------------------------------------------ +void et_display_packet_sctp_data(const sctp_datahdr_t * const sctp) +{ + if (sctp) { + fprintf(stdout, "\t\tSCTP.data.tsn : %u\n", sctp->tsn); + fprintf(stdout, "\t\tSCTP.data.stream : %u\n", sctp->stream); + fprintf(stdout, "\t\tSCTP.data.ssn : %u\n", sctp->ssn); + fprintf(stdout, "\t\tSCTP.data.ppid : %u\n", sctp->ppid); + if (sctp->ppid == 18) { + et_display_packet_s1ap_data(&sctp->payload); + } + fprintf(stdout, "\t\tSCTP.data.binary_stream_allocated_size : %u\n", sctp->payload.binary_stream_allocated_size); + if (NULL != sctp->payload.binary_stream) { + fprintf(stdout, "\t\tSCTP.data.binary_stream :\n"); + et_print_hex_octets(sctp->payload.binary_stream, sctp->payload.binary_stream_allocated_size); + } else { + fprintf(stdout, "\t\tSCTP.data.binary_stream : NULL\n"); + } + } +} + +//------------------------------------------------------------------------------ +void et_display_packet_sctp(const et_sctp_hdr_t * const sctp) +{ + if (sctp) { + fprintf(stdout, "\t\tSCTP.src_port : %u\n", sctp->src_port); + fprintf(stdout, "\t\tSCTP.dst_port : %u\n", sctp->dst_port); + fprintf(stdout, "\t\tSCTP.chunk_type : %s\n", et_chunk_type_cid2str(sctp->chunk_type)); + switch (sctp->chunk_type) { + case SCTP_CID_DATA: + et_display_packet_sctp_data(&sctp->u.data_hdr); + break; + case SCTP_CID_INIT: + et_display_packet_sctp_initack(&sctp->u.init_hdr); + break; + case SCTP_CID_INIT_ACK: + et_display_packet_sctp_initack(&sctp->u.init_ack_hdr); + break; + default: + ; + } + } +} +//------------------------------------------------------------------------------ +void et_display_packet_ip(const et_ip_hdr_t * const ip) +{ + if (ip) { + fprintf(stdout, "\t\tSource address : %s\n", et_ip2ip_str(&ip->src)); + fprintf(stdout, "\t\tDestination address : %s\n", et_ip2ip_str(&ip->dst)); + } +} + +//------------------------------------------------------------------------------ +void et_display_packet(const et_packet_t * const packet) +{ + if (packet) { + fprintf(stdout, "-------------------------------------------------------------------------------\n"); + fprintf(stdout, "\tPacket:\tnum %u | original frame number %u \n", packet->packet_number, packet->original_frame_number); + fprintf(stdout, "\tPacket:\ttime relative to 1st packet %ld.%06lu\n", + packet->time_relative_to_first_packet.tv_sec, packet->time_relative_to_first_packet.tv_usec); + fprintf(stdout, "\tPacket:\ttime relative to last tx packet %ld.%06lu\n", + packet->time_relative_to_last_sent_packet.tv_sec, packet->time_relative_to_last_sent_packet.tv_usec); + fprintf(stdout, "\tPacket:\ttime relative to last_received packet %ld.%06lu\n", + packet->time_relative_to_last_received_packet.tv_sec, packet->time_relative_to_last_received_packet.tv_usec); + + switch(packet->action) { + case ET_PACKET_ACTION_S1C_SEND: + fprintf(stdout, "\tPacket:\tAction SEND\n"); + break; + case ET_PACKET_ACTION_S1C_RECEIVE: + fprintf(stdout, "\tPacket:\tAction RECEIVE\n"); + break; + default: + fprintf(stdout, "\tPacket:\tAction UNKNOWN\n"); + } + et_display_packet_ip(&packet->ip_hdr); + et_display_packet_sctp(&packet->sctp_hdr); + } +} +//------------------------------------------------------------------------------ +void et_display_scenario(const et_scenario_t * const scenario) +{ + et_packet_t *packet = NULL; + if (scenario) { + fprintf(stdout, "Scenario: %s\n", (scenario->name != NULL) ? (char*)scenario->name:"UNKNOWN NAME"); + packet = scenario->list_packet; + while (packet) { + et_display_packet(packet); + packet = packet->next; + } + } +} diff --git a/openair3/TEST/EPC_TEST/play_scenario_fsm.c b/openair3/TEST/EPC_TEST/play_scenario_fsm.c new file mode 100644 index 0000000000..6c73793f4d --- /dev/null +++ b/openair3/TEST/EPC_TEST/play_scenario_fsm.c @@ -0,0 +1,127 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2014 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see . + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE + + *******************************************************************************/ + +/* + play_scenario_fsm.c + ------------------- + AUTHOR : Lionel GAUTHIER + COMPANY : EURECOM + EMAIL : Lionel.Gauthier@eurecom.fr + */ +#include + +#include "intertask_interface.h" +#include "platform_types.h" +#include "assertions.h" +#include "play_scenario.h" + + +et_scenario_t *g_scenario = NULL; +et_fsm_state_t g_fsm_state = ET_FSM_STATE_NULL; +//------------------------------------------------------------------------------ +int et_scenario_fsm_notify_event_state_null(et_event_t event) +{ + et_packet_t *packet = NULL; + const Enb_properties_array_t *enb_properties_p = NULL; + uint32_t register_enb_pending; + + switch (event.code){ + case ET_EVENT_INIT: + AssertFatal(NULL == g_scenario, "Current scenario not ended"); + g_scenario = event.u.init.scenario; + packet = g_scenario->list_packet; + while (NULL != packet) { + switch (packet->sctp_hdr.chunk_type) { + + case SCTP_CID_DATA : + // no init in this scenario, may be sub-scenario + if (packet->action == ET_PACKET_ACTION_S1C_SEND) { + } else if (packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { + g_scenario->waited_packet = packet; + } else { + packet->status = ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT; + packet = packet->next; + } + break; + case SCTP_CID_INIT: + case SCTP_CID_INIT_ACK: + enb_properties_p = enb_config_get(); + /* Try to register each eNB */ + g_fsm_state = ET_FSM_STATE_CONNECTING_SCTP; + register_enb_pending = et_eNB_app_register (enb_properties_p); + break; + case SCTP_CID_HEARTBEAT: + case SCTP_CID_HEARTBEAT_ACK: + case SCTP_CID_COOKIE_ECHO: + case SCTP_CID_COOKIE_ACK: + case SCTP_CID_ECN_ECNE: + case SCTP_CID_ECN_CWR: + packet->status = ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT; + packet = packet->next; + break; + case SCTP_CID_ABORT: + case SCTP_CID_SHUTDOWN: + case SCTP_CID_SHUTDOWN_ACK: + case SCTP_CID_ERROR: + case SCTP_CID_SHUTDOWN_COMPLETE: + AssertFatal(0, "The scenario should be cleaned (packet %s cannot be processed at this time)", et_chunk_type_cid2str(packet->sctp_hdr.chunk_type)); + break; + + default: + packet->status = ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT; + packet = packet->next; + } + } + fprintf(stderr, "No Packet found in this scenario: %s\n", g_scenario->name); + return -1; + break; + + case ET_EVENT_STOP: + break; + + default: + AssertFatal(0, "Case event %d not handled in ET_FSM_STATE_NULL", event.code); + } + return 0; +} + +//------------------------------------------------------------------------------ +int et_scenario_fsm_notify_event(et_event_t event) +{ + AssertFatal((event.code >= ET_EVENT_START) && (event.code < ET_EVENT_END), "Unknown et_event_t.code %d", event.code); + + switch (g_fsm_state){ + case ET_FSM_STATE_NULL: return et_scenario_fsm_notify_event_state_null(event); break; + case ET_FSM_STATE_CONNECTING_SCTP: return et_scenario_fsm_notify_event_state_null(event); break; + case ET_FSM_STATE_WAITING_TX_EVENT: return et_scenario_fsm_notify_event_state_null(event); break; + case ET_FSM_STATE_WAITING_RX_EVENT: return et_scenario_fsm_notify_event_state_null(event); break; + default: + return -1; + } +} diff --git a/openair3/TEST/EPC_TEST/play_scenario_parse.c b/openair3/TEST/EPC_TEST/play_scenario_parse.c new file mode 100644 index 0000000000..236c17963a --- /dev/null +++ b/openair3/TEST/EPC_TEST/play_scenario_parse.c @@ -0,0 +1,561 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2014 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see . + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE + + *******************************************************************************/ + +/* + play_scenario_parse.c + ------------------- + AUTHOR : Lionel GAUTHIER + COMPANY : EURECOM + EMAIL : Lionel.Gauthier@eurecom.fr + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "intertask_interface.h" +#include "platform_types.h" +#include "enb_config.h" +#include "assertions.h" +#include "play_scenario.h" +//------------------------------------------------------------------------------ +#define ENB_CONFIG_MAX_XSLT_PARAMS 32 +//------------------------------------------------------------------------------ +extern char *g_openair_dir; +extern Enb_properties_array_t enb_properties; +//------------------------------------------------------------------------------ +void et_parse_s1ap(xmlDocPtr doc, const xmlNode const *s1ap_node, et_s1ap_t * const s1ap) +{ + xmlNode *cur_node = NULL; + xmlChar *xml_char = NULL; + xmlChar *xml_char2 = NULL; + unsigned int size = 0; + int rc = 0; + unsigned int go_deeper_in_tree = 1; + + if ((NULL != s1ap_node) && (NULL != s1ap)) { + for (cur_node = (xmlNode *)s1ap_node; cur_node; cur_node = cur_node->next) { + go_deeper_in_tree = 1; + if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"field"))) { + // do not get hidden fields + xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"hide"); + if (NULL != xml_char) { + if ((!xmlStrcmp(xml_char, (const xmlChar *)"yes"))) { + go_deeper_in_tree = 0; + } + xmlFree(xml_char); + } + if (0 < go_deeper_in_tree) { + // first get size + xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"size"); + if (NULL != xml_char) { + size = strtoul((const char *)xml_char, NULL, 0); + xmlFree(xml_char); + // second: try to get value (always hex) + xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"value"); + if (NULL != xml_char) { + xml_char2 = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"name"); + fprintf(stdout, "s1ap %p field %s size %d value %s\n",s1ap, xml_char2, size, xml_char); + xmlFree(xml_char2); + // if success to get value, do not parse children + //AssertFatal ((xmlStrlen(xml_char) == size), "ERROR %s() mismatch in size %d and strlen %d\n", __FUNCTION__, size, xmlStrlen(xml_char)); + //if (xmlStrlen(xml_char) == size) { + AssertFatal ((s1ap->binary_stream_pos+xmlStrlen(xml_char)/2) <= s1ap->binary_stream_allocated_size, + "ERROR %s() in buffer size: binary_stream_pos %d xmlStrlen(xml_char)/2=%d\n", __FUNCTION__, s1ap->binary_stream_pos, xmlStrlen(xml_char)/2); + rc = et_hex2data( &s1ap->binary_stream[s1ap->binary_stream_pos], xml_char, xmlStrlen(xml_char)); + s1ap->binary_stream_pos += xmlStrlen(xml_char)/2; + et_display_node(cur_node, 0); + AssertFatal (rc >= 0, "ERROR %s() in converting hex string %s len %d size %d rc %d\n", __FUNCTION__, xml_char, xmlStrlen(xml_char), size, rc); + go_deeper_in_tree = 0; + //} + xmlFree(xml_char); + } + } + } + } + if (0 < go_deeper_in_tree) { + et_parse_s1ap(doc, cur_node->children, s1ap); + } + } + } +} + +//------------------------------------------------------------------------------ +void et_parse_sctp_data_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_datahdr_t * const sctp_hdr) +{ + xmlNode *cur_node = NULL; + xmlChar *xml_char = NULL; + xmlChar *xml_char2 = NULL; + + if ((NULL != sctp_node) && (NULL != sctp_hdr)) { + xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"name"); + if (NULL != xml_char) { + if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.data_payload_proto_id"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); + if (NULL != xml_char2) { + sctp_hdr->ppid = strtoul((const char *)xml_char2, NULL, 0); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.data_sid"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); + if (NULL != xml_char2) { + sctp_hdr->stream = strtoul((const char *)xml_char2, NULL, 16); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.data_tsn"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); + if (NULL != xml_char2) { + sctp_hdr->tsn = strtoul((const char *)xml_char2, NULL, 0); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.data_ssn"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); + if (NULL != xml_char2) { + sctp_hdr->ssn = strtoul((const char *)xml_char2, NULL, 0); + xmlFree(xml_char2); + } + } + xmlFree(xml_char); + } + for (cur_node = sctp_node->children; cur_node; cur_node = cur_node->next) { + et_parse_sctp_data_chunk(doc, cur_node, sctp_hdr); + } + } + +} +//------------------------------------------------------------------------------ +void et_parse_sctp_init_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_inithdr_t * const sctp_hdr) +{ + xmlNode *cur_node = NULL; + xmlChar *xml_char = NULL; + xmlChar *xml_char2 = NULL; + + if ((NULL != sctp_node) && (NULL != sctp_hdr)) { + xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"name"); + if (NULL != xml_char) { + if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.init_nr_out_streams"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); + if (NULL != xml_char2) { + sctp_hdr->num_outbound_streams = strtoul((const char *)xml_char2, NULL, 0); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.init_nr_in_streams"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); + if (NULL != xml_char2) { + sctp_hdr->num_inbound_streams = strtoul((const char *)xml_char2, NULL, 0); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.init_credit"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); + if (NULL != xml_char2) { + sctp_hdr->a_rwnd = strtoul((const char *)xml_char2, NULL, 0); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.init_initial_tsn"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); + if (NULL != xml_char2) { + sctp_hdr->initial_tsn = strtoul((const char *)xml_char2, NULL, 0); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.init_initiate_tag"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); + if (NULL != xml_char2) { + sctp_hdr->init_tag = strtoul((const char *)xml_char2, NULL, 16); + xmlFree(xml_char2); + } + } + xmlFree(xml_char); + } + for (cur_node = sctp_node->children; cur_node; cur_node = cur_node->next) { + et_parse_sctp_init_chunk(doc, cur_node, sctp_hdr); + } + } +} +//------------------------------------------------------------------------------ +void et_parse_sctp_init_ack_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_initackhdr_t * const sctp_hdr) +{ + xmlNode *cur_node = NULL; + xmlChar *xml_char = NULL; + xmlChar *xml_char2 = NULL; + + if ((NULL != sctp_node) && (NULL != sctp_hdr)) { + xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"name"); + if (NULL != xml_char) { + if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.initack_nr_out_streams"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); + if (NULL != xml_char2) { + sctp_hdr->num_outbound_streams = strtoul((const char *)xml_char2, NULL, 0); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.initack_nr_in_streams"))) { + xml_char2 = xmlGetProp((xmlNode *)(xmlNode *)sctp_node, (const xmlChar *)"value"); + if (NULL != xml_char2) { + sctp_hdr->num_inbound_streams = strtoul((const char *)xml_char2, NULL, 0); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.initack_credit"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); + if (NULL != xml_char2) { + sctp_hdr->a_rwnd = strtoul((const char *)xml_char2, NULL, 0); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.initack_initial_tsn"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); + if (NULL != xml_char2) { + sctp_hdr->initial_tsn = strtoul((const char *)xml_char2, NULL, 0); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.initack_initiate_tag"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show"); + if (NULL != xml_char2) { + sctp_hdr->init_tag = strtoul((const char *)xml_char2, NULL, 16); + xmlFree(xml_char2); + } + } + xmlFree(xml_char); + } + for (cur_node = sctp_node->children; cur_node; cur_node = cur_node->next) { + et_parse_sctp_init_ack_chunk(doc, cur_node, sctp_hdr); + } + } +} +//------------------------------------------------------------------------------ +void et_parse_sctp(xmlDocPtr doc, const xmlNode const *sctp_node, et_sctp_hdr_t * const sctp_hdr) +{ + xmlNode *cur_node = NULL; + xmlChar *xml_char = NULL; + xmlChar *xml_char2 = NULL; + + if ((NULL != sctp_node) && (NULL != sctp_hdr)) { + if ((!xmlStrcmp(sctp_node->name, (const xmlChar *)"proto"))) { + xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"name"); + if (NULL != xml_char) { + if ((!xmlStrcmp(xml_char, (const xmlChar *)"s1ap"))) { + xmlFree(xml_char); + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"size"); + if (NULL != xml_char2) { + sctp_hdr->u.data_hdr.payload.binary_stream_allocated_size = strtoul((const char *)xml_char2, NULL, 0); + sctp_hdr->u.data_hdr.payload.binary_stream = calloc(1, sctp_hdr->u.data_hdr.payload.binary_stream_allocated_size); + xmlFree(xml_char2); + } + et_parse_s1ap(doc, sctp_node, &sctp_hdr->u.data_hdr.payload); + et_decode_s1ap(&sctp_hdr->u.data_hdr.payload); + return; + } + xmlFree(xml_char); + } + } + //if ((cur_node->type == XML_ATTRIBUTE_NODE) || (cur_node->type == XML_ELEMENT_NODE)) { + xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"name"); + if (NULL != xml_char) { + if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.srcport"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); + if (NULL != xml_char2) { + sctp_hdr->src_port = strtoul((const char *)xml_char2, NULL, 16); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.dstport"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); + if (NULL != xml_char2) { + sctp_hdr->dst_port = strtoul((const char *)xml_char2, NULL, 16); + xmlFree(xml_char2); + } + } else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.chunk_type"))) { + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value"); + if (NULL != xml_char2) { + sctp_hdr->chunk_type = strtoul((const char *)xml_char2, NULL, 0); + xmlFree(xml_char2); + switch (sctp_hdr->chunk_type) { + case SCTP_CID_DATA: + et_parse_sctp_data_chunk(doc, sctp_node->parent, &sctp_hdr->u.data_hdr); + break; + case SCTP_CID_INIT: + et_parse_sctp_init_chunk(doc, sctp_node->parent, &sctp_hdr->u.init_hdr); + break; + case SCTP_CID_INIT_ACK: + et_parse_sctp_init_ack_chunk(doc, sctp_node->parent, &sctp_hdr->u.init_ack_hdr); + break; + default: + ; + } + } + } + } + for (cur_node = sctp_node->children; cur_node; cur_node = cur_node->next) { + et_parse_sctp(doc, cur_node, sctp_hdr); + } + } +} +//------------------------------------------------------------------------------ +et_packet_t* et_parse_xml_packet(xmlDocPtr doc, xmlNodePtr node) { + + et_packet_t *packet = NULL; + xmlNode *cur_node = NULL; + xmlChar *xml_char = NULL; + float afloat = (float)0.0; + static struct timeval initial_time = { .tv_sec = 0, .tv_usec = 0 }; + static struct timeval relative_last_sent_packet = { .tv_sec = 0, .tv_usec = 0 }; + static struct timeval relative_last_received_packet = { .tv_sec = 0, .tv_usec = 0 }; + static char first_packet = 1; + static char first_sent_packet = 1; + static char first_received_packet = 1; + static unsigned int packet_number = 1; + + if (NULL != node) { + packet = calloc(1, sizeof(*packet)); + + xml_char = xmlGetProp(node, (const xmlChar *)"action"); + packet->action = et_action_str2et_action_t(xml_char); + xmlFree(xml_char); + packet->packet_number = packet_number++; + + for (cur_node = node->children; cur_node; cur_node = cur_node->next) { + //if (cur_node->type == XML_ELEMENT_NODE) { + if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"frame.time_relative"))) { + xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"value"); + afloat = atof((const char*)xml_char); + xmlFree(xml_char); + packet->time_relative_to_first_packet.tv_sec = (int)afloat; + packet->time_relative_to_first_packet.tv_usec = (int)((afloat - packet->time_relative_to_first_packet.tv_sec)*1000000); + + if (first_packet > 0) { + initial_time = packet->time_relative_to_first_packet; + packet->time_relative_to_first_packet.tv_sec = 0; + packet->time_relative_to_first_packet.tv_usec = 0; + first_packet = 0; + } else { + timersub(&packet->time_relative_to_first_packet, &initial_time, + &packet->time_relative_to_first_packet); + } + if (packet->action == ET_PACKET_ACTION_S1C_SEND) { + if (first_sent_packet > 0) { + relative_last_sent_packet = packet->time_relative_to_first_packet; + packet->time_relative_to_last_sent_packet.tv_sec = 0; + packet->time_relative_to_last_sent_packet.tv_usec = 0; + first_sent_packet = 0; + } else { + timersub(&packet->time_relative_to_first_packet, &relative_last_sent_packet, + &packet->time_relative_to_last_sent_packet); + relative_last_sent_packet = packet->time_relative_to_first_packet; + } + } else if (packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { + if (first_received_packet > 0) { + relative_last_received_packet.tv_sec = packet->time_relative_to_first_packet.tv_sec; + relative_last_received_packet.tv_usec = packet->time_relative_to_first_packet.tv_usec; + packet->time_relative_to_last_received_packet.tv_sec = 0; + packet->time_relative_to_last_received_packet.tv_usec = 0; + first_received_packet = 0; + } else { + timersub(&packet->time_relative_to_first_packet, &relative_last_received_packet, + &packet->time_relative_to_last_received_packet); + relative_last_received_packet = packet->time_relative_to_first_packet; + } + } + + } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"frame.number"))) { + xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"value"); + packet->original_frame_number = strtoul((const char *)xml_char, NULL, 0); + xmlFree(xml_char); + } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"ip.src"))) { + xml_char = xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1); + et_ip_str2et_ip(xml_char, &packet->ip_hdr.src); + xmlFree(xml_char); + } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"ip.dst"))) { + xml_char = xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1); + et_ip_str2et_ip(xml_char, &packet->ip_hdr.dst); + xmlFree(xml_char); + } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"proto"))) { + xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"name"); + if (NULL != xml_char) { + if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp"))) { + et_parse_sctp(doc, cur_node, &packet->sctp_hdr); + } + xmlFree(xml_char); + } + } + //} + } + } + return packet; +} +//------------------------------------------------------------------------------ +et_scenario_t* et_generate_scenario( + const char * const tsml_out_scenario_filename ) +{ + xmlDocPtr doc = NULL; + xmlNodePtr root = NULL; + xmlNodePtr node = NULL; + xmlChar *xml_char = NULL; + et_scenario_t *scenario = NULL; + et_packet_t *packet = NULL; + et_packet_t **next_packet = NULL; + + doc = xmlParseFile(tsml_out_scenario_filename); + if (NULL == doc) { + AssertFatal (0, "Could not parse scenario xml file %s!\n", tsml_out_scenario_filename); + } else { + fprintf(stdout, "Test scenario file to play: %s\n", tsml_out_scenario_filename); + //xmlDebugDumpDocument(NULL, doc); + } + + // Get root + root = xmlDocGetRootElement(doc); + if (NULL != root) { + if ((!xmlStrcmp(root->name, (const xmlChar *)"scenario"))) { + xml_char = xmlGetProp(root, (const xmlChar *)"name"); + printf("scenario name: %s\n", xml_char); + scenario = calloc(1, sizeof(*scenario)); + scenario->name = xml_char; // nodup nofree + next_packet = &scenario->list_packet; + for (node = root->children; node != NULL; node = node->next) { + if ((!xmlStrcmp(node->name, (const xmlChar *)"packet"))) { + packet = et_parse_xml_packet(doc, node); + if (NULL != packet) { + *next_packet = packet; + next_packet = &packet->next; + } else { + fprintf(stdout, "WARNING omitted packet:\n"); + et_display_node(node, 0); + } + } + } + } + } else { + fprintf(stderr, "Empty xml document\n"); + } + xmlFreeDoc(doc); + xmlCleanupParser(); + return scenario; +} +//------------------------------------------------------------------------------ +int et_generate_xml_scenario( + const char const * xml_in_dir_name, + const char const * xml_in_scenario_filename, + const char const * enb_config_filename, + char const * tsml_out_scenario_filename) +//------------------------------------------------------------------------------ +{ + //int fd_pdml_in; + xsltStylesheetPtr cur = NULL; + xmlDocPtr doc, res; + FILE *play_scenario_file = NULL; + const char *params[2*ENB_CONFIG_MAX_XSLT_PARAMS]; + int nb_params = 0; + int i,j; + char astring[1024]; + struct in_addr addr; + int ret = 0; + + memset(astring, 0, sizeof(astring)); + if (getcwd(astring, sizeof(astring)) != NULL) { + fprintf(stdout, "working in %s directory\n", astring); + } else { + perror("getcwd() ERROR"); + exit(1); + } + + memset(astring, 0, sizeof(astring)); + strcat(astring, g_openair_dir); + strcat(astring, "/openair3/TEST/EPC_TEST/play_scenario.xsl"); + + xmlSubstituteEntitiesDefault(1); + xmlLoadExtDtdDefaultValue = 1; + cur = xsltParseStylesheetFile((const xmlChar *)astring); + if (NULL == cur) { + AssertFatal (0, "Could not parse stylesheet file %s (check OPENAIR_DIR env variable)!\n", astring); + } else { + fprintf(stdout, "XSLT style sheet: %s\n", astring); + } + + doc = xmlParseFile(xml_in_scenario_filename); + if (NULL == doc) { + AssertFatal (0, "Could not parse scenario xml file %s!\n", xml_in_scenario_filename); + } else { + fprintf(stdout, "Test scenario file: %s\n", xml_in_scenario_filename); + } + + for (i = 0; i < enb_properties.number; i++) { + // eNB S1-C IPv4 address + sprintf(astring, "enb_s1c%d", i); + params[nb_params++] = strdup(astring); + addr.s_addr = enb_properties.properties[i]->enb_ipv4_address_for_S1_MME; + sprintf(astring, "\"%s\"", inet_ntoa(addr)); + params[nb_params++] = strdup(astring); + + // MME S1-C IPv4 address + for (j = 0; j < enb_properties.properties[i]->nb_mme; j++) { + sprintf(astring, "mme_s1c%d_%d", i, j); + params[nb_params++] = strdup(astring); + AssertFatal (enb_properties.properties[i]->mme_ip_address[j].ipv4_address, + "Only support MME IPv4 address\n"); + sprintf(astring, "\"%s\"", enb_properties.properties[i]->mme_ip_address[j].ipv4_address); + params[nb_params++] = strdup(astring); + } + } + params[nb_params] = NULL; + res = xsltApplyStylesheet(cur, doc, params); + if (NULL != res) { + sprintf((char *)tsml_out_scenario_filename,"%s",xml_in_scenario_filename); + if (et_strip_extension((char *)tsml_out_scenario_filename) > 0) { + strcat((char *)tsml_out_scenario_filename, ".tsml"); + play_scenario_file = fopen( tsml_out_scenario_filename, "w+"); + if (NULL != play_scenario_file) { + xsltSaveResultToFile(play_scenario_file, res, cur); + fclose(play_scenario_file); + fprintf(stdout, "Wrote test scenario to %s\n", tsml_out_scenario_filename); + } else { + fprintf(stderr, "ERROR in fopen(%s)\n", tsml_out_scenario_filename); + ret = -1; + } + } else { + fprintf(stderr, "ERROR in strip_extension()\n"); + ret = -1; + } + } else { + fprintf(stderr, "ERROR in xsltApplyStylesheet()\n"); + ret = -1; + } + xsltFreeStylesheet(cur); + xmlFreeDoc(doc); + xmlFreeDoc(res); + + xsltCleanupGlobals(); + xmlCleanupParser(); + return ret; +} + diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c new file mode 100644 index 0000000000..cb5571c28b --- /dev/null +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c @@ -0,0 +1,162 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2014 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see . + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE + + *******************************************************************************/ + +/* + play_scenario_s1ap.c + ------------------- + AUTHOR : Lionel GAUTHIER + COMPANY : EURECOM + EMAIL : Lionel.Gauthier@eurecom.fr + */ +#include +#include +#include +#include +#include "tree.h" +#include "queue.h" + + +#include "intertask_interface.h" +#include "messages_types.h" +#include "platform_types.h" +#include "s1ap_common.h" +#include "s1ap_eNB_defs.h" +#include "s1ap_eNB_default_values.h" +#include "s1ap_eNB_management_procedures.h" +#include "s1ap_eNB.h" +#include "play_scenario.h" +#include "msc.h" +#include "assertions.h" +#include "conversions.h" + + +//------------------------------------------------------------------------------ +extern void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp); +extern void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *s1ap_register_eNB); +//------------------------------------------------------------------------------ +void et_s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) +{ + int result = 0; + et_event_t event; + + DevAssert(sctp_data_ind != NULL); + + memset((void*)&event, 0, sizeof(event)); + + event.code = ET_EVENT_RX_S1AP; + event.u.s1ap_data_ind.sctp_datahdr.tsn = 0; + event.u.s1ap_data_ind.sctp_datahdr.stream = sctp_data_ind->stream; + event.u.s1ap_data_ind.sctp_datahdr.ssn = 0; + event.u.s1ap_data_ind.sctp_datahdr.ppid = 18; // find constant + + event.u.s1ap_data_ind.sctp_datahdr.payload.binary_stream_pos = 0; + event.u.s1ap_data_ind.sctp_datahdr.payload.binary_stream_allocated_size = sctp_data_ind->buffer_length; + event.u.s1ap_data_ind.sctp_datahdr.payload.binary_stream = NULL; + if ((sctp_data_ind->buffer_length > 0) && (NULL != sctp_data_ind->buffer)) { + event.u.s1ap_data_ind.sctp_datahdr.payload.binary_stream = calloc(1, sctp_data_ind->buffer_length); + memcpy(event.u.s1ap_data_ind.sctp_datahdr.payload.binary_stream, + sctp_data_ind->buffer, + sctp_data_ind->buffer_length); + + if (et_s1ap_decode_pdu( + &event.u.s1ap_data_ind.sctp_datahdr.payload.pdu, + &event.u.s1ap_data_ind.sctp_datahdr.payload.message, + event.u.s1ap_data_ind.sctp_datahdr.payload.binary_stream, + event.u.s1ap_data_ind.sctp_datahdr.payload.binary_stream_allocated_size) < 0) { + AssertFatal (0, "ERROR %s() Cannot decode RX S1AP message!\n", __FUNCTION__); + } + + } + + result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + + et_scenario_fsm_notify_event(event); + +} +//------------------------------------------------------------------------------ +void *et_s1ap_eNB_task(void *arg) +{ + MessageDef *received_msg = NULL; + int result; + + S1AP_DEBUG("Starting S1AP layer\n"); + + s1ap_eNB_prepare_internal_data(); + + itti_mark_task_ready(TASK_S1AP); + MSC_START_USE(); + + while (1) { + itti_receive_msg(TASK_S1AP, &received_msg); + + switch (ITTI_MSG_ID(received_msg)) { + case TERMINATE_MESSAGE: + itti_exit_task(); + break; + + case S1AP_REGISTER_ENB_REQ: { + /* Register a new eNB. + * in Virtual mode eNBs will be distinguished using the mod_id/ + * Each eNB has to send an S1AP_REGISTER_ENB message with its + * own parameters. + */ + s1ap_eNB_handle_register_eNB(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &S1AP_REGISTER_ENB_REQ(received_msg)); + } + break; + + case SCTP_NEW_ASSOCIATION_RESP: { + s1ap_eNB_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_new_association_resp); + } + break; + + case SCTP_DATA_IND: { + et_s1ap_eNB_handle_sctp_data_ind(&received_msg->ittiMsg.sctp_data_ind); + } + break; + + + default: + S1AP_ERROR("Received unhandled message: %d:%s\n", + ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); + break; + } + + result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + + received_msg = NULL; + } + + return NULL; +} + + diff --git a/openair3/TEST/EPC_TEST/play_scenario_sctp.c b/openair3/TEST/EPC_TEST/play_scenario_sctp.c new file mode 100644 index 0000000000..6856cb2933 --- /dev/null +++ b/openair3/TEST/EPC_TEST/play_scenario_sctp.c @@ -0,0 +1,45 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2014 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see . + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE + + *******************************************************************************/ + +/* + play_scenario_sctp.c + ------------------- + AUTHOR : Lionel GAUTHIER + COMPANY : EURECOM + EMAIL : Lionel.Gauthier@eurecom.fr + */ + + +#include + +#include "intertask_interface.h" +#include "platform_types.h" +#include "assertions.h" +#include "play_scenario.h" + diff --git a/openair3/UTILS/conversions.h b/openair3/UTILS/conversions.h index aaa2b9714f..47912f0d92 100644 --- a/openair3/UTILS/conversions.h +++ b/openair3/UTILS/conversions.h @@ -275,7 +275,6 @@ do { \ (bITsTRING)->size = 3; \ (bITsTRING)->bits_unused = 4; \ } while(0) -/* /* TS 36.413 v10.9.0 section 9.2.1.38: * E-UTRAN CGI/Cell Identity * The leftmost bits of the Cell From e58be6bbc14cc1b1bde0a126d9bd9bd9206bca8c Mon Sep 17 00:00:00 2001 From: gauthier Date: Mon, 23 Nov 2015 16:54:44 +0100 Subject: [PATCH 11/47] Remaining TODO fill assoc_id and mme_ue_id of packets --- cmake_targets/CMakeLists.txt | 5 +- openair3/TEST/EPC_TEST/generate_scenario.c | 4 +- openair3/TEST/EPC_TEST/generic_scenario.xsl | 144 ++++-- openair3/TEST/EPC_TEST/play_scenario.c | 309 ++++++++++-- openair3/TEST/EPC_TEST/play_scenario.h | 186 +++++++- openair3/TEST/EPC_TEST/play_scenario_fsm.c | 325 +++++++++++-- openair3/TEST/EPC_TEST/play_scenario_parse.c | 27 +- openair3/TEST/EPC_TEST/play_scenario_s1ap.c | 447 +++++++++++++++++- .../EPC_TEST/play_scenario_s1ap_eNB_defs.h | 250 ++++++++++ 9 files changed, 1522 insertions(+), 175 deletions(-) create mode 100644 openair3/TEST/EPC_TEST/play_scenario_s1ap_eNB_defs.h diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 148aae2419..bcf90bdb83 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1667,17 +1667,16 @@ add_executable(test_epc_play_scenario ${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario_fsm.c ${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario_parse.c ${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario_s1ap.c + ${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario_s1ap_eNB_defs.h ${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario_sctp.c ${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario.h - ${OPENAIR2_DIR}/ENB_APP/enb_config.h ${OPENAIR2_DIR}/COMMON/commonDef.h ${OPENAIR2_DIR}/COMMON/messages_def.h ${OPENAIR2_DIR}/COMMON/messages_types.h - ${OPENAIR3_DIR}/S1AP/s1ap_eNB_defs.h ${OPENAIR_BIN_DIR}/messages_xml.h ) target_link_libraries (test_epc_play_scenario - -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES} + -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/TEST/EPC_TEST/generate_scenario.c b/openair3/TEST/EPC_TEST/generate_scenario.c index 8f39b9873e..9f4e16baef 100644 --- a/openair3/TEST/EPC_TEST/generate_scenario.c +++ b/openair3/TEST/EPC_TEST/generate_scenario.c @@ -228,7 +228,7 @@ int generate_test_scenario(const char const * test_nameP, const char const * pdm for (i = 0; i < g_enb_properties.number; i++) { // eNB S1-C IPv4 address - sprintf(astring, "enb_s1c%d", i); + sprintf(astring, "enb%d_s1c", i); params[nb_params++] = strdup(astring); addr.s_addr = g_enb_properties.properties[i]->enb_ipv4_address_for_S1_MME; sprintf(astring, "\"%s\"", inet_ntoa(addr)); @@ -236,7 +236,7 @@ int generate_test_scenario(const char const * test_nameP, const char const * pdm // MME S1-C IPv4 address for (j = 0; j < g_enb_properties.properties[i]->nb_mme; j++) { - sprintf(astring, "mme_s1c%d_%d", i, j); + sprintf(astring, "mme%d_s1c_%d", i, j); params[nb_params++] = strdup(astring); AssertFatal (g_enb_properties.properties[i]->mme_ip_address[j].ipv4_address, "Only support MME IPv4 address\n"); diff --git a/openair3/TEST/EPC_TEST/generic_scenario.xsl b/openair3/TEST/EPC_TEST/generic_scenario.xsl index 1d49b4942e..592bef83d4 100644 --- a/openair3/TEST/EPC_TEST/generic_scenario.xsl +++ b/openair3/TEST/EPC_TEST/generic_scenario.xsl @@ -8,30 +8,30 @@ /> - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + @@ -39,30 +39,30 @@ - enb_s1c0 - enb_s1c1 - enb_s1c2 - enb_s1c3 - enb_s1c4 - enb_s1c5 - enb_s1c6 - enb_s1c7 - mme_s1c0_0 - mme_s1c0_1 - mme_s1c0_2 - mme_s1c0_3 - mme_s1c1_0 - mme_s1c1_1 - mme_s1c1_2 - mme_s1c1_3 - mme_s1c2_0 - mme_s1c2_1 - mme_s1c2_2 - mme_s1c2_3 - mme_s1c3_0 - mme_s1c3_1 - mme_s1c3_2 - mme_s1c3_3 + enb0_s1c + enb1_s1c + enb2_s1c + enb3_s1c + enb4_s1c + enb5_s1c + enb6_s1c + enb7_s1c + mme0_s1c_0 + mme0_s1c_1 + mme0_s1c_2 + mme0_s1c_3 + mme1_s1c_0 + mme1_s1c_1 + mme1_s1c_2 + mme1_s1c_3 + mme2_s1c_0 + mme2_s1c_1 + mme2_s1c_2 + mme2_s1c_3 + mme3_s1c_0 + mme3_s1c_1 + mme3_s1c_2 + mme3_s1c_3 ERROR: Cannot reverse resolv IP ! @@ -70,6 +70,26 @@ + + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + + ERROR: Cannot set eNB instance ! + + + + + + + @@ -120,8 +140,26 @@ - SEND - RECEIVE + SEND + RECEIVE + + ERROR: UNKNOWN ACTION ! + + + + + + + + + + + + + + + + ERROR: UNKNOWN ACTION ! @@ -156,6 +194,7 @@ + @@ -177,6 +216,7 @@ + @@ -197,6 +237,7 @@ + @@ -218,6 +259,7 @@ + @@ -233,6 +275,7 @@ + @@ -249,6 +292,7 @@ + diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c index fda38dbcb8..f29393f0e7 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.c +++ b/openair3/TEST/EPC_TEST/play_scenario.c @@ -48,6 +48,9 @@ #include #include #include +#include +#include +#include #include "intertask_interface_init.h" @@ -63,11 +66,19 @@ #define GS_IS_FILE 1 #define GS_IS_DIR 2 //------------------------------------------------------------------------------ -char *g_openair_dir = NULL; +char *g_openair_dir = NULL; +Enb_properties_array_t g_enb_properties; //------------------------------------------------------------------------------ -extern int xmlLoadExtDtdDefaultValue; -extern int asn_debug; -extern int asn1_xer_print; +extern et_scenario_t *g_scenario; +extern int xmlLoadExtDtdDefaultValue; +extern int asn_debug; +extern int asn1_xer_print; + +//------------------------------------------------------------------------------ +// MEMO: +// Scenario with several eNBs: We may have to create ethx.y interfaces +// + //------------------------------------------------------------------------------ @@ -159,6 +170,7 @@ void et_free_scenario(et_scenario_t* scenario) packet = next_packet->next; } et_free_pointer(scenario); + pthread_mutex_destroy(&scenario->fsm_lock); } } @@ -290,17 +302,250 @@ void et_ip_str2et_ip(const xmlChar * const ip_str, et_ip_t * const ip) AssertFatal (0, "ERROR %s() Could not parse ip address %s!\n", __FUNCTION__, ip_str); } } +#ifdef LIBCONFIG_LONG +#define libconfig_int long +#else +#define libconfig_int int +#endif +//------------------------------------------------------------------------------ +void et_enb_config_init(const char const * lib_config_file_name_pP) +//------------------------------------------------------------------------------ +{ + config_t cfg; + config_setting_t *setting = NULL; + config_setting_t *subsetting = NULL; + config_setting_t *setting_mme_addresses = NULL; + config_setting_t *setting_mme_address = NULL; + config_setting_t *setting_enb = NULL; + int num_enb_properties = 0; + int enb_properties_index = 0; + int num_enbs = 0; + int num_mme_address = 0; + int i = 0; + int j = 0; + int parse_errors = 0; + libconfig_int enb_id = 0; + const char* cell_type = NULL; + const char* tac = 0; + const char* enb_name = NULL; + const char* mcc = 0; + const char* mnc = 0; + char* ipv4 = NULL; + char* ipv6 = NULL; + char* active = NULL; + char* preference = NULL; + const char* active_enb[MAX_ENB]; + char* enb_interface_name_for_S1U = NULL; + char* enb_ipv4_address_for_S1U = NULL; + libconfig_int enb_port_for_S1U = 0; + char* enb_interface_name_for_S1_MME = NULL; + char* enb_ipv4_address_for_S1_MME = NULL; + char *address = NULL; + char *cidr = NULL; + + + AssertFatal (lib_config_file_name_pP != NULL, + "Bad parameter lib_config_file_name_pP %s , must reference a valid eNB config file\n", + lib_config_file_name_pP); + + memset((char*)active_enb, 0 , MAX_ENB * sizeof(char*)); + + config_init(&cfg); + + /* Read the file. If there is an error, report it and exit. */ + if (! config_read_file(&cfg, lib_config_file_name_pP)) { + config_destroy(&cfg); + AssertFatal (0, "Failed to parse eNB configuration file %s!\n", lib_config_file_name_pP); + } + + // Get list of active eNBs, (only these will be configured) + setting = config_lookup(&cfg, ENB_CONFIG_STRING_ACTIVE_ENBS); + + if (setting != NULL) { + num_enbs = config_setting_length(setting); + + for (i = 0; i < num_enbs; i++) { + setting_enb = config_setting_get_elem(setting, i); + active_enb[i] = config_setting_get_string (setting_enb); + AssertFatal (active_enb[i] != NULL, + "Failed to parse config file %s, %uth attribute %s \n", + lib_config_file_name_pP, i, ENB_CONFIG_STRING_ACTIVE_ENBS); + active_enb[i] = strdup(active_enb[i]); + num_enb_properties += 1; + } + } + + /* Output a list of all eNBs. */ + setting = config_lookup(&cfg, ENB_CONFIG_STRING_ENB_LIST); + + if (setting != NULL) { + enb_properties_index = g_enb_properties.number; + parse_errors = 0; + num_enbs = config_setting_length(setting); + + for (i = 0; i < num_enbs; i++) { + setting_enb = config_setting_get_elem(setting, i); + + if (! config_setting_lookup_int(setting_enb, ENB_CONFIG_STRING_ENB_ID, &enb_id)) { + /* Calculate a default eNB ID */ +# if defined(ENABLE_USE_MME) + uint32_t hash; + + hash = et_s1ap_generate_eNB_id (); + enb_id = i + (hash & 0xFFFF8); +# else + enb_id = i; +# endif + } + + if ( !( config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_CELL_TYPE, &cell_type) + && config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_ENB_NAME, &enb_name) + && config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_TRACKING_AREA_CODE, &tac) + && config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE, &mcc) + && config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_MOBILE_NETWORK_CODE, &mnc) + + + ) + ) { + AssertError (0, parse_errors ++, + "Failed to parse eNB configuration file %s, %u th enb\n", + lib_config_file_name_pP, i); + continue; // FIXME this prevents segfaults below, not sure what happens after function exit + } + + // search if in active list + for (j=0; j < num_enb_properties; j++) { + if (strcmp(active_enb[j], enb_name) == 0) { + g_enb_properties.properties[enb_properties_index] = calloc(1, sizeof(Enb_properties_t)); + + g_enb_properties.properties[enb_properties_index]->eNB_id = enb_id; + + if (strcmp(cell_type, "CELL_MACRO_ENB") == 0) { + g_enb_properties.properties[enb_properties_index]->cell_type = CELL_MACRO_ENB; + } else if (strcmp(cell_type, "CELL_HOME_ENB") == 0) { + g_enb_properties.properties[enb_properties_index]->cell_type = CELL_HOME_ENB; + } else { + AssertError (0, parse_errors ++, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n", + lib_config_file_name_pP, i, cell_type); + } + + g_enb_properties.properties[enb_properties_index]->eNB_name = strdup(enb_name); + g_enb_properties.properties[enb_properties_index]->tac = (uint16_t)atoi(tac); + g_enb_properties.properties[enb_properties_index]->mcc = (uint16_t)atoi(mcc); + g_enb_properties.properties[enb_properties_index]->mnc = (uint16_t)atoi(mnc); + g_enb_properties.properties[enb_properties_index]->mnc_digit_length = strlen(mnc); + AssertFatal((g_enb_properties.properties[enb_properties_index]->mnc_digit_length == 2) || + (g_enb_properties.properties[enb_properties_index]->mnc_digit_length == 3), + "BAD MNC DIGIT LENGTH %d", + g_enb_properties.properties[i]->mnc_digit_length); + + + setting_mme_addresses = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_MME_IP_ADDRESS); + num_mme_address = config_setting_length(setting_mme_addresses); + g_enb_properties.properties[enb_properties_index]->nb_mme = 0; + + for (j = 0; j < num_mme_address; j++) { + setting_mme_address = config_setting_get_elem(setting_mme_addresses, j); + + if ( !( + config_setting_lookup_string(setting_mme_address, ENB_CONFIG_STRING_MME_IPV4_ADDRESS, (const char **)&ipv4) + && config_setting_lookup_string(setting_mme_address, ENB_CONFIG_STRING_MME_IPV6_ADDRESS, (const char **)&ipv6) + && config_setting_lookup_string(setting_mme_address, ENB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE, (const char **)&active) + && config_setting_lookup_string(setting_mme_address, ENB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE, (const char **)&preference) + ) + ) { + AssertError (0, parse_errors ++, + "Failed to parse eNB configuration file %s, %u th enb %u th mme address !\n", + lib_config_file_name_pP, i, j); + continue; // FIXME will prevent segfaults below, not sure what happens at function exit... + } + + g_enb_properties.properties[enb_properties_index]->nb_mme += 1; + + g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv4_address = strdup(ipv4); + g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv6_address = strdup(ipv6); + + if (strcmp(active, "yes") == 0) { + g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].active = 1; + } // else { (calloc) + + if (strcmp(preference, "ipv4") == 0) { + g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv4 = 1; + } else if (strcmp(preference, "ipv6") == 0) { + g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv6 = 1; + } else if (strcmp(preference, "no") == 0) { + g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv4 = 1; + g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv6 = 1; + } + } + + + // NETWORK_INTERFACES + subsetting = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); + + if (subsetting != NULL) { + if ( ( + config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1_MME, + (const char **)&enb_interface_name_for_S1_MME) + && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_ENB_IPV4_ADDRESS_FOR_S1_MME, + (const char **)&enb_ipv4_address_for_S1_MME) + && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1U, + (const char **)&enb_interface_name_for_S1U) + && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U, + (const char **)&enb_ipv4_address_for_S1U) + && config_setting_lookup_int(subsetting, ENB_CONFIG_STRING_ENB_PORT_FOR_S1U, + &enb_port_for_S1U) + ) + ) { + g_enb_properties.properties[enb_properties_index]->enb_interface_name_for_S1U = strdup(enb_interface_name_for_S1U); + cidr = enb_ipv4_address_for_S1U; + address = strtok(cidr, "/"); + + if (address) { + IPV4_STR_ADDR_TO_INT_NWBO ( address, g_enb_properties.properties[enb_properties_index]->enb_ipv4_address_for_S1U, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" ); + } + + g_enb_properties.properties[enb_properties_index]->enb_port_for_S1U = enb_port_for_S1U; + + g_enb_properties.properties[enb_properties_index]->enb_interface_name_for_S1_MME = strdup(enb_interface_name_for_S1_MME); + cidr = enb_ipv4_address_for_S1_MME; + address = strtok(cidr, "/"); + + if (address) { + IPV4_STR_ADDR_TO_INT_NWBO ( address, g_enb_properties.properties[enb_properties_index]->enb_ipv4_address_for_S1_MME, "BAD IP ADDRESS FORMAT FOR eNB S1_MME !\n" ); + } + } + } // if (subsetting != NULL) { + enb_properties_index += 1; + } // if (strcmp(active_enb[j], enb_name) == 0) + } // for (j=0; j < num_enb_properties; j++) + } // for (i = 0; i < num_enbs; i++) + } // if (setting != NULL) { + + g_enb_properties.number += num_enb_properties; + + + AssertFatal (parse_errors == 0, + "Failed to parse eNB configuration file %s, found %d error%s !\n", + lib_config_file_name_pP, parse_errors, parse_errors > 1 ? "s" : ""); +} +/*------------------------------------------------------------------------------*/ +const Enb_properties_array_t *et_enb_config_get(void) +{ + return &g_enb_properties; +} /*------------------------------------------------------------------------------*/ uint32_t et_eNB_app_register(const Enb_properties_array_t *enb_properties) { uint32_t enb_id; uint32_t mme_id; MessageDef *msg_p; - uint32_t register_enb_pending = 0; char *str = NULL; struct in_addr addr; + g_scenario->register_enb_pending = 0; for (enb_id = 0; (enb_id < enb_properties->number) ; enb_id++) { { s1ap_register_enb_req_t *s1ap_register_eNB; @@ -318,7 +563,6 @@ uint32_t et_eNB_app_register(const Enb_properties_array_t *enb_properties) s1ap_register_eNB->mcc = enb_properties->properties[enb_id]->mcc; s1ap_register_eNB->mnc = enb_properties->properties[enb_id]->mnc; s1ap_register_eNB->mnc_digit_length = enb_properties->properties[enb_id]->mnc_digit_length; - s1ap_register_eNB->default_drx = enb_properties->properties[enb_id]->pcch_defaultPagingCycle[0]; s1ap_register_eNB->nb_mme = enb_properties->properties[enb_id]->nb_mme; AssertFatal (s1ap_register_eNB->nb_mme <= S1AP_MAX_NB_MME_IP_ADDRESS, "Too many MME for eNB %d (%d/%d)!", enb_id, s1ap_register_eNB->nb_mme, @@ -347,20 +591,16 @@ uint32_t et_eNB_app_register(const Enb_properties_array_t *enb_properties) itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); - register_enb_pending++; + g_scenario->register_enb_pending++; } } - return register_enb_pending; + return g_scenario->register_enb_pending; } /*------------------------------------------------------------------------------*/ void *et_eNB_app_task(void *args_p) { - const Enb_properties_array_t *enb_properties_p = NULL; - uint32_t register_enb_pending; - uint32_t registered_enb; - long enb_register_retry_timer_id; - uint32_t enb_id; + et_scenario_t *scenario = (et_scenario_t*)args_p; MessageDef *msg_p = NULL; const char *msg_name = NULL; instance_t instance; @@ -369,14 +609,6 @@ void *et_eNB_app_task(void *args_p) itti_mark_task_ready (TASK_ENB_APP); - enb_properties_p = enb_config_get(); - - - /* Try to register each eNB */ - registered_enb = 0; - register_enb_pending = et_eNB_app_register (enb_properties_p); - - do { // Wait for a message itti_receive_msg (TASK_ENB_APP, &msg_p); @@ -389,40 +621,40 @@ void *et_eNB_app_task(void *args_p) itti_exit_task (); break; - - case S1AP_REGISTER_ENB_CNF: LOG_I(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, msg_name, S1AP_REGISTER_ENB_CNF(msg_p).nb_mme); - DevAssert(register_enb_pending > 0); - register_enb_pending--; + DevAssert(g_scenario->register_enb_pending > 0); + g_scenario->register_enb_pending--; /* Check if at least eNB is registered with one MME */ if (S1AP_REGISTER_ENB_CNF(msg_p).nb_mme > 0) { - registered_enb++; + g_scenario->registered_enb++; } /* Check if all register eNB requests have been processed */ - if (register_enb_pending == 0) { - if (registered_enb == enb_properties_p->number) { + if (scenario->register_enb_pending == 0) { + if (scenario->registered_enb == scenario->enb_properties->number) { /* If all eNB are registered, start scenario */ - + et_event_t event; + event.code = ET_EVENT_S1C_CONNECTED; + et_scenario_fsm_notify_event(event); } else { - uint32_t not_associated = enb_properties_p->number - registered_enb; + uint32_t not_associated = scenario->enb_properties->number - scenario->registered_enb; LOG_W(ENB_APP, " %d eNB %s not associated with a MME, retrying registration in %d seconds ...\n", not_associated, not_associated > 1 ? "are" : "is", ET_ENB_REGISTER_RETRY_DELAY); /* Restart the eNB registration process in ENB_REGISTER_RETRY_DELAY seconds */ if (timer_setup (ET_ENB_REGISTER_RETRY_DELAY, 0, TASK_ENB_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT, - NULL, &enb_register_retry_timer_id) < 0) { + NULL, &scenario->enb_register_retry_timer_id) < 0) { LOG_E(ENB_APP, " Can not start eNB register retry timer, use \"sleep\" instead!\n"); sleep(ET_ENB_REGISTER_RETRY_DELAY); /* Restart the registration process */ - registered_enb = 0; - register_enb_pending = et_eNB_app_register (enb_properties_p); + scenario->registered_enb = 0; + scenario->register_enb_pending = et_eNB_app_register (scenario->enb_properties); } } } @@ -439,10 +671,10 @@ void *et_eNB_app_task(void *args_p) case TIMER_HAS_EXPIRED: LOG_I(ENB_APP, " Received %s: timer_id %d\n", msg_name, TIMER_HAS_EXPIRED(msg_p).timer_id); - if (TIMER_HAS_EXPIRED (msg_p).timer_id == enb_register_retry_timer_id) { + if (TIMER_HAS_EXPIRED (msg_p).timer_id == scenario->enb_register_retry_timer_id) { /* Restart the registration process */ - registered_enb = 0; - register_enb_pending = et_eNB_app_register (enb_properties_p); + scenario->registered_enb = 0; + scenario->register_enb_pending = et_eNB_app_register (scenario->enb_properties); } break; @@ -476,7 +708,7 @@ int et_play_scenario(et_scenario_t* const scenario) } // create ENB_APP ITTI task: not as same as eNB code - if (itti_create_task (TASK_ENB_APP, et_eNB_app_task, NULL) < 0) { + if (itti_create_task (TASK_ENB_APP, et_eNB_app_task, scenario) < 0) { LOG_E(ENB_APP, "Create task for ENB_APP failed\n"); return -1; } @@ -523,7 +755,6 @@ et_config_parse_opt_line ( { int option; int rv = 0; - const Enb_properties_array_t *enb_properties_p = NULL; enum long_option_e { LONG_OPTION_START = 0x100, /* Start after regular single char options */ @@ -606,7 +837,7 @@ et_config_parse_opt_line ( if (is_file_exists(*enb_config_file_name, "eNB config file") != GS_IS_FILE) { fprintf(stderr, "ERROR: original eNB config file name %s is not found in dir %s\n", *enb_config_file_name, *et_dir_name); } - enb_properties_p = enb_config_init(*enb_config_file_name); + et_enb_config_init(*enb_config_file_name); if (NULL == *scenario_file_name) { fprintf(stderr, "ERROR: please provide the scenario file name that should be in %s\n", *et_dir_name); diff --git a/openair3/TEST/EPC_TEST/play_scenario.h b/openair3/TEST/EPC_TEST/play_scenario.h index 725b5abc0e..3a52c6a0b8 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.h +++ b/openair3/TEST/EPC_TEST/play_scenario.h @@ -28,7 +28,7 @@ *******************************************************************************/ /* - et_scenario.h + play_scenario.h ------------------- AUTHOR : Lionel GAUTHIER COMPANY : EURECOM @@ -39,14 +39,121 @@ #define PLAY_SCENARIO_H_ # include # include +# include # include # include -#include "enb_config.h" +#include "S1AP-PDU.h" #include "s1ap_ies_defs.h" +#include "play_scenario_s1ap_eNB_defs.h" +#include "hashtable.h" -# define ET_ENB_REGISTER_RETRY_DELAY 3 +#define MAX_ENB 16 + +#define ENB_CONFIG_STRING_ACTIVE_ENBS "Active_eNBs" + +#define ENB_CONFIG_STRING_ENB_LIST "eNBs" +#define ENB_CONFIG_STRING_ENB_ID "eNB_ID" +#define ENB_CONFIG_STRING_CELL_TYPE "cell_type" +#define ENB_CONFIG_STRING_ENB_NAME "eNB_name" + +#define ENB_CONFIG_STRING_TRACKING_AREA_CODE "tracking_area_code" +#define ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE "mobile_country_code" +#define ENB_CONFIG_STRING_MOBILE_NETWORK_CODE "mobile_network_code" + + +#define ENB_CONFIG_STRING_MME_IP_ADDRESS "mme_ip_address" +#define ENB_CONFIG_STRING_MME_IPV4_ADDRESS "ipv4" +#define ENB_CONFIG_STRING_MME_IPV6_ADDRESS "ipv6" +#define ENB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE "active" +#define ENB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE "preference" + +#define ENB_CONFIG_STRING_SCTP_CONFIG "SCTP" +#define ENB_CONFIG_STRING_SCTP_INSTREAMS "SCTP_INSTREAMS" +#define ENB_CONFIG_STRING_SCTP_OUTSTREAMS "SCTP_OUTSTREAMS" + +#define ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG "NETWORK_INTERFACES" +#define ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1_MME "ENB_INTERFACE_NAME_FOR_S1_MME" +#define ENB_CONFIG_STRING_ENB_IPV4_ADDRESS_FOR_S1_MME "ENB_IPV4_ADDRESS_FOR_S1_MME" +#define ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1U "ENB_INTERFACE_NAME_FOR_S1U" +#define ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U "ENB_IPV4_ADDRESS_FOR_S1U" +#define ENB_CONFIG_STRING_ENB_PORT_FOR_S1U "ENB_PORT_FOR_S1U" + + +typedef struct mme_ip_address_s { + unsigned ipv4:1; + unsigned ipv6:1; + unsigned active:1; + char *ipv4_address; + char *ipv6_address; +} mme_ip_address_t; + +#define IPV4_STR_ADDR_TO_INT_NWBO(AdDr_StR,NwBo,MeSsAgE ) do {\ + struct in_addr inp;\ + if ( inet_aton(AdDr_StR, &inp ) < 0 ) {\ + AssertFatal (0, MeSsAgE);\ + } else {\ + NwBo = inp.s_addr;\ + }\ + } while (0); + + +typedef struct Enb_properties_s { + /* Unique eNB_id to identify the eNB within EPC. + * For macro eNB ids this field should be 20 bits long. + * For home eNB ids this field should be 28 bits long. + */ + uint32_t eNB_id; + + /* The type of the cell */ + enum cell_type_e cell_type; + + /* Optional name for the cell + * NOTE: the name can be NULL (i.e no name) and will be cropped to 150 + * characters. + */ + char *eNB_name; + + /* Tracking area code */ + uint16_t tac; + + /* Mobile Country Code + * Mobile Network Code + */ + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + + + + /* Physical parameters */ + + int16_t Nid_cell[1+MAX_NUM_CCs];// for testing, change later + /* Nb of MME to connect to */ + uint8_t nb_mme; + /* List of MME to connect to */ + mme_ip_address_t mme_ip_address[S1AP_MAX_NB_MME_IP_ADDRESS]; + + int sctp_in_streams; + int sctp_out_streams; + + char *enb_interface_name_for_S1U; + in_addr_t enb_ipv4_address_for_S1U; + tcp_udp_port_t enb_port_for_S1U; + + char *enb_interface_name_for_S1_MME; + in_addr_t enb_ipv4_address_for_S1_MME; + +} Enb_properties_t; + +typedef struct Enb_properties_array_s { + int number; + Enb_properties_t *properties[MAX_ENB]; +} Enb_properties_array_t; + +# define ET_ENB_REGISTER_RETRY_DELAY 3 +# define ET_FSM_STATE_WAITING_RX_EVENT_DELAY_SEC 15 typedef enum { ET_PACKET_STATUS_START = 0, @@ -54,19 +161,17 @@ typedef enum { ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT, ET_PACKET_STATUS_SCHEDULED_FOR_SENDING, ET_PACKET_STATUS_SENT, - ET_PACKET_STATUS_SENT_WITH_ERRORS, ET_PACKET_STATUS_SCHEDULED_FOR_RECEIVING, ET_PACKET_STATUS_RECEIVED, - ET_PACKET_STATUS_RECEIVED_WITH_ERRORS, ET_PACKET_STATUS_END } et_packet_status_t; typedef enum { ET_FSM_STATE_START = 0, ET_FSM_STATE_NULL = ET_FSM_STATE_START, - ET_FSM_STATE_CONNECTING_SCTP, - ET_FSM_STATE_WAITING_TX_EVENT, - ET_FSM_STATE_WAITING_RX_EVENT, + ET_FSM_STATE_CONNECTING_S1C, + ET_FSM_STATE_WAITING_EVENT, + ET_FSM_STATE_RUNNING, ET_FSM_STATE_END } et_fsm_state_t; @@ -136,6 +241,7 @@ typedef struct sctp_datahdr_s { uint16_t stream; uint16_t ssn; uint32_t ppid; + uint32_t assoc_id; // filled when running scenario et_s1ap_t payload; } sctp_datahdr_t; @@ -182,11 +288,15 @@ typedef struct et_packet_s { struct timeval time_relative_to_last_received_packet; unsigned int original_frame_number; unsigned int packet_number; + instance_t enb_instance; et_ip_hdr_t ip_hdr; et_sctp_hdr_t sctp_hdr; struct et_packet_s *next; + //scenario running vars et_packet_status_t status; + long timer_id; // ITTI timer id for waiting rx packets + struct timeval timestamp_packet; // timestamp when rx or tx packet }et_packet_t; @@ -203,24 +313,37 @@ typedef struct sctp_epoll_s { } thread_desc_t; typedef struct et_scenario_s { - xmlChar *name; - et_packet_t *list_packet; - + xmlChar *name; + et_packet_t *list_packet; + //-------------------------- // playing scenario - et_packet_t *waited_packet; - et_packet_t *current_packet; + //-------------------------- + Enb_properties_array_t *enb_properties; + uint32_t register_enb_pending; + uint32_t registered_enb; + long enb_register_retry_timer_id; + + pthread_mutex_t fsm_lock; + et_fsm_state_t fsm_state; + + hash_table_t *hash_mme2association_id; + hash_table_t *hash_old_ue_mme_id2ue_mme_id; + struct timeval time_last_tx_packet; + struct timeval time_last_rx_packet; + et_packet_t *last_rx_packet; + et_packet_t *last_tx_packet; + et_packet_t *next_packet; } et_scenario_t; typedef enum { ET_EVENT_START = 0, ET_EVENT_INIT = ET_EVENT_START, + ET_EVENT_S1C_CONNECTED, ET_EVENT_RX_SCTP_EVENT, ET_EVENT_RX_S1AP, - ET_EVENT_RX_X2AP, ET_EVENT_RX_PACKET_TIME_OUT, - ET_EVENT_TX_PACKET, - ET_EVENT_STOP, + ET_EVENT_TX_TIMED_PACKET, ET_EVENT_END } et_event_code_t; @@ -241,7 +364,8 @@ typedef struct et_event_s { union { et_event_init_t init; et_event_s1ap_data_ind_t s1ap_data_ind; - et_event_s1ap_data_req_t s1ap_data_req; + et_packet_t *tx_timed_packet; + et_packet_t *rx_packet_time_out; } u; } et_event_t; @@ -266,16 +390,36 @@ int et_s1ap_decode_unsuccessful_outcome(s1ap_message *message, S1ap_Unsuccessful int et_s1ap_decode_pdu(S1AP_PDU_t * const pdu, s1ap_message * const message, const uint8_t * const buffer, const uint32_t length); void et_decode_s1ap(et_s1ap_t * const s1ap); //------------------------- -void et_s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind); +int et_s1ap_eNB_compare_assoc_id( struct s1ap_eNB_mme_data_s *p1, struct s1ap_eNB_mme_data_s *p2); +uint16_t et_s1ap_eNB_fetch_add_global_cnx_id(void); +void et_s1ap_eNB_prepare_internal_data(void); +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); +void et_s1ap_process_rx_packet(et_event_s1ap_data_ind_t * const sctp_data_ind); +void et_s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t * const sctp_data_ind); +void et_s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, + net_ip_address_t *mme_ip_address, + net_ip_address_t *local_ip_addr, + uint16_t in_streams, + uint16_t out_streams); +void et_s1ap_handle_s1_setup_message(s1ap_eNB_mme_data_t *mme_desc_p, int sctp_shutdown); +void et_s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *s1ap_register_eNB); +void et_s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp); void * et_s1ap_eNB_task(void *arg); +//------------------------- int et_generate_xml_scenario( const char const * xml_in_dir_name, const char const * xml_in_scenario_filename, const char const * enb_config_filename, char const * tsml_out_scenario_filename); //------------------------- -int et_scenario_fsm_notify_event_state_null(et_event_t event); -int et_scenario_fsm_notify_event(et_event_t event); +et_fsm_state_t et_scenario_fsm_notify_event_state_running(et_event_t event); +et_fsm_state_t et_scenario_fsm_notify_event_state_waiting(et_event_t event); +et_fsm_state_t et_scenario_fsm_notify_event_state_connecting_s1c(et_event_t event); +et_fsm_state_t et_scenario_fsm_notify_event_state_null(et_event_t event); +et_fsm_state_t et_scenario_fsm_notify_event(et_event_t event); //------------------------- void et_parse_s1ap(xmlDocPtr doc, const xmlNode const *s1ap_node, et_s1ap_t * const s1ap); void et_parse_sctp_data_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_datahdr_t * const sctp_hdr); @@ -297,6 +441,8 @@ sctp_cid_t et_chunk_type_str2cid(const xmlChar * const chunk_type_str); const char * const et_chunk_type_cid2str(const sctp_cid_t chunk_type); et_packet_action_t et_action_str2et_action_t(const xmlChar * const action); void et_ip_str2et_ip(const xmlChar * const ip_str, et_ip_t * const ip); +void et_enb_config_init(const char const * lib_config_file_name_pP); +const Enb_properties_array_t *et_enb_config_get(void); uint32_t et_eNB_app_register(const Enb_properties_array_t *enb_properties); void *et_eNB_app_task(void *args_p); int et_play_scenario(et_scenario_t* const scenario); diff --git a/openair3/TEST/EPC_TEST/play_scenario_fsm.c b/openair3/TEST/EPC_TEST/play_scenario_fsm.c index 6c73793f4d..8e59a98258 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_fsm.c +++ b/openair3/TEST/EPC_TEST/play_scenario_fsm.c @@ -35,74 +35,322 @@ EMAIL : Lionel.Gauthier@eurecom.fr */ #include +#include #include "intertask_interface.h" #include "platform_types.h" #include "assertions.h" #include "play_scenario.h" +#include "s1ap_ies_defs.h" +#include "play_scenario_s1ap_eNB_defs.h" +#include "timer.h" - -et_scenario_t *g_scenario = NULL; -et_fsm_state_t g_fsm_state = ET_FSM_STATE_NULL; //------------------------------------------------------------------------------ -int et_scenario_fsm_notify_event_state_null(et_event_t event) +et_scenario_t *g_scenario = NULL; +//------------------------------------------------------------------------------ +int timeval_subtract (struct timeval * const result, struct timeval * const a, struct timeval * const b) +{ + struct timeval b2; + b2.tv_sec = b->tv_sec; + b2.tv_usec = b->tv_usec; + + /* Perform the carry for the later subtraction by updating y. */ + if (a->tv_usec < b2.tv_usec) { + int nsec = (b2.tv_usec - a->tv_usec) / 1000000 + 1; + b2.tv_usec -= 1000000 * nsec; + b2.tv_sec += nsec; + } + if (a->tv_usec - b2.tv_usec > 1000000) { + int nsec = (a->tv_usec - b2.tv_usec) / 1000000; + b2.tv_usec += 1000000 * nsec; + b2.tv_sec -= nsec; + } + + /* Compute the time remaining to wait. + tv_usec is certainly positive. */ + result->tv_sec = a->tv_sec - b2.tv_sec; + result->tv_usec = a->tv_usec - b2.tv_usec; + + /* Return 1 if result is negative. */ + return a->tv_sec < b2.tv_sec; +} + + +//------------------------------------------------------------------------------ +void et_scenario_wait_rx_packet(et_packet_t * const packet) +{ + if (timer_setup (ET_FSM_STATE_WAITING_RX_EVENT_DELAY_SEC, 0, TASK_S1AP, INSTANCE_DEFAULT, TIMER_ONE_SHOT, + NULL, &packet->timer_id) < 0) { + AssertFatal(0, " Can not start waiting RX event timer\n"); + } + g_scenario->fsm_state = ET_FSM_STATE_WAITING_EVENT; + packet->status = ET_PACKET_STATUS_SCHEDULED_FOR_RECEIVING; +} +//------------------------------------------------------------------------------ +void et_scenario_schedule_tx_packet(et_packet_t * const packet) +{ + s1ap_eNB_instance_t *s1ap_eNB_instance = NULL; + struct timeval now = { .tv_sec = 0, .tv_usec = 0 }; + struct timeval offset_last_tx_packet = { .tv_sec = 0, .tv_usec = 0 }; + struct timeval offset_last_rx_packet = { .tv_sec = 0, .tv_usec = 0 }; + struct timeval offset_tx_rx = { .tv_sec = 0, .tv_usec = 0 }; + struct timeval offset = { .tv_sec = 0, .tv_usec = 0 }; + int last_packet_was_tx = 0; + int we_are_too_early = 0; + + AssertFatal(NULL != packet, "packet argument is NULL"); + s1ap_eNB_instance = et_s1ap_eNB_get_instance(packet->enb_instance); + AssertFatal(NULL != s1ap_eNB_instance, "Cannot get s1ap_eNB_instance_t for eNB instance %d", packet->enb_instance); + + g_scenario->fsm_state = ET_FSM_STATE_WAITING_EVENT; + + switch (packet->sctp_hdr.chunk_type) { + case SCTP_CID_DATA: + // check if we can send it now + // TODO: BUG we have to discard in scenario all packets that cannot be processed (SACK, COOKIEs, etc) + AssertFatal(gettimeofday(&now, NULL) == 0, "gettimeofday failed"); + timeval_subtract(&offset_last_tx_packet,&now,&g_scenario->time_last_tx_packet); + timeval_subtract(&offset_last_rx_packet,&now,&g_scenario->time_last_rx_packet); + last_packet_was_tx = timeval_subtract(&offset_tx_rx,&offset_last_tx_packet,&offset_last_rx_packet); + if (last_packet_was_tx) { + we_are_too_early = timeval_subtract(&offset,&offset_last_tx_packet,&packet->time_relative_to_last_sent_packet); + } else { + we_are_too_early = timeval_subtract(&offset,&offset_last_rx_packet,&packet->time_relative_to_last_received_packet); + } + if (we_are_too_early > 0) { + // set timer + packet->status = ET_PACKET_STATUS_SCHEDULED_FOR_SENDING; + if (timer_setup (offset.tv_sec, offset.tv_usec, TASK_S1AP, INSTANCE_DEFAULT, TIMER_ONE_SHOT, + NULL, &packet->timer_id) < 0) { + AssertFatal(0, " Can not start TX event timer\n"); + } + // Done g_scenario->fsm_state = ET_FSM_STATE_WAITING_TX_EVENT; + } else { + // send immediately + et_s1ap_eNB_itti_send_sctp_data_req( + packet->enb_instance, + packet->sctp_hdr.u.data_hdr.assoc_id, + packet->sctp_hdr.u.data_hdr.payload.binary_stream, + packet->sctp_hdr.u.data_hdr.payload.binary_stream_allocated_size, + packet->sctp_hdr.u.data_hdr.stream); + packet->status = ET_PACKET_STATUS_SENT; + g_scenario->fsm_state = ET_FSM_STATE_RUNNING; + } + break; + case SCTP_CID_INIT: + case SCTP_CID_INIT_ACK: + AssertFatal(0, "Invalid case TX packet SCTP_CID_INIT or SCTP_CID_INIT_ACK"); + break; + default: + AssertFatal(0, "Invalid case TX packet SCTP_CID %d", packet->sctp_hdr.chunk_type); + } +} +//------------------------------------------------------------------------------ +et_fsm_state_t et_scenario_fsm_notify_event_state_running(et_event_t event) { - et_packet_t *packet = NULL; - const Enb_properties_array_t *enb_properties_p = NULL; - uint32_t register_enb_pending; switch (event.code){ - case ET_EVENT_INIT: - AssertFatal(NULL == g_scenario, "Current scenario not ended"); - g_scenario = event.u.init.scenario; - packet = g_scenario->list_packet; - while (NULL != packet) { - switch (packet->sctp_hdr.chunk_type) { + case ET_EVENT_RX_PACKET_TIME_OUT: + AssertFatal(0, "Event ET_EVENT_RX_PACKET_TIME_OUT not handled in FSM state ET_FSM_STATE_RUNNING"); + break; + case ET_EVENT_TX_TIMED_PACKET: + AssertFatal(0, "Event ET_EVENT_TX_TIMED_PACKET not handled in FSM state ET_FSM_STATE_RUNNING"); + break; + case ET_EVENT_RX_S1AP: + AssertFatal(0, "TODO"); + break; + default: + AssertFatal(0, "Case event %d not handled in ET_FSM_STATE_RUNNING", event.code); + } + pthread_mutex_unlock(&g_scenario->fsm_lock); + return 0; +} +//------------------------------------------------------------------------------ +et_fsm_state_t et_scenario_fsm_notify_event_state_waiting(et_event_t event) +{ + + switch (event.code){ + case ET_EVENT_RX_PACKET_TIME_OUT: + fprintf(stderr, "Error The following packet is not received:\n"); + et_display_packet(event.u.rx_packet_time_out); + AssertFatal(0, "Waited packet not received"); + break; + case ET_EVENT_RX_S1AP: + et_s1ap_process_rx_packet(&event.u.s1ap_data_ind); + break; + case ET_EVENT_TX_TIMED_PACKET: + // send immediately + et_s1ap_eNB_itti_send_sctp_data_req( + event.u.tx_timed_packet->enb_instance, + event.u.tx_timed_packet->sctp_hdr.u.data_hdr.assoc_id, + event.u.tx_timed_packet->sctp_hdr.u.data_hdr.payload.binary_stream, + event.u.tx_timed_packet->sctp_hdr.u.data_hdr.payload.binary_stream_allocated_size, + event.u.tx_timed_packet->sctp_hdr.u.data_hdr.stream); + event.u.tx_timed_packet->status = ET_PACKET_STATUS_SENT; + g_scenario->fsm_state = ET_FSM_STATE_RUNNING; + break; + + + default: + AssertFatal(0, "Case event %d not handled in ET_FSM_STATE_WAITING", event.code); + } + pthread_mutex_unlock(&g_scenario->fsm_lock); + return 0; +} + +//------------------------------------------------------------------------------ +et_fsm_state_t et_scenario_fsm_notify_event_state_connecting_s1c(et_event_t event) +{ + + switch (event.code){ + case ET_EVENT_S1C_CONNECTED: + // hack simulate we have been able to get the right timing values + AssertFatal(gettimeofday(&g_scenario->time_last_tx_packet, NULL) == 0, "gettimeofday failed"); + AssertFatal(gettimeofday(&g_scenario->time_last_rx_packet, NULL) == 0, "gettimeofday failed"); + + while (NULL != g_scenario->next_packet) { + switch (g_scenario->next_packet->sctp_hdr.chunk_type) { case SCTP_CID_DATA : // no init in this scenario, may be sub-scenario - if (packet->action == ET_PACKET_ACTION_S1C_SEND) { - } else if (packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { - g_scenario->waited_packet = packet; + if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_SEND) { + et_scenario_schedule_tx_packet(g_scenario->next_packet); + pthread_mutex_unlock(&g_scenario->fsm_lock); + return g_scenario->fsm_state; + } else if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { + if (g_scenario->next_packet->status == ET_PACKET_STATUS_RECEIVED) { + g_scenario->last_rx_packet = g_scenario->next_packet; + g_scenario->next_packet = g_scenario->next_packet->next; + g_scenario->time_last_rx_packet = g_scenario->last_rx_packet->timestamp_packet; + g_scenario->next_packet = g_scenario->next_packet->next; + + } else if (g_scenario->next_packet->status == ET_PACKET_STATUS_NONE) { + et_scenario_wait_rx_packet(g_scenario->next_packet); + pthread_mutex_unlock(&g_scenario->fsm_lock); + return g_scenario->fsm_state; + } else { + AssertFatal(0, "Invalid packet status %d", g_scenario->next_packet->status); + } } else { - packet->status = ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT; - packet = packet->next; + AssertFatal(0, "Invalid packet action %d", g_scenario->next_packet->action); } - break; + break; + case SCTP_CID_INIT: case SCTP_CID_INIT_ACK: - enb_properties_p = enb_config_get(); - /* Try to register each eNB */ - g_fsm_state = ET_FSM_STATE_CONNECTING_SCTP; - register_enb_pending = et_eNB_app_register (enb_properties_p); - break; case SCTP_CID_HEARTBEAT: case SCTP_CID_HEARTBEAT_ACK: case SCTP_CID_COOKIE_ECHO: case SCTP_CID_COOKIE_ACK: case SCTP_CID_ECN_ECNE: case SCTP_CID_ECN_CWR: - packet->status = ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT; - packet = packet->next; + g_scenario->next_packet->status = ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT; + g_scenario->next_packet = g_scenario->next_packet->next; break; + case SCTP_CID_ABORT: case SCTP_CID_SHUTDOWN: case SCTP_CID_SHUTDOWN_ACK: case SCTP_CID_ERROR: case SCTP_CID_SHUTDOWN_COMPLETE: - AssertFatal(0, "The scenario should be cleaned (packet %s cannot be processed at this time)", et_chunk_type_cid2str(packet->sctp_hdr.chunk_type)); + AssertFatal(0, "The scenario should be cleaned (packet %s cannot be processed at this time)", + et_chunk_type_cid2str(g_scenario->next_packet->sctp_hdr.chunk_type)); break; default: - packet->status = ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT; - packet = packet->next; + g_scenario->next_packet->status = ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT; + g_scenario->next_packet = g_scenario->next_packet->next; } } fprintf(stderr, "No Packet found in this scenario: %s\n", g_scenario->name); - return -1; + g_scenario->fsm_state = ET_FSM_STATE_NULL; + pthread_mutex_unlock(&g_scenario->fsm_lock); + return g_scenario->fsm_state; break; - case ET_EVENT_STOP: + default: + AssertFatal(0, "Case event %d not handled in ET_FSM_STATE_CONNECTING_S1C", event.code); + } + pthread_mutex_unlock(&g_scenario->fsm_lock); + return 0; +} +//------------------------------------------------------------------------------ +et_fsm_state_t et_scenario_fsm_notify_event_state_null(et_event_t event) +{ + switch (event.code){ + case ET_EVENT_INIT: + AssertFatal(NULL == g_scenario, "Current scenario not ended"); + g_scenario = event.u.init.scenario; + g_scenario->next_packet = g_scenario->list_packet; + while (NULL != g_scenario->next_packet) { + switch (g_scenario->next_packet->sctp_hdr.chunk_type) { + + case SCTP_CID_DATA : + // no init in this scenario, may be sub-scenario + if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_SEND) { + et_scenario_schedule_tx_packet(g_scenario->next_packet); + pthread_mutex_unlock(&g_scenario->fsm_lock); + return g_scenario->fsm_state; + } else if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { + if (g_scenario->next_packet->status == ET_PACKET_STATUS_RECEIVED) { + g_scenario->last_rx_packet = g_scenario->next_packet; + g_scenario->next_packet = g_scenario->next_packet->next; + g_scenario->time_last_rx_packet = g_scenario->last_rx_packet->timestamp_packet; + g_scenario->next_packet = g_scenario->next_packet->next; + + } else if (g_scenario->next_packet->status == ET_PACKET_STATUS_NONE) { + et_scenario_wait_rx_packet(g_scenario->next_packet); + pthread_mutex_unlock(&g_scenario->fsm_lock); + return g_scenario->fsm_state; + } else { + AssertFatal(0, "Invalid packet status %d", g_scenario->next_packet->status); + } + } else { + AssertFatal(0, "Invalid packet action %d", g_scenario->next_packet->action); + } + break; + + case SCTP_CID_INIT: + case SCTP_CID_INIT_ACK: + g_scenario->enb_properties = (Enb_properties_array_t *)et_enb_config_get(); + g_scenario->hash_old_ue_mme_id2ue_mme_id = hashtable_create (256,NULL,NULL); + g_scenario->hash_mme2association_id = hashtable_create (256,NULL,NULL); + // Try to register each eNB + g_scenario->registered_enb = 0; + g_scenario->fsm_state = ET_FSM_STATE_CONNECTING_S1C; + g_scenario->register_enb_pending = et_eNB_app_register (g_scenario->enb_properties); + pthread_mutex_unlock(&g_scenario->fsm_lock); + return g_scenario->fsm_state; + break; + + case SCTP_CID_HEARTBEAT: + case SCTP_CID_HEARTBEAT_ACK: + case SCTP_CID_COOKIE_ECHO: + case SCTP_CID_COOKIE_ACK: + case SCTP_CID_ECN_ECNE: + case SCTP_CID_ECN_CWR: + g_scenario->next_packet->status = ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT; + g_scenario->next_packet = g_scenario->next_packet->next; + break; + + case SCTP_CID_ABORT: + case SCTP_CID_SHUTDOWN: + case SCTP_CID_SHUTDOWN_ACK: + case SCTP_CID_ERROR: + case SCTP_CID_SHUTDOWN_COMPLETE: + AssertFatal(0, "The scenario should be cleaned (packet %s cannot be processed at this time)", + et_chunk_type_cid2str(g_scenario->next_packet->sctp_hdr.chunk_type)); + break; + + default: + g_scenario->next_packet->status = ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT; + g_scenario->next_packet = g_scenario->next_packet->next; + } + } + fprintf(stderr, "No Useful packet found in this scenario: %s\n", g_scenario->name); + g_scenario->fsm_state = ET_FSM_STATE_NULL; + pthread_mutex_unlock(&g_scenario->fsm_lock); + return g_scenario->fsm_state; break; default: @@ -112,16 +360,19 @@ int et_scenario_fsm_notify_event_state_null(et_event_t event) } //------------------------------------------------------------------------------ -int et_scenario_fsm_notify_event(et_event_t event) +et_fsm_state_t et_scenario_fsm_notify_event(et_event_t event) { AssertFatal((event.code >= ET_EVENT_START) && (event.code < ET_EVENT_END), "Unknown et_event_t.code %d", event.code); - switch (g_fsm_state){ + pthread_mutex_lock(&g_scenario->fsm_lock); + switch (g_scenario->fsm_state){ case ET_FSM_STATE_NULL: return et_scenario_fsm_notify_event_state_null(event); break; - case ET_FSM_STATE_CONNECTING_SCTP: return et_scenario_fsm_notify_event_state_null(event); break; - case ET_FSM_STATE_WAITING_TX_EVENT: return et_scenario_fsm_notify_event_state_null(event); break; - case ET_FSM_STATE_WAITING_RX_EVENT: return et_scenario_fsm_notify_event_state_null(event); break; + case ET_FSM_STATE_CONNECTING_S1C: return et_scenario_fsm_notify_event_state_connecting_s1c(event); break; + case ET_FSM_STATE_WAITING_EVENT: return et_scenario_fsm_notify_event_state_waiting(event); break; + case ET_FSM_STATE_RUNNING: return et_scenario_fsm_notify_event_state_running(event); break; default: - return -1; + AssertFatal(0, "Case fsm_state %d not handled", g_scenario->fsm_state); } + pthread_mutex_unlock(&g_scenario->fsm_lock); + return g_scenario->fsm_state; } diff --git a/openair3/TEST/EPC_TEST/play_scenario_parse.c b/openair3/TEST/EPC_TEST/play_scenario_parse.c index 236c17963a..f6d8aa73ac 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_parse.c +++ b/openair3/TEST/EPC_TEST/play_scenario_parse.c @@ -47,17 +47,19 @@ #include #include #include +#include +#include +#include #include "intertask_interface.h" #include "platform_types.h" -#include "enb_config.h" #include "assertions.h" #include "play_scenario.h" //------------------------------------------------------------------------------ #define ENB_CONFIG_MAX_XSLT_PARAMS 32 //------------------------------------------------------------------------------ extern char *g_openair_dir; -extern Enb_properties_array_t enb_properties; +extern Enb_properties_array_t g_enb_properties; //------------------------------------------------------------------------------ void et_parse_s1ap(xmlDocPtr doc, const xmlNode const *s1ap_node, et_s1ap_t * const s1ap) { @@ -407,6 +409,10 @@ et_packet_t* et_parse_xml_packet(xmlDocPtr doc, xmlNodePtr node) { } xmlFree(xml_char); } + } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"eNB.instance"))) { + xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"value"); + packet->enb_instance = strtoul((const char *)xml_char, NULL, 0); + xmlFree(xml_char); } //} } @@ -439,8 +445,11 @@ et_scenario_t* et_generate_scenario( if ((!xmlStrcmp(root->name, (const xmlChar *)"scenario"))) { xml_char = xmlGetProp(root, (const xmlChar *)"name"); printf("scenario name: %s\n", xml_char); - scenario = calloc(1, sizeof(*scenario)); - scenario->name = xml_char; // nodup nofree + scenario = calloc(1, sizeof(*scenario)); + scenario->name = xml_char; // nodup nofree + scenario->fsm_state = ET_FSM_STATE_NULL; + pthread_mutex_init(&scenario->fsm_lock, NULL); + next_packet = &scenario->list_packet; for (node = root->children; node != NULL; node = node->next) { if ((!xmlStrcmp(node->name, (const xmlChar *)"packet"))) { @@ -509,21 +518,21 @@ int et_generate_xml_scenario( fprintf(stdout, "Test scenario file: %s\n", xml_in_scenario_filename); } - for (i = 0; i < enb_properties.number; i++) { + for (i = 0; i < g_enb_properties.number; i++) { // eNB S1-C IPv4 address sprintf(astring, "enb_s1c%d", i); params[nb_params++] = strdup(astring); - addr.s_addr = enb_properties.properties[i]->enb_ipv4_address_for_S1_MME; + addr.s_addr = g_enb_properties.properties[i]->enb_ipv4_address_for_S1_MME; sprintf(astring, "\"%s\"", inet_ntoa(addr)); params[nb_params++] = strdup(astring); // MME S1-C IPv4 address - for (j = 0; j < enb_properties.properties[i]->nb_mme; j++) { + for (j = 0; j < g_enb_properties.properties[i]->nb_mme; j++) { sprintf(astring, "mme_s1c%d_%d", i, j); params[nb_params++] = strdup(astring); - AssertFatal (enb_properties.properties[i]->mme_ip_address[j].ipv4_address, + AssertFatal (g_enb_properties.properties[i]->mme_ip_address[j].ipv4_address, "Only support MME IPv4 address\n"); - sprintf(astring, "\"%s\"", enb_properties.properties[i]->mme_ip_address[j].ipv4_address); + sprintf(astring, "\"%s\"", g_enb_properties.properties[i]->mme_ip_address[j].ipv4_address); params[nb_params++] = strdup(astring); } } diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c index cb5571c28b..7dd80904ae 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c @@ -38,29 +38,173 @@ #include #include #include +#include +#include #include "tree.h" #include "queue.h" #include "intertask_interface.h" -#include "messages_types.h" +#include "timer.h" #include "platform_types.h" -#include "s1ap_common.h" -#include "s1ap_eNB_defs.h" -#include "s1ap_eNB_default_values.h" -#include "s1ap_eNB_management_procedures.h" -#include "s1ap_eNB.h" -#include "play_scenario.h" -#include "msc.h" #include "assertions.h" #include "conversions.h" +#include "s1ap_common.h" +#include "play_scenario_s1ap_eNB_defs.h" +#include "play_scenario.h" +#include "msc.h" +//------------------------------------------------------------------------------ +s1ap_eNB_internal_data_t s1ap_eNB_internal_data; +RB_GENERATE(s1ap_mme_map, s1ap_eNB_mme_data_s, entry, et_s1ap_eNB_compare_assoc_id); +//------------------------------------------------------------------------------ +extern et_scenario_t *g_scenario; +//------------------------------------------------------------------------------ +int et_s1ap_eNB_compare_assoc_id( + struct s1ap_eNB_mme_data_s *p1, struct s1ap_eNB_mme_data_s *p2) +{ + if (p1->assoc_id == -1) { + if (p1->cnx_id < p2->cnx_id) { + return -1; + } + if (p1->cnx_id > p2->cnx_id) { + return 1; + } + } else { + if (p1->assoc_id < p2->assoc_id) { + return -1; + } + + if (p1->assoc_id > p2->assoc_id) { + return 1; + } + } + + /* Matching reference */ + return 0; +} +//------------------------------------------------------------------------------ +uint32_t et_s1ap_generate_eNB_id(void) +{ + char *out; + char hostname[50]; + int ret; + uint32_t eNB_id; + + /* Retrieve the host name */ + ret = gethostname(hostname, sizeof(hostname)); + DevAssert(ret == 0); + + out = crypt(hostname, "eurecom"); + DevAssert(out != NULL); + + eNB_id = ((out[0] << 24) | (out[1] << 16) | (out[2] << 8) | out[3]); + + return eNB_id; +} +//------------------------------------------------------------------------------ +uint16_t et_s1ap_eNB_fetch_add_global_cnx_id(void) +{ + return ++s1ap_eNB_internal_data.global_cnx_id; +} //------------------------------------------------------------------------------ -extern void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp); -extern void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *s1ap_register_eNB); +void et_s1ap_eNB_prepare_internal_data(void) +{ + memset(&s1ap_eNB_internal_data, 0, sizeof(s1ap_eNB_internal_data)); + STAILQ_INIT(&s1ap_eNB_internal_data.s1ap_eNB_instances_head); +} + //------------------------------------------------------------------------------ -void et_s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) +void et_s1ap_eNB_insert_new_instance(s1ap_eNB_instance_t *new_instance_p) +{ + DevAssert(new_instance_p != NULL); + + STAILQ_INSERT_TAIL(&s1ap_eNB_internal_data.s1ap_eNB_instances_head, + new_instance_p, s1ap_eNB_entries); +} + +//------------------------------------------------------------------------------ +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) +{ + struct s1ap_eNB_mme_data_s temp; + struct s1ap_eNB_mme_data_s *found; + + memset(&temp, 0, sizeof(struct s1ap_eNB_mme_data_s)); + + temp.assoc_id = assoc_id; + temp.cnx_id = cnx_id; + + if (instance_p == NULL) { + STAILQ_FOREACH(instance_p, &s1ap_eNB_internal_data.s1ap_eNB_instances_head, + s1ap_eNB_entries) { + found = RB_FIND(s1ap_mme_map, &instance_p->s1ap_mme_head, &temp); + + if (found != NULL) { + return found; + } + } + } else { + return RB_FIND(s1ap_mme_map, &instance_p->s1ap_mme_head, &temp); + } + + return NULL; +} + +//------------------------------------------------------------------------------ +s1ap_eNB_instance_t *et_s1ap_eNB_get_instance(instance_t instance) +{ + s1ap_eNB_instance_t *temp = NULL; + + STAILQ_FOREACH(temp, &s1ap_eNB_internal_data.s1ap_eNB_instances_head, + s1ap_eNB_entries) { + if (temp->instance == instance) { + /* Matching occurence */ + return temp; + } + } + + return NULL; +} +//------------------------------------------------------------------------------ +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) +{ + MessageDef *message_p; + sctp_data_req_t *sctp_data_req; + + message_p = itti_alloc_new_message(TASK_S1AP, SCTP_DATA_REQ); + + sctp_data_req = &message_p->ittiMsg.sctp_data_req; + + sctp_data_req->assoc_id = assoc_id; + sctp_data_req->buffer = buffer; + sctp_data_req->buffer_length = buffer_length; + sctp_data_req->stream = stream; + + itti_send_msg_to_task(TASK_SCTP, instance, message_p); +} +//------------------------------------------------------------------------------ +void et_s1ap_process_rx_packet(et_event_s1ap_data_ind_t * const sctp_data_ind) +{ + et_packet_t * packet = NULL; + unsigned long int not_found = 1; + + packet = g_scenario->next_packet; + // 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) { + //TODO + } + not_found += 1; + packet = packet->next; + } +} + +//------------------------------------------------------------------------------ +void et_s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t * const sctp_data_ind) { int result = 0; et_event_t event; @@ -73,7 +217,8 @@ void et_s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) event.u.s1ap_data_ind.sctp_datahdr.tsn = 0; event.u.s1ap_data_ind.sctp_datahdr.stream = sctp_data_ind->stream; event.u.s1ap_data_ind.sctp_datahdr.ssn = 0; - event.u.s1ap_data_ind.sctp_datahdr.ppid = 18; // find constant + event.u.s1ap_data_ind.sctp_datahdr.ppid = S1AP_SCTP_PPID; + event.u.s1ap_data_ind.sctp_datahdr.assoc_id = sctp_data_ind->assoc_id; event.u.s1ap_data_ind.sctp_datahdr.payload.binary_stream_pos = 0; event.u.s1ap_data_ind.sctp_datahdr.payload.binary_stream_allocated_size = sctp_data_ind->buffer_length; @@ -100,6 +245,253 @@ void et_s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) et_scenario_fsm_notify_event(event); } +//------------------------------------------------------------------------------ +void et_s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, + net_ip_address_t *mme_ip_address, + net_ip_address_t *local_ip_addr, + uint16_t in_streams, + uint16_t out_streams) +{ + MessageDef *message_p = NULL; + sctp_new_association_req_t *sctp_new_association_req_p = NULL; + s1ap_eNB_mme_data_t *s1ap_mme_data_p = NULL; + + DevAssert(instance_p != NULL); + DevAssert(mme_ip_address != NULL); + + message_p = itti_alloc_new_message(TASK_S1AP, SCTP_NEW_ASSOCIATION_REQ); + + sctp_new_association_req_p = &message_p->ittiMsg.sctp_new_association_req; + + sctp_new_association_req_p->port = S1AP_PORT_NUMBER; + sctp_new_association_req_p->ppid = S1AP_SCTP_PPID; + + sctp_new_association_req_p->in_streams = in_streams; + sctp_new_association_req_p->out_streams = out_streams; + + memcpy(&sctp_new_association_req_p->remote_address, + mme_ip_address, + sizeof(*mme_ip_address)); + + memcpy(&sctp_new_association_req_p->local_address, + local_ip_addr, + sizeof(*local_ip_addr)); + + /* Create new MME descriptor */ + s1ap_mme_data_p = calloc(1, sizeof(*s1ap_mme_data_p)); + DevAssert(s1ap_mme_data_p != NULL); + + s1ap_mme_data_p->cnx_id = et_s1ap_eNB_fetch_add_global_cnx_id(); + sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id; + + s1ap_mme_data_p->assoc_id = -1; + s1ap_mme_data_p->s1ap_eNB_instance = instance_p; + + memcpy((void*)&s1ap_mme_data_p->mme_net_ip_address, mme_ip_address, sizeof(*mme_ip_address)); + + + STAILQ_INIT(&s1ap_mme_data_p->served_gummei); + + /* Insert the new descriptor in list of known MME + * but not yet associated. + */ + RB_INSERT(s1ap_mme_map, &instance_p->s1ap_mme_head, s1ap_mme_data_p); + s1ap_mme_data_p->state = S1AP_ENB_STATE_WAITING; + instance_p->s1ap_mme_nb ++; + instance_p->s1ap_mme_pending_nb ++; + + itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p); +} +//------------------------------------------------------------------------------ +void et_s1ap_update_assoc_id_of_packets(const int32_t assoc_id, + struct s1ap_eNB_instance_s * const s1ap_eNB_instance, + s1ap_eNB_mme_data_t * const mme_desc_p) +{ + et_packet_t *packet = NULL; + struct in6_addr s1c_mme_ipv6 = IN6ADDR_ANY_INIT; + in_addr_t s1c_mme_ipv4 = INADDR_ANY; + struct in6_addr s1c_enb_ipv6 = IN6ADDR_ANY_INIT; + in_addr_t s1c_enb_ipv4 = INADDR_ANY; + + packet = g_scenario->next_packet; + while (NULL != packet) { + switch (packet->sctp_hdr.chunk_type) { + + case SCTP_CID_DATA : + if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_SEND) { + // TODO compare addresses and ports + if (packet->ip_hdr.dst) + packet->sctp_hdr.dst_port == 0; + packet->sctp_hdr.src_port == 0; + + } else if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { + } + break; + + case SCTP_CID_INIT: + case SCTP_CID_INIT_ACK: + case SCTP_CID_HEARTBEAT: + case SCTP_CID_HEARTBEAT_ACK: + case SCTP_CID_COOKIE_ECHO: + case SCTP_CID_COOKIE_ACK: + case SCTP_CID_ECN_ECNE: + case SCTP_CID_ECN_CWR: + break; + + case SCTP_CID_ABORT: + case SCTP_CID_SHUTDOWN: + case SCTP_CID_SHUTDOWN_ACK: + case SCTP_CID_ERROR: + case SCTP_CID_SHUTDOWN_COMPLETE: + //TODO + break; + + default: + ; + } + packet = packet->next; + } +} +//------------------------------------------------------------------------------ +void et_s1ap_handle_s1_setup_message(s1ap_eNB_mme_data_t *mme_desc_p, int sctp_shutdown) +{ + if (sctp_shutdown) { + /* A previously connected MME has been shutdown */ + + /* TODO check if it was used by some eNB and send a message to inform these eNB if there is no more associated MME */ + if (mme_desc_p->state == S1AP_ENB_STATE_CONNECTED) { + mme_desc_p->state = S1AP_ENB_STATE_DISCONNECTED; + + if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb > 0) { + /* Decrease associated MME number */ + mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb --; + } + + /* If there are no more associated MME, inform eNB app */ + if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb == 0) { + MessageDef *message_p; + + message_p = itti_alloc_new_message(TASK_S1AP, S1AP_DEREGISTERED_ENB_IND); + S1AP_DEREGISTERED_ENB_IND(message_p).nb_mme = 0; + itti_send_msg_to_task(TASK_ENB_APP, mme_desc_p->s1ap_eNB_instance->instance, message_p); + } + } + } else { + /* Check that at least one setup message is pending */ + DevCheck(mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb > 0, mme_desc_p->s1ap_eNB_instance->instance, + mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb, 0); + + if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb > 0) { + /* Decrease pending messages number */ + mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb --; + } + + et_s1ap_update_assoc_id_of_packets(mme_desc_p->assoc_id, + mme_desc_p->s1ap_eNB_instance, + mme_desc_p); + + /* If there are no more pending messages, inform eNB app */ + if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb == 0) { + MessageDef *message_p; + + message_p = itti_alloc_new_message(TASK_S1AP, S1AP_REGISTER_ENB_CNF); + S1AP_REGISTER_ENB_CNF(message_p).nb_mme = mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb; + itti_send_msg_to_task(TASK_ENB_APP, mme_desc_p->s1ap_eNB_instance->instance, message_p); + } + } +} +//------------------------------------------------------------------------------ +void et_s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *s1ap_register_eNB) +{ + s1ap_eNB_instance_t *new_instance; + uint8_t index; + + DevAssert(s1ap_register_eNB != NULL); + + /* Look if the provided instance already exists */ + new_instance = et_s1ap_eNB_get_instance(instance); + + if (new_instance != NULL) { + /* Checks if it is a retry on the same eNB */ + DevCheck(new_instance->eNB_id == s1ap_register_eNB->eNB_id, new_instance->eNB_id, s1ap_register_eNB->eNB_id, 0); + DevCheck(new_instance->cell_type == s1ap_register_eNB->cell_type, new_instance->cell_type, s1ap_register_eNB->cell_type, 0); + DevCheck(new_instance->tac == s1ap_register_eNB->tac, new_instance->tac, s1ap_register_eNB->tac, 0); + DevCheck(new_instance->mcc == s1ap_register_eNB->mcc, new_instance->mcc, s1ap_register_eNB->mcc, 0); + DevCheck(new_instance->mnc == s1ap_register_eNB->mnc, new_instance->mnc, s1ap_register_eNB->mnc, 0); + DevCheck(new_instance->mnc_digit_length == s1ap_register_eNB->mnc_digit_length, new_instance->mnc_digit_length, s1ap_register_eNB->mnc_digit_length, 0); + } else { + new_instance = calloc(1, sizeof(s1ap_eNB_instance_t)); + DevAssert(new_instance != NULL); + + RB_INIT(&new_instance->s1ap_ue_head); + RB_INIT(&new_instance->s1ap_mme_head); + + /* Copy usefull parameters */ + new_instance->instance = instance; + new_instance->eNB_name = s1ap_register_eNB->eNB_name; + new_instance->eNB_id = s1ap_register_eNB->eNB_id; + new_instance->cell_type = s1ap_register_eNB->cell_type; + new_instance->tac = s1ap_register_eNB->tac; + new_instance->mcc = s1ap_register_eNB->mcc; + new_instance->mnc = s1ap_register_eNB->mnc; + new_instance->mnc_digit_length = s1ap_register_eNB->mnc_digit_length; + + /* Add the new instance to the list of eNB (meaningfull in virtual mode) */ + et_s1ap_eNB_insert_new_instance(new_instance); + + S1AP_DEBUG("Registered new eNB[%d] and %s eNB id %u\n", + instance, + s1ap_register_eNB->cell_type == CELL_MACRO_ENB ? "macro" : "home", + s1ap_register_eNB->eNB_id); + } + + DevCheck(s1ap_register_eNB->nb_mme <= S1AP_MAX_NB_MME_IP_ADDRESS, + S1AP_MAX_NB_MME_IP_ADDRESS, s1ap_register_eNB->nb_mme, 0); + + /* Trying to connect to provided list of MME ip address */ + for (index = 0; index < s1ap_register_eNB->nb_mme; index++) { + et_s1ap_eNB_register_mme(new_instance, + &s1ap_register_eNB->mme_ip_address[index], + &s1ap_register_eNB->enb_ip_address, + s1ap_register_eNB->sctp_in_streams, + s1ap_register_eNB->sctp_out_streams); + } +} + +//------------------------------------------------------------------------------ +void et_s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) +{ + s1ap_eNB_instance_t *instance_p = NULL; + s1ap_eNB_mme_data_t *s1ap_mme_data_p = NULL; + + DevAssert(sctp_new_association_resp != NULL); + + instance_p = et_s1ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + s1ap_mme_data_p = et_s1ap_eNB_get_MME(instance_p, -1, + sctp_new_association_resp->ulp_cnx_id); + DevAssert(s1ap_mme_data_p != NULL); + + if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { + S1AP_WARN("Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n", + sctp_new_association_resp->sctp_state, + instance, + sctp_new_association_resp->ulp_cnx_id); + + et_s1ap_handle_s1_setup_message(s1ap_mme_data_p, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN); + + return; + } + + /* Update parameters */ + s1ap_mme_data_p->assoc_id = sctp_new_association_resp->assoc_id; + s1ap_mme_data_p->in_streams = sctp_new_association_resp->in_streams; + s1ap_mme_data_p->out_streams = sctp_new_association_resp->out_streams; + + et_s1ap_handle_s1_setup_message(s1ap_mme_data_p, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN); +} + //------------------------------------------------------------------------------ void *et_s1ap_eNB_task(void *arg) { @@ -108,7 +500,7 @@ void *et_s1ap_eNB_task(void *arg) S1AP_DEBUG("Starting S1AP layer\n"); - s1ap_eNB_prepare_internal_data(); + et_s1ap_eNB_prepare_internal_data(); itti_mark_task_ready(TASK_S1AP); MSC_START_USE(); @@ -127,13 +519,13 @@ void *et_s1ap_eNB_task(void *arg) * Each eNB has to send an S1AP_REGISTER_ENB message with its * own parameters. */ - s1ap_eNB_handle_register_eNB(ITTI_MESSAGE_GET_INSTANCE(received_msg), + et_s1ap_eNB_handle_register_eNB(ITTI_MESSAGE_GET_INSTANCE(received_msg), &S1AP_REGISTER_ENB_REQ(received_msg)); } break; case SCTP_NEW_ASSOCIATION_RESP: { - s1ap_eNB_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + et_s1ap_eNB_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_new_association_resp); } break; @@ -143,6 +535,31 @@ void *et_s1ap_eNB_task(void *arg) } break; + case TIMER_HAS_EXPIRED: + LOG_I(S1AP, " Received TIMER_HAS_EXPIRED: timer_id %d\n", TIMER_HAS_EXPIRED(received_msg).timer_id); + { + et_packet_t * packet = (et_packet_t*)TIMER_HAS_EXPIRED (received_msg).arg; + et_event_t event; + if (packet->status == ET_PACKET_STATUS_SCHEDULED_FOR_RECEIVING) { + memset((void*)&event, 0, sizeof(event)); + event.code = ET_EVENT_RX_PACKET_TIME_OUT; + event.u.rx_packet_time_out = packet; + et_scenario_fsm_notify_event(event); + } else if (packet->status == ET_PACKET_STATUS_SCHEDULED_FOR_SENDING) { + memset((void*)&event, 0, sizeof(event)); + event.code = ET_EVENT_TX_TIMED_PACKET; + event.u.tx_timed_packet = packet; + et_scenario_fsm_notify_event(event); + } else if ((packet->status != ET_PACKET_STATUS_SENT) && ((packet->status != ET_PACKET_STATUS_RECEIVED))) { + AssertFatal (0, "Bad status %d of packet timed out!\n", packet->status); + } + } + if (TIMER_HAS_EXPIRED (received_msg).timer_id == g_scenario->enb_register_retry_timer_id) { + /* Restart the registration process */ + g_scenario->registered_enb = 0; + g_scenario->register_enb_pending = et_eNB_app_register (g_scenario->enb_properties); + } + break; default: S1AP_ERROR("Received unhandled message: %d:%s\n", diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap_eNB_defs.h b/openair3/TEST/EPC_TEST/play_scenario_s1ap_eNB_defs.h new file mode 100644 index 0000000000..ac77b88b24 --- /dev/null +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap_eNB_defs.h @@ -0,0 +1,250 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2014 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see . + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France. + + *******************************************************************************/ + +#include + +#include "queue.h" +#include "tree.h" + +#include "sctp_eNB_defs.h" + +#ifndef PLAY_SCENARIO_S1AP_ENB_DEFS_H_ +#define PLAY_SCENARIO_S1AP_ENB_DEFS_H_ + +#define ENB_TAC (1) +#define ENB_MCC (208) +#define ENB_MNC (92) + +#define ENB_NAME "Eurecom ENB" +#define ENB_NAME_FORMAT (ENB_NAME" %u") + +#define S1AP_PORT_NUMBER (36412) +#define S1AP_SCTP_PPID (18) + +#define X2AP_PORT_NUMBER (36422) +#define X2AP_SCTP_PPID (27) + +#define S1AP_ENB_NAME_LENGTH_MAX (150) + +typedef enum { + /* Disconnected state: initial state for any association. */ + S1AP_ENB_STATE_DISCONNECTED = 0x0, + /* State waiting for S1 Setup response message if eNB is MME accepted or + * S1 Setup failure if MME rejects the eNB. + */ + S1AP_ENB_STATE_WAITING = 0x1, + /* The eNB is successfully connected to MME, UE contexts can be created. */ + S1AP_ENB_STATE_CONNECTED = 0x2, + /* The MME has sent an overload start message. Once the MME disables the + * OVERLOAD marker, the state of the association will be + * S1AP_ENB_STATE_CONNECTED. + */ + S1AP_ENB_OVERLOAD = 0x3, + /* Max number of states available */ + S1AP_ENB_STATE_MAX, +} s1ap_eNB_state_t; + + +/* If the Overload Action IE in the OVERLOAD START message is set to + * - “reject all RRC connection establishments for non-emergency mobile + * originated data transfer “ (i.e. reject traffic corresponding to RRC cause + * “mo-data “ (TS 36.331 [16])), or + * - “reject all RRC connection establishments for signalling “ (i.e. reject + * traffic corresponding to RRC cause “modata” and “mo-signalling” + * (TS 36.331 [16])),or + * - “only permit RRC connection establishments for emergency sessions and + * mobile terminated services” (i.e. only permit traffic corresponding to RRC + * cause “emergency” and “mt-Access” (TS 36.331 [16])). + * + * NOTE: When the Overload Action IE is set to “only permit RRC connection + * establishments for emergency sessions and mobile terminated services”, + * emergency calls with RRC cause “highPriorityAcess” from high priority users + * are rejected (TS 24.301 [24]). + */ +typedef enum { + S1AP_OVERLOAD_REJECT_MO_DATA = 0x0, + S1AP_OVERLOAD_REJECT_ALL_SIGNALLING = 0x1, + S1AP_OVERLOAD_ONLY_EMERGENCY_AND_MT = 0x2, + S1AP_NO_OVERLOAD = 0x3, + S1AP_OVERLOAD_MAX, +} s1ap_overload_state_t; + +/* Served PLMN identity element */ +struct plmn_identity_s { + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + STAILQ_ENTRY(plmn_identity_s) next; +}; + +/* Served group id element */ +struct served_group_id_s { + uint16_t mme_group_id; + STAILQ_ENTRY(served_group_id_s) next; +}; + +/* Served mme code for a particular MME */ +struct mme_code_s { + uint8_t mme_code; + STAILQ_ENTRY(mme_code_s) next; +}; + +/* Served gummei element */ +struct served_gummei_s { + /* Number of MME served PLMNs */ + uint8_t nb_served_plmns; + /* List of served PLMNs by MME */ + STAILQ_HEAD(served_plmns_s, plmn_identity_s) served_plmns; + + /* Number of group id in list */ + uint8_t nb_group_id; + /* Served group id list */ + STAILQ_HEAD(served_group_ids_s, served_group_id_s) served_group_ids; + + /* Number of MME code */ + uint8_t nb_mme_code; + /* MME Code to uniquely identify an MME within an MME pool area */ + STAILQ_HEAD(mme_codes_s, mme_code_s) mme_codes; + + /* Next GUMMEI element */ + STAILQ_ENTRY(served_gummei_s) next; +}; + +struct s1ap_eNB_instance_s; + +/* This structure describes association of a eNB to a MME */ +typedef struct s1ap_eNB_mme_data_s { + /* MME descriptors tree, ordered by sctp assoc id */ + RB_ENTRY(s1ap_eNB_mme_data_s) entry; + + /* This is the optional name provided by the MME */ + char *mme_name; + net_ip_address_t mme_net_ip_address; // useful for joining assoc_id and ip address of packets + + /* List of served GUMMEI per MME. There is one GUMMEI per RAT with a max + * number of 8 RATs but in our case only one is used. The LTE related pool + * configuration is included on the first place in the list. + */ + STAILQ_HEAD(served_gummeis_s, served_gummei_s) served_gummei; + + /* Relative processing capacity of an MME with respect to the other MMEs + * in the pool in order to load-balance MMEs within a pool as defined + * in TS 23.401. + */ + uint8_t relative_mme_capacity; + + /* Current MME overload information (if any). */ + s1ap_overload_state_t overload_state; + /* Current eNB->MME S1AP association state */ + s1ap_eNB_state_t state; + + /* Next usable stream for UE signalling */ + int32_t nextstream; + + /* Number of input/ouput streams */ + uint16_t in_streams; + uint16_t out_streams; + + /* Connexion id used between SCTP/S1AP */ + uint16_t cnx_id; + + /* SCTP association id */ + int32_t assoc_id; + + /* Only meaningfull in virtual mode */ + struct s1ap_eNB_instance_s *s1ap_eNB_instance; +} s1ap_eNB_mme_data_t; + +typedef struct s1ap_eNB_instance_s { + /* Next s1ap eNB association. + * Only used for virtual mode. + */ + STAILQ_ENTRY(s1ap_eNB_instance_s) s1ap_eNB_entries; + + /* Number of MME requested by eNB (tree size) */ + uint32_t s1ap_mme_nb; + /* Number of MME for which association is pending */ + uint32_t s1ap_mme_pending_nb; + /* Number of MME successfully associated to eNB */ + uint32_t s1ap_mme_associated_nb; + /* Tree of S1AP MME associations ordered by association ID */ + RB_HEAD(s1ap_mme_map, s1ap_eNB_mme_data_s) s1ap_mme_head; + + /* TODO: add a map ordered by relative MME capacity */ + + /* Tree of UE ordered by eNB_ue_s1ap_id's */ + RB_HEAD(s1ap_ue_map, s1ap_eNB_ue_context_s) s1ap_ue_head; + + /* For virtual mode, mod_id as defined in the rest of the L1/L2 stack */ + instance_t instance; + + /* Displayable name of eNB */ + char *eNB_name; + net_ip_address_t s1c_net_ip_address; + + /* Unique eNB_id to identify the eNB within EPC. + * In our case the eNB is a macro eNB so the id will be 20 bits long. + * For Home eNB id, this field should be 28 bits long. + */ + uint32_t eNB_id; + /* The type of the cell */ + enum cell_type_e cell_type; + + /* Tracking area code */ + uint16_t tac; + + /* Mobile Country Code + * Mobile Network Code + */ + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + +} s1ap_eNB_instance_t; + +typedef struct { + /* List of served eNBs + * Only used for virtual mode + */ + STAILQ_HEAD(s1ap_eNB_instances_head_s, s1ap_eNB_instance_s) s1ap_eNB_instances_head; + /* Nb of registered eNBs */ + uint8_t nb_registered_eNBs; + + /* Generate a unique connexion id used between S1AP and SCTP */ + uint16_t global_cnx_id; +} s1ap_eNB_internal_data_t; + +int s1ap_eNB_compare_assoc_id( + struct s1ap_eNB_mme_data_s *p1, struct s1ap_eNB_mme_data_s *p2); + +/* Generate the tree management functions */ +RB_PROTOTYPE(s1ap_mme_map, s1ap_eNB_mme_data_s, entry, + s1ap_eNB_compare_assoc_id); + +#endif /* PLAY_SCENARIO_S1AP_ENB_DEFS_H_ */ From 717cd8a102d002fba32f57ba04c7421347e06c36 Mon Sep 17 00:00:00 2001 From: gauthier Date: Tue, 24 Nov 2015 16:51:15 +0100 Subject: [PATCH 12/47] Starting debug, remainig TODO report new mme_ue_id --- openair2/COMMON/s1ap_messages_types.h | 2 +- openair3/SCTP/sctp_eNB_task.c | 9 ++ openair3/TEST/EPC_TEST/play_scenario.c | 97 +++++++++---- openair3/TEST/EPC_TEST/play_scenario.h | 8 +- openair3/TEST/EPC_TEST/play_scenario.xsl | 144 +++++++++---------- openair3/TEST/EPC_TEST/play_scenario_fsm.c | 68 ++++----- openair3/TEST/EPC_TEST/play_scenario_parse.c | 2 - openair3/TEST/EPC_TEST/play_scenario_s1ap.c | 86 +++++++++-- 8 files changed, 266 insertions(+), 150 deletions(-) diff --git a/openair2/COMMON/s1ap_messages_types.h b/openair2/COMMON/s1ap_messages_types.h index c39725b737..f2c6a2a3a2 100644 --- a/openair2/COMMON/s1ap_messages_types.h +++ b/openair2/COMMON/s1ap_messages_types.h @@ -112,7 +112,7 @@ typedef struct net_ip_address_s { unsigned ipv4:1; unsigned ipv6:1; char ipv4_address[16]; - char ipv6_address[40]; + char ipv6_address[46]; } net_ip_address_t; typedef uint64_t bitrate_t; diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c index c1e7d989e9..357803ac4f 100644 --- a/openair3/SCTP/sctp_eNB_task.c +++ b/openair3/SCTP/sctp_eNB_task.c @@ -100,6 +100,7 @@ static STAILQ_HEAD(sctp_cnx_list_head, sctp_cnx_list_elm_s) sctp_cnx_list; static uint16_t sctp_nb_cnx = 0; +//------------------------------------------------------------------------------ struct sctp_cnx_list_elm_s *sctp_get_cnx(int32_t assoc_id, int sd) { struct sctp_cnx_list_elm_s *elm; @@ -119,6 +120,7 @@ struct sctp_cnx_list_elm_s *sctp_get_cnx(int32_t assoc_id, int sd) return NULL; } +//------------------------------------------------------------------------------ void sctp_handle_new_association_req( const instance_t instance, @@ -388,6 +390,7 @@ sctp_handle_new_association_req( sd, sctp_nb_cnx, assoc_id); } + //------------------------------------------------------------------------------ void sctp_send_data( instance_t instance, task_id_t task_id, @@ -430,6 +433,7 @@ void sctp_send_data( sctp_cnx->assoc_id); } +//------------------------------------------------------------------------------ static int sctp_close_association( const instance_t instance, const task_id_t requestor, @@ -456,6 +460,7 @@ static int sctp_close_association( return 0; } +//------------------------------------------------------------------------------ static int sctp_create_new_listener( const instance_t instance, const task_id_t requestor, @@ -580,6 +585,7 @@ err: return -1; } +//------------------------------------------------------------------------------ static inline void sctp_eNB_accept_associations( @@ -646,6 +652,7 @@ sctp_eNB_accept_associations( } } +//------------------------------------------------------------------------------ static inline void sctp_eNB_read_from_socket( @@ -770,6 +777,7 @@ sctp_eNB_read_from_socket( } } +//------------------------------------------------------------------------------ void sctp_eNB_flush_sockets( struct epoll_event *events, int nb_events) @@ -799,6 +807,7 @@ sctp_eNB_flush_sockets( } +//------------------------------------------------------------------------------ void *sctp_eNB_task(void *arg) { int nb_events; diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c index f29393f0e7..f8f334dd9c 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.c +++ b/openair3/TEST/EPC_TEST/play_scenario.c @@ -51,6 +51,7 @@ #include #include #include +#include #include "intertask_interface_init.h" @@ -60,6 +61,7 @@ #include "intertask_interface.h" #include "play_scenario.h" #include "sctp_eNB_task.h" +#include "sctp_default_values.h" #include "log.h" //------------------------------------------------------------------------------ #define PLAY_SCENARIO 1 @@ -73,6 +75,7 @@ extern et_scenario_t *g_scenario; extern int xmlLoadExtDtdDefaultValue; extern int asn_debug; extern int asn1_xer_print; +extern pthread_mutex_t g_fsm_lock; //------------------------------------------------------------------------------ // MEMO: @@ -170,7 +173,7 @@ void et_free_scenario(et_scenario_t* scenario) packet = next_packet->next; } et_free_pointer(scenario); - pthread_mutex_destroy(&scenario->fsm_lock); + pthread_mutex_destroy(&g_fsm_lock); } } @@ -276,7 +279,7 @@ const char * const et_chunk_type_cid2str(const sctp_cid_t chunk_type) case SCTP_CID_ASCONF: return "ASCONF"; break; case SCTP_CID_ASCONF_ACK: return "ASCONF_ACK"; break; default: - AssertFatal (0, "ERROR %s(): Unknown chunk_type %d!\n", __FUNCTION__, chunk_type); + AssertFatal (0, "ERROR: Unknown chunk_type %d!\n", chunk_type); } } //------------------------------------------------------------------------------ @@ -284,24 +287,50 @@ et_packet_action_t et_action_str2et_action_t(const xmlChar * const action) { if ((!xmlStrcmp(action, (const xmlChar *)"SEND"))) { return ET_PACKET_ACTION_S1C_SEND;} if ((!xmlStrcmp(action, (const xmlChar *)"RECEIVE"))) { return ET_PACKET_ACTION_S1C_RECEIVE;} - AssertFatal (0, "ERROR: %s cannot convert: %s\n", __FUNCTION__, action); + AssertFatal (0, "ERROR: cannot convert: %s\n", action); //if (NULL == action) {return ACTION_S1C_NULL;} } //------------------------------------------------------------------------------ void et_ip_str2et_ip(const xmlChar * const ip_str, et_ip_t * const ip) { - AssertFatal (NULL != ip_str, "ERROR %s() Cannot convert null string to ip address!\n", __FUNCTION__); - AssertFatal (NULL != ip, "ERROR %s() out parameter pointer is NULL!\n", __FUNCTION__); + AssertFatal (NULL != ip_str, "ERROR Cannot convert null string to ip address!\n"); + AssertFatal (NULL != ip, "ERROR out parameter pointer is NULL!\n"); // store this IP address in sa: if (inet_pton(AF_INET, (const char*)ip_str, (void*)&(ip->address.ipv4)) > 0) { ip->address_family = AF_INET; + strncpy((char *)ip->str, (const char *)ip_str, INET_ADDRSTRLEN+1); } else if (inet_pton(AF_INET6, (const char*)ip_str, (void*)&(ip->address.ipv6)) > 0) { ip->address_family = AF_INET6; + strncpy((char *)ip->str, (const char *)ip_str, INET6_ADDRSTRLEN+1); } else { ip->address_family = AF_UNSPEC; AssertFatal (0, "ERROR %s() Could not parse ip address %s!\n", __FUNCTION__, ip_str); } } +//------------------------------------------------------------------------------ +int et_compare_et_ip_to_net_ip_address(const et_ip_t * const ip, const net_ip_address_t * const net_ip) +{ + AssertFatal (NULL != ip, "ERROR ip parameter\n"); + AssertFatal (NULL != net_ip, "ERROR net_ip parameter\n"); + switch (ip->address_family) { + case AF_INET: + if (net_ip->ipv4) { + S1AP_DEBUG("%s(%s,%s)=%d\n",__FUNCTION__,ip->str, net_ip->ipv4_address, strcmp(ip->str, net_ip->ipv4_address)); + return strcmp(ip->str, net_ip->ipv4_address); + } + return -1; + break; + case AF_INET6: + if (net_ip->ipv6) { + return strcmp(ip->str, net_ip->ipv6_address); + } + return -1; + break; + default: + return -1; + } +} + #ifdef LIBCONFIG_LONG #define libconfig_int long #else @@ -317,6 +346,7 @@ void et_enb_config_init(const char const * lib_config_file_name_pP) config_setting_t *setting_mme_addresses = NULL; config_setting_t *setting_mme_address = NULL; config_setting_t *setting_enb = NULL; + libconfig_int my_int; int num_enb_properties = 0; int enb_properties_index = 0; int num_enbs = 0; @@ -479,6 +509,20 @@ void et_enb_config_init(const char const * lib_config_file_name_pP) g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv6 = 1; } } + // SCTP SETTING + g_enb_properties.properties[enb_properties_index]->sctp_out_streams = SCTP_OUT_STREAMS; + g_enb_properties.properties[enb_properties_index]->sctp_in_streams = SCTP_IN_STREAMS; + subsetting = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_SCTP_CONFIG); + + if (subsetting != NULL) { + if ( (config_setting_lookup_int( subsetting, ENB_CONFIG_STRING_SCTP_INSTREAMS, &my_int) )) { + g_enb_properties.properties[enb_properties_index]->sctp_in_streams = (uint16_t)my_int; + } + + if ( (config_setting_lookup_int( subsetting, ENB_CONFIG_STRING_SCTP_OUTSTREAMS, &my_int) )) { + g_enb_properties.properties[enb_properties_index]->sctp_out_streams = (uint16_t)my_int; + } + } // NETWORK_INTERFACES @@ -536,19 +580,19 @@ const Enb_properties_array_t *et_enb_config_get(void) return &g_enb_properties; } /*------------------------------------------------------------------------------*/ -uint32_t et_eNB_app_register(const Enb_properties_array_t *enb_properties) +void et_eNB_app_register(const Enb_properties_array_t *enb_properties) { - uint32_t enb_id; - uint32_t mme_id; - MessageDef *msg_p; - char *str = NULL; - struct in_addr addr; + uint32_t enb_id = 0; + uint32_t mme_id = 0; + MessageDef *msg_p = NULL; + char *str = NULL; + struct in_addr addr = {.s_addr = 0}; g_scenario->register_enb_pending = 0; for (enb_id = 0; (enb_id < enb_properties->number) ; enb_id++) { { - s1ap_register_enb_req_t *s1ap_register_eNB; + s1ap_register_enb_req_t *s1ap_register_eNB = NULL; /* note: there is an implicit relationship between the data structure and the message name */ msg_p = itti_alloc_new_message (TASK_ENB_APP, S1AP_REGISTER_ENB_REQ); @@ -589,13 +633,10 @@ uint32_t et_eNB_app_register(const Enb_properties_array_t *enb_properties) str = inet_ntoa(addr); strcpy(s1ap_register_eNB->enb_ip_address.ipv4_address, str); - itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); - g_scenario->register_enb_pending++; + itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); } } - - return g_scenario->register_enb_pending; } /*------------------------------------------------------------------------------*/ void *et_eNB_app_task(void *args_p) @@ -603,12 +644,11 @@ void *et_eNB_app_task(void *args_p) et_scenario_t *scenario = (et_scenario_t*)args_p; MessageDef *msg_p = NULL; const char *msg_name = NULL; - instance_t instance; - int result; + instance_t instance = 0; + int result = 0; itti_mark_task_ready (TASK_ENB_APP); - do { // Wait for a message itti_receive_msg (TASK_ENB_APP, &msg_p); @@ -625,18 +665,20 @@ void *et_eNB_app_task(void *args_p) LOG_I(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, msg_name, S1AP_REGISTER_ENB_CNF(msg_p).nb_mme); - DevAssert(g_scenario->register_enb_pending > 0); - g_scenario->register_enb_pending--; + DevAssert(scenario->register_enb_pending > 0); + scenario->register_enb_pending--; /* Check if at least eNB is registered with one MME */ if (S1AP_REGISTER_ENB_CNF(msg_p).nb_mme > 0) { - g_scenario->registered_enb++; + scenario->registered_enb++; } /* Check if all register eNB requests have been processed */ if (scenario->register_enb_pending == 0) { + timer_remove(scenario->enb_register_retry_timer_id); if (scenario->registered_enb == scenario->enb_properties->number) { /* If all eNB are registered, start scenario */ + LOG_D(ENB_APP, " All eNB are now associated with a MME\n"); et_event_t event; event.code = ET_EVENT_S1C_CONNECTED; et_scenario_fsm_notify_event(event); @@ -654,7 +696,7 @@ void *et_eNB_app_task(void *args_p) sleep(ET_ENB_REGISTER_RETRY_DELAY); /* Restart the registration process */ scenario->registered_enb = 0; - scenario->register_enb_pending = et_eNB_app_register (scenario->enb_properties); + et_eNB_app_register (scenario->enb_properties); } } } @@ -674,7 +716,7 @@ void *et_eNB_app_task(void *args_p) if (TIMER_HAS_EXPIRED (msg_p).timer_id == scenario->enb_register_retry_timer_id) { /* Restart the registration process */ scenario->registered_enb = 0; - scenario->register_enb_pending = et_eNB_app_register (scenario->enb_properties); + et_eNB_app_register (scenario->enb_properties); } break; @@ -870,10 +912,13 @@ int main( int argc, char **argv ) // logging logInit(); + set_glog(LOG_TRACE, LOG_MED); + itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, NULL); + set_comp_log(ENB_APP, LOG_TRACE, LOG_MED, 1); set_comp_log(S1AP, LOG_TRACE, LOG_MED, 1); - set_comp_log(SCTP, LOG_TRACE, LOG_MED, 1); + set_comp_log(SCTP, LOG_TRACE, LOG_FULL, 1); asn_debug = 0; asn1_xer_print = 1; @@ -895,6 +940,6 @@ int main( int argc, char **argv ) et_free_pointer(scenario_file_name); et_free_pointer(enb_config_file_name); } - + itti_wait_tasks_end(); return ret; } diff --git a/openair3/TEST/EPC_TEST/play_scenario.h b/openair3/TEST/EPC_TEST/play_scenario.h index 3a52c6a0b8..060c77b8ee 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.h +++ b/openair3/TEST/EPC_TEST/play_scenario.h @@ -39,7 +39,6 @@ #define PLAY_SCENARIO_H_ # include # include -# include # include # include @@ -274,6 +273,7 @@ typedef struct et_ip_s { struct in6_addr ipv6; in_addr_t ipv4; }address; + char str[INET6_ADDRSTRLEN+1]; }et_ip_t; typedef struct et_ip_hdr_s { @@ -323,8 +323,6 @@ typedef struct et_scenario_s { uint32_t registered_enb; long enb_register_retry_timer_id; - pthread_mutex_t fsm_lock; - et_fsm_state_t fsm_state; hash_table_t *hash_mme2association_id; hash_table_t *hash_old_ue_mme_id2ue_mme_id; @@ -391,6 +389,7 @@ int et_s1ap_decode_pdu(S1AP_PDU_t * const pdu, s1ap_message * const message, con void et_decode_s1ap(et_s1ap_t * const s1ap); //------------------------- int et_s1ap_eNB_compare_assoc_id( struct s1ap_eNB_mme_data_s *p1, struct s1ap_eNB_mme_data_s *p2); +uint32_t et_s1ap_generate_eNB_id(void); uint16_t et_s1ap_eNB_fetch_add_global_cnx_id(void); void et_s1ap_eNB_prepare_internal_data(void); void et_s1ap_eNB_insert_new_instance(s1ap_eNB_instance_t *new_instance_p); @@ -436,6 +435,7 @@ int et_split_path ( char * pathP, char *** resP); void et_display_node ( xmlNodePtr node, unsigned int indent); void et_display_tree ( xmlNodePtr node, unsigned int indent); char * et_ip2ip_str(const et_ip_t * const ip); +int et_compare_et_ip_to_net_ip_address(const et_ip_t * const ip, const net_ip_address_t * const net_ip); int et_hex2data(unsigned char * const data, const unsigned char * const hexstring, const unsigned int len); sctp_cid_t et_chunk_type_str2cid(const xmlChar * const chunk_type_str); const char * const et_chunk_type_cid2str(const sctp_cid_t chunk_type); @@ -443,7 +443,7 @@ et_packet_action_t et_action_str2et_action_t(const xmlChar * const action); void et_ip_str2et_ip(const xmlChar * const ip_str, et_ip_t * const ip); void et_enb_config_init(const char const * lib_config_file_name_pP); const Enb_properties_array_t *et_enb_config_get(void); -uint32_t et_eNB_app_register(const Enb_properties_array_t *enb_properties); +void et_eNB_app_register(const Enb_properties_array_t *enb_properties); void *et_eNB_app_task(void *args_p); int et_play_scenario(et_scenario_t* const scenario); diff --git a/openair3/TEST/EPC_TEST/play_scenario.xsl b/openair3/TEST/EPC_TEST/play_scenario.xsl index 6b1c36cc3d..0ce22c08df 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.xsl +++ b/openair3/TEST/EPC_TEST/play_scenario.xsl @@ -9,57 +9,57 @@ /> - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + ERROR: Cannot resolv IP ! @@ -69,30 +69,30 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + ERROR: Cannot resolv IP ! diff --git a/openair3/TEST/EPC_TEST/play_scenario_fsm.c b/openair3/TEST/EPC_TEST/play_scenario_fsm.c index 8e59a98258..18dba384b0 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_fsm.c +++ b/openair3/TEST/EPC_TEST/play_scenario_fsm.c @@ -36,6 +36,7 @@ */ #include #include +#include #include "intertask_interface.h" #include "platform_types.h" @@ -46,7 +47,9 @@ #include "timer.h" //------------------------------------------------------------------------------ -et_scenario_t *g_scenario = NULL; +et_scenario_t *g_scenario = NULL; +pthread_mutex_t g_fsm_lock = PTHREAD_MUTEX_INITIALIZER; +et_fsm_state_t g_fsm_state = ET_FSM_STATE_NULL; //------------------------------------------------------------------------------ int timeval_subtract (struct timeval * const result, struct timeval * const a, struct timeval * const b) { @@ -83,7 +86,7 @@ void et_scenario_wait_rx_packet(et_packet_t * const packet) NULL, &packet->timer_id) < 0) { AssertFatal(0, " Can not start waiting RX event timer\n"); } - g_scenario->fsm_state = ET_FSM_STATE_WAITING_EVENT; + g_fsm_state = ET_FSM_STATE_WAITING_EVENT; packet->status = ET_PACKET_STATUS_SCHEDULED_FOR_RECEIVING; } //------------------------------------------------------------------------------ @@ -102,7 +105,8 @@ void et_scenario_schedule_tx_packet(et_packet_t * const packet) s1ap_eNB_instance = et_s1ap_eNB_get_instance(packet->enb_instance); AssertFatal(NULL != s1ap_eNB_instance, "Cannot get s1ap_eNB_instance_t for eNB instance %d", packet->enb_instance); - g_scenario->fsm_state = ET_FSM_STATE_WAITING_EVENT; + LOG_D(ENB_APP, "%s\n", __FUNCTION__); + g_fsm_state = ET_FSM_STATE_WAITING_EVENT; switch (packet->sctp_hdr.chunk_type) { case SCTP_CID_DATA: @@ -124,7 +128,7 @@ void et_scenario_schedule_tx_packet(et_packet_t * const packet) NULL, &packet->timer_id) < 0) { AssertFatal(0, " Can not start TX event timer\n"); } - // Done g_scenario->fsm_state = ET_FSM_STATE_WAITING_TX_EVENT; + // Done g_fsm_state = ET_FSM_STATE_WAITING_TX_EVENT; } else { // send immediately et_s1ap_eNB_itti_send_sctp_data_req( @@ -134,7 +138,7 @@ void et_scenario_schedule_tx_packet(et_packet_t * const packet) packet->sctp_hdr.u.data_hdr.payload.binary_stream_allocated_size, packet->sctp_hdr.u.data_hdr.stream); packet->status = ET_PACKET_STATUS_SENT; - g_scenario->fsm_state = ET_FSM_STATE_RUNNING; + g_fsm_state = ET_FSM_STATE_RUNNING; } break; case SCTP_CID_INIT: @@ -162,7 +166,7 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_running(et_event_t event) default: AssertFatal(0, "Case event %d not handled in ET_FSM_STATE_RUNNING", event.code); } - pthread_mutex_unlock(&g_scenario->fsm_lock); + pthread_mutex_unlock(&g_fsm_lock); return 0; } @@ -188,14 +192,14 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_waiting(et_event_t event) event.u.tx_timed_packet->sctp_hdr.u.data_hdr.payload.binary_stream_allocated_size, event.u.tx_timed_packet->sctp_hdr.u.data_hdr.stream); event.u.tx_timed_packet->status = ET_PACKET_STATUS_SENT; - g_scenario->fsm_state = ET_FSM_STATE_RUNNING; + g_fsm_state = ET_FSM_STATE_RUNNING; break; default: AssertFatal(0, "Case event %d not handled in ET_FSM_STATE_WAITING", event.code); } - pthread_mutex_unlock(&g_scenario->fsm_lock); + pthread_mutex_unlock(&g_fsm_lock); return 0; } @@ -215,8 +219,8 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_connecting_s1c(et_event_t even // no init in this scenario, may be sub-scenario if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_SEND) { et_scenario_schedule_tx_packet(g_scenario->next_packet); - pthread_mutex_unlock(&g_scenario->fsm_lock); - return g_scenario->fsm_state; + pthread_mutex_unlock(&g_fsm_lock); + return g_fsm_state; } else if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { if (g_scenario->next_packet->status == ET_PACKET_STATUS_RECEIVED) { g_scenario->last_rx_packet = g_scenario->next_packet; @@ -226,8 +230,8 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_connecting_s1c(et_event_t even } else if (g_scenario->next_packet->status == ET_PACKET_STATUS_NONE) { et_scenario_wait_rx_packet(g_scenario->next_packet); - pthread_mutex_unlock(&g_scenario->fsm_lock); - return g_scenario->fsm_state; + pthread_mutex_unlock(&g_fsm_lock); + return g_fsm_state; } else { AssertFatal(0, "Invalid packet status %d", g_scenario->next_packet->status); } @@ -263,15 +267,15 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_connecting_s1c(et_event_t even } } fprintf(stderr, "No Packet found in this scenario: %s\n", g_scenario->name); - g_scenario->fsm_state = ET_FSM_STATE_NULL; - pthread_mutex_unlock(&g_scenario->fsm_lock); - return g_scenario->fsm_state; + g_fsm_state = ET_FSM_STATE_NULL; + pthread_mutex_unlock(&g_fsm_lock); + return g_fsm_state; break; default: AssertFatal(0, "Case event %d not handled in ET_FSM_STATE_CONNECTING_S1C", event.code); } - pthread_mutex_unlock(&g_scenario->fsm_lock); + pthread_mutex_unlock(&g_fsm_lock); return 0; } //------------------------------------------------------------------------------ @@ -289,8 +293,8 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_null(et_event_t event) // no init in this scenario, may be sub-scenario if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_SEND) { et_scenario_schedule_tx_packet(g_scenario->next_packet); - pthread_mutex_unlock(&g_scenario->fsm_lock); - return g_scenario->fsm_state; + pthread_mutex_unlock(&g_fsm_lock); + return g_fsm_state; } else if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { if (g_scenario->next_packet->status == ET_PACKET_STATUS_RECEIVED) { g_scenario->last_rx_packet = g_scenario->next_packet; @@ -300,8 +304,8 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_null(et_event_t event) } else if (g_scenario->next_packet->status == ET_PACKET_STATUS_NONE) { et_scenario_wait_rx_packet(g_scenario->next_packet); - pthread_mutex_unlock(&g_scenario->fsm_lock); - return g_scenario->fsm_state; + pthread_mutex_unlock(&g_fsm_lock); + return g_fsm_state; } else { AssertFatal(0, "Invalid packet status %d", g_scenario->next_packet->status); } @@ -317,10 +321,10 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_null(et_event_t event) g_scenario->hash_mme2association_id = hashtable_create (256,NULL,NULL); // Try to register each eNB g_scenario->registered_enb = 0; - g_scenario->fsm_state = ET_FSM_STATE_CONNECTING_S1C; - g_scenario->register_enb_pending = et_eNB_app_register (g_scenario->enb_properties); - pthread_mutex_unlock(&g_scenario->fsm_lock); - return g_scenario->fsm_state; + g_fsm_state = ET_FSM_STATE_CONNECTING_S1C; + et_eNB_app_register (g_scenario->enb_properties); + pthread_mutex_unlock(&g_fsm_lock); + return g_fsm_state; break; case SCTP_CID_HEARTBEAT: @@ -348,9 +352,9 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_null(et_event_t event) } } fprintf(stderr, "No Useful packet found in this scenario: %s\n", g_scenario->name); - g_scenario->fsm_state = ET_FSM_STATE_NULL; - pthread_mutex_unlock(&g_scenario->fsm_lock); - return g_scenario->fsm_state; + g_fsm_state = ET_FSM_STATE_NULL; + pthread_mutex_unlock(&g_fsm_lock); + return g_fsm_state; break; default: @@ -364,15 +368,15 @@ et_fsm_state_t et_scenario_fsm_notify_event(et_event_t event) { AssertFatal((event.code >= ET_EVENT_START) && (event.code < ET_EVENT_END), "Unknown et_event_t.code %d", event.code); - pthread_mutex_lock(&g_scenario->fsm_lock); - switch (g_scenario->fsm_state){ + pthread_mutex_lock(&g_fsm_lock); + switch (g_fsm_state){ case ET_FSM_STATE_NULL: return et_scenario_fsm_notify_event_state_null(event); break; case ET_FSM_STATE_CONNECTING_S1C: return et_scenario_fsm_notify_event_state_connecting_s1c(event); break; case ET_FSM_STATE_WAITING_EVENT: return et_scenario_fsm_notify_event_state_waiting(event); break; case ET_FSM_STATE_RUNNING: return et_scenario_fsm_notify_event_state_running(event); break; default: - AssertFatal(0, "Case fsm_state %d not handled", g_scenario->fsm_state); + AssertFatal(0, "Case fsm_state %d not handled", g_fsm_state); } - pthread_mutex_unlock(&g_scenario->fsm_lock); - return g_scenario->fsm_state; + pthread_mutex_unlock(&g_fsm_lock); + return g_fsm_state; } diff --git a/openair3/TEST/EPC_TEST/play_scenario_parse.c b/openair3/TEST/EPC_TEST/play_scenario_parse.c index f6d8aa73ac..13c4746a5e 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_parse.c +++ b/openair3/TEST/EPC_TEST/play_scenario_parse.c @@ -447,8 +447,6 @@ et_scenario_t* et_generate_scenario( printf("scenario name: %s\n", xml_char); scenario = calloc(1, sizeof(*scenario)); scenario->name = xml_char; // nodup nofree - scenario->fsm_state = ET_FSM_STATE_NULL; - pthread_mutex_init(&scenario->fsm_lock, NULL); next_packet = &scenario->list_packet; for (node = root->children; node != NULL; node = node->next) { diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c index 7dd80904ae..d11d032b43 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c @@ -308,28 +308,82 @@ void et_s1ap_update_assoc_id_of_packets(const int32_t assoc_id, s1ap_eNB_mme_data_t * const mme_desc_p) { et_packet_t *packet = NULL; - struct in6_addr s1c_mme_ipv6 = IN6ADDR_ANY_INIT; - in_addr_t s1c_mme_ipv4 = INADDR_ANY; - struct in6_addr s1c_enb_ipv6 = IN6ADDR_ANY_INIT; - in_addr_t s1c_enb_ipv4 = INADDR_ANY; + int ret; + unsigned int old_enb_port = 0; + unsigned int old_mme_port = 0; - packet = g_scenario->next_packet; + S1AP_DEBUG("%s for SCTP association (%u)\n",__FUNCTION__,assoc_id); + + packet = g_scenario->list_packet; while (NULL != packet) { switch (packet->sctp_hdr.chunk_type) { case SCTP_CID_DATA : - if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_SEND) { - // TODO compare addresses and ports - if (packet->ip_hdr.dst) - packet->sctp_hdr.dst_port == 0; - packet->sctp_hdr.src_port == 0; - - } else if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { + if (ET_PACKET_STATUS_NONE == packet->status) { + if (0 < old_mme_port) { + if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_SEND) { + ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.dst, &mme_desc_p->mme_net_ip_address); + if (0 == ret) { + ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.src, &s1ap_eNB_instance->s1c_net_ip_address); + if (0 == ret) { + // same IP src, same IP dst + if ((packet->sctp_hdr.dst_port == old_mme_port) && (packet->sctp_hdr.src_port == old_enb_port)) { + packet->sctp_hdr.u.data_hdr.assoc_id = assoc_id; + S1AP_DEBUG("tPacket:\tnum %u | original frame number %u \n", packet->packet_number, packet->original_frame_number); + S1AP_DEBUG("\tUpdated assoc id: %u\n", assoc_id); + } + } + } + } else if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { + ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.src, &mme_desc_p->mme_net_ip_address); + if (0 == ret) { + ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.dst, &s1ap_eNB_instance->s1c_net_ip_address); + if (0 == ret) { + // same IP src, same IP dst + if ((packet->sctp_hdr.src_port == old_mme_port) && (packet->sctp_hdr.dst_port == old_enb_port)) { + packet->sctp_hdr.u.data_hdr.assoc_id = assoc_id; + S1AP_DEBUG("tPacket:\tnum %u | original frame number %u \n", packet->packet_number, packet->original_frame_number); + S1AP_DEBUG("\tUpdated assoc id: %u\n", assoc_id); + } + } + } + } + } } break; + // Strong assumption + // in replayed scenario, the order of SCTP INIT packets is supposed to be the same as in the catched scenario case SCTP_CID_INIT: + ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.dst, &mme_desc_p->mme_net_ip_address); + if (0 == ret) { + ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.src, &s1ap_eNB_instance->s1c_net_ip_address); + if (0 == ret) { + if (0 == old_enb_port) { + if (ET_PACKET_STATUS_NONE == packet->status) { + packet->status = ET_PACKET_STATUS_SENT; + old_enb_port = packet->sctp_hdr.src_port; + } + } + } + } + break; + case SCTP_CID_INIT_ACK: + ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.dst, &mme_desc_p->mme_net_ip_address); + if (0 == ret) { + ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.src, &s1ap_eNB_instance->s1c_net_ip_address); + if (0 == ret) { + if (old_enb_port == packet->sctp_hdr.dst_port) { + if (ET_PACKET_STATUS_NONE == packet->status) { + packet->status = ET_PACKET_STATUS_RECEIVED; + old_mme_port = packet->sctp_hdr.dst_port; + } + } + } + } + break; + case SCTP_CID_HEARTBEAT: case SCTP_CID_HEARTBEAT_ACK: case SCTP_CID_COOKIE_ECHO: @@ -384,12 +438,14 @@ void et_s1ap_handle_s1_setup_message(s1ap_eNB_mme_data_t *mme_desc_p, int sctp_s if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb > 0) { /* Decrease pending messages number */ mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb --; + mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb++; } et_s1ap_update_assoc_id_of_packets(mme_desc_p->assoc_id, mme_desc_p->s1ap_eNB_instance, mme_desc_p); + /* If there are no more pending messages, inform eNB app */ if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb == 0) { MessageDef *message_p; @@ -484,6 +540,10 @@ void et_s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_asso return; } + S1AP_DEBUG("Received successful result for SCTP association (%u), instance %d, cnx_id %u\n", + sctp_new_association_resp->sctp_state, + instance, + sctp_new_association_resp->ulp_cnx_id); /* Update parameters */ s1ap_mme_data_p->assoc_id = sctp_new_association_resp->assoc_id; s1ap_mme_data_p->in_streams = sctp_new_association_resp->in_streams; @@ -557,7 +617,7 @@ void *et_s1ap_eNB_task(void *arg) if (TIMER_HAS_EXPIRED (received_msg).timer_id == g_scenario->enb_register_retry_timer_id) { /* Restart the registration process */ g_scenario->registered_enb = 0; - g_scenario->register_enb_pending = et_eNB_app_register (g_scenario->enb_properties); + et_eNB_app_register (g_scenario->enb_properties); } break; From 610e07a96cfc87aa190df76757e81cf6441106ba Mon Sep 17 00:00:00 2001 From: gauthier Date: Tue, 1 Dec 2015 16:55:41 +0100 Subject: [PATCH 13/47] For backup only, dont compile, TODO missing patch for asn1c compiler --- cmake_targets/CMakeLists.txt | 2 + openair3/S1AP/MESSAGES/ASN1/asn1tostruct.py | 146 +++++++++- openair3/TEST/EPC_TEST/play_scenario.c | 4 + openair3/TEST/EPC_TEST/play_scenario.h | 11 + openair3/TEST/EPC_TEST/play_scenario_fsm.c | 11 +- openair3/TEST/EPC_TEST/play_scenario_parse.c | 4 +- openair3/TEST/EPC_TEST/play_scenario_s1ap.c | 83 +++++- .../EPC_TEST/play_scenario_s1ap_compare_ie.c | 273 ++++++++++++++++++ openair3/TEST/EPC_TEST/play_scenario_sctp.c | 45 +++ 9 files changed, 570 insertions(+), 9 deletions(-) create mode 100644 openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index bcf90bdb83..9c5bbad0de 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -337,6 +337,7 @@ set(S1AP_OAI_generated ${S1AP_C_DIR}/s1ap_decoder.c ${S1AP_C_DIR}/s1ap_encoder.c ${S1AP_C_DIR}/s1ap_xer_print.c + ${S1AP_C_DIR}/s1ap_compare.c ${S1AP_C_DIR}/s1ap_ies_defs.h ) file(GLOB s1ap_h ${S1AP_C_DIR}/*.h) @@ -1667,6 +1668,7 @@ add_executable(test_epc_play_scenario ${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario_fsm.c ${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario_parse.c ${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario_s1ap.c + ${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c ${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario_s1ap_eNB_defs.h ${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario_sctp.c ${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario.h diff --git a/openair3/S1AP/MESSAGES/ASN1/asn1tostruct.py b/openair3/S1AP/MESSAGES/ASN1/asn1tostruct.py index c298e8ae87..f5daf03c25 100644 --- a/openair3/S1AP/MESSAGES/ASN1/asn1tostruct.py +++ b/openair3/S1AP/MESSAGES/ASN1/asn1tostruct.py @@ -250,20 +250,31 @@ for key in iesDefs: asn1cStruct = re.sub('Item', 'List', asn1cStruct) keylowerunderscore = re.sub('-', '_', key.lower()) firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct))) + + f.write("/* %s in iesDefs not in ieofielist.values() */\n" % (key)) f.write("/** \\brief Decode function for %s ies.\n" % (key)) if len(iesDefs[key]["ies"]) != 0: f.write(" * \\param %s Pointer to ASN1 structure in which data will be stored\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))) f.write(" * \\param any_p Pointer to the ANY value to decode.\n") f.write(" **/\n") f.write("int %s_decode_%s(\n" % (fileprefix, keylowerunderscore)) - if len(iesDefs[key]["ies"]) != 0: f.write(" %s_t *%s,\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key)))) f.write(" ANY_t *any_p);\n\n") + f.write("/* %s in iesDefs not in ieofielist.values() */\n" % (key)) + f.write("/** \\brief Compare function for %s ies.\n" % (key)) + 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(" %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)))) + if len(iesDefs[key]["ies"]) == 0: continue + f.write("/* %s in iesDefs not in ieofielist.values() */\n" % (key)) f.write("/** \\brief Encode function for %s ies.\n" % (key)) f.write(" * \\param %s Pointer to the ASN1 structure.\n" % (firstlower)) f.write(" * \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))) @@ -272,16 +283,19 @@ for key in iesDefs: f.write(" %s_t *%s,\n" % (asn1cStruct, firstlower)) f.write(" %s_t *%s);\n\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key)))) + for key in iesDefs: if key not in ieofielist.values(): continue asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key)) asn1cStruct = re.sub('Item', 'List', asn1cStruct) firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct))) + f.write("/* %s in iesDefs in ieofielist.values() */\n" % (key)) f.write("/** \\brief Encode function for %s ies.\n" % (key)) f.write(" * \\param %s Pointer to the ASN1 structure.\n" % (firstlower)) f.write(" * \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))) f.write(" **/\n") + f.write("/* %s in iesDefs in ieofielist.values() */\n" % (key)) f.write("int %s_encode_%s(\n" % (fileprefix, firstlower.lower())) f.write(" %s_t *%s,\n" % (asn1cStruct, firstlower)) f.write(" %sIEs_t *%sIEs);\n\n" % (asn1cStruct, firstlower)) @@ -289,9 +303,19 @@ for key in iesDefs: f.write(" * \\param any_p Pointer to the ANY value to decode.\n") f.write(" * \\param callback Callback function called when any_p is successfully decoded.\n") f.write(" **/\n") + f.write("/* %s in iesDefs in ieofielist.values() */\n" % (key)) f.write("int %s_decode_%s(\n" % (fileprefix, firstlower.lower())) f.write(" %sIEs_t *%sIEs,\n" % (asn1cStruct, firstlower)) f.write(" %s_t *%s);\n\n" % (asn1cStruct, lowerFirstCamelWord(asn1cStruct))) + f.write("/** \\brief Compare function for %s ies.\n" % (key)) + 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(" %sIEs_t *%s1,\n" % (asn1cStruct, firstlower)) + f.write(" %sIEs_t *%s2);\n\n" % (asn1cStruct, firstlower)) + + for key in iesDefs: asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key)) @@ -704,3 +728,123 @@ for (key, value) in iesDefs.items(): #f.write("cb_failed:\n") #f.write(" return er;\n") f.write("}\n\n") + + +#Generate xer print functions +f = open(outdir + fileprefix + '_compare.c', 'w') +outputHeaderToFile(f, filename) +f.write("#include \n") +f.write("#include \n\n") +f.write("#include \n#include \n\n") +f.write("#include \"%s_common.h\"\n#include \"%s_ies_defs.h\"\n" % (fileprefix, fileprefix)) +f.write("#include \"%s-ProtocolIE-ID.h\"\n\n" % (fileprefix_first_upper)) + + +for key in iesDefs: + if key in ieofielist.values(): + continue + structName = re.sub('ies', '', key) + asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key)) + asn1cStruct = re.sub('Item', 'List', asn1cStruct) + if asn1cStruct.rfind('_') == len(asn1cStruct) - 1: + asn1cStruct = asn1cStruct[:-1] + asn1cStructfirstlower = asn1cStruct[:1].lower() + asn1cStruct[1:] + firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct))) + + iesaccess = "" + if key not in ieofielist.values(): + iesaccess = "%s_ies." % (firstwordlower) + + keyName = re.sub('-', '_', key) + keyupperunderscore = keyName.upper() + # No IE to encode... + if len(iesDefs[key]["ies"]) == 0: + continue + + f.write("long %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(" assert(%s1 != NULL);\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))); + f.write(" assert(%s2 != NULL);\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))); + + loop = 0 + for ie in iesDefs[key]["ies"]: + iename = re.sub('-', '_', re.sub('id-', '', ie[0])) + ienameunderscore = re.sub('-', '_', iename) + ienamefirstwordlower = lowerFirstCamelWord(iename) + ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper() + ietypeunderscore = re.sub('-', '_', ie[2]) + + if ie[3] != "mandatory": + + loop = loop + 1 + 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)))) + + if ie[3] == "optional": + f.write(" /* Optional field */\n") + elif ie[3] == "conditional": + f.write(" /* Conditional field */\n") + f.write(" if (%s1->presenceMask & %s_%s_PRESENT) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore)) + + + 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)) + 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(" 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)) + 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("}\n\n") + +for (key, value) in iesDefs.items(): + if key not in ieofielist.values(): + continue + + ie = value["ies"][0] + ietypeunderscore = re.sub('-', '_', ie[2]) + asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key))) + asn1cStruct = re.sub('Item', 'List', asn1cStruct) + firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct))) + + for (i, j) in ieofielist.items(): + if j == key: + break + + 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(" %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(" 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(" }\n") + f.write(" return 0;\n") + f.write("}\n\n") + diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c index f8f334dd9c..216e098a01 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.c +++ b/openair3/TEST/EPC_TEST/play_scenario.c @@ -318,15 +318,19 @@ int et_compare_et_ip_to_net_ip_address(const et_ip_t * const ip, const net_ip_ad S1AP_DEBUG("%s(%s,%s)=%d\n",__FUNCTION__,ip->str, net_ip->ipv4_address, strcmp(ip->str, net_ip->ipv4_address)); return strcmp(ip->str, net_ip->ipv4_address); } + S1AP_DEBUG("%s(%s,%s)=-1 (IP version (4) not matching)\n",__FUNCTION__,ip->str, net_ip->ipv4_address); return -1; break; case AF_INET6: if (net_ip->ipv6) { + S1AP_DEBUG("%s(%s,%s)=%d\n",__FUNCTION__,ip->str, net_ip->ipv4_address, strcmp(ip->str, net_ip->ipv6_address)); return strcmp(ip->str, net_ip->ipv6_address); } + S1AP_DEBUG("%s(%s,%s)=-1 (IP version (6) not matching)\n",__FUNCTION__,ip->str, net_ip->ipv6_address); return -1; break; default: + S1AP_DEBUG("%s(%s,...)=-1 (unknown IP version)\n",__FUNCTION__,ip->str); return -1; } } diff --git a/openair3/TEST/EPC_TEST/play_scenario.h b/openair3/TEST/EPC_TEST/play_scenario.h index 060c77b8ee..3c8c5faef8 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.h +++ b/openair3/TEST/EPC_TEST/play_scenario.h @@ -47,6 +47,10 @@ #include "play_scenario_s1ap_eNB_defs.h" #include "hashtable.h" +// powers of 2 +#define ET_BIT_MASK_MATCH_SCTP_STREAM 1 +#define ET_BIT_MASK_MATCH_SCTP_SSN 2 +//#define ET_BIT_MASK_MATCH_S1AP_ 2 #define MAX_ENB 16 @@ -396,6 +400,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); +int 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); void et_s1ap_process_rx_packet(et_event_s1ap_data_ind_t * const sctp_data_ind); void et_s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t * const sctp_data_ind); void et_s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, @@ -428,6 +434,11 @@ 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 ); //------------------------- +int et_s1ap_ies_is_matching(const S1AP_PDU_PR present, s1ap_message * const m1, s1ap_message * const m2, const uint32_t constraints); +//------------------------- +int et_sctp_data_is_matching(sctp_datahdr_t * const sctp1, sctp_datahdr_t * const sctp2, const uint32_t constraints); +int 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); int et_strip_extension( char *in_filename); diff --git a/openair3/TEST/EPC_TEST/play_scenario_fsm.c b/openair3/TEST/EPC_TEST/play_scenario_fsm.c index 18dba384b0..23ef72035c 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_fsm.c +++ b/openair3/TEST/EPC_TEST/play_scenario_fsm.c @@ -50,6 +50,7 @@ et_scenario_t *g_scenario = NULL; pthread_mutex_t g_fsm_lock = PTHREAD_MUTEX_INITIALIZER; et_fsm_state_t g_fsm_state = ET_FSM_STATE_NULL; +uint32_t g_constraints = ET_BIT_MASK_MATCH_SCTP_STREAM | ET_BIT_MASK_MATCH_SCTP_SSN; //------------------------------------------------------------------------------ int timeval_subtract (struct timeval * const result, struct timeval * const a, struct timeval * const b) { @@ -123,6 +124,9 @@ void et_scenario_schedule_tx_packet(et_packet_t * const packet) } if (we_are_too_early > 0) { // set timer + LOG_D(ENB_APP, "Send packet num %u original frame number %u in %ld.%d sec\n", + packet->packet_number, packet->original_frame_number, offset.tv_sec, offset.tv_usec); + packet->status = ET_PACKET_STATUS_SCHEDULED_FOR_SENDING; if (timer_setup (offset.tv_sec, offset.tv_usec, TASK_S1AP, INSTANCE_DEFAULT, TIMER_ONE_SHOT, NULL, &packet->timer_id) < 0) { @@ -130,7 +134,9 @@ void et_scenario_schedule_tx_packet(et_packet_t * const packet) } // Done g_fsm_state = ET_FSM_STATE_WAITING_TX_EVENT; } else { + LOG_D(ENB_APP, "Send packet num %u original frame number %u immediately\n", packet->packet_number, packet->original_frame_number); // send immediately + AssertFatal(0 == gettimeofday(&packet->timestamp_packet, NULL), "gettimeofday() Failed"); et_s1ap_eNB_itti_send_sctp_data_req( packet->enb_instance, packet->sctp_hdr.u.data_hdr.assoc_id, @@ -161,7 +167,7 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_running(et_event_t event) AssertFatal(0, "Event ET_EVENT_TX_TIMED_PACKET not handled in FSM state ET_FSM_STATE_RUNNING"); break; case ET_EVENT_RX_S1AP: - AssertFatal(0, "TODO"); + et_s1ap_process_rx_packet(&event.u.s1ap_data_ind); break; default: AssertFatal(0, "Case event %d not handled in ET_FSM_STATE_RUNNING", event.code); @@ -185,6 +191,7 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_waiting(et_event_t event) break; case ET_EVENT_TX_TIMED_PACKET: // send immediately + AssertFatal(0 == gettimeofday(&event.u.tx_timed_packet->timestamp_packet, NULL), "gettimeofday() Failed"); et_s1ap_eNB_itti_send_sctp_data_req( event.u.tx_timed_packet->enb_instance, event.u.tx_timed_packet->sctp_hdr.u.data_hdr.assoc_id, @@ -290,7 +297,7 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_null(et_event_t event) switch (g_scenario->next_packet->sctp_hdr.chunk_type) { case SCTP_CID_DATA : - // no init in this scenario, may be sub-scenario + // no init in this scenario, may be sub-scenario, ... if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_SEND) { et_scenario_schedule_tx_packet(g_scenario->next_packet); pthread_mutex_unlock(&g_fsm_lock); diff --git a/openair3/TEST/EPC_TEST/play_scenario_parse.c b/openair3/TEST/EPC_TEST/play_scenario_parse.c index 13c4746a5e..cb302f229a 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_parse.c +++ b/openair3/TEST/EPC_TEST/play_scenario_parse.c @@ -518,7 +518,7 @@ int et_generate_xml_scenario( for (i = 0; i < g_enb_properties.number; i++) { // eNB S1-C IPv4 address - sprintf(astring, "enb_s1c%d", i); + sprintf(astring, "enb%d_s1c", i); params[nb_params++] = strdup(astring); addr.s_addr = g_enb_properties.properties[i]->enb_ipv4_address_for_S1_MME; sprintf(astring, "\"%s\"", inet_ntoa(addr)); @@ -526,7 +526,7 @@ int et_generate_xml_scenario( // MME S1-C IPv4 address for (j = 0; j < g_enb_properties.properties[i]->nb_mme; j++) { - sprintf(astring, "mme_s1c%d_%d", i, j); + sprintf(astring, "mme%d_s1c_%d", i, j); params[nb_params++] = strdup(astring); AssertFatal (g_enb_properties.properties[i]->mme_ip_address[j].ipv4_address, "Only support MME IPv4 address\n"); diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c index d11d032b43..408ff72a4a 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "tree.h" #include "queue.h" @@ -58,6 +59,7 @@ s1ap_eNB_internal_data_t s1ap_eNB_internal_data; RB_GENERATE(s1ap_mme_map, s1ap_eNB_mme_data_s, entry, et_s1ap_eNB_compare_assoc_id); //------------------------------------------------------------------------------ extern et_scenario_t *g_scenario; +extern uint32_t g_constraints; //------------------------------------------------------------------------------ int et_s1ap_eNB_compare_assoc_id( struct s1ap_eNB_mme_data_s *p1, struct s1ap_eNB_mme_data_s *p2) @@ -187,20 +189,86 @@ 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); } //------------------------------------------------------------------------------ -void et_s1ap_process_rx_packet(et_event_s1ap_data_ind_t * const sctp_data_ind) +int et_s1ap_is_matching(et_s1ap_t * const s1ap1, et_s1ap_t * const s1ap2, const uint32_t constraints) +{ + if (s1ap1->pdu.present != s1ap2->pdu.present) return -6; + 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 -7; + if (s1ap1->pdu.choice.initiatingMessage.criticality != s1ap2->pdu.choice.initiatingMessage.criticality) return -8; + break; + case S1AP_PDU_PR_successfulOutcome: + if (s1ap1->pdu.choice.successfulOutcome.procedureCode != s1ap2->pdu.choice.successfulOutcome.procedureCode) return -7; + if (s1ap1->pdu.choice.successfulOutcome.criticality != s1ap2->pdu.choice.successfulOutcome.criticality) return -8; + break; + case S1AP_PDU_PR_unsuccessfulOutcome: + if (s1ap1->pdu.choice.unsuccessfulOutcome.procedureCode != s1ap2->pdu.choice.unsuccessfulOutcome.procedureCode) return -7; + if (s1ap1->pdu.choice.unsuccessfulOutcome.criticality != s1ap2->pdu.choice.unsuccessfulOutcome.criticality) return -8; + 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 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); +} + +//------------------------------------------------------------------------------ +et_packet_t* et_build_packet_from_s1ap_data_ind(et_event_s1ap_data_ind_t * const s1ap_data_ind) { et_packet_t * packet = NULL; + AssertFatal (NULL != s1ap_data_ind, "Bad parameter sctp_data_ind\n"); + packet = calloc(1, sizeof(*packet)); + packet->action = ET_PACKET_ACTION_S1C_NULL; + //packet->time_relative_to_first_packet.tv_sec = 0; + //packet->time_relative_to_first_packet.tv_usec = 0; + //packet->time_relative_to_last_sent_packet.tv_sec = 0; + //packet->time_relative_to_last_sent_packet.tv_usec = 0; + //packet->time_relative_to_last_received_packet.tv_sec = 0; + //packet->time_relative_to_last_received_packet.tv_usec = 0; + //packet->original_frame_number = 0; + //packet->packet_number = 0; + packet->enb_instance = 0; //TODO + //packet->ip_hdr; + // keep in mind: allocated buffer: sctp_datahdr.payload.binary_stream + memcpy((void*)&packet->sctp_hdr, (void*)&s1ap_data_ind->sctp_datahdr, sizeof(packet->sctp_hdr)); + //packet->next = NULL; + packet->status = ET_PACKET_STATUS_RECEIVED; + //packet->timer_id = 0; + AssertFatal(0 == gettimeofday(&packet->timestamp_packet, NULL), "gettimeofday() Failed"); + return packet; +} + + +//------------------------------------------------------------------------------ +void 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; + AssertFatal (NULL != s1ap_data_ind, "Bad parameter sctp_data_ind\n"); + rx_packet = et_build_packet_from_s1ap_data_ind(s1ap_data_ind); + packet = g_scenario->next_packet; // 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) { //TODO + if (et_sctp_is_matching(&packet->sctp_hdr, &rx_packet->sctp_hdr, g_constraints) == 0) { + et_scenario_set_packet_received(packet); + } } not_found += 1; packet = packet->next; } + S1AP_DEBUG("Rx packet not found in scenario:\n"); + et_display_packet_sctp(&rx_packet->sctp_hdr); } //------------------------------------------------------------------------------ @@ -234,7 +302,7 @@ void et_s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t * const sctp_data_ind) &event.u.s1ap_data_ind.sctp_datahdr.payload.message, event.u.s1ap_data_ind.sctp_datahdr.payload.binary_stream, event.u.s1ap_data_ind.sctp_datahdr.payload.binary_stream_allocated_size) < 0) { - AssertFatal (0, "ERROR %s() Cannot decode RX S1AP message!\n", __FUNCTION__); + AssertFatal (0, "ERROR Cannot decode RX S1AP message!\n"); } } @@ -319,6 +387,7 @@ void et_s1ap_update_assoc_id_of_packets(const int32_t assoc_id, switch (packet->sctp_hdr.chunk_type) { case SCTP_CID_DATA : + S1AP_DEBUG("%s for SCTP association (%u) SCTP_CID_DATA\n",__FUNCTION__,assoc_id); if (ET_PACKET_STATUS_NONE == packet->status) { if (0 < old_mme_port) { if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_SEND) { @@ -355,6 +424,7 @@ void et_s1ap_update_assoc_id_of_packets(const int32_t assoc_id, // Strong assumption // in replayed scenario, the order of SCTP INIT packets is supposed to be the same as in the catched scenario case SCTP_CID_INIT: + S1AP_DEBUG("%s for SCTP association (%u) SCTP_CID_INIT\n",__FUNCTION__,assoc_id); ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.dst, &mme_desc_p->mme_net_ip_address); if (0 == ret) { ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.src, &s1ap_eNB_instance->s1c_net_ip_address); @@ -363,6 +433,7 @@ void et_s1ap_update_assoc_id_of_packets(const int32_t assoc_id, if (ET_PACKET_STATUS_NONE == packet->status) { packet->status = ET_PACKET_STATUS_SENT; old_enb_port = packet->sctp_hdr.src_port; + S1AP_DEBUG("%s for SCTP association (%u) SCTP_CID_INIT SUCCESS\n",__FUNCTION__,assoc_id); } } } @@ -370,14 +441,16 @@ void et_s1ap_update_assoc_id_of_packets(const int32_t assoc_id, break; case SCTP_CID_INIT_ACK: - ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.dst, &mme_desc_p->mme_net_ip_address); + S1AP_DEBUG("%s for SCTP association (%u) SCTP_CID_INIT_ACK\n",__FUNCTION__,assoc_id); + ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.src, &mme_desc_p->mme_net_ip_address); if (0 == ret) { - ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.src, &s1ap_eNB_instance->s1c_net_ip_address); + ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.dst, &s1ap_eNB_instance->s1c_net_ip_address); if (0 == ret) { if (old_enb_port == packet->sctp_hdr.dst_port) { if (ET_PACKET_STATUS_NONE == packet->status) { packet->status = ET_PACKET_STATUS_RECEIVED; old_mme_port = packet->sctp_hdr.dst_port; + S1AP_DEBUG("%s for SCTP association (%u) SCTP_CID_INIT_ACK SUCCESS\n",__FUNCTION__,assoc_id); } } } @@ -475,6 +548,7 @@ void et_s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_ DevCheck(new_instance->mcc == s1ap_register_eNB->mcc, new_instance->mcc, s1ap_register_eNB->mcc, 0); DevCheck(new_instance->mnc == s1ap_register_eNB->mnc, new_instance->mnc, s1ap_register_eNB->mnc, 0); DevCheck(new_instance->mnc_digit_length == s1ap_register_eNB->mnc_digit_length, new_instance->mnc_digit_length, s1ap_register_eNB->mnc_digit_length, 0); + DevCheck(memcmp((void*)&new_instance->s1c_net_ip_address, (void*)&s1ap_register_eNB->enb_ip_address, sizeof(new_instance->s1c_net_ip_address)) == 0, 0,0,0); } else { new_instance = calloc(1, sizeof(s1ap_eNB_instance_t)); DevAssert(new_instance != NULL); @@ -491,6 +565,7 @@ void et_s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_ new_instance->mcc = s1ap_register_eNB->mcc; new_instance->mnc = s1ap_register_eNB->mnc; new_instance->mnc_digit_length = s1ap_register_eNB->mnc_digit_length; + memcpy((void*)&new_instance->s1c_net_ip_address, (void*)&s1ap_register_eNB->enb_ip_address, sizeof(new_instance->s1c_net_ip_address)); /* Add the new instance to the list of eNB (meaningfull in virtual mode) */ et_s1ap_eNB_insert_new_instance(new_instance); diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c new file mode 100644 index 0000000000..5ad5708bab --- /dev/null +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c @@ -0,0 +1,273 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2014 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see . + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE + + *******************************************************************************/ + +/* + play_scenario_s1ap_compare_ie.c + ------------------- + AUTHOR : Lionel GAUTHIER + COMPANY : EURECOM + EMAIL : Lionel.Gauthier@eurecom.fr + */ +#include +#include +#include +#include +#include +#include +#include "tree.h" +#include "queue.h" + + +#include "intertask_interface.h" +#include "timer.h" +#include "platform_types.h" +#include "assertions.h" +#include "conversions.h" +#include "s1ap_common.h" +#include "play_scenario_s1ap_eNB_defs.h" +#include "play_scenario.h" +#include "msc.h" +//------------------------------------------------------------------------------ +extern et_scenario_t *g_scenario; +extern uint32_t g_constraints; +//------------------------------------------------------------------------------ + +int 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; + AssertFatal(m1 != NULL, "bad parameter m1"); + AssertFatal(m2 != NULL, "bad parameter m2"); + if (m1->procedureCode != m2->procedureCode) return -1; + + + // some cases can never occur since uplink only. + switch (m1->procedureCode) { + case S1ap_ProcedureCode_id_HandoverPreparation: + AssertFatal(0, "S1ap_ProcedureCode_id_InitialContextSetup not implemented"); + break; + case S1ap_ProcedureCode_id_HandoverResourceAllocation: + AssertFatal(0, "S1ap_ProcedureCode_id_InitialContextSetup not implemented"); + break; + case S1ap_ProcedureCode_id_HandoverNotification: + AssertFatal(0, "S1ap_ProcedureCode_id_HandoverNotification not implemented"); + break; + case S1ap_ProcedureCode_id_PathSwitchRequest: + ret = s1ap_compare_s1ap_pathswitchrequesties( + &m1->msg.s1ap_PathSwitchRequestIEs, + &m2->msg.s1ap_PathSwitchRequestIEs); + break; + case S1ap_ProcedureCode_id_HandoverCancel: + ret = s1ap_compare_s1ap_handovercancelies( + &m1->msg.s1ap_HandoverCancelIEs, + &m2->msg.s1ap_HandoverCancelIEs); + break; + case S1ap_ProcedureCode_id_E_RABSetup: + case S1ap_ProcedureCode_id_E_RABModify: + case S1ap_ProcedureCode_id_E_RABRelease: + if (present == S1AP_PDU_PR_initiatingMessage) { + ret = s1ap_compare_s1ap_e_rabreleasecommandies( + &m1->msg.s1ap_E_RABReleaseCommandIEs, + &m2->msg.s1ap_E_RABReleaseCommandIEs); + } else if (present == S1AP_PDU_PR_successfulOutcome) { + ret = s1ap_compare_s1ap_e_rabreleaseresponseies( + &m1->msg.s1ap_E_RABReleaseResponseIEs, + &m2->msg.s1ap_E_RABReleaseResponseIEs); + } + break; + case S1ap_ProcedureCode_id_E_RABReleaseIndication: + ret = s1ap_compare_s1ap_e_rabreleaseindicationies( + &m1->msg.s1ap_E_RABReleaseIndicationIEs, + &m2->msg.s1ap_E_RABReleaseIndicationIEs); + break; + case S1ap_ProcedureCode_id_InitialContextSetup: + AssertFatal(0, "S1ap_ProcedureCode_id_InitialContextSetup not implemented"); + break; + case S1ap_ProcedureCode_id_Paging: + ret = s1ap_compare_s1ap_pagingies( + &m1->msg.s1ap_PagingIEs, + &m2->msg.s1ap_PagingIEs); + break; + case S1ap_ProcedureCode_id_downlinkNASTransport: + ret = s1ap_compare_s1ap_downlinknastransporties( + &m1->msg.s1ap_DownlinkNASTransportIEs, + &m2->msg.s1ap_DownlinkNASTransportIEs); + break; + case S1ap_ProcedureCode_id_initialUEMessage: + ret = s1ap_compare_s1ap_initialuemessageies( + &m1->msg.s1ap_InitialUEMessageIEs, + &m2->msg.s1ap_InitialUEMessageIEs); + break; + case S1ap_ProcedureCode_id_uplinkNASTransport: + ret = s1ap_compare_s1ap_uplinknastransporties( + &m1->msg.s1ap_UplinkNASTransportIEs, + &m2->msg.s1ap_UplinkNASTransportIEs); + break; + case S1ap_ProcedureCode_id_Reset: + ret = s1ap_compare_s1ap_reseties( + &m1->msg.s1ap_ResetIEs, + &m2->msg.s1ap_ResetIEs); + break; + case S1ap_ProcedureCode_id_ErrorIndication: + ret = s1ap_compare_s1ap_errorindicationies( + &m1->msg.s1ap_ErrorIndicationIEs, + &m2->msg.s1ap_ErrorIndicationIEs); + break; + case S1ap_ProcedureCode_id_NASNonDeliveryIndication: + ret = s1ap_compare_s1ap_nasnondeliveryindication_ies( + &m1->msg.s1ap_NASNonDeliveryIndication_IEs, + &m2->msg.s1ap_NASNonDeliveryIndication_IEs); + break; + case S1ap_ProcedureCode_id_S1Setup: + if (present == S1AP_PDU_PR_initiatingMessage) { + ret = s1ap_compare_s1ap_s1setuprequesties( + &m1->msg.s1ap_S1SetupRequestIEs, + &m2->msg.s1ap_S1SetupRequestIEs); + } else if (present == S1AP_PDU_PR_successfulOutcome) { + ret = s1ap_compare_s1ap_s1setupresponseies( + &m1->msg.s1ap_S1SetupResponseIEs, + &m2->msg.s1ap_S1SetupResponseIEs); + } else if (present == S1AP_PDU_PR_unsuccessfulOutcome) { + ret = s1ap_compare_s1ap_s1setupfailureies( + &m1->msg.s1ap_S1SetupFailureIEs, + &m2->msg.s1ap_S1SetupFailureIEs); + } + break; + case S1ap_ProcedureCode_id_UEContextReleaseRequest: + ret = s1ap_compare_s1ap_uecontextreleaserequesties( + &m1->msg.s1ap_UEContextReleaseRequestIEs, + &m2->msg.s1ap_UEContextReleaseRequestIEs); + break; + case S1ap_ProcedureCode_id_DownlinkS1cdma2000tunneling: + ret = s1ap_compare_s1ap_downlinks1cdma2000tunnelingies( + &m1->msg.s1ap_DownlinkS1cdma2000tunnelingIEs, + &m2->msg.s1ap_DownlinkS1cdma2000tunnelingIEs); + break; + case S1ap_ProcedureCode_id_UplinkS1cdma2000tunneling: + ret = s1ap_compare_s1ap_uplinks1cdma2000tunnelingies( + &m1->msg.s1ap_UplinkS1cdma2000tunnelingIEs, + &m2->msg.s1ap_UplinkS1cdma2000tunnelingIEs); + break; + case S1ap_ProcedureCode_id_UEContextModification: + if (present == S1AP_PDU_PR_initiatingMessage) { + ret = s1ap_compare_s1ap_uecontextmodificationrequesties( + &m1->msg.s1ap_UEContextModificationRequestIEs, + &m2->msg.s1ap_UEContextModificationRequestIEs); + } else if (present == S1AP_PDU_PR_successfulOutcome) { + ret = s1ap_compare_s1ap_uecontextmodificationresponseies( + &m1->msg.s1ap_UEContextModificationResponseIEs, + &m2->msg.s1ap_UEContextModificationResponseIEs); + } else if (present == S1AP_PDU_PR_unsuccessfulOutcome) { + ret = s1ap_compare_s1ap_uecontextmodificationfailureies( + &m1->msg.s1ap_UEContextModificationFailureIEs, + &m2->msg.s1ap_UEContextModificationFailureIEs); + } + break; + case S1ap_ProcedureCode_id_UECapabilityInfoIndication: + ret = s1ap_compare_s1ap_uecapabilityinfoindicationies( + &m1->msg.s1ap_UECapabilityInfoIndicationIEs, + &m2->msg.s1ap_UECapabilityInfoIndicationIEs); + break; + case S1ap_ProcedureCode_id_UEContextRelease: + + break; + case S1ap_ProcedureCode_id_eNBStatusTransfer: + ret = s1ap_compare_s1ap_enbstatustransferies( + &m1->msg.s1ap_ENBStatusTransferIEs, + &m2->msg.s1ap_ENBStatusTransferIEs); + break; + case S1ap_ProcedureCode_id_MMEStatusTransfer: + ret = s1ap_compare_s1ap_mmestatustransferies( + &m1->msg.s1ap_MMEStatusTransferIEs, + &m2->msg.s1ap_MMEStatusTransferIEs); + break; + case S1ap_ProcedureCode_id_DeactivateTrace: + ret = s1ap_compare_s1ap_deactivatetraceies( + &m1->msg.s1ap_DeactivateTraceIEs, + &m2->msg.s1ap_DeactivateTraceIEs); + break; + case S1ap_ProcedureCode_id_TraceStart: + ret = s1ap_compare_s1ap_tracestarties( + &m1->msg.s1ap_TraceStartIEs, + &m2->msg.s1ap_TraceStartIEs); + break; + case S1ap_ProcedureCode_id_TraceFailureIndication: + ret = s1ap_compare_s1ap_tracefailureindicationies( + &m1->msg.s1ap_TraceFailureIndicationIEs, + &m2->msg.s1ap_TraceFailureIndicationIEs); + break; + case S1ap_ProcedureCode_id_ENBConfigurationUpdate: + case S1ap_ProcedureCode_id_MMEConfigurationUpdate: + case S1ap_ProcedureCode_id_LocationReportingControl: + case S1ap_ProcedureCode_id_LocationReportingFailureIndication: + case S1ap_ProcedureCode_id_LocationReport: + case S1ap_ProcedureCode_id_OverloadStart: + case S1ap_ProcedureCode_id_OverloadStop: + case S1ap_ProcedureCode_id_WriteReplaceWarning: + case S1ap_ProcedureCode_id_eNBDirectInformationTransfer: + case S1ap_ProcedureCode_id_MMEDirectInformationTransfer: + case S1ap_ProcedureCode_id_PrivateMessage: + case S1ap_ProcedureCode_id_eNBConfigurationTransfer: + case S1ap_ProcedureCode_id_MMEConfigurationTransfer: + case S1ap_ProcedureCode_id_CellTrafficTrace: + case S1ap_ProcedureCode_id_Kill: + if (present == S1AP_PDU_PR_initiatingMessage) { + ret = s1ap_compare_s1ap_killrequesties( + &m1->msg.s1ap_KillRequestIEs, + &m2->msg.s1ap_KillRequestIEs); + } else { + ret = s1ap_compare_s1ap_killresponseies( + &m1->msg.s1ap_KillResponseIEs, + &m2->msg.s1ap_KillResponseIEs); + } + break; + case S1ap_ProcedureCode_id_downlinkUEAssociatedLPPaTransport: + ret = s1ap_compare_s1ap_downlinkueassociatedlppatransport_ies( + &m1->msg.s1ap_DownlinkUEAssociatedLPPaTransport_IEs, + &m2->msg.s1ap_DownlinkUEAssociatedLPPaTransport_IEs); + break; + case S1ap_ProcedureCode_id_uplinkUEAssociatedLPPaTransport: + ret = s1ap_compare_s1ap_uplinkueassociatedlppatransport_ies( + &m1->msg.s1ap_UplinkUEAssociatedLPPaTransport_IEs, + &m2->msg.s1ap_UplinkUEAssociatedLPPaTransport_IEs); + break; + case S1ap_ProcedureCode_id_downlinkNonUEAssociatedLPPaTransport: + ret = s1ap_compare_s1ap_downlinknonueassociatedlppatransport_ies( + &m1->msg.s1ap_DownlinkNonUEAssociatedLPPaTransport_IEs, + &m2->msg.s1ap_DownlinkNonUEAssociatedLPPaTransport_IEs); + break; + case S1ap_ProcedureCode_id_uplinkNonUEAssociatedLPPaTransport: + ret = s1ap_compare_s1ap_uplinknonueassociatedlppatransport_ies( + &m1->msg.s1ap_UplinkNonUEAssociatedLPPaTransport_IEs, + &m2->msg.s1ap_UplinkNonUEAssociatedLPPaTransport_IEs); + break; + default: + AssertFatal(0, "Unknown procedure code %ld", m1->procedureCode); + } + return 0; +} diff --git a/openair3/TEST/EPC_TEST/play_scenario_sctp.c b/openair3/TEST/EPC_TEST/play_scenario_sctp.c index 6856cb2933..314beae8e1 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_sctp.c +++ b/openair3/TEST/EPC_TEST/play_scenario_sctp.c @@ -43,3 +43,48 @@ #include "assertions.h" #include "play_scenario.h" +//------------------------------------------------------------------------------ +int et_sctp_data_is_matching(sctp_datahdr_t * const sctp1, sctp_datahdr_t * const sctp2, const uint32_t constraints) +{ + // no comparison for ports + if (sctp1->ppid != sctp2->ppid) return -4; + if (sctp1->assoc_id != sctp2->assoc_id) return -5; + if (sctp1->stream != sctp2->stream) { + if (constraints & ET_BIT_MASK_MATCH_SCTP_STREAM) { + return -2; + } 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 -3; + } else { + S1AP_WARN("No Matching SCTP ssn %u %u\n", sctp1->ssn, sctp2->ssn); + } + } + return et_s1ap_is_matching(&sctp1->payload, &sctp2->payload, constraints); +} + +//------------------------------------------------------------------------------ +int 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 -1; + switch (sctp1->chunk_type) { + case SCTP_CID_DATA: + return et_sctp_data_is_matching(&sctp1->u.data_hdr, &sctp2->u.data_hdr, constraints); + break; + + case SCTP_CID_INIT: + AssertFatal(0, "Not needed now"); + break; + case SCTP_CID_INIT_ACK: + AssertFatal(0, "Not needed now"); + break; + default: + AssertFatal(0, "Not needed now cid %d", sctp1->chunk_type); + } + + return 0; +} From 44355e1a7355cc0d36c5f5f636d88533287c2fe6 Mon Sep 17 00:00:00 2001 From: gauthier Date: Wed, 2 Dec 2015 11:26:21 +0100 Subject: [PATCH 14/47] Receiving setupresponse success, TBC --- openair3/TEST/EPC_TEST/play_scenario.c | 16 ++ openair3/TEST/EPC_TEST/play_scenario.h | 21 +- .../TEST/EPC_TEST/play_scenario_display.c | 22 ++ openair3/TEST/EPC_TEST/play_scenario_fsm.c | 5 +- openair3/TEST/EPC_TEST/play_scenario_s1ap.c | 61 ++++-- .../EPC_TEST/play_scenario_s1ap_compare_ie.c | 194 +++++++++++++++++- openair3/TEST/EPC_TEST/play_scenario_sctp.c | 18 +- 7 files changed, 305 insertions(+), 32 deletions(-) diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c index 216e098a01..9a9cb881b1 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.c +++ b/openair3/TEST/EPC_TEST/play_scenario.c @@ -283,6 +283,22 @@ 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; + default: + AssertFatal (0, "ERROR: Unknown match error %d!(TODO handle an1c error codes)\n", err); + } +} +//------------------------------------------------------------------------------ et_packet_action_t et_action_str2et_action_t(const xmlChar * const action) { if ((!xmlStrcmp(action, (const xmlChar *)"SEND"))) { return ET_PACKET_ACTION_S1C_SEND;} diff --git a/openair3/TEST/EPC_TEST/play_scenario.h b/openair3/TEST/EPC_TEST/play_scenario.h index 3c8c5faef8..d5f11e40f9 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.h +++ b/openair3/TEST/EPC_TEST/play_scenario.h @@ -178,6 +178,19 @@ typedef enum { ET_FSM_STATE_END } et_fsm_state_t; +typedef enum { + ET_ERROR_MATCH_START = 1, + ET_ERROR_MATCH_PACKET_SCTP_CHUNK_TYPE = ET_ERROR_MATCH_START, + ET_ERROR_MATCH_PACKET_SCTP_PPID, + ET_ERROR_MATCH_PACKET_SCTP_ASSOC_ID, + ET_ERROR_MATCH_PACKET_SCTP_STREAM_ID, + ET_ERROR_MATCH_PACKET_SCTP_SSN, + ET_ERROR_MATCH_PACKET_S1AP_PRESENT, + ET_ERROR_MATCH_PACKET_S1AP_PROCEDURE_CODE, + ET_ERROR_MATCH_PACKET_S1AP_CRITICALITY, + ET_ERROR_MATCH_END +} et_error_match_code_t; + @@ -332,9 +345,9 @@ typedef struct et_scenario_s { hash_table_t *hash_old_ue_mme_id2ue_mme_id; struct timeval time_last_tx_packet; struct timeval time_last_rx_packet; - et_packet_t *last_rx_packet; - et_packet_t *last_tx_packet; - et_packet_t *next_packet; + et_packet_t *last_rx_packet; // last packet received with all previous scenario RX packet received. + et_packet_t *last_tx_packet; // last sent packet + et_packet_t *next_packet; // next packet to be handled in the scenario (RX or TX packet) } et_scenario_t; @@ -402,6 +415,7 @@ 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); int 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); +void et_scenario_set_packet_received(et_packet_t * const packet); void et_s1ap_process_rx_packet(et_event_s1ap_data_ind_t * const sctp_data_ind); void et_s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t * const sctp_data_ind); void et_s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, @@ -450,6 +464,7 @@ int et_compare_et_ip_to_net_ip_address(const et_ip_t * const ip, const net_ip_ad int et_hex2data(unsigned char * const data, const unsigned char * const hexstring, const unsigned int len); sctp_cid_t et_chunk_type_str2cid(const xmlChar * const chunk_type_str); const char * const et_chunk_type_cid2str(const sctp_cid_t chunk_type); +const char * const et_error_match2str(const int err); et_packet_action_t et_action_str2et_action_t(const xmlChar * const action); void et_ip_str2et_ip(const xmlChar * const ip_str, et_ip_t * const ip); void et_enb_config_init(const char const * lib_config_file_name_pP); diff --git a/openair3/TEST/EPC_TEST/play_scenario_display.c b/openair3/TEST/EPC_TEST/play_scenario_display.c index 406c69c858..2a924e952c 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_display.c +++ b/openair3/TEST/EPC_TEST/play_scenario_display.c @@ -273,6 +273,28 @@ void et_display_packet(const et_packet_t * const packet) default: fprintf(stdout, "\tPacket:\tAction UNKNOWN\n"); } + switch(packet->status) { + case ET_PACKET_STATUS_NONE: + fprintf(stdout, "\tPacket:\tStatus NONE\n"); + break; + case ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT: + fprintf(stdout, "\tPacket:\tStatus NOT_TAKEN_IN_ACCOUNT\n"); + break; + case ET_PACKET_STATUS_SCHEDULED_FOR_SENDING: + fprintf(stdout, "\tPacket:\tStatus SCHEDULED_FOR_SENDING\n"); + break; + case ET_PACKET_STATUS_SENT: + fprintf(stdout, "\tPacket:\tStatus SENT\n"); + break; + case ET_PACKET_STATUS_SCHEDULED_FOR_RECEIVING: + fprintf(stdout, "\tPacket:\tStatus SCHEDULED_FOR_RECEIVING\n"); + break; + case ET_PACKET_STATUS_RECEIVED: + fprintf(stdout, "\tPacket:\tStatus RECEIVED\n"); + break; + default: + fprintf(stdout, "\tPacket:\tStatus UNKNOWN\n"); + } et_display_packet_ip(&packet->ip_hdr); et_display_packet_sctp(&packet->sctp_hdr); } diff --git a/openair3/TEST/EPC_TEST/play_scenario_fsm.c b/openair3/TEST/EPC_TEST/play_scenario_fsm.c index 23ef72035c..d561668b17 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_fsm.c +++ b/openair3/TEST/EPC_TEST/play_scenario_fsm.c @@ -292,7 +292,10 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_null(et_event_t event) case ET_EVENT_INIT: AssertFatal(NULL == g_scenario, "Current scenario not ended"); g_scenario = event.u.init.scenario; - g_scenario->next_packet = g_scenario->list_packet; + g_scenario->next_packet = g_scenario->list_packet; + g_scenario->last_rx_packet = NULL; + g_scenario->last_tx_packet = NULL; + while (NULL != g_scenario->next_packet) { switch (g_scenario->next_packet->sctp_hdr.chunk_type) { diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c index 408ff72a4a..92cc3f766e 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c @@ -191,21 +191,21 @@ void et_s1ap_eNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, //------------------------------------------------------------------------------ int et_s1ap_is_matching(et_s1ap_t * const s1ap1, et_s1ap_t * const s1ap2, const uint32_t constraints) { - if (s1ap1->pdu.present != s1ap2->pdu.present) return -6; + if (s1ap1->pdu.present != s1ap2->pdu.present) return -ET_ERROR_MATCH_PACKET_S1AP_PRESENT; 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 -7; - if (s1ap1->pdu.choice.initiatingMessage.criticality != s1ap2->pdu.choice.initiatingMessage.criticality) return -8; + 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; break; case S1AP_PDU_PR_successfulOutcome: - if (s1ap1->pdu.choice.successfulOutcome.procedureCode != s1ap2->pdu.choice.successfulOutcome.procedureCode) return -7; - if (s1ap1->pdu.choice.successfulOutcome.criticality != s1ap2->pdu.choice.successfulOutcome.criticality) return -8; + 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; break; case S1AP_PDU_PR_unsuccessfulOutcome: - if (s1ap1->pdu.choice.unsuccessfulOutcome.procedureCode != s1ap2->pdu.choice.unsuccessfulOutcome.procedureCode) return -7; - if (s1ap1->pdu.choice.unsuccessfulOutcome.criticality != s1ap2->pdu.choice.unsuccessfulOutcome.criticality) return -8; + 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; break; default: AssertFatal(0, "Unknown pdu.present %d", s1ap1->pdu.present); @@ -236,7 +236,8 @@ et_packet_t* et_build_packet_from_s1ap_data_ind(et_event_s1ap_data_ind_t * const packet->enb_instance = 0; //TODO //packet->ip_hdr; // keep in mind: allocated buffer: sctp_datahdr.payload.binary_stream - memcpy((void*)&packet->sctp_hdr, (void*)&s1ap_data_ind->sctp_datahdr, sizeof(packet->sctp_hdr)); + packet->sctp_hdr.chunk_type = SCTP_CID_DATA; + memcpy((void*)&packet->sctp_hdr.u.data_hdr, (void*)&s1ap_data_ind->sctp_datahdr, sizeof(packet->sctp_hdr)); //packet->next = NULL; packet->status = ET_PACKET_STATUS_RECEIVED; //packet->timer_id = 0; @@ -245,23 +246,54 @@ et_packet_t* et_build_packet_from_s1ap_data_ind(et_event_s1ap_data_ind_t * const } +//------------------------------------------------------------------------------ +void et_scenario_set_packet_received(et_packet_t * const packet) +{ + int rc = 0; + packet->status = ET_PACKET_STATUS_RECEIVED; + S1AP_DEBUG("Packet num %d received\n", packet->packet_number); + if (packet->timer_id != 0) { + rc = timer_remove(packet->timer_id); + AssertFatal(rc == 0, "Timer on Rx packet num %d unknown", packet->packet_number); + } +} + //------------------------------------------------------------------------------ void 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; AssertFatal (NULL != s1ap_data_ind, "Bad parameter sctp_data_ind\n"); rx_packet = et_build_packet_from_s1ap_data_ind(s1ap_data_ind); - packet = g_scenario->next_packet; + if (NULL == g_scenario->last_rx_packet) { + packet = g_scenario->list_packet; + while (NULL != packet) { + if (packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { + if (packet->status == ET_PACKET_STATUS_RECEIVED) { + g_scenario->last_rx_packet = packet; + } else { + break; + } + } + packet = packet->next; + } + packet = g_scenario->list_packet; + } else { + packet = g_scenario->last_rx_packet; + } // 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) { - //TODO - if (et_sctp_is_matching(&packet->sctp_hdr, &rx_packet->sctp_hdr, g_constraints) == 0) { + rv = et_sctp_is_matching(&packet->sctp_hdr, &rx_packet->sctp_hdr, g_constraints); + if (0 == rv) { + S1AP_DEBUG("Compare RX packet with packet num %d succeeded\n", packet->packet_number); et_scenario_set_packet_received(packet); + } else { + S1AP_DEBUG("Compare RX packet with packet num %d failed %s\n", packet->packet_number, et_error_match2str(rv)); } } not_found += 1; @@ -388,9 +420,9 @@ void et_s1ap_update_assoc_id_of_packets(const int32_t assoc_id, case SCTP_CID_DATA : S1AP_DEBUG("%s for SCTP association (%u) SCTP_CID_DATA\n",__FUNCTION__,assoc_id); - if (ET_PACKET_STATUS_NONE == packet->status) { + if ((ET_PACKET_STATUS_NONE == packet->status) || (ET_PACKET_STATUS_SCHEDULED_FOR_RECEIVING == packet->status)) { if (0 < old_mme_port) { - if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_SEND) { + if (packet->action == ET_PACKET_ACTION_S1C_SEND) { ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.dst, &mme_desc_p->mme_net_ip_address); if (0 == ret) { ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.src, &s1ap_eNB_instance->s1c_net_ip_address); @@ -403,7 +435,7 @@ void et_s1ap_update_assoc_id_of_packets(const int32_t assoc_id, } } } - } else if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { + } else if (packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.src, &mme_desc_p->mme_net_ip_address); if (0 == ret) { ret = et_compare_et_ip_to_net_ip_address(&packet->ip_hdr.dst, &s1ap_eNB_instance->s1c_net_ip_address); @@ -474,6 +506,7 @@ void et_s1ap_update_assoc_id_of_packets(const int32_t assoc_id, break; default: + AssertFatal(0, "Unknown chunk_type %d packet num %d", packet->sctp_hdr.chunk_type, packet->packet_number); ; } packet = packet->next; 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 5ad5708bab..239621854a 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c @@ -63,86 +63,156 @@ int et_s1ap_ies_is_matching(const S1AP_PDU_PR present, s1ap_message * const m1, long ret = 0; AssertFatal(m1 != NULL, "bad parameter m1"); AssertFatal(m2 != NULL, "bad parameter m2"); - if (m1->procedureCode != m2->procedureCode) return -1; + AssertFatal((present == S1AP_PDU_PR_initiatingMessage) || + (present == S1AP_PDU_PR_successfulOutcome) || + (present == S1AP_PDU_PR_unsuccessfulOutcome) , "bad parameter S1AP_PDU_PR present "); + if (m1->procedureCode != m2->procedureCode) return -ET_ERROR_MATCH_PACKET_S1AP_PROCEDURE_CODE; // some cases can never occur since uplink only. switch (m1->procedureCode) { case S1ap_ProcedureCode_id_HandoverPreparation: - AssertFatal(0, "S1ap_ProcedureCode_id_InitialContextSetup not implemented"); + if (present == S1AP_PDU_PR_initiatingMessage) { + ret = s1ap_compare_s1ap_handoverrequiredies( + &m1->msg.s1ap_HandoverRequiredIEs, + &m2->msg.s1ap_HandoverRequiredIEs); + } else { + ret = s1ap_compare_s1ap_handovercommandies( + &m1->msg.s1ap_HandoverCommandIEs, + &m2->msg.s1ap_HandoverCommandIEs); + } break; + case S1ap_ProcedureCode_id_HandoverResourceAllocation: - AssertFatal(0, "S1ap_ProcedureCode_id_InitialContextSetup not implemented"); + if (present == S1AP_PDU_PR_initiatingMessage) { + ret = s1ap_compare_s1ap_handoverrequesties( + &m1->msg.s1ap_HandoverRequestIEs, + &m2->msg.s1ap_HandoverRequestIEs); + } else if (present == S1AP_PDU_PR_successfulOutcome) { + ret = s1ap_compare_s1ap_handoverrequestacknowledgeies( + &m1->msg.s1ap_HandoverRequestAcknowledgeIEs, + &m2->msg.s1ap_HandoverRequestAcknowledgeIEs); + } else if (present == S1AP_PDU_PR_unsuccessfulOutcome) { + ret = s1ap_compare_s1ap_handoverfailureies( + &m1->msg.s1ap_HandoverFailureIEs, + &m2->msg.s1ap_HandoverFailureIEs); + } break; + case S1ap_ProcedureCode_id_HandoverNotification: - AssertFatal(0, "S1ap_ProcedureCode_id_HandoverNotification not implemented"); + ret = s1ap_compare_s1ap_handovernotifyies( + &m1->msg.s1ap_HandoverNotifyIEs, + &m2->msg.s1ap_HandoverNotifyIEs); break; + case S1ap_ProcedureCode_id_PathSwitchRequest: ret = s1ap_compare_s1ap_pathswitchrequesties( &m1->msg.s1ap_PathSwitchRequestIEs, &m2->msg.s1ap_PathSwitchRequestIEs); break; + case S1ap_ProcedureCode_id_HandoverCancel: ret = s1ap_compare_s1ap_handovercancelies( &m1->msg.s1ap_HandoverCancelIEs, &m2->msg.s1ap_HandoverCancelIEs); break; + case S1ap_ProcedureCode_id_E_RABSetup: + if (present == S1AP_PDU_PR_initiatingMessage) { + ret = s1ap_compare_s1ap_e_rabsetuprequesties( + &m1->msg.s1ap_E_RABSetupRequestIEs, + &m2->msg.s1ap_E_RABSetupRequestIEs); + } else { + ret = s1ap_compare_s1ap_e_rabsetupresponseies( + &m1->msg.s1ap_E_RABSetupResponseIEs, + &m2->msg.s1ap_E_RABSetupResponseIEs); + } + break; + case S1ap_ProcedureCode_id_E_RABModify: + if (present == S1AP_PDU_PR_initiatingMessage) { + ret = s1ap_compare_s1ap_e_rabmodifyrequesties( + &m1->msg.s1ap_E_RABModifyRequestIEs, + &m2->msg.s1ap_E_RABModifyRequestIEs); + } else { + ret = s1ap_compare_s1ap_e_rabmodifyresponseies( + &m1->msg.s1ap_E_RABModifyResponseIEs, + &m2->msg.s1ap_E_RABModifyResponseIEs); + } + break; + case S1ap_ProcedureCode_id_E_RABRelease: if (present == S1AP_PDU_PR_initiatingMessage) { ret = s1ap_compare_s1ap_e_rabreleasecommandies( &m1->msg.s1ap_E_RABReleaseCommandIEs, &m2->msg.s1ap_E_RABReleaseCommandIEs); - } else if (present == S1AP_PDU_PR_successfulOutcome) { + } else { ret = s1ap_compare_s1ap_e_rabreleaseresponseies( &m1->msg.s1ap_E_RABReleaseResponseIEs, &m2->msg.s1ap_E_RABReleaseResponseIEs); } break; + case S1ap_ProcedureCode_id_E_RABReleaseIndication: ret = s1ap_compare_s1ap_e_rabreleaseindicationies( &m1->msg.s1ap_E_RABReleaseIndicationIEs, &m2->msg.s1ap_E_RABReleaseIndicationIEs); break; + case S1ap_ProcedureCode_id_InitialContextSetup: - AssertFatal(0, "S1ap_ProcedureCode_id_InitialContextSetup not implemented"); + if (present == S1AP_PDU_PR_initiatingMessage) { + ret = s1ap_compare_s1ap_initialcontextsetuprequesties( + &m1->msg.s1ap_InitialContextSetupRequestIEs, + &m2->msg.s1ap_InitialContextSetupRequestIEs); + } else { + ret = s1ap_compare_s1ap_initialcontextsetupresponseies( + &m1->msg.s1ap_InitialContextSetupResponseIEs, + &m2->msg.s1ap_InitialContextSetupResponseIEs); + } break; + case S1ap_ProcedureCode_id_Paging: ret = s1ap_compare_s1ap_pagingies( &m1->msg.s1ap_PagingIEs, &m2->msg.s1ap_PagingIEs); break; + case S1ap_ProcedureCode_id_downlinkNASTransport: ret = s1ap_compare_s1ap_downlinknastransporties( &m1->msg.s1ap_DownlinkNASTransportIEs, &m2->msg.s1ap_DownlinkNASTransportIEs); break; + case S1ap_ProcedureCode_id_initialUEMessage: ret = s1ap_compare_s1ap_initialuemessageies( &m1->msg.s1ap_InitialUEMessageIEs, &m2->msg.s1ap_InitialUEMessageIEs); break; + case S1ap_ProcedureCode_id_uplinkNASTransport: ret = s1ap_compare_s1ap_uplinknastransporties( &m1->msg.s1ap_UplinkNASTransportIEs, &m2->msg.s1ap_UplinkNASTransportIEs); break; + case S1ap_ProcedureCode_id_Reset: ret = s1ap_compare_s1ap_reseties( &m1->msg.s1ap_ResetIEs, &m2->msg.s1ap_ResetIEs); break; + case S1ap_ProcedureCode_id_ErrorIndication: ret = s1ap_compare_s1ap_errorindicationies( &m1->msg.s1ap_ErrorIndicationIEs, &m2->msg.s1ap_ErrorIndicationIEs); break; + case S1ap_ProcedureCode_id_NASNonDeliveryIndication: ret = s1ap_compare_s1ap_nasnondeliveryindication_ies( &m1->msg.s1ap_NASNonDeliveryIndication_IEs, &m2->msg.s1ap_NASNonDeliveryIndication_IEs); break; + case S1ap_ProcedureCode_id_S1Setup: if (present == S1AP_PDU_PR_initiatingMessage) { ret = s1ap_compare_s1ap_s1setuprequesties( @@ -158,21 +228,25 @@ int et_s1ap_ies_is_matching(const S1AP_PDU_PR present, s1ap_message * const m1, &m2->msg.s1ap_S1SetupFailureIEs); } break; + case S1ap_ProcedureCode_id_UEContextReleaseRequest: ret = s1ap_compare_s1ap_uecontextreleaserequesties( &m1->msg.s1ap_UEContextReleaseRequestIEs, &m2->msg.s1ap_UEContextReleaseRequestIEs); break; + case S1ap_ProcedureCode_id_DownlinkS1cdma2000tunneling: ret = s1ap_compare_s1ap_downlinks1cdma2000tunnelingies( &m1->msg.s1ap_DownlinkS1cdma2000tunnelingIEs, &m2->msg.s1ap_DownlinkS1cdma2000tunnelingIEs); break; + case S1ap_ProcedureCode_id_UplinkS1cdma2000tunneling: ret = s1ap_compare_s1ap_uplinks1cdma2000tunnelingies( &m1->msg.s1ap_UplinkS1cdma2000tunnelingIEs, &m2->msg.s1ap_UplinkS1cdma2000tunnelingIEs); break; + case S1ap_ProcedureCode_id_UEContextModification: if (present == S1AP_PDU_PR_initiatingMessage) { ret = s1ap_compare_s1ap_uecontextmodificationrequesties( @@ -188,53 +262,152 @@ int et_s1ap_ies_is_matching(const S1AP_PDU_PR present, s1ap_message * const m1, &m2->msg.s1ap_UEContextModificationFailureIEs); } break; + case S1ap_ProcedureCode_id_UECapabilityInfoIndication: ret = s1ap_compare_s1ap_uecapabilityinfoindicationies( &m1->msg.s1ap_UECapabilityInfoIndicationIEs, &m2->msg.s1ap_UECapabilityInfoIndicationIEs); break; - case S1ap_ProcedureCode_id_UEContextRelease: + case S1ap_ProcedureCode_id_UEContextRelease: + if (present == S1AP_PDU_PR_initiatingMessage) { + ret = s1ap_compare_s1ap_uecontextreleasecommandies( + &m1->msg.s1ap_UEContextReleaseCommandIEs, + &m2->msg.s1ap_UEContextReleaseCommandIEs); + } else { + ret = s1ap_compare_s1ap_uecontextreleasecompleteies( + &m1->msg.s1ap_UEContextReleaseCompleteIEs, + &m2->msg.s1ap_UEContextReleaseCompleteIEs); + } break; + case S1ap_ProcedureCode_id_eNBStatusTransfer: ret = s1ap_compare_s1ap_enbstatustransferies( &m1->msg.s1ap_ENBStatusTransferIEs, &m2->msg.s1ap_ENBStatusTransferIEs); break; + case S1ap_ProcedureCode_id_MMEStatusTransfer: ret = s1ap_compare_s1ap_mmestatustransferies( &m1->msg.s1ap_MMEStatusTransferIEs, &m2->msg.s1ap_MMEStatusTransferIEs); break; + case S1ap_ProcedureCode_id_DeactivateTrace: ret = s1ap_compare_s1ap_deactivatetraceies( &m1->msg.s1ap_DeactivateTraceIEs, &m2->msg.s1ap_DeactivateTraceIEs); break; + case S1ap_ProcedureCode_id_TraceStart: ret = s1ap_compare_s1ap_tracestarties( &m1->msg.s1ap_TraceStartIEs, &m2->msg.s1ap_TraceStartIEs); break; + case S1ap_ProcedureCode_id_TraceFailureIndication: ret = s1ap_compare_s1ap_tracefailureindicationies( &m1->msg.s1ap_TraceFailureIndicationIEs, &m2->msg.s1ap_TraceFailureIndicationIEs); break; + case S1ap_ProcedureCode_id_ENBConfigurationUpdate: + if (present == S1AP_PDU_PR_initiatingMessage) { + ret = s1ap_compare_s1ap_enbconfigurationupdateies( + &m1->msg.s1ap_ENBConfigurationUpdateIEs, + &m2->msg.s1ap_ENBConfigurationUpdateIEs); + } else if (present == S1AP_PDU_PR_successfulOutcome) { + ret = s1ap_compare_s1ap_enbconfigurationupdateacknowledgeies( + &m1->msg.s1ap_ENBConfigurationUpdateAcknowledgeIEs, + &m2->msg.s1ap_ENBConfigurationUpdateAcknowledgeIEs); + } else { + ret = s1ap_compare_s1ap_enbconfigurationupdatefailureies( + &m1->msg.s1ap_ENBConfigurationUpdateFailureIEs, + &m2->msg.s1ap_ENBConfigurationUpdateFailureIEs); + } + break; + case S1ap_ProcedureCode_id_MMEConfigurationUpdate: + if (present == S1AP_PDU_PR_initiatingMessage) { + ret = s1ap_compare_s1ap_mmeconfigurationupdateies( + &m1->msg.s1ap_MMEConfigurationUpdateIEs, + &m2->msg.s1ap_MMEConfigurationUpdateIEs); + } else if (present == S1AP_PDU_PR_successfulOutcome) { + ret = s1ap_compare_s1ap_mmeconfigurationupdateacknowledgeies( + &m1->msg.s1ap_MMEConfigurationUpdateAcknowledgeIEs, + &m2->msg.s1ap_MMEConfigurationUpdateAcknowledgeIEs); + } else { + ret = s1ap_compare_s1ap_mmeconfigurationupdatefailureies( + &m1->msg.s1ap_MMEConfigurationUpdateFailureIEs, + &m2->msg.s1ap_MMEConfigurationUpdateFailureIEs); + } + break; + case S1ap_ProcedureCode_id_LocationReportingControl: + ret = s1ap_compare_s1ap_locationreportingcontrolies( + &m1->msg.s1ap_LocationReportingControlIEs, + &m2->msg.s1ap_LocationReportingControlIEs); + break; + case S1ap_ProcedureCode_id_LocationReportingFailureIndication: + ret = s1ap_compare_s1ap_locationreportingfailureindicationies( + &m1->msg.s1ap_LocationReportingFailureIndicationIEs, + &m2->msg.s1ap_LocationReportingFailureIndicationIEs); + break; + case S1ap_ProcedureCode_id_LocationReport: + ret = s1ap_compare_s1ap_locationreporties( + &m1->msg.s1ap_LocationReportIEs, + &m2->msg.s1ap_LocationReportIEs); + break; + case S1ap_ProcedureCode_id_OverloadStart: + ret = s1ap_compare_s1ap_overloadstarties( + &m1->msg.s1ap_OverloadStartIEs, + &m2->msg.s1ap_OverloadStartIEs); + break; + case S1ap_ProcedureCode_id_OverloadStop: + ret = s1ap_compare_s1ap_overloadstopies( + &m1->msg.s1ap_OverloadStopIEs, + &m2->msg.s1ap_OverloadStopIEs); + break; + case S1ap_ProcedureCode_id_WriteReplaceWarning: + if (present == S1AP_PDU_PR_initiatingMessage) { + ret = s1ap_compare_s1ap_writereplacewarningrequesties( + &m1->msg.s1ap_WriteReplaceWarningRequestIEs, + &m2->msg.s1ap_WriteReplaceWarningRequestIEs); + } else { + ret = s1ap_compare_s1ap_writereplacewarningresponseies( + &m1->msg.s1ap_WriteReplaceWarningResponseIEs, + &m2->msg.s1ap_WriteReplaceWarningResponseIEs); + } + break; + case S1ap_ProcedureCode_id_eNBDirectInformationTransfer: + ret = s1ap_compare_s1ap_enbdirectinformationtransferies( + &m1->msg.s1ap_ENBDirectInformationTransferIEs, + &m2->msg.s1ap_ENBDirectInformationTransferIEs); + break; + case S1ap_ProcedureCode_id_MMEDirectInformationTransfer: + + ret = s1ap_compare_s1ap_mmedirectinformationtransferies( + &m1->msg.s1ap_MMEDirectInformationTransferIEs, + &m2->msg.s1ap_MMEDirectInformationTransferIEs); + break; + case S1ap_ProcedureCode_id_PrivateMessage: case S1ap_ProcedureCode_id_eNBConfigurationTransfer: case S1ap_ProcedureCode_id_MMEConfigurationTransfer: + case S1ap_ProcedureCode_id_CellTrafficTrace: + ret = s1ap_compare_s1ap_celltraffictraceies( + &m1->msg.s1ap_CellTrafficTraceIEs, + &m2->msg.s1ap_CellTrafficTraceIEs); + break; + case S1ap_ProcedureCode_id_Kill: if (present == S1AP_PDU_PR_initiatingMessage) { ret = s1ap_compare_s1ap_killrequesties( @@ -246,28 +419,33 @@ int et_s1ap_ies_is_matching(const S1AP_PDU_PR present, s1ap_message * const m1, &m2->msg.s1ap_KillResponseIEs); } break; + case S1ap_ProcedureCode_id_downlinkUEAssociatedLPPaTransport: ret = s1ap_compare_s1ap_downlinkueassociatedlppatransport_ies( &m1->msg.s1ap_DownlinkUEAssociatedLPPaTransport_IEs, &m2->msg.s1ap_DownlinkUEAssociatedLPPaTransport_IEs); break; + case S1ap_ProcedureCode_id_uplinkUEAssociatedLPPaTransport: ret = s1ap_compare_s1ap_uplinkueassociatedlppatransport_ies( &m1->msg.s1ap_UplinkUEAssociatedLPPaTransport_IEs, &m2->msg.s1ap_UplinkUEAssociatedLPPaTransport_IEs); break; + case S1ap_ProcedureCode_id_downlinkNonUEAssociatedLPPaTransport: ret = s1ap_compare_s1ap_downlinknonueassociatedlppatransport_ies( &m1->msg.s1ap_DownlinkNonUEAssociatedLPPaTransport_IEs, &m2->msg.s1ap_DownlinkNonUEAssociatedLPPaTransport_IEs); break; + case S1ap_ProcedureCode_id_uplinkNonUEAssociatedLPPaTransport: ret = s1ap_compare_s1ap_uplinknonueassociatedlppatransport_ies( &m1->msg.s1ap_UplinkNonUEAssociatedLPPaTransport_IEs, &m2->msg.s1ap_UplinkNonUEAssociatedLPPaTransport_IEs); break; + default: AssertFatal(0, "Unknown procedure code %ld", m1->procedureCode); } - return 0; + return ret; } diff --git a/openair3/TEST/EPC_TEST/play_scenario_sctp.c b/openair3/TEST/EPC_TEST/play_scenario_sctp.c index 314beae8e1..a61701d92d 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_sctp.c +++ b/openair3/TEST/EPC_TEST/play_scenario_sctp.c @@ -47,20 +47,26 @@ int et_sctp_data_is_matching(sctp_datahdr_t * const sctp1, sctp_datahdr_t * const sctp2, const uint32_t constraints) { // no comparison for ports - if (sctp1->ppid != sctp2->ppid) return -4; - if (sctp1->assoc_id != sctp2->assoc_id) return -5; + 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; + } + 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; + } if (sctp1->stream != sctp2->stream) { if (constraints & ET_BIT_MASK_MATCH_SCTP_STREAM) { - return -2; + return -ET_ERROR_MATCH_PACKET_SCTP_STREAM_ID; } 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 -3; + return -ET_ERROR_MATCH_PACKET_SCTP_SSN; } else { - S1AP_WARN("No Matching SCTP ssn %u %u\n", sctp1->ssn, sctp2->ssn); + S1AP_WARN("No Matching SCTP STREAM SN %u %u\n", sctp1->ssn, sctp2->ssn); } } return et_s1ap_is_matching(&sctp1->payload, &sctp2->payload, constraints); @@ -70,7 +76,7 @@ int et_sctp_data_is_matching(sctp_datahdr_t * const sctp1, sctp_datahdr_t * cons int 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 -1; + if (sctp1->chunk_type != sctp2->chunk_type) return -ET_ERROR_MATCH_PACKET_SCTP_CHUNK_TYPE; switch (sctp1->chunk_type) { case SCTP_CID_DATA: return et_sctp_data_is_matching(&sctp1->u.data_hdr, &sctp2->u.data_hdr, constraints); From 8a001c57bc4432786d2d5f8d1a5a8a3de5b3ef9b Mon Sep 17 00:00:00 2001 From: gauthier Date: Wed, 2 Dec 2015 13:04:21 +0100 Subject: [PATCH 15/47] Backup, need to feed with packets, still patch for asn1c to be comited --- openair3/TEST/EPC_TEST/play_scenario.h | 19 +++-- openair3/TEST/EPC_TEST/play_scenario_fsm.c | 74 ++++++++++++++++--- openair3/TEST/EPC_TEST/play_scenario_s1ap.c | 24 ++++-- .../EPC_TEST/play_scenario_s1ap_compare_ie.c | 6 +- openair3/TEST/EPC_TEST/play_scenario_sctp.c | 4 +- 5 files changed, 97 insertions(+), 30 deletions(-) diff --git a/openair3/TEST/EPC_TEST/play_scenario.h b/openair3/TEST/EPC_TEST/play_scenario.h index d5f11e40f9..604d0000bc 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.h +++ b/openair3/TEST/EPC_TEST/play_scenario.h @@ -173,7 +173,8 @@ typedef enum { ET_FSM_STATE_START = 0, ET_FSM_STATE_NULL = ET_FSM_STATE_START, ET_FSM_STATE_CONNECTING_S1C, - ET_FSM_STATE_WAITING_EVENT, + ET_FSM_STATE_WAITING_RX_EVENT, + ET_FSM_STATE_WAITING_TX_EVENT, ET_FSM_STATE_RUNNING, ET_FSM_STATE_END } et_fsm_state_t; @@ -359,6 +360,7 @@ typedef enum { ET_EVENT_RX_S1AP, ET_EVENT_RX_PACKET_TIME_OUT, ET_EVENT_TX_TIMED_PACKET, + ET_EVENT_TICK, ET_EVENT_END } et_event_code_t; @@ -413,10 +415,10 @@ 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); -int et_s1ap_is_matching(et_s1ap_t * const s1ap1, et_s1ap_t * const s1ap2, const uint32_t constraints); +long 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); -void et_scenario_set_packet_received(et_packet_t * const packet); -void et_s1ap_process_rx_packet(et_event_s1ap_data_ind_t * const sctp_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); void et_s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t * const sctp_data_ind); void et_s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, net_ip_address_t *mme_ip_address, @@ -435,7 +437,8 @@ int et_generate_xml_scenario( char const * tsml_out_scenario_filename); //------------------------- et_fsm_state_t et_scenario_fsm_notify_event_state_running(et_event_t event); -et_fsm_state_t et_scenario_fsm_notify_event_state_waiting(et_event_t event); +et_fsm_state_t et_scenario_fsm_notify_event_state_waiting_tx(et_event_t event); +et_fsm_state_t et_scenario_fsm_notify_event_state_waiting_rx(et_event_t event); et_fsm_state_t et_scenario_fsm_notify_event_state_connecting_s1c(et_event_t event); et_fsm_state_t et_scenario_fsm_notify_event_state_null(et_event_t event); et_fsm_state_t et_scenario_fsm_notify_event(et_event_t event); @@ -448,10 +451,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 ); //------------------------- -int et_s1ap_ies_is_matching(const S1AP_PDU_PR present, s1ap_message * const m1, s1ap_message * const m2, const uint32_t constraints); +long et_s1ap_ies_is_matching(const S1AP_PDU_PR present, s1ap_message * const m1, s1ap_message * const m2, const uint32_t constraints); //------------------------- -int et_sctp_data_is_matching(sctp_datahdr_t * const sctp1, sctp_datahdr_t * const sctp2, const uint32_t constraints); -int et_sctp_is_matching(et_sctp_hdr_t * const sctp1, et_sctp_hdr_t * const sctp2, 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); //------------------------------------------------------------------------------ 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_fsm.c b/openair3/TEST/EPC_TEST/play_scenario_fsm.c index d561668b17..b6ff0de859 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_fsm.c +++ b/openair3/TEST/EPC_TEST/play_scenario_fsm.c @@ -87,7 +87,7 @@ void et_scenario_wait_rx_packet(et_packet_t * const packet) NULL, &packet->timer_id) < 0) { AssertFatal(0, " Can not start waiting RX event timer\n"); } - g_fsm_state = ET_FSM_STATE_WAITING_EVENT; + g_fsm_state = ET_FSM_STATE_WAITING_RX_EVENT; packet->status = ET_PACKET_STATUS_SCHEDULED_FOR_RECEIVING; } //------------------------------------------------------------------------------ @@ -107,7 +107,7 @@ void et_scenario_schedule_tx_packet(et_packet_t * const packet) AssertFatal(NULL != s1ap_eNB_instance, "Cannot get s1ap_eNB_instance_t for eNB instance %d", packet->enb_instance); LOG_D(ENB_APP, "%s\n", __FUNCTION__); - g_fsm_state = ET_FSM_STATE_WAITING_EVENT; + g_fsm_state = ET_FSM_STATE_WAITING_TX_EVENT; switch (packet->sctp_hdr.chunk_type) { case SCTP_CID_DATA: @@ -160,6 +160,10 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_running(et_event_t event) { switch (event.code){ + case ET_EVENT_TICK: + //TODO + + break; case ET_EVENT_RX_PACKET_TIME_OUT: AssertFatal(0, "Event ET_EVENT_RX_PACKET_TIME_OUT not handled in FSM state ET_FSM_STATE_RUNNING"); break; @@ -177,18 +181,17 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_running(et_event_t event) } //------------------------------------------------------------------------------ -et_fsm_state_t et_scenario_fsm_notify_event_state_waiting(et_event_t event) +et_fsm_state_t et_scenario_fsm_notify_event_state_waiting_tx(et_event_t event) { - + int rv = 0; switch (event.code){ - case ET_EVENT_RX_PACKET_TIME_OUT: - fprintf(stderr, "Error The following packet is not received:\n"); - et_display_packet(event.u.rx_packet_time_out); - AssertFatal(0, "Waited packet not received"); + case ET_EVENT_TICK: break; + case ET_EVENT_RX_S1AP: - et_s1ap_process_rx_packet(&event.u.s1ap_data_ind); + rv = et_s1ap_process_rx_packet(&event.u.s1ap_data_ind); break; + case ET_EVENT_TX_TIMED_PACKET: // send immediately AssertFatal(0 == gettimeofday(&event.u.tx_timed_packet->timestamp_packet, NULL), "gettimeofday() Failed"); @@ -202,9 +205,39 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_waiting(et_event_t event) g_fsm_state = ET_FSM_STATE_RUNNING; break; - + case ET_EVENT_RX_PACKET_TIME_OUT: default: - AssertFatal(0, "Case event %d not handled in ET_FSM_STATE_WAITING", event.code); + AssertFatal(0, "Case event %d not handled in ET_FSM_STATE_WAITING_TX", event.code); + } + pthread_mutex_unlock(&g_fsm_lock); + return 0; +} + +//------------------------------------------------------------------------------ +et_fsm_state_t et_scenario_fsm_notify_event_state_waiting_rx(et_event_t event) +{ + int rv = 0; + switch (event.code){ + case ET_EVENT_TICK: + break; + + case ET_EVENT_RX_PACKET_TIME_OUT: + fprintf(stderr, "Error The following packet is not received:\n"); + et_display_packet(event.u.rx_packet_time_out); + AssertFatal(0, "Waited packet not received"); + break; + + case ET_EVENT_RX_S1AP: + rv = et_s1ap_process_rx_packet(&event.u.s1ap_data_ind); + // waited packet + if (rv == 0) { + g_fsm_state = ET_FSM_STATE_RUNNING; + } + break; + + case ET_EVENT_TX_TIMED_PACKET: + default: + AssertFatal(0, "Case event %d not handled in ET_FSM_STATE_WAITING_RX", event.code); } pthread_mutex_unlock(&g_fsm_lock); return 0; @@ -215,6 +248,9 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_connecting_s1c(et_event_t even { switch (event.code){ + case ET_EVENT_TICK: + break; + case ET_EVENT_S1C_CONNECTED: // hack simulate we have been able to get the right timing values AssertFatal(gettimeofday(&g_scenario->time_last_tx_packet, NULL) == 0, "gettimeofday failed"); @@ -227,6 +263,11 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_connecting_s1c(et_event_t even if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_SEND) { et_scenario_schedule_tx_packet(g_scenario->next_packet); pthread_mutex_unlock(&g_fsm_lock); + + et_event_t continue_event; + continue_event.code = ET_EVENT_TICK; + et_scenario_fsm_notify_event(continue_event); + return g_fsm_state; } else if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { if (g_scenario->next_packet->status == ET_PACKET_STATUS_RECEIVED) { @@ -289,6 +330,9 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_connecting_s1c(et_event_t even et_fsm_state_t et_scenario_fsm_notify_event_state_null(et_event_t event) { switch (event.code){ + case ET_EVENT_TICK: + break; + case ET_EVENT_INIT: AssertFatal(NULL == g_scenario, "Current scenario not ended"); g_scenario = event.u.init.scenario; @@ -304,6 +348,11 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_null(et_event_t event) if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_SEND) { et_scenario_schedule_tx_packet(g_scenario->next_packet); pthread_mutex_unlock(&g_fsm_lock); + + et_event_t continue_event; + continue_event.code = ET_EVENT_TICK; + et_scenario_fsm_notify_event(continue_event); + return g_fsm_state; } else if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { if (g_scenario->next_packet->status == ET_PACKET_STATUS_RECEIVED) { @@ -382,7 +431,8 @@ et_fsm_state_t et_scenario_fsm_notify_event(et_event_t event) switch (g_fsm_state){ case ET_FSM_STATE_NULL: return et_scenario_fsm_notify_event_state_null(event); break; case ET_FSM_STATE_CONNECTING_S1C: return et_scenario_fsm_notify_event_state_connecting_s1c(event); break; - case ET_FSM_STATE_WAITING_EVENT: return et_scenario_fsm_notify_event_state_waiting(event); break; + case ET_FSM_STATE_WAITING_TX_EVENT: return et_scenario_fsm_notify_event_state_waiting_tx(event); break; + case ET_FSM_STATE_WAITING_RX_EVENT: return et_scenario_fsm_notify_event_state_waiting_rx(event); break; case ET_FSM_STATE_RUNNING: return et_scenario_fsm_notify_event_state_running(event); break; default: AssertFatal(0, "Case fsm_state %d not handled", g_fsm_state); diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c index 92cc3f766e..336dc547d5 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c @@ -189,7 +189,7 @@ 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); } //------------------------------------------------------------------------------ -int et_s1ap_is_matching(et_s1ap_t * const s1ap1, et_s1ap_t * const s1ap2, const uint32_t constraints) +long et_s1ap_is_matching(et_s1ap_t * const s1ap1, et_s1ap_t * const s1ap2, const uint32_t constraints) { if (s1ap1->pdu.present != s1ap2->pdu.present) return -ET_ERROR_MATCH_PACKET_S1AP_PRESENT; switch (s1ap1->pdu.present) { @@ -247,19 +247,22 @@ et_packet_t* et_build_packet_from_s1ap_data_ind(et_event_s1ap_data_ind_t * const //------------------------------------------------------------------------------ -void et_scenario_set_packet_received(et_packet_t * const packet) +// return 0 if packet was waited +int et_scenario_set_packet_received(et_packet_t * const packet) { int rc = 0; packet->status = ET_PACKET_STATUS_RECEIVED; S1AP_DEBUG("Packet num %d received\n", packet->packet_number); if (packet->timer_id != 0) { rc = timer_remove(packet->timer_id); - AssertFatal(rc == 0, "Timer on Rx packet num %d unknown", packet->packet_number); + AssertFatal(rc == 0, "TODO: Debug Timer on Rx packet num %d unknown", packet->packet_number); + return rc; } + return 1; } //------------------------------------------------------------------------------ -void et_s1ap_process_rx_packet(et_event_s1ap_data_ind_t * const s1ap_data_ind) +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; @@ -291,9 +294,15 @@ void et_s1ap_process_rx_packet(et_event_s1ap_data_ind_t * const s1ap_data_ind) rv = et_sctp_is_matching(&packet->sctp_hdr, &rx_packet->sctp_hdr, g_constraints); if (0 == rv) { S1AP_DEBUG("Compare RX packet with packet num %d succeeded\n", packet->packet_number); - et_scenario_set_packet_received(packet); + return et_scenario_set_packet_received(packet); } else { S1AP_DEBUG("Compare RX packet with packet num %d failed %s\n", packet->packet_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"); + } } } not_found += 1; @@ -301,6 +310,7 @@ void et_s1ap_process_rx_packet(et_event_s1ap_data_ind_t * const s1ap_data_ind) } S1AP_DEBUG("Rx packet not found in scenario:\n"); et_display_packet_sctp(&rx_packet->sctp_hdr); + return -1; } //------------------------------------------------------------------------------ @@ -344,6 +354,10 @@ void et_s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t * const sctp_data_ind) et_scenario_fsm_notify_event(event); + memset((void*)&event, 0, sizeof(event)); + event.code = ET_EVENT_TICK; + et_scenario_fsm_notify_event(event); + } //------------------------------------------------------------------------------ void et_s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, 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 239621854a..5300476e98 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c @@ -58,15 +58,15 @@ extern et_scenario_t *g_scenario; extern uint32_t g_constraints; //------------------------------------------------------------------------------ -int et_s1ap_ies_is_matching(const S1AP_PDU_PR present, s1ap_message * const m1, s1ap_message * const m2, const uint32_t constraints) +long 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; AssertFatal(m1 != NULL, "bad parameter m1"); AssertFatal(m2 != NULL, "bad parameter m2"); AssertFatal((present == S1AP_PDU_PR_initiatingMessage) || (present == S1AP_PDU_PR_successfulOutcome) || - (present == S1AP_PDU_PR_unsuccessfulOutcome) , "bad parameter S1AP_PDU_PR present "); - if (m1->procedureCode != m2->procedureCode) return -ET_ERROR_MATCH_PACKET_S1AP_PROCEDURE_CODE; + (present == S1AP_PDU_PR_unsuccessfulOutcome) , "Bad parameter S1AP_PDU_PR present "); + AssertFatal( m1->procedureCode == m2->procedureCode, "Bad parameters: no matching procedure codes"); // some cases can never occur since uplink only. diff --git a/openair3/TEST/EPC_TEST/play_scenario_sctp.c b/openair3/TEST/EPC_TEST/play_scenario_sctp.c index a61701d92d..07206f53b8 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_sctp.c +++ b/openair3/TEST/EPC_TEST/play_scenario_sctp.c @@ -44,7 +44,7 @@ #include "play_scenario.h" //------------------------------------------------------------------------------ -int et_sctp_data_is_matching(sctp_datahdr_t * const sctp1, sctp_datahdr_t * const sctp2, const uint32_t constraints) +long et_sctp_data_is_matching(sctp_datahdr_t * const sctp1, sctp_datahdr_t * const sctp2, const uint32_t constraints) { // no comparison for ports if (sctp1->ppid != sctp2->ppid) { @@ -73,7 +73,7 @@ int et_sctp_data_is_matching(sctp_datahdr_t * const sctp1, sctp_datahdr_t * cons } //------------------------------------------------------------------------------ -int et_sctp_is_matching(et_sctp_hdr_t * const sctp1, et_sctp_hdr_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) { // no comparison for ports if (sctp1->chunk_type != sctp2->chunk_type) return -ET_ERROR_MATCH_PACKET_SCTP_CHUNK_TYPE; From e547fa872442df5571f2e23c0329b5aa9dcb5c75 Mon Sep 17 00:00:00 2001 From: gauthier Date: Fri, 4 Dec 2015 11:16:47 +0100 Subject: [PATCH 16/47] Able to begin replay a scenario...debug needed --- cmake_targets/tools/build_helper | 1 + cmake_targets/tools/build_test_epc_tools | 5 + openair3/S1AP/MESSAGES/ASN1/asn1cpatch_3.p0 | 1030 +++++++++++++++++++ openair3/TEST/EPC_TEST/play_scenario.c | 8 +- openair3/TEST/EPC_TEST/play_scenario_fsm.c | 77 +- openair3/TEST/EPC_TEST/play_scenario_s1ap.c | 22 +- 6 files changed, 1133 insertions(+), 10 deletions(-) create mode 100644 openair3/S1AP/MESSAGES/ASN1/asn1cpatch_3.p0 diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 46997c2773..350dae86a6 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -274,6 +274,7 @@ install_asn1c_from_source(){ patch -p0 < $OPENAIR_DIR/openair3/S1AP/MESSAGES/ASN1/asn1cpatch.p0 >> /tmp/log_compile_asn1c patch -p0 < $OPENAIR_DIR/openair3/S1AP/MESSAGES/ASN1/asn1cpatch_2.p0 >> /tmp/log_compile_asn1c patch -p0 < $OPENAIR_DIR/openair2/RRC/LITE/MESSAGES/asn1c/asn1cpatch.p0 >> /tmp/log_compile_asn1c + patch -p0 < $OPENAIR_DIR/openair3/S1AP/MESSAGES/ASN1/asn1cpatch_3.p0 >> /tmp/log_compile_asn1c ./configure make > /tmp/log_compile_asn1c 2>&1 $SUDO make install diff --git a/cmake_targets/tools/build_test_epc_tools b/cmake_targets/tools/build_test_epc_tools index db49fa017b..b67cf15810 100755 --- a/cmake_targets/tools/build_test_epc_tools +++ b/cmake_targets/tools/build_test_epc_tools @@ -141,9 +141,14 @@ function main() compilations \ epc_test test_epc_generate_scenario \ test_epc_generate_scenario $dbin/test_epc_generate_scenario + compilations \ epc_test test_epc_play_scenario \ test_epc_play_scenario $dbin/test_epc_play_scenario + + $SUDO cp -upv test_epc_generate_scenario /usr/local/bin + $SUDO cp -upv test_epc_play_scenario /usr/local/bin + $SUDO cp -upv $OPENAIR_DIR/openair3/TEST/EPC_TEST/mme_test_s1_pcap2pdml /usr/local/bin } diff --git a/openair3/S1AP/MESSAGES/ASN1/asn1cpatch_3.p0 b/openair3/S1AP/MESSAGES/ASN1/asn1cpatch_3.p0 new file mode 100644 index 0000000000..cf3553c362 --- /dev/null +++ b/openair3/S1AP/MESSAGES/ASN1/asn1cpatch_3.p0 @@ -0,0 +1,1030 @@ +--- ./asn1c/unber.c 2015-12-03 09:43:33.959009150 +0100 ++++ ./asn1c/unber.c 2015-11-30 13:20:40.751264003 +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; } ++ + 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 +@@ -1082,6 +1082,8 @@ + enum tvm_compat tv_mode; + enum etd_spec etd_spec; + char *p; ++ char tmp_buf[512]; ++ int i = 0; + + if(arg->embed) { + enum tnfmt tnfmt = TNF_CTYPE; +@@ -1243,7 +1245,8 @@ + OUT("td->uper_decoder = asn_DEF_%s.uper_decoder;\n", type_name); + OUT("td->uper_encoder = asn_DEF_%s.uper_encoder;\n", type_name); + OUT("td->aper_decoder = asn_DEF_%s.aper_decoder;\n", type_name); +- OUT("td->aper_encoder = asn_DEF_%s.aper_encoder;\n", type_name); ++ OUT("td->aper_encoder = asn_DEF_%s.aper_encoder;\n", type_name); ++ OUT("td->compare = asn_DEF_%s.compare;\n", type_name); + if(!terminal && !tags_count) { + OUT("/* The next four lines are here because of -fknown-extern-type */\n"); + OUT("td->tags = asn_DEF_%s.tags;\n", type_name); +@@ -1413,6 +1416,49 @@ + OUT("}\n"); + OUT("\n"); + ++ ++ i = 0; ++ while ((p[i] != '_') && (i < sizeof(tmp_buf))) { ++ tmp_buf[i] = p[i]; ++ i++; ++ } ++ tmp_buf[i] = '\0'; ++ // hack, only for s1ap ++ if ((strcmp("S1ap", tmp_buf) == 0) || (strcmp("X2ap", tmp_buf) == 0)) ++ OUT("#include \"%s-ProtocolIE-ID.h\"\n", tmp_buf); ++ ++ ++ p = MKID(expr); ++ if(HIDE_INNER_DEFS) OUT("static "); ++ OUT("long\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("%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("}\n"); ++ OUT("\n"); ++ + p = MKID(expr); + + if(HIDE_INNER_DEFS) OUT("static "); +@@ -1450,7 +1496,8 @@ + OUT("per_type_decoder_f %s_decode_uper;\n", p); + OUT("per_type_encoder_f %s_encode_uper;\n", p); + OUT("per_type_decoder_f %s_decode_aper;\n", p); +- OUT("per_type_encoder_f %s_encode_aper;\n", p); ++ OUT("per_type_encoder_f %s_encode_aper;\n", p); ++ OUT("type_compare_f %s_compare;\n", p); + } + } + +@@ -2501,6 +2548,7 @@ + OUT("0, 0,\t/* No APER support, " + "use \"-gen-PER\" to enable */\n"); + } ++ FUNCREF(compare); + + if(!terminal || terminal->expr_type == ASN_CONSTR_CHOICE) { + //if(expr->expr_type == ASN_CONSTR_CHOICE) { +--- ./skeletons/ANY.c 2015-12-03 09:43:33.971009150 +0100 ++++ ./skeletons/ANY.c 2015-11-26 14:40:56.547616803 +0100 +@@ -24,7 +24,8 @@ + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, +- OCTET_STRING_encode_aper, ++ OCTET_STRING_encode_aper, ++ OCTET_STRING_compare, + 0, /* Use generic outmost tag fetcher */ + 0, 0, 0, 0, + 0, /* No PER visible constraints */ +--- ./skeletons/BIT_STRING.c 2015-12-03 09:43:33.967009150 +0100 ++++ ./skeletons/BIT_STRING.c 2015-11-26 14:41:50.159616747 +0100 +@@ -30,7 +30,8 @@ + OCTET_STRING_decode_uper, /* Unaligned PER decoder */ + OCTET_STRING_encode_uper, /* Unaligned PER encoder */ + OCTET_STRING_decode_aper, /* Aligned PER decoder */ +- OCTET_STRING_encode_aper, /* Aligned PER encoder */ ++ OCTET_STRING_encode_aper, /* Aligned PER encoder */ ++ OCTET_STRING_compare, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_BIT_STRING_tags, + sizeof(asn_DEF_BIT_STRING_tags) +--- ./skeletons/BMPString.c 2015-12-03 09:43:33.963009150 +0100 ++++ ./skeletons/BMPString.c 2015-11-26 14:42:08.487616728 +0100 +@@ -36,7 +36,8 @@ + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, /* Aligned PER decoder */ +- OCTET_STRING_encode_aper, /* Aligned PER encoder */ ++ OCTET_STRING_encode_aper, /* Aligned PER encoder */ ++ OCTET_STRING_compare, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_BMPString_tags, + sizeof(asn_DEF_BMPString_tags) +--- ./skeletons/BOOLEAN.c 2015-12-03 09:43:33.967009150 +0100 ++++ ./skeletons/BOOLEAN.c 2015-11-30 13:16:30.275264262 +0100 +@@ -25,7 +25,8 @@ + BOOLEAN_decode_uper, /* Unaligned PER decoder */ + BOOLEAN_encode_uper, /* Unaligned PER encoder */ + BOOLEAN_decode_aper, /* Aligned PER decoder */ +- BOOLEAN_encode_aper, /* Aligned PER encoder */ ++ BOOLEAN_encode_aper, /* Aligned PER encoder */ ++ BOOLEAN_compare, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_BOOLEAN_tags, + sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]), +@@ -326,3 +327,21 @@ + + _ASN_ENCODED_OK(er); + } ++ ++long ++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); ++} ++ +--- ./skeletons/BOOLEAN.h 2015-12-03 09:43:33.967009150 +0100 ++++ ./skeletons/BOOLEAN.h 2015-11-26 12:46:58.491623882 +0100 +@@ -30,6 +30,7 @@ + per_type_encoder_f BOOLEAN_encode_uper; + per_type_decoder_f BOOLEAN_decode_aper; + per_type_encoder_f BOOLEAN_encode_aper; ++type_compare_f BOOLEAN_compare; + + #ifdef __cplusplus + } +--- ./skeletons/compare.h 1970-01-01 01:00:00.000000000 +0100 ++++ ./skeletons/compare.h 2015-11-30 13:15:56.415264297 +0100 +@@ -0,0 +1,27 @@ ++/*- ++ * Eurecom 2015. ++ */ ++#ifndef _COMPARE_H_ ++#define _COMPARE_H_ ++ ++#include ++#include ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++struct asn_TYPE_descriptor_s; /* Forward declaration */ ++ ++typedef long (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 @@ + assert(pres_size != sizeof(int)); + } + } ++ ++long ++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; ++ ++ 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; ++ } ++ } ++ } ++ ++ /* ++ * Figure out which CHOICE element is encoded. ++ */ ++ present1 = _fetch_present_idx(sptr1, specs1->pres_offset,specs1->pres_size); ++ // same specs ++ present2 = _fetch_present_idx(sptr2, specs2->pres_offset,specs2->pres_size); ++ ++ if (td1->elements_count != td2->elements_count) return -1; ++ if (present1 != present2) return -1; ++ if(present1 > 0 && present1 <= td1->elements_count) { ++ asn_TYPE_member_t *elm1 = &td1->elements[present1-1]; ++ asn_TYPE_member_t *elm2 = &td2->elements[present2-1]; ++ const void *memb_ptr1; ++ const void *memb_ptr2; ++ ++ if((elm1->flags & ATF_POINTER) && (elm1->flags & ATF_POINTER)){ ++ memb_ptr1 = *(const void * const *)((const char *)sptr1 + elm1->memb_offset); ++ memb_ptr2 = *(const void * const *)((const char *)sptr2 + elm2->memb_offset); ++ if((!memb_ptr1) && (!memb_ptr2)) return -1; ++ if (!memb_ptr1) return -1; ++ if (!memb_ptr2) return -1; ++ } 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; ++ } ++ return elm1->type->compare(elm1->type, memb_ptr1, elm2->type, memb_ptr2); ++ } ++ return 0; ++} +--- ./skeletons/constr_CHOICE.h 2015-12-03 09:43:33.967009150 +0100 ++++ ./skeletons/constr_CHOICE.h 2015-11-26 14:43:57.647616615 +0100 +@@ -39,7 +39,7 @@ + /* + * A set specialized functions dealing with the CHOICE type. + */ +-asn_struct_free_f CHOICE_free; ++asn_struct_free_f CHOICE_free; + asn_struct_print_f CHOICE_print; + asn_constr_check_f CHOICE_constraint; + ber_type_decoder_f CHOICE_decode_ber; +@@ -50,7 +50,8 @@ + per_type_encoder_f CHOICE_encode_uper; + per_type_decoder_f CHOICE_decode_aper; + per_type_encoder_f CHOICE_encode_aper; +-asn_outmost_tag_f CHOICE_outmost_tag; ++type_compare_f CHOICE_compare; ++asn_outmost_tag_f CHOICE_outmost_tag; + + #ifdef __cplusplus + } +--- ./skeletons/constr_SEQUENCE.c 2015-12-03 09:43:33.967009150 +0100 ++++ ./skeletons/constr_SEQUENCE.c 2015-11-30 13:17:33.871264196 +0100 +@@ -1761,3 +1761,50 @@ + + _ASN_ENCODED_OK(er); + } ++ ++long ++SEQUENCE_compare(asn_TYPE_descriptor_t *td1, void *sptr1, asn_TYPE_descriptor_t *td2, void *sptr2) { ++ int edx; ++ int ret; ++ ++ if((!sptr1) && (!sptr2)) return -1; ++ 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; ++ } ++ } ++ } ++ ++ 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]; ++ const void *memb_ptr1; ++ const void *memb_ptr2; ++ ++ if(elm1->flags & ATF_POINTER) { ++ memb_ptr1 = *(const void * const *)((const char *)sptr1 + elm1->memb_offset); ++ memb_ptr2 = *(const void * const *)((const char *)sptr2 + elm2->memb_offset); ++ if((!memb_ptr1) && (!memb_ptr2)) { ++ if(elm1->optional) continue; ++ } ++ if (!memb_ptr1) return -1; ++ if (!memb_ptr2) return -1; ++ } 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; ++ } ++ return 0; ++} +--- ./skeletons/constr_SEQUENCE.h 2015-12-03 09:43:33.971009150 +0100 ++++ ./skeletons/constr_SEQUENCE.h 2015-11-26 14:48:14.123616350 +0100 +@@ -54,6 +54,7 @@ + per_type_encoder_f SEQUENCE_encode_uper; + per_type_decoder_f SEQUENCE_decode_aper; + per_type_encoder_f SEQUENCE_encode_aper; ++type_compare_f SEQUENCE_compare; + + #ifdef __cplusplus + } +--- ./skeletons/constr_SEQUENCE_OF.h 2015-12-03 09:43:33.963009150 +0100 ++++ ./skeletons/constr_SEQUENCE_OF.h 2015-11-26 15:05:25.399615282 +0100 +@@ -22,7 +22,8 @@ + #define SEQUENCE_OF_decode_ber SET_OF_decode_ber + #define SEQUENCE_OF_decode_xer SET_OF_decode_xer + #define SEQUENCE_OF_decode_uper SET_OF_decode_uper +-#define SEQUENCE_OF_decode_aper SET_OF_decode_aper ++#define SEQUENCE_OF_decode_aper SET_OF_decode_aper ++#define SEQUENCE_OF_compare SET_OF_compare + der_type_encoder_f SEQUENCE_OF_encode_der; + xer_type_encoder_f SEQUENCE_OF_encode_xer; + per_type_encoder_f SEQUENCE_OF_encode_uper; +--- ./skeletons/constr_SET.c 2015-12-03 09:43:33.963009150 +0100 ++++ ./skeletons/constr_SET.c 2015-11-30 13:17:49.903264180 +0100 +@@ -1108,7 +1108,7 @@ + } + } + +-int ++long + SET_constraint(asn_TYPE_descriptor_t *td, const void *sptr, + asn_app_constraint_failed_f *ctfailcb, void *app_key) { + int edx; +--- ./skeletons/constr_SET.h 2015-12-03 09:43:33.963009150 +0100 ++++ ./skeletons/constr_SET.h 2015-11-26 14:49:09.243616293 +0100 +@@ -56,6 +56,7 @@ + per_type_decoder_f SET_decode_aper; + per_type_encoder_f SET_encode_uper; + per_type_encoder_f SET_encode_aper; ++type_compare_f SET_compare; + + /*********************** + * Some handy helpers. * +--- ./skeletons/constr_SET_OF.c 2015-12-03 09:43:33.963009150 +0100 ++++ ./skeletons/constr_SET_OF.c 2015-11-30 13:17:42.099264188 +0100 +@@ -1039,3 +1039,46 @@ + rv.consumed = 0; + return rv; + } ++ ++long ++SET_OF_compare(asn_TYPE_descriptor_t *td1, void *sptr1, asn_TYPE_descriptor_t *td2, void *sptr2) ++{ ++ asn_TYPE_member_t *elm1 = td1->elements; ++ asn_TYPE_member_t *elm2 = td2->elements; ++ const asn_anonymous_set_ *list1 = _A_CSET_FROM_VOID(sptr1); ++ const asn_anonymous_set_ *list2 = _A_CSET_FROM_VOID(sptr2); ++ int ret; ++ int i; ++ ++ 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; ++ } ++ } ++ } ++ ++ if (td1->elements_count != td2->elements_count) return -1; ++ ++ ++ if (list1->count != list2->count ) return -1; ++ ++ 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; ++ } ++ ++ return 0; ++} +--- ./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 +@@ -36,6 +36,7 @@ + per_type_encoder_f SET_OF_encode_uper; + per_type_decoder_f SET_OF_decode_aper; + per_type_encoder_f SET_OF_encode_aper; ++type_compare_f SET_OF_compare; + + #ifdef __cplusplus + } +--- ./skeletons/constr_TYPE.h 2015-12-03 09:43:33.963009150 +0100 ++++ ./skeletons/constr_TYPE.h 2015-11-26 15:28:05.495613874 +0100 +@@ -41,7 +41,8 @@ + #include /* Encoder into XER (XML, text) */ + #include /* Packet Encoding Rules decoder */ + #include /* Packet Encoding Rules encoder */ +-#include /* Subtype constraints support */ ++#include /* Subtype constraints support */ ++#include /* Comparison */ + + /* + * Free the structure according to its specification. +@@ -101,6 +102,7 @@ + per_type_encoder_f *uper_encoder; /* Unaligned PER encoder */ + per_type_decoder_f *aper_decoder; /* Aligned PER decoder */ + per_type_encoder_f *aper_encoder; /* Aligned PER encoder */ ++ type_compare_f *compare; /* Comparison between 2 instances */ + + /*********************************************************************** + * Internally useful members. Not to be used by applications directly. * +--- ./skeletons/ENUMERATED.c 2015-12-03 09:43:33.963009150 +0100 ++++ ./skeletons/ENUMERATED.c 2015-11-30 13:18:05.399264164 +0100 +@@ -27,7 +27,8 @@ + ENUMERATED_decode_uper, /* Unaligned PER decoder */ + ENUMERATED_encode_uper, /* Unaligned PER encoder */ + ENUMERATED_decode_aper, /* Aligned PER decoder */ +- ENUMERATED_encode_aper, /* Aligned PER encoder */ ++ ENUMERATED_encode_aper, /* Aligned PER encoder */ ++ ENUMERATED_compare, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_ENUMERATED_tags, + sizeof(asn_DEF_ENUMERATED_tags) / sizeof(asn_DEF_ENUMERATED_tags[0]), +@@ -103,3 +104,22 @@ + + return NativeEnumerated_encode_aper(td, constraints, &value, po); + } ++ ++long ++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; ++ ++ 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); ++} ++ +--- ./skeletons/ENUMERATED.h 2015-12-03 09:43:33.963009150 +0100 ++++ ./skeletons/ENUMERATED.h 2015-11-26 12:46:35.523623906 +0100 +@@ -19,6 +19,7 @@ + per_type_encoder_f ENUMERATED_encode_uper; + per_type_decoder_f ENUMERATED_decode_aper; + per_type_encoder_f ENUMERATED_encode_aper; ++type_compare_f ENUMERATED_compare; + + #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 @@ + 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 +-constr_SET_OF.h constr_SET_OF.c asn_SET_OF.h ++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 +@@ -168,7 +168,8 @@ + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, +- OCTET_STRING_encode_aper, ++ OCTET_STRING_encode_aper, ++ OCTET_STRING_compare, + 0, /* Use generic outmost tag fetcher */ + 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 +@@ -25,7 +25,8 @@ + OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ + OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, +- OCTET_STRING_encode_aper, ++ OCTET_STRING_encode_aper, ++ OCTET_STRING_compare, + 0, /* Use generic outmost tag fetcher */ + 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 +@@ -25,7 +25,8 @@ + OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ + OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, +- OCTET_STRING_encode_aper, ++ OCTET_STRING_encode_aper, ++ OCTET_STRING_compare, + 0, /* Use generic outmost tag fetcher */ + 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 +@@ -31,6 +31,7 @@ + OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, + OCTET_STRING_encode_aper, ++ OCTET_STRING_compare, + 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 +@@ -35,6 +35,7 @@ + INTEGER_decode_aper, + INTEGER_encode_aper, + #endif /* ASN_DISABLE_PER_SUPPORT */ ++ INTEGER_compare, + 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 @@ + } + + ++long ++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; ++ } ++ } ++ } ++ if (st1->size != st2->size) return -1; ++ return memcmp(st1->buf, st2->buf, st1->size); ++} +--- ./skeletons/INTEGER.h 2015-12-03 09:43:33.967009150 +0100 ++++ ./skeletons/INTEGER.h 2015-11-26 12:50:41.551623651 +0100 +@@ -43,6 +43,7 @@ + per_type_encoder_f INTEGER_encode_uper; + per_type_decoder_f INTEGER_decode_aper; + per_type_encoder_f INTEGER_encode_aper; ++type_compare_f INTEGER_compare; + + /*********************************** + * 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 +@@ -30,7 +30,8 @@ + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, +- OCTET_STRING_encode_aper, ++ OCTET_STRING_encode_aper, ++ OCTET_STRING_compare, + 0, /* Use generic outmost tag fetcher */ + 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 @@ + ber_decoder.c ber_decoder.h \ + ber_tlv_length.c ber_tlv_length.h \ + ber_tlv_tag.c ber_tlv_tag.h \ +- constr_CHOICE.c constr_CHOICE.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 +@@ -31,7 +31,8 @@ + NativeEnumerated_decode_uper, + NativeEnumerated_encode_uper, + NativeEnumerated_decode_aper, +- NativeEnumerated_encode_aper, ++ NativeEnumerated_encode_aper, ++ NativeEnumerated_compare, + 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 @@ + + _ASN_ENCODED_OK(er); + } ++ ++long ++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; ++ } ++ } ++ } ++ ++ if(a->nat_value == b->nat_value) ++ return 0; ++ if(a->nat_value < b->nat_value) ++ return -1; ++ return 1; ++} +--- ./skeletons/NativeEnumerated.h 2015-12-03 09:43:33.967009150 +0100 ++++ ./skeletons/NativeEnumerated.h 2015-11-26 14:51:43.315616133 +0100 +@@ -26,6 +26,7 @@ + per_type_encoder_f NativeEnumerated_encode_uper; + per_type_decoder_f NativeEnumerated_decode_aper; + per_type_encoder_f NativeEnumerated_encode_aper; ++type_compare_f NativeEnumerated_compare; + + #ifdef __cplusplus + } +--- ./skeletons/NativeInteger.c 2015-12-03 09:43:33.967009150 +0100 ++++ ./skeletons/NativeInteger.c 2015-11-30 13:18:39.887264128 +0100 +@@ -32,7 +32,8 @@ + NativeInteger_decode_uper, /* Unaligned PER decoder */ + NativeInteger_encode_uper, /* Unaligned PER encoder */ + NativeInteger_decode_aper, /* Aligned PER decoder */ +- NativeInteger_encode_aper, /* Aligned PER encoder */ ++ NativeInteger_encode_aper, /* Aligned PER encoder */ ++ NativeInteger_compare, + 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 @@ + } + } + ++ ++long ++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); ++} +--- ./skeletons/NativeInteger.h 2015-12-03 09:43:33.971009150 +0100 ++++ ./skeletons/NativeInteger.h 2015-11-26 14:52:13.931616101 +0100 +@@ -31,6 +31,7 @@ + per_type_encoder_f NativeInteger_encode_uper; + per_type_decoder_f NativeInteger_decode_aper; + per_type_encoder_f NativeInteger_encode_aper; ++type_compare_f NativeInteger_compare; + + #ifdef __cplusplus + } +--- ./skeletons/NativeReal.c 2015-12-03 09:43:33.971009150 +0100 ++++ ./skeletons/NativeReal.c 2015-11-30 13:18:46.655264121 +0100 +@@ -33,7 +33,8 @@ + NativeReal_decode_uper, + NativeReal_encode_uper, + NativeReal_decode_aper, +- NativeReal_encode_aper, ++ NativeReal_encode_aper, ++ NativeReal_compare, + 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 @@ + } + } + ++long ++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; ++ ++ 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 (st1->size != st2->size) return -1; ++ return memcmp(st1->buf, st2->buf, st1->size); ++} +--- ./skeletons/NativeReal.h 2015-12-03 09:43:33.971009150 +0100 ++++ ./skeletons/NativeReal.h 2015-11-26 14:31:12.631617407 +0100 +@@ -29,6 +29,7 @@ + per_type_encoder_f NativeReal_encode_uper; + per_type_decoder_f NativeReal_decode_aper; + per_type_encoder_f NativeReal_encode_aper; ++type_compare_f NativeReal_compare; + + #ifdef __cplusplus + } +--- ./skeletons/NULL.c 2015-12-03 09:43:33.963009150 +0100 ++++ ./skeletons/NULL.c 2015-11-30 13:18:53.047264114 +0100 +@@ -26,7 +26,8 @@ + NULL_decode_uper, /* Unaligned PER decoder */ + NULL_encode_uper, /* Unaligned PER encoder */ + NULL_decode_aper, /* Aligned PER decoder */ +- NULL_encode_aper, /* Aligned PER encoder */ ++ NULL_encode_aper, /* Aligned PER encoder */ ++ NULL_compare, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_NULL_tags, + sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]), +@@ -192,3 +193,10 @@ + er.encoded = 0; + _ASN_ENCODED_OK(er); + } ++ ++long ++NULL_compare(asn_TYPE_descriptor_t *td1, void *sptr1, ++ asn_TYPE_descriptor_t *td2, void *sptr2) { ++ ++ return 0; ++} +--- ./skeletons/NULL.h 2015-12-03 09:43:33.963009150 +0100 ++++ ./skeletons/NULL.h 2015-11-26 14:53:03.875616050 +0100 +@@ -27,6 +27,7 @@ + per_type_encoder_f NULL_encode_uper; + per_type_decoder_f NULL_decode_aper; + per_type_encoder_f NULL_encode_aper; ++type_compare_f NULL_compare; + + #ifdef __cplusplus + } +--- ./skeletons/NumericString.c 2015-12-03 09:43:33.963009150 +0100 ++++ ./skeletons/NumericString.c 2015-11-26 14:40:39.407616820 +0100 +@@ -50,7 +50,8 @@ + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, +- OCTET_STRING_encode_aper, ++ OCTET_STRING_encode_aper, ++ OCTET_STRING_compare, + 0, /* Use generic outmost tag fetcher */ + 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 +@@ -25,7 +25,8 @@ + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, +- OCTET_STRING_encode_aper, ++ OCTET_STRING_encode_aper, ++ OCTET_STRING_compare, + 0, /* Use generic outmost tag fetcher */ + 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 +@@ -28,7 +28,8 @@ + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, +- OCTET_STRING_encode_aper, ++ OCTET_STRING_encode_aper, ++ OCTET_STRING_compare, + 0, /* Use generic outmost tag fetcher */ + 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 +@@ -37,7 +37,8 @@ + OCTET_STRING_decode_uper, /* Unaligned PER decoder */ + OCTET_STRING_encode_uper, /* Unaligned PER encoder */ + OCTET_STRING_decode_aper, /* Aligned PER decoder */ +- OCTET_STRING_encode_aper, /* Aligned PER encoder */ ++ OCTET_STRING_encode_aper, /* Aligned PER encoder */ ++ OCTET_STRING_compare, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_OCTET_STRING_tags, + sizeof(asn_DEF_OCTET_STRING_tags) +@@ -2160,3 +2161,21 @@ + return st; + } + ++long ++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; ++ ++ 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 (st1->size != st2->size) return -1; ++ return memcmp(st1->buf, st2->buf, st1->size); ++} +--- ./skeletons/OCTET_STRING.h 2015-12-03 09:43:33.971009150 +0100 ++++ ./skeletons/OCTET_STRING.h 2015-11-26 12:56:15.259623305 +0100 +@@ -34,6 +34,7 @@ + per_type_encoder_f OCTET_STRING_encode_uper; + per_type_decoder_f OCTET_STRING_decode_aper; + per_type_encoder_f OCTET_STRING_encode_aper; ++type_compare_f OCTET_STRING_compare; + + /****************************** + * 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 +@@ -60,7 +60,8 @@ + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, +- OCTET_STRING_encode_aper, ++ OCTET_STRING_encode_aper, ++ OCTET_STRING_compare, + 0, /* Use generic outmost tag fetcher */ + 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 +@@ -46,7 +46,8 @@ + REAL_decode_uper, + REAL_encode_uper, + REAL_decode_aper, +- REAL_encode_aper, ++ REAL_encode_aper, ++ REAL_compare, + 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 @@ + + return 0; + } ++ ++ ++long ++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; ++ ++ 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 (st1->size != st2->size) return -1; ++ return memcmp(st1->buf, st2->buf, st1->size); ++} +--- ./skeletons/REAL.h 2015-12-03 09:43:33.971009150 +0100 ++++ ./skeletons/REAL.h 2015-11-26 13:00:46.183623025 +0100 +@@ -23,6 +23,7 @@ + per_type_encoder_f REAL_encode_uper; + per_type_decoder_f REAL_decode_aper; + per_type_encoder_f REAL_encode_aper; ++type_compare_f REAL_compare; + + /*********************************** + * 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 +@@ -29,7 +29,8 @@ + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, +- OCTET_STRING_encode_aper, ++ OCTET_STRING_encode_aper, ++ OCTET_STRING_compare, + 0, /* Use generic outmost tag fetcher */ + 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 +@@ -25,7 +25,8 @@ + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, +- OCTET_STRING_encode_aper, ++ OCTET_STRING_encode_aper, ++ OCTET_STRING_compare, + 0, /* Use generic outmost tag fetcher */ + 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 +@@ -25,7 +25,8 @@ + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, +- OCTET_STRING_encode_aper, ++ OCTET_STRING_encode_aper, ++ OCTET_STRING_compare, + 0, /* Use generic outmost tag fetcher */ + 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 +@@ -36,7 +36,8 @@ + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, +- OCTET_STRING_encode_aper, ++ OCTET_STRING_encode_aper, ++ OCTET_STRING_compare, + 0, /* Use generic outmost tag fetcher */ + 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 +@@ -41,7 +41,8 @@ + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, +- OCTET_STRING_encode_aper, ++ OCTET_STRING_encode_aper, ++ OCTET_STRING_compare, + 0, /* Use generic outmost tag fetcher */ + 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 +@@ -27,6 +27,7 @@ + OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, + OCTET_STRING_encode_aper, ++ OCTET_STRING_compare, + 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 +@@ -25,7 +25,8 @@ + OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ + OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, +- OCTET_STRING_encode_aper, ++ OCTET_STRING_encode_aper, ++ OCTET_STRING_compare, + 0, /* Use generic outmost tag fetcher */ + 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 +@@ -30,7 +30,8 @@ + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, +- OCTET_STRING_encode_aper, ++ OCTET_STRING_encode_aper, ++ OCTET_STRING_compare, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_VisibleString_tags, + sizeof(asn_DEF_VisibleString_tags) diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c index 9a9cb881b1..1aab216428 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.c +++ b/openair3/TEST/EPC_TEST/play_scenario.c @@ -331,18 +331,18 @@ int et_compare_et_ip_to_net_ip_address(const et_ip_t * const ip, const net_ip_ad switch (ip->address_family) { case AF_INET: if (net_ip->ipv4) { - S1AP_DEBUG("%s(%s,%s)=%d\n",__FUNCTION__,ip->str, net_ip->ipv4_address, strcmp(ip->str, net_ip->ipv4_address)); + //S1AP_DEBUG("%s(%s,%s)=%d\n",__FUNCTION__,ip->str, net_ip->ipv4_address, strcmp(ip->str, net_ip->ipv4_address)); return strcmp(ip->str, net_ip->ipv4_address); } - S1AP_DEBUG("%s(%s,%s)=-1 (IP version (4) not matching)\n",__FUNCTION__,ip->str, net_ip->ipv4_address); + //S1AP_DEBUG("%s(%s,%s)=-1 (IP version (4) not matching)\n",__FUNCTION__,ip->str, net_ip->ipv4_address); return -1; break; case AF_INET6: if (net_ip->ipv6) { - S1AP_DEBUG("%s(%s,%s)=%d\n",__FUNCTION__,ip->str, net_ip->ipv4_address, strcmp(ip->str, net_ip->ipv6_address)); + //S1AP_DEBUG("%s(%s,%s)=%d\n",__FUNCTION__,ip->str, net_ip->ipv4_address, strcmp(ip->str, net_ip->ipv6_address)); return strcmp(ip->str, net_ip->ipv6_address); } - S1AP_DEBUG("%s(%s,%s)=-1 (IP version (6) not matching)\n",__FUNCTION__,ip->str, net_ip->ipv6_address); + //S1AP_DEBUG("%s(%s,%s)=-1 (IP version (6) not matching)\n",__FUNCTION__,ip->str, net_ip->ipv6_address); return -1; break; default: diff --git a/openair3/TEST/EPC_TEST/play_scenario_fsm.c b/openair3/TEST/EPC_TEST/play_scenario_fsm.c index b6ff0de859..1db9df632e 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_fsm.c +++ b/openair3/TEST/EPC_TEST/play_scenario_fsm.c @@ -87,6 +87,7 @@ void et_scenario_wait_rx_packet(et_packet_t * const packet) NULL, &packet->timer_id) < 0) { AssertFatal(0, " Can not start waiting RX event timer\n"); } + LOG_D(ENB_APP, "Waiting RX packet num %d\n", packet->packet_number); g_fsm_state = ET_FSM_STATE_WAITING_RX_EVENT; packet->status = ET_PACKET_STATUS_SCHEDULED_FOR_RECEIVING; } @@ -144,6 +145,7 @@ void et_scenario_schedule_tx_packet(et_packet_t * const packet) packet->sctp_hdr.u.data_hdr.payload.binary_stream_allocated_size, packet->sctp_hdr.u.data_hdr.stream); packet->status = ET_PACKET_STATUS_SENT; + g_scenario->next_packet = g_scenario->next_packet->next; g_fsm_state = ET_FSM_STATE_RUNNING; } break; @@ -161,8 +163,76 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_running(et_event_t event) switch (event.code){ case ET_EVENT_TICK: - //TODO + while (NULL != g_scenario->next_packet) { + LOG_D(ENB_APP, "EVENT_TICK: Considering packet num %d:\n", g_scenario->next_packet->packet_number); + switch (g_scenario->next_packet->sctp_hdr.chunk_type) { + case SCTP_CID_DATA : + // no init in this scenario, may be sub-scenario + if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_SEND) { + if (g_scenario->next_packet->status == ET_PACKET_STATUS_NONE) { + et_scenario_schedule_tx_packet(g_scenario->next_packet); + pthread_mutex_unlock(&g_fsm_lock); + et_event_t continue_event; + continue_event.code = ET_EVENT_TICK; + et_scenario_fsm_notify_event(continue_event); + + return g_fsm_state; + } else if (g_scenario->next_packet->status != ET_PACKET_STATUS_SCHEDULED_FOR_SENDING) { + AssertFatal(0, "Invalid packet status %d", g_scenario->next_packet->status); + } + } else if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { + if (g_scenario->next_packet->status == ET_PACKET_STATUS_RECEIVED) { + g_scenario->next_packet = g_scenario->next_packet->next; + + } else if (g_scenario->next_packet->status == ET_PACKET_STATUS_NONE) { + et_scenario_wait_rx_packet(g_scenario->next_packet); + pthread_mutex_unlock(&g_fsm_lock); + return g_fsm_state; + } else { + AssertFatal(0, "Invalid packet status %d", g_scenario->next_packet->status); + } + } else { + AssertFatal(0, "Invalid packet action %d", g_scenario->next_packet->action); + } + break; + + case SCTP_CID_INIT: + case SCTP_CID_INIT_ACK: + case SCTP_CID_HEARTBEAT: + case SCTP_CID_HEARTBEAT_ACK: + case SCTP_CID_COOKIE_ECHO: + case SCTP_CID_COOKIE_ACK: + case SCTP_CID_ECN_ECNE: + case SCTP_CID_ECN_CWR: + LOG_D(ENB_APP, "EVENT_TICK: Ignoring packet num %d SCTP CID %s\n", + g_scenario->next_packet->packet_number, + et_chunk_type_cid2str(g_scenario->next_packet->sctp_hdr.chunk_type)); + g_scenario->next_packet->status = ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT; + g_scenario->next_packet = g_scenario->next_packet->next; + break; + + case SCTP_CID_ABORT: + case SCTP_CID_SHUTDOWN: + case SCTP_CID_SHUTDOWN_ACK: + case SCTP_CID_ERROR: + case SCTP_CID_SHUTDOWN_COMPLETE: + AssertFatal(0, "The scenario should be cleaned (packet %s cannot be processed at this time)", + et_chunk_type_cid2str(g_scenario->next_packet->sctp_hdr.chunk_type)); + break; + + default: + LOG_D(ENB_APP, "EVENT_TICK: Ignoring packet num %d SCTP CID %s\n", + g_scenario->next_packet->packet_number, + et_chunk_type_cid2str(g_scenario->next_packet->sctp_hdr.chunk_type)); + g_scenario->next_packet->status = ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT; + g_scenario->next_packet = g_scenario->next_packet->next; + } + } + fprintf(stderr, "No Packet found in this scenario: %s\n", g_scenario->name); + g_fsm_state = ET_FSM_STATE_NULL; + pthread_mutex_unlock(&g_fsm_lock); + return g_fsm_state; break; case ET_EVENT_RX_PACKET_TIME_OUT: AssertFatal(0, "Event ET_EVENT_RX_PACKET_TIME_OUT not handled in FSM state ET_FSM_STATE_RUNNING"); @@ -186,6 +256,7 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_waiting_tx(et_event_t event) int rv = 0; switch (event.code){ case ET_EVENT_TICK: + fprintf(stdout, "EVENT_TICK: waiting for tx event\n"); break; case ET_EVENT_RX_S1AP: @@ -202,6 +273,7 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_waiting_tx(et_event_t event) event.u.tx_timed_packet->sctp_hdr.u.data_hdr.payload.binary_stream_allocated_size, event.u.tx_timed_packet->sctp_hdr.u.data_hdr.stream); event.u.tx_timed_packet->status = ET_PACKET_STATUS_SENT; + g_scenario->next_packet = event.u.tx_timed_packet->next; g_fsm_state = ET_FSM_STATE_RUNNING; break; @@ -219,6 +291,7 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_waiting_rx(et_event_t event) int rv = 0; switch (event.code){ case ET_EVENT_TICK: + fprintf(stdout, "EVENT_TICK: waiting for rx event\n"); break; case ET_EVENT_RX_PACKET_TIME_OUT: @@ -272,7 +345,6 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_connecting_s1c(et_event_t even } else if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { if (g_scenario->next_packet->status == ET_PACKET_STATUS_RECEIVED) { g_scenario->last_rx_packet = g_scenario->next_packet; - g_scenario->next_packet = g_scenario->next_packet->next; g_scenario->time_last_rx_packet = g_scenario->last_rx_packet->timestamp_packet; g_scenario->next_packet = g_scenario->next_packet->next; @@ -357,7 +429,6 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_null(et_event_t event) } else if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { if (g_scenario->next_packet->status == ET_PACKET_STATUS_RECEIVED) { g_scenario->last_rx_packet = g_scenario->next_packet; - g_scenario->next_packet = g_scenario->next_packet->next; g_scenario->time_last_rx_packet = g_scenario->last_rx_packet->timestamp_packet; g_scenario->next_packet = g_scenario->next_packet->next; diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c index 336dc547d5..142ab069e9 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c @@ -250,9 +250,24 @@ et_packet_t* et_build_packet_from_s1ap_data_ind(et_event_s1ap_data_ind_t * const // return 0 if packet was waited int et_scenario_set_packet_received(et_packet_t * const packet) { - int rc = 0; + et_packet_t * p = NULL; + int rc = 0; + packet->status = ET_PACKET_STATUS_RECEIVED; S1AP_DEBUG("Packet num %d received\n", packet->packet_number); + + p = g_scenario->last_rx_packet; + while (NULL != p) { + if (p->action == ET_PACKET_ACTION_S1C_RECEIVE) { + if (p->status == ET_PACKET_STATUS_RECEIVED) { + g_scenario->last_rx_packet = p; + } else { + break; + } + } + p = p->next; + } + if (packet->timer_id != 0) { rc = timer_remove(packet->timer_id); AssertFatal(rc == 0, "TODO: Debug Timer on Rx packet num %d unknown", packet->packet_number); @@ -278,6 +293,7 @@ int et_s1ap_process_rx_packet(et_event_s1ap_data_ind_t * const s1ap_data_ind) if (packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { if (packet->status == ET_PACKET_STATUS_RECEIVED) { g_scenario->last_rx_packet = packet; + g_scenario->time_last_rx_packet = g_scenario->last_rx_packet->timestamp_packet; } else { break; } @@ -286,7 +302,7 @@ int et_s1ap_process_rx_packet(et_event_s1ap_data_ind_t * const s1ap_data_ind) } packet = g_scenario->list_packet; } else { - packet = g_scenario->last_rx_packet; + packet = g_scenario->last_rx_packet->next; } // not_found threshold may sure depend on number of mme, may be not sure on number of UE while ((NULL != packet) && (not_found < 5)) { @@ -308,8 +324,8 @@ int et_s1ap_process_rx_packet(et_event_s1ap_data_ind_t * const s1ap_data_ind) not_found += 1; packet = packet->next; } - S1AP_DEBUG("Rx packet not found in scenario:\n"); et_display_packet_sctp(&rx_packet->sctp_hdr); + AssertFatal(0, "Rx packet not found in scenario (see dump above)"); return -1; } From afa23c829b015c6a024e04fc7e9e0db4f92e1148 Mon Sep 17 00:00:00 2001 From: gauthier Date: Fri, 4 Dec 2015 16:12:49 +0100 Subject: [PATCH 17/47] Timings seems to be OK, (to be checked more accurately) --- openair3/TEST/EPC_TEST/play_scenario.h | 10 +++---- openair3/TEST/EPC_TEST/play_scenario_fsm.c | 30 ++++++++++++++++---- openair3/TEST/EPC_TEST/play_scenario_parse.c | 1 + openair3/TEST/EPC_TEST/play_scenario_s1ap.c | 29 +++++++++++++------ 4 files changed, 51 insertions(+), 19 deletions(-) diff --git a/openair3/TEST/EPC_TEST/play_scenario.h b/openair3/TEST/EPC_TEST/play_scenario.h index 604d0000bc..a926ea55e4 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.h +++ b/openair3/TEST/EPC_TEST/play_scenario.h @@ -344,11 +344,11 @@ typedef struct et_scenario_s { hash_table_t *hash_mme2association_id; hash_table_t *hash_old_ue_mme_id2ue_mme_id; - struct timeval time_last_tx_packet; - struct timeval time_last_rx_packet; - et_packet_t *last_rx_packet; // last packet received with all previous scenario RX packet received. - et_packet_t *last_tx_packet; // last sent packet - et_packet_t *next_packet; // next packet to be handled in the scenario (RX or TX packet) + struct timeval time_last_tx_packet; // Time last sent packet + struct timeval time_last_rx_packet; // Time last packet received with all previous scenario RX packet received. + et_packet_t *last_rx_packet; // Last packet received with all previous scenario RX packet received. + et_packet_t *last_tx_packet; // Last sent packet + et_packet_t *next_packet; // Next packet to be handled in the scenario (RX or TX packet) } et_scenario_t; diff --git a/openair3/TEST/EPC_TEST/play_scenario_fsm.c b/openair3/TEST/EPC_TEST/play_scenario_fsm.c index 1db9df632e..b76d2240f5 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_fsm.c +++ b/openair3/TEST/EPC_TEST/play_scenario_fsm.c @@ -55,17 +55,19 @@ uint32_t g_constraints = ET_BIT_MASK_MATCH_SCTP_STREAM | ET_BIT_MASK_MA int timeval_subtract (struct timeval * const result, struct timeval * const a, struct timeval * const b) { struct timeval b2; + int nsec = 0; b2.tv_sec = b->tv_sec; b2.tv_usec = b->tv_usec; + /* Perform the carry for the later subtraction by updating y. */ if (a->tv_usec < b2.tv_usec) { - int nsec = (b2.tv_usec - a->tv_usec) / 1000000 + 1; + nsec = (b2.tv_usec - a->tv_usec) / 1000000 + 1; b2.tv_usec -= 1000000 * nsec; b2.tv_sec += nsec; } if (a->tv_usec - b2.tv_usec > 1000000) { - int nsec = (a->tv_usec - b2.tv_usec) / 1000000; + nsec = (a->tv_usec - b2.tv_usec) / 1000000; b2.tv_usec += 1000000 * nsec; b2.tv_sec -= nsec; } @@ -75,7 +77,8 @@ int timeval_subtract (struct timeval * const result, struct timeval * const a, s result->tv_sec = a->tv_sec - b2.tv_sec; result->tv_usec = a->tv_usec - b2.tv_usec; - /* Return 1 if result is negative. */ + LOG_D(ENB_APP, "timeval_subtract(%ld.%06d, %ld.%06d)=%ld.%06d\n", a->tv_sec, a->tv_usec, b->tv_sec, b->tv_usec, result->tv_sec, result->tv_usec); + return a->tv_sec < b2.tv_sec; } @@ -117,15 +120,22 @@ void et_scenario_schedule_tx_packet(et_packet_t * const packet) AssertFatal(gettimeofday(&now, NULL) == 0, "gettimeofday failed"); timeval_subtract(&offset_last_tx_packet,&now,&g_scenario->time_last_tx_packet); timeval_subtract(&offset_last_rx_packet,&now,&g_scenario->time_last_rx_packet); + LOG_D(ENB_APP, "offset_last_tx_packet=%ld.%06d\n", offset_last_tx_packet.tv_sec, offset_last_tx_packet.tv_usec); + LOG_D(ENB_APP, "offset_last_rx_packet=%ld.%06d\n", offset_last_rx_packet.tv_sec, offset_last_rx_packet.tv_usec); + last_packet_was_tx = timeval_subtract(&offset_tx_rx,&offset_last_tx_packet,&offset_last_rx_packet); if (last_packet_was_tx) { + LOG_D(ENB_APP, "last_packet_was_tx\n"); we_are_too_early = timeval_subtract(&offset,&offset_last_tx_packet,&packet->time_relative_to_last_sent_packet); + LOG_D(ENB_APP, "we_are_too_early=%d, offset=%ld.%06d\n", we_are_too_early, offset.tv_sec, offset.tv_usec); } else { + LOG_D(ENB_APP, "last_packet_was_rx\n"); we_are_too_early = timeval_subtract(&offset,&offset_last_rx_packet,&packet->time_relative_to_last_received_packet); + LOG_D(ENB_APP, "we_are_too_early=%d, offset=%ld.%06d\n", we_are_too_early, offset.tv_sec, offset.tv_usec); } if (we_are_too_early > 0) { // set timer - LOG_D(ENB_APP, "Send packet num %u original frame number %u in %ld.%d sec\n", + LOG_D(ENB_APP, "Send packet num %u original frame number %u in %ld.%06d sec\n", packet->packet_number, packet->original_frame_number, offset.tv_sec, offset.tv_usec); packet->status = ET_PACKET_STATUS_SCHEDULED_FOR_SENDING; @@ -138,6 +148,10 @@ void et_scenario_schedule_tx_packet(et_packet_t * const packet) LOG_D(ENB_APP, "Send packet num %u original frame number %u immediately\n", packet->packet_number, packet->original_frame_number); // send immediately AssertFatal(0 == gettimeofday(&packet->timestamp_packet, NULL), "gettimeofday() Failed"); + + g_scenario->time_last_tx_packet.tv_sec = packet->timestamp_packet.tv_sec; + g_scenario->time_last_tx_packet.tv_usec = packet->timestamp_packet.tv_usec; + et_s1ap_eNB_itti_send_sctp_data_req( packet->enb_instance, packet->sctp_hdr.u.data_hdr.assoc_id, @@ -266,6 +280,10 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_waiting_tx(et_event_t event) case ET_EVENT_TX_TIMED_PACKET: // send immediately AssertFatal(0 == gettimeofday(&event.u.tx_timed_packet->timestamp_packet, NULL), "gettimeofday() Failed"); + + g_scenario->time_last_tx_packet.tv_sec = event.u.tx_timed_packet->timestamp_packet.tv_sec; + g_scenario->time_last_tx_packet.tv_usec = event.u.tx_timed_packet->timestamp_packet.tv_usec; + et_s1ap_eNB_itti_send_sctp_data_req( event.u.tx_timed_packet->enb_instance, event.u.tx_timed_packet->sctp_hdr.u.data_hdr.assoc_id, @@ -325,8 +343,7 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_connecting_s1c(et_event_t even break; case ET_EVENT_S1C_CONNECTED: - // hack simulate we have been able to get the right timing values - AssertFatal(gettimeofday(&g_scenario->time_last_tx_packet, NULL) == 0, "gettimeofday failed"); + // hack simulate we have been able to get the right timing values for STCP connect AssertFatal(gettimeofday(&g_scenario->time_last_rx_packet, NULL) == 0, "gettimeofday failed"); while (NULL != g_scenario->next_packet) { @@ -452,6 +469,7 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_null(et_event_t event) // Try to register each eNB g_scenario->registered_enb = 0; g_fsm_state = ET_FSM_STATE_CONNECTING_S1C; + AssertFatal(gettimeofday(&g_scenario->time_last_tx_packet, NULL) == 0, "gettimeofday failed"); et_eNB_app_register (g_scenario->enb_properties); pthread_mutex_unlock(&g_fsm_lock); return g_fsm_state; diff --git a/openair3/TEST/EPC_TEST/play_scenario_parse.c b/openair3/TEST/EPC_TEST/play_scenario_parse.c index cb302f229a..496102449a 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_parse.c +++ b/openair3/TEST/EPC_TEST/play_scenario_parse.c @@ -343,6 +343,7 @@ et_packet_t* et_parse_xml_packet(xmlDocPtr doc, xmlNodePtr node) { xml_char = xmlGetProp(node, (const xmlChar *)"action"); packet->action = et_action_str2et_action_t(xml_char); + packet->status = ET_PACKET_STATUS_NONE; xmlFree(xml_char); packet->packet_number = packet_number++; diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c index 142ab069e9..df26de97c2 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c @@ -254,13 +254,18 @@ int et_scenario_set_packet_received(et_packet_t * const packet) int rc = 0; packet->status = ET_PACKET_STATUS_RECEIVED; - S1AP_DEBUG("Packet num %d received\n", packet->packet_number); + S1AP_DEBUG("Packet received: num %u | original frame number %u \n", packet->packet_number, packet->original_frame_number); + S1AP_DEBUG("Last Packet received: num %u | original frame number %u \n", g_scenario->last_rx_packet->packet_number, g_scenario->last_rx_packet->original_frame_number); p = g_scenario->last_rx_packet; while (NULL != p) { - if (p->action == ET_PACKET_ACTION_S1C_RECEIVE) { - if (p->status == ET_PACKET_STATUS_RECEIVED) { + if (ET_PACKET_ACTION_S1C_RECEIVE == p->action) { + if ((ET_PACKET_STATUS_RECEIVED == p->status) || (ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT == p->status)) { g_scenario->last_rx_packet = p; + g_scenario->time_last_rx_packet.tv_sec = p->timestamp_packet.tv_sec; + g_scenario->time_last_rx_packet.tv_usec = p->timestamp_packet.tv_usec; + S1AP_DEBUG("Set Last Packet received: num %u | original frame number %u \n", g_scenario->last_rx_packet->packet_number, g_scenario->last_rx_packet->original_frame_number); + S1AP_DEBUG("Set time_last_rx_packet %ld.%06d\n", g_scenario->time_last_rx_packet.tv_sec, g_scenario->time_last_rx_packet.tv_usec); } else { break; } @@ -268,7 +273,7 @@ int et_scenario_set_packet_received(et_packet_t * const packet) p = p->next; } - if (packet->timer_id != 0) { + if (0 != packet->timer_id) { rc = timer_remove(packet->timer_id); AssertFatal(rc == 0, "TODO: Debug Timer on Rx packet num %d unknown", packet->packet_number); return rc; @@ -291,9 +296,14 @@ int et_s1ap_process_rx_packet(et_event_s1ap_data_ind_t * const s1ap_data_ind) packet = g_scenario->list_packet; while (NULL != packet) { if (packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { - if (packet->status == ET_PACKET_STATUS_RECEIVED) { + if ((ET_PACKET_STATUS_RECEIVED == packet->status) || (ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT == packet->status)) { g_scenario->last_rx_packet = packet; - g_scenario->time_last_rx_packet = g_scenario->last_rx_packet->timestamp_packet; + if (ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT != packet->status) { + g_scenario->time_last_rx_packet.tv_sec = packet->timestamp_packet.tv_sec; + g_scenario->time_last_rx_packet.tv_usec = packet->timestamp_packet.tv_usec; + } + S1AP_DEBUG("Set Last Packet received: num %u | original frame number %u \n", g_scenario->last_rx_packet->packet_number, g_scenario->last_rx_packet->original_frame_number); + S1AP_DEBUG("Set time_last_rx_packet %ld.%06d\n", g_scenario->time_last_rx_packet.tv_sec, g_scenario->time_last_rx_packet.tv_usec); } else { break; } @@ -309,10 +319,13 @@ int et_s1ap_process_rx_packet(et_event_s1ap_data_ind_t * const s1ap_data_ind) 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) { - S1AP_DEBUG("Compare RX packet with packet num %d succeeded\n", packet->packet_number); + 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 %d failed %s\n", packet->packet_number, et_error_match2str(rv)); + 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)) { From 1b86363795b0931fc47d78899e9d079df659f408 Mon Sep 17 00:00:00 2001 From: gauthier Date: Tue, 8 Dec 2015 15:08:02 +0100 Subject: [PATCH 18/47] 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 9c5bbad0de..a562a5ebc0 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 cf3553c362..3986a6a83b 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 -+#include + +#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 /* Encoder into XER (XML, text) */ #include /* 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 (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/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 (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/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 (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/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 f5daf03c25..446266d6a3 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 1aab216428..133e9adf4b 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 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 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 Directory where a set of files related to a particular test are located\n"); fprintf (stdout, "\t-c | --enb-conf-file Provide an eNB config file, valid for the testbed\n"); fprintf (stdout, "\t-s | --scenario 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 a926ea55e4..f44974dae0 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 df26de97c2..d58b16c2d3 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 5300476e98..213be2b347 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 07206f53b8..181009c2c9 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; } From 3e3bdd9ef23c6c3a3738021f3f288509dda30903 Mon Sep 17 00:00:00 2001 From: gauthier Date: Tue, 15 Dec 2015 13:19:00 +0100 Subject: [PATCH 19/47] Removed from this repo epc xsl files, commiting for sync --- cmake_targets/tools/build_helper | 179 ++++++++- cmake_targets/tools/build_test_epc_tools | 1 - openair3/TEST/EPC_TEST/generate_scenario.c | 17 +- openair3/TEST/EPC_TEST/generic_scenario.xsl | 312 ---------------- openair3/TEST/EPC_TEST/mme_test_s1_pcap2pdml | 104 ------ openair3/TEST/EPC_TEST/play_scenario.c | 6 - openair3/TEST/EPC_TEST/play_scenario.h | 3 +- openair3/TEST/EPC_TEST/play_scenario.xsl | 113 ------ openair3/TEST/EPC_TEST/play_scenario_parse.c | 13 +- openair3/TEST/EPC_TEST/play_scenario_s1ap.c | 14 +- .../EPC_TEST/play_scenario_s1ap_compare_ie.c | 351 ++++++++++++++++++ .../enb.band7.tm1.usrpb210.epc.local.conf | 12 +- 12 files changed, 557 insertions(+), 568 deletions(-) delete mode 100644 openair3/TEST/EPC_TEST/generic_scenario.xsl delete mode 100755 openair3/TEST/EPC_TEST/mme_test_s1_pcap2pdml delete mode 100644 openair3/TEST/EPC_TEST/play_scenario.xsl diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 350dae86a6..0a0118581e 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -30,7 +30,7 @@ ################################################################################ # file build_helper # brief -# author Laurent Thomas +# authors Laurent Thomas, Lionel GAUTHIER # ####################################### SUDO='sudo -E' @@ -301,6 +301,183 @@ install_nas_tools() { fi } +################################################# +# 3. Network interfaces utilities +################################################ + +cidr2mask(){ + local i mask="" + local full_octets=$(($1/8)) + local partial_octet=$(($1%8)) + + for ((i=0;i<4;i+=1)); do + if [ $i -lt $full_octets ]; then + mask+=255 + elif [ $i -eq $full_octets ]; then + mask+=$((256 - 2**(8-$partial_octet))) + else + mask+=0 + fi + test $i -lt 3 && mask+=. + done + + echo $mask +} + +# example: netcalc 192.168.12.100 255.255.255.0 +netcalc(){ + local IFS='.' ip i + local -a oct msk + + read -ra oct <<<"$1" + read -ra msk <<<"$2" + + for i in ${!oct[@]}; do + ip+=( "$(( oct[i] & msk[i] ))" ) + done + + echo "${ip[*]}" +} + +# example: +bcastcalc(){ + local IFS='.' ip i + local -a oct msk + + read -ra oct <<<"$1" + read -ra msk <<<"$2" + + for i in ${!oct[@]}; do + ip+=( "$(( oct[i] + ( 255 - ( oct[i] | msk[i] ) ) ))" ) + done + echo "${ip[*]}" +} + + +is_real_interface(){ + my_bool=1 + for var in "$@" + do + if [ "a$var" == "a" ]; then + return 0 + fi + if [ "a$var" == "anone" ]; then + return 0 + fi + IF=`cat /etc/udev/rules.d/70-persistent-net.rules | grep $var | sed 's/^.*NAME=//' | tr -d '"'` + if [ "$IF" == "$var" ]; then + if [ "a${var:0:3}" != "aeth" ]; then + if [ "a${var:0:4}" != "awlan" ]; then + if [ "a${var:0:4}" != "awifi" ]; then + my_bool=0; + fi + fi + fi + fi + done + return $my_bool +} + +is_virtual_interface(){ + my_bool=1 + for var in "$@" + do + if [ "a$var" == "a" ]; then + return 0 + fi + if [ "a$var" == "anone" ]; then + return 0 + fi + num=`expr index "$var" :` + + if [ $num -eq 0 ]; then + my_bool=0; + fi + done + return $my_bool +} + +# arg1 = interface name +# arg2 = ipv4 addr cidr +set_interface_up(){ + interface=$1 + address=${2%/*} #part before '/' + cidr_netmask=${2#*/} # part after '/' + + if [ "a${interface:0:4}" == "anone" ]; then + return; + fi + echo "ifconfig $interface up" + $SUDO ifconfig $interface up + sync + netmask=`cidr2mask $cidr_netmask` + broadcast=`bcastcalc $address $netmask` + echo "ip -4 addr add $address/$cidr_netmask broadcast $broadcast dev $interface" + $SUDO ip -4 addr add $address/$cidr_netmask broadcast $broadcast dev $interface + sync +} + +# arg1 = interface name +# arg2 = ipv4 addr cidr +set_virtual_interface_up(){ + interface=$1 + address=${2%/*} #part before '/' + cidr_netmask=${2#*/} # part after '/' + + if [ "a${interface:0:4}" == "anone" ]; then + return; + fi + $SUDO ifconfig $interface down > /dev/null 2>&1 + sync + echo "ifconfig $interface $address up" + $SUDO ifconfig $interface $address up + sync +} + +#arg1 is interface name +#arg2 is IP address (CIDR) +set_network_interface(){ + local interface_name=$1 + local ip_cidr=$2 + + is_virtual_interface $interface_name + if [ $? -eq 1 ]; then + echo "$interface_name is virtual interface" + set_virtual_interface_up $interface_name $ip_cidr + else + is_real_interface $interface_name + if [ $? -eq 1 ]; then + echo "$interface_name is real interface" + set_interface_up $interface_name $ip_cidr + else + echo_warning "$interface_name not handled, not configuring it" + return + fi + fi +} + +# arg1 is a 'libconfig-like' config file +set_epc_network_interfaces(){ + value="`cat $1 | cut -d "#" -f1 | grep 'ADDRESS\|INTERFACE' | tr -d " " | grep "="`" + eval $value + + # check all var names are correct + list_var_name="\ + ENB_INTERFACE_NAME_FOR_S1_MME ENB_IPV4_ADDRESS_FOR_S1_MME \ + ENB_INTERFACE_NAME_FOR_S1U ENB_IPV4_ADDRESS_FOR_S1U " + for var_name in $list_var_name + do + if [ -n "$${var_name}" ]; then + echo_success "Found ${var_name} = ${!var_name}" + else + echo_fatal "${var_name} does does not exist in your config file $1" + fi + done + + # configure interfaces + set_network_interface $ENB_INTERFACE_NAME_FOR_S1_MME $ENB_IPV4_ADDRESS_FOR_S1_MME + set_network_interface $ENB_INTERFACE_NAME_FOR_S1U $ENB_IPV4_ADDRESS_FOR_S1U +} diff --git a/cmake_targets/tools/build_test_epc_tools b/cmake_targets/tools/build_test_epc_tools index b67cf15810..aa7103fd78 100755 --- a/cmake_targets/tools/build_test_epc_tools +++ b/cmake_targets/tools/build_test_epc_tools @@ -148,7 +148,6 @@ function main() $SUDO cp -upv test_epc_generate_scenario /usr/local/bin $SUDO cp -upv test_epc_play_scenario /usr/local/bin - $SUDO cp -upv $OPENAIR_DIR/openair3/TEST/EPC_TEST/mme_test_s1_pcap2pdml /usr/local/bin } diff --git a/openair3/TEST/EPC_TEST/generate_scenario.c b/openair3/TEST/EPC_TEST/generate_scenario.c index 9f4e16baef..238ba0ff11 100644 --- a/openair3/TEST/EPC_TEST/generate_scenario.c +++ b/openair3/TEST/EPC_TEST/generate_scenario.c @@ -97,7 +97,6 @@ #define ENB_CONFIG_MAX_XSLT_PARAMS 32 Enb_properties_array_t g_enb_properties; -char *g_openair_dir = NULL; char *g_test_dir = NULL; char *g_pdml_in_origin = NULL; extern int xmlLoadExtDtdDefaultValue; @@ -195,17 +194,13 @@ int generate_test_scenario(const char const * test_nameP, const char const * pdm exit(1); } - memset(astring, 0, sizeof(astring)); - strcat(astring, g_openair_dir); - strcat(astring, "/openair3/TEST/EPC_TEST/generic_scenario.xsl"); - xmlSubstituteEntitiesDefault(1); xmlLoadExtDtdDefaultValue = 1; - cur = xsltParseStylesheetFile(astring); + cur = xsltParseStylesheetFile("/usr/share/oai/xsl/generic_scenario.xsl"); if (NULL == cur) { - AssertFatal (0, "Could not parse stylesheet file %s (check OPENAIR_DIR env variable)!\n", astring); + AssertFatal (0, "Could not parse stylesheet file /usr/share/oai/xsl/generic_scenario.xsl!\n"); } else { - fprintf(stdout, "XSLT style sheet: %s\n", astring); + fprintf(stdout, "XSLT style sheet: /usr/share/oai/xsl/generic_scenario.xsl\n"); } doc = xmlParseFile(pdml_in_basenameP); @@ -686,12 +681,6 @@ int main( int argc, char **argv ) { int actions = 0; - g_openair_dir = getenv("OPENAIR_DIR"); - if (NULL == g_openair_dir) { - fprintf(stderr, "Error: Could not get OPENAIR_DIR environment variable\n"); - exit(1); - } - memset((char*) &g_enb_properties, 0 , sizeof(g_enb_properties)); actions = config_parse_opt_line (argc, argv); //Command-line options diff --git a/openair3/TEST/EPC_TEST/generic_scenario.xsl b/openair3/TEST/EPC_TEST/generic_scenario.xsl deleted file mode 100644 index 592bef83d4..0000000000 --- a/openair3/TEST/EPC_TEST/generic_scenario.xsl +++ /dev/null @@ -1,312 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - enb0_s1c - enb1_s1c - enb2_s1c - enb3_s1c - enb4_s1c - enb5_s1c - enb6_s1c - enb7_s1c - mme0_s1c_0 - mme0_s1c_1 - mme0_s1c_2 - mme0_s1c_3 - mme1_s1c_0 - mme1_s1c_1 - mme1_s1c_2 - mme1_s1c_3 - mme2_s1c_0 - mme2_s1c_1 - mme2_s1c_2 - mme2_s1c_3 - mme3_s1c_0 - mme3_s1c_1 - mme3_s1c_2 - mme3_s1c_3 - - ERROR: Cannot reverse resolv IP ! - - - - - - - - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - - ERROR: Cannot set eNB instance ! - - - - - - - - - - - DATA - INIT - INIT_ACK - SACK - HEARTBEAT - HEARTBEAT_ACK - ABORT - SHUTDOWN - SHUTDOWN_ACK - ERROR - COOKIE_ECHO - COOKIE_ACK - ECNE - CWR - SHUTDOWN_COMPLETE - - ERROR: UNKNOWN CHUNK TYPE ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SEND - RECEIVE - - ERROR: UNKNOWN ACTION ! - - - - - - - - - - - - - - - - - - ERROR: UNKNOWN ACTION ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/openair3/TEST/EPC_TEST/mme_test_s1_pcap2pdml b/openair3/TEST/EPC_TEST/mme_test_s1_pcap2pdml deleted file mode 100755 index 796fa9a45b..0000000000 --- a/openair3/TEST/EPC_TEST/mme_test_s1_pcap2pdml +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -import sys -import subprocess -import re -import socket -import datetime -from datetime import date -import os, errno -import argparse -import tempfile -from lxml import etree -from xml.dom.minidom import parse, parseString - -##################### -# program arguments -##################### -parser = argparse.ArgumentParser() -parser.add_argument("--pcap_file", "-p", type=str,help="input pcap file to be translated") -args = parser.parse_args() - -##################### -# get xml document from pcap -##################### -orig_pcap_file_name = args.pcap_file.strip() -orig_pdml_string = subprocess.check_output(["tshark", '-T', 'pdml', '-r', orig_pcap_file_name]) - -orig_dom = parseString(orig_pdml_string) - -##################### -# filtering unwanted packets -##################### -#cases = orig_etree.findall(".//proto[@name='sctp']") -packets = orig_dom.getElementsByTagName("packet") -for packet in packets: - found_sctp = False - found_s1ap = False - sctp_node = None - frame_node = None - ip_node = None - protos = packet.getElementsByTagName("proto") - for proto in protos: - attrs = proto.attributes - urlnode = attrs['name'] - if urlnode.nodeValue == 'frame': - frame_node = proto - elif urlnode.nodeValue == 'ip': - frame_node.appendChild(proto) - ip_node = proto - elif urlnode.nodeValue == 'sctp': - found_sctp = True - ip_node.appendChild(proto) - sctp_node = proto - elif urlnode.nodeValue == 's1ap': - found_s1ap = True - sctp_node.appendChild(proto) - elif urlnode.nodeValue == 'geninfo': - packet.removeChild(proto) - elif urlnode.nodeValue == 'eth': - packet.removeChild(proto) - if found_sctp == False: - # hopefully it seems to work (remove iterated packet) - packet.parentNode.removeChild(packet) - -##################### -# dom to xml string -##################### -filtered_pdml_string = orig_dom.toprettyxml(indent=" ") -cleaned_pdml_string = "" -##################### -# remove blank lines in xml string -##################### -lines = filtered_pdml_string.splitlines() -for line in lines: - if len(line.strip()): - if line[:-1]: - cleaned_pdml_string += line + '\r\n' -#print "'%s'" % cleaned_pdml_string -##################### -# write pdml string to pdml file -##################### -out_pdml_file_name = os.path.dirname(orig_pcap_file_name) + '/' + os.path.splitext(os.path.basename(orig_pcap_file_name))[0] + '.pdml' -out_file = open(out_pdml_file_name, "w") -out_file.write(cleaned_pdml_string) -out_file.close() - -############################################################ -# DECEIVING HTML BONUS: DO NOT SEEM TO WORK CORRECTLY IN FIREFOX -# DID NOT INVESTIGATE -##################### -# write xml string to html file -##################### -xsl_root = etree.fromstring(open('/usr/share/wireshark/pdml2html.xsl').read()) -transform = etree.XSLT(xsl_root) -xml_root = etree.fromstring(cleaned_pdml_string) -trans_root = transform(xml_root) -filtered_html_string = etree.tostring(trans_root) -##################### -# write html string to html file -##################### -out_html_file_name = os.path.dirname(orig_pcap_file_name) + '/' +os.path.splitext(os.path.basename(orig_pcap_file_name))[0] + '.html' -out_file = open(out_html_file_name, "w") -out_file.write(filtered_html_string) -out_file.close() diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c index 133e9adf4b..a801d2cf23 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.c +++ b/openair3/TEST/EPC_TEST/play_scenario.c @@ -68,7 +68,6 @@ #define GS_IS_FILE 1 #define GS_IS_DIR 2 //------------------------------------------------------------------------------ -char *g_openair_dir = NULL; Enb_properties_array_t g_enb_properties; //------------------------------------------------------------------------------ extern et_scenario_t *g_scenario; @@ -936,11 +935,6 @@ int main( int argc, char **argv ) char play_scenario_filename[NAME_MAX]; memset(play_scenario_filename, 0, sizeof(play_scenario_filename)); - g_openair_dir = getenv("OPENAIR_DIR"); - if (NULL == g_openair_dir) { - fprintf(stderr, "ERROR: Could not get OPENAIR_DIR environment variable\n"); - exit(1); - } // logging logInit(); diff --git a/openair3/TEST/EPC_TEST/play_scenario.h b/openair3/TEST/EPC_TEST/play_scenario.h index f44974dae0..758ee97981 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.h +++ b/openair3/TEST/EPC_TEST/play_scenario.h @@ -252,6 +252,7 @@ typedef struct et_s1ap_s { uint16_t binary_stream_allocated_size; uint8_t *binary_stream; s1ap_message message; // decoded message: information elements + xmlNodePtr xml_node; // XML representation of the S1AP PDU } et_s1ap_t; @@ -418,7 +419,7 @@ 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); -int et_handle_s1ap_mismatch(et_packet_t * const spacket, et_packet_t * const rx_packet); +int et_handle_s1ap_mismatch_mme_ue_s1ap_id(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); diff --git a/openair3/TEST/EPC_TEST/play_scenario.xsl b/openair3/TEST/EPC_TEST/play_scenario.xsl deleted file mode 100644 index 0ce22c08df..0000000000 --- a/openair3/TEST/EPC_TEST/play_scenario.xsl +++ /dev/null @@ -1,113 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ERROR: Cannot resolv IP ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ERROR: Cannot resolv IP ! - - - - - - - - - - - - - - - - diff --git a/openair3/TEST/EPC_TEST/play_scenario_parse.c b/openair3/TEST/EPC_TEST/play_scenario_parse.c index 496102449a..35ed5c8603 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_parse.c +++ b/openair3/TEST/EPC_TEST/play_scenario_parse.c @@ -58,7 +58,6 @@ //------------------------------------------------------------------------------ #define ENB_CONFIG_MAX_XSLT_PARAMS 32 //------------------------------------------------------------------------------ -extern char *g_openair_dir; extern Enb_properties_array_t g_enb_properties; //------------------------------------------------------------------------------ void et_parse_s1ap(xmlDocPtr doc, const xmlNode const *s1ap_node, et_s1ap_t * const s1ap) @@ -71,6 +70,9 @@ void et_parse_s1ap(xmlDocPtr doc, const xmlNode const *s1ap_node, et_s1ap_t * co unsigned int go_deeper_in_tree = 1; if ((NULL != s1ap_node) && (NULL != s1ap)) { + // seee http://www.xmlsoft.org/html/libxml-tree.html#xmlCopyNode + s1ap->xml_node = xmlCopyNode(s1ap_node, 1); + AssertFatal(NULL != s1ap->xml_node, "xmlCopyNode Failed"); for (cur_node = (xmlNode *)s1ap_node; cur_node; cur_node = cur_node->next) { go_deeper_in_tree = 1; if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"field"))) { @@ -497,17 +499,14 @@ int et_generate_xml_scenario( exit(1); } - memset(astring, 0, sizeof(astring)); - strcat(astring, g_openair_dir); - strcat(astring, "/openair3/TEST/EPC_TEST/play_scenario.xsl"); xmlSubstituteEntitiesDefault(1); xmlLoadExtDtdDefaultValue = 1; - cur = xsltParseStylesheetFile((const xmlChar *)astring); + cur = xsltParseStylesheetFile((const xmlChar *)"/usr/share/oai/xsl/play_scenario.xsl"); if (NULL == cur) { - AssertFatal (0, "Could not parse stylesheet file %s (check OPENAIR_DIR env variable)!\n", astring); + AssertFatal (0, "Could not parse stylesheet file /usr/share/oai/xsl/play_scenario.xsl!\n"); } else { - fprintf(stdout, "XSLT style sheet: %s\n", astring); + fprintf(stdout, "XSLT style sheet: /usr/share/oai/xsl/play_scenario.xsl\n"); } doc = xmlParseFile(xml_in_scenario_filename); diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c index d58b16c2d3..f5afebd786 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c @@ -189,7 +189,7 @@ 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); } //------------------------------------------------------------------------------ -int et_handle_s1ap_mismatch(et_packet_t * const spacket, et_packet_t * const rx_packet) +int et_handle_s1ap_mismatch_mme_ue_s1ap_id(et_packet_t * const spacket, et_packet_t * const rx_packet) { S1ap_MME_UE_S1AP_ID_t scenario_mme_ue_s1ap_id = 0; S1ap_MME_UE_S1AP_ID_t rx_mme_ue_s1ap_id = 0; @@ -512,7 +512,15 @@ int et_handle_s1ap_mismatch(et_packet_t * const spacket, et_packet_t * const rx_ default: AssertFatal(0, "Unknown procedure code %ld", rx_packet->sctp_hdr.u.data_hdr.payload.message.procedureCode); } - return 0; + if (scenario_mme_ue_s1ap_id != rx_mme_ue_s1ap_id) { + et_packet_t * p = spacket; + while (p) { + et_s1ap_update_mme_ue_s1ap_id(p, scenario_mme_ue_s1ap_id, rx_mme_ue_s1ap_id); + p = p->next; + } + return 0; + } + return 1; } //------------------------------------------------------------------------------ asn_comp_rval_t * et_s1ap_is_matching(et_s1ap_t * const s1ap1, et_s1ap_t * const s1ap2, const uint32_t constraints) @@ -669,7 +677,7 @@ int et_s1ap_process_rx_packet(et_event_s1ap_data_ind_t * const s1ap_data_ind) //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)) { + if (0 == et_handle_s1ap_mismatch_mme_ue_s1ap_id((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); 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 213be2b347..3533ee086e 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c @@ -451,3 +451,354 @@ asn_comp_rval_t * et_s1ap_ies_is_matching(const S1AP_PDU_PR present, s1ap_messag } return ret; } + +//------------------------------------------------------------------------------ +int et_s1ap_update_mme_ue_s1ap_id(et_packet_t * const packet, const S1ap_MME_UE_S1AP_ID_t old_id, const S1ap_MME_UE_S1AP_ID_t new_id) +{ + S1ap_MME_UE_S1AP_ID_t mme_ue_s1ap_id = 0; + S1AP_PDU_PR present; + ssize_t encoded; + + present = packet->sctp_hdr.u.data_hdr.payload.pdu.present; + + S1AP_DEBUG("Updating mme_ue_s1ap_id of packet num %d...\n", packet->packet_number); + + switch (packet->sctp_hdr.u.data_hdr.payload.message.procedureCode) { + case S1ap_ProcedureCode_id_HandoverPreparation: + if (present == S1AP_PDU_PR_initiatingMessage) { + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequiredIEs.mme_ue_s1ap_id; + if (old_id == mme_ue_s1ap_id) { + packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequiredIEs.mme_ue_s1ap_id = new_id; + // re-encode + S1ap_HandoverRequired_t msg; + S1ap_HandoverRequired_t *msg_p = &msg; + memset((void *)msg_p, 0, sizeof(msg)); + + if (s1ap_encode_s1ap_handoverrequiredies( + msg_p, &packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequiredIEs) < 0) { + AssertFatal(0, "Re-encoding handoverrequiredies failed"); + } + + ANY_fromType_aper(&packet->sctp_hdr.u.data_hdr.payload.pdu.choice.initiatingMessage.value, + &asn_DEF_S1ap_HandoverRequired, + &packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequiredIEs); + + packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequiredIEs; + encoded = aper_encode_to_new_buffer(&asn_DEF_S1AP_PDU, 0, &packet->sctp_hdr.u.data_hdr.payload.pdu, + (void **)&packet->sctp_hdr.u.data_hdr.payload.binary_stream); + AssertFatal(encoded < 0, "Re-encoding PDU failed"); + } + } else { + mme_ue_s1ap_id = packet->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) { + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequestIEs.mme_ue_s1ap_id; + } else if (present == S1AP_PDU_PR_successfulOutcome) { + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequestAcknowledgeIEs.mme_ue_s1ap_id; + } else if (present == S1AP_PDU_PR_unsuccessfulOutcome) { + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverFailureIEs.mme_ue_s1ap_id; + } + break; + + case S1ap_ProcedureCode_id_HandoverNotification: + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverNotifyIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_PathSwitchRequest: + //mme_ue_s1ap_id = 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: + mme_ue_s1ap_id = packet->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) { + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABSetupRequestIEs.mme_ue_s1ap_id; + } else { + mme_ue_s1ap_id = packet->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) { + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABModifyRequestIEs.mme_ue_s1ap_id; + } else { + mme_ue_s1ap_id = packet->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) { + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABReleaseCommandIEs.mme_ue_s1ap_id; + } else { + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABReleaseResponseIEs.mme_ue_s1ap_id; + } + break; + + case S1ap_ProcedureCode_id_E_RABReleaseIndication: + mme_ue_s1ap_id = packet->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) { + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_InitialContextSetupRequestIEs.mme_ue_s1ap_id; + } else { + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_InitialContextSetupResponseIEs.mme_ue_s1ap_id; + } + break; + + case S1ap_ProcedureCode_id_Paging: + //mme_ue_s1ap_id = 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: + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkNASTransportIEs.mme_ue_s1ap_id; + if (old_id == mme_ue_s1ap_id) { + packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkNASTransportIEs.mme_ue_s1ap_id = new_id; + // re-encode + S1ap_DownlinkNASTransport_t msg; + S1ap_DownlinkNASTransport_t *msg_p = &msg; + memset((void *)msg_p, 0, sizeof(msg)); + + if (s1ap_encode_s1ap_downlinknastransporties( + msg_p, &packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkNASTransportIEs) < 0) { + AssertFatal(0, "Re-encoding downlinknastransporties failed"); + } + + ANY_fromType_aper(&packet->sctp_hdr.u.data_hdr.payload.pdu.choice.initiatingMessage.value, + &asn_DEF_S1ap_DownlinkNASTransport, + &packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkNASTransportIEs); + + encoded = aper_encode_to_new_buffer(&asn_DEF_S1AP_PDU, 0, &packet->sctp_hdr.u.data_hdr.payload.pdu, + (void **)&packet->sctp_hdr.u.data_hdr.payload.binary_stream); + AssertFatal(encoded < 0, "Re-encoding PDU failed"); + } + break; + + case S1ap_ProcedureCode_id_initialUEMessage: + //mme_ue_s1ap_id = 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: + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkNASTransportIEs.mme_ue_s1ap_id; + if (old_id == mme_ue_s1ap_id) { + packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkNASTransportIEs.mme_ue_s1ap_id = new_id; + // re-encode + S1ap_UplinkNASTransport_t msg; + S1ap_UplinkNASTransport_t *msg_p = &msg; + memset((void *)msg_p, 0, sizeof(msg)); + + if (s1ap_encode_s1ap_uplinknastransporties( + msg_p, &packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkNASTransportIEs) < 0) { + AssertFatal(0, "Re-encoding uplinknastransporties failed"); + } + + ANY_fromType_aper(&packet->sctp_hdr.u.data_hdr.payload.pdu.choice.initiatingMessage.value, + &asn_DEF_S1ap_DownlinkNASTransport, + &packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkNASTransportIEs); + + encoded = aper_encode_to_new_buffer(&asn_DEF_S1AP_PDU, 0, &packet->sctp_hdr.u.data_hdr.payload.pdu, + (void **)&packet->sctp_hdr.u.data_hdr.payload.binary_stream); + AssertFatal(encoded < 0, "Re-encoding PDU failed"); + } + break; + + case S1ap_ProcedureCode_id_Reset: + //mme_ue_s1ap_id = 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: + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ErrorIndicationIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_NASNonDeliveryIndication: + mme_ue_s1ap_id = packet->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) { + mme_ue_s1ap_id = 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) { + mme_ue_s1ap_id = 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) { + mme_ue_s1ap_id = 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: + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextReleaseRequestIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_DownlinkS1cdma2000tunneling: + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkS1cdma2000tunnelingIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_UplinkS1cdma2000tunneling: + mme_ue_s1ap_id = packet->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) { + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextModificationRequestIEs.mme_ue_s1ap_id; + } else if (present == S1AP_PDU_PR_successfulOutcome) { + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextModificationResponseIEs.mme_ue_s1ap_id; + } else if (present == S1AP_PDU_PR_unsuccessfulOutcome) { + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextModificationFailureIEs.mme_ue_s1ap_id; + } + break; + + case S1ap_ProcedureCode_id_UECapabilityInfoIndication: + mme_ue_s1ap_id = packet->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) { + //mme_ue_s1ap_id = 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 { + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextReleaseCompleteIEs.mme_ue_s1ap_id; + } + break; + + case S1ap_ProcedureCode_id_eNBStatusTransfer: + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ENBStatusTransferIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_MMEStatusTransfer: + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_MMEStatusTransferIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_DeactivateTrace: + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DeactivateTraceIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_TraceStart: + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_TraceStartIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_TraceFailureIndication: + mme_ue_s1ap_id = packet->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) { + mme_ue_s1ap_id = 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) { + mme_ue_s1ap_id = 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 { + mme_ue_s1ap_id = 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) { + mme_ue_s1ap_id = 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) { + mme_ue_s1ap_id = 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 { + mme_ue_s1ap_id = 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: + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_LocationReportingControlIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_LocationReportingFailureIndication: + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_LocationReportingFailureIndicationIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_LocationReport: + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_LocationReportIEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_OverloadStart: + //mme_ue_s1ap_id = 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: + //mme_ue_s1ap_id = 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) { + mme_ue_s1ap_id = 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 { + mme_ue_s1ap_id = 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: + //mme_ue_s1ap_id = 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: + //mme_ue_s1ap_id = 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: + mme_ue_s1ap_id = packet->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) { + mme_ue_s1ap_id = 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 { + mme_ue_s1ap_id = 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: + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkUEAssociatedLPPaTransport_IEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_uplinkUEAssociatedLPPaTransport: + mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkUEAssociatedLPPaTransport_IEs.mme_ue_s1ap_id; + break; + + case S1ap_ProcedureCode_id_downlinkNonUEAssociatedLPPaTransport: + //mme_ue_s1ap_id = 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: + //mme_ue_s1ap_id = 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", packet->sctp_hdr.u.data_hdr.payload.message.procedureCode); + } + return 0; +} diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf index e864f47edb..a2df43fec0 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf @@ -131,7 +131,7 @@ eNBs = ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.188.2.2"; + mme_ip_address = ( { ipv4 = "192.170.0.1"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -140,12 +140,12 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "tun2"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "192.188.2.2/24"; + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0:3"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.170.0.2/24"; - ENB_INTERFACE_NAME_FOR_S1U = "lo"; - ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.1/24"; - ENB_PORT_FOR_S1U = 2153; # Spec 2152 + ENB_INTERFACE_NAME_FOR_S1U = "eth0:4"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.170.1.2/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 }; log_config : From cc4286f27bdb827267b105a4f33bc5a63024606a Mon Sep 17 00:00:00 2001 From: gauthier Date: Tue, 15 Dec 2015 16:56:55 +0100 Subject: [PATCH 20/47] sync --- openair3/TEST/EPC_TEST/play_scenario.h | 5 +- openair3/TEST/EPC_TEST/play_scenario_parse.c | 9 +- .../EPC_TEST/play_scenario_s1ap_compare_ie.c | 475 +++++------------- 3 files changed, 146 insertions(+), 343 deletions(-) diff --git a/openair3/TEST/EPC_TEST/play_scenario.h b/openair3/TEST/EPC_TEST/play_scenario.h index 758ee97981..4ac46e84b5 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.h +++ b/openair3/TEST/EPC_TEST/play_scenario.h @@ -48,6 +48,9 @@ #include "hashtable.h" #include "asn_compare.h" +#define ET_XPATH_EXPRESSION_MAX_LENGTH 400 + + // powers of 2 #define ET_BIT_MASK_MATCH_SCTP_STREAM 1 #define ET_BIT_MASK_MATCH_SCTP_SSN 2 @@ -252,7 +255,7 @@ typedef struct et_s1ap_s { uint16_t binary_stream_allocated_size; uint8_t *binary_stream; s1ap_message message; // decoded message: information elements - xmlNodePtr xml_node; // XML representation of the S1AP PDU + xmlDocPtr doc; // XML representation of the S1AP PDU } et_s1ap_t; diff --git a/openair3/TEST/EPC_TEST/play_scenario_parse.c b/openair3/TEST/EPC_TEST/play_scenario_parse.c index 35ed5c8603..b9d24f366c 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_parse.c +++ b/openair3/TEST/EPC_TEST/play_scenario_parse.c @@ -70,9 +70,12 @@ void et_parse_s1ap(xmlDocPtr doc, const xmlNode const *s1ap_node, et_s1ap_t * co unsigned int go_deeper_in_tree = 1; if ((NULL != s1ap_node) && (NULL != s1ap)) { - // seee http://www.xmlsoft.org/html/libxml-tree.html#xmlCopyNode - s1ap->xml_node = xmlCopyNode(s1ap_node, 1); - AssertFatal(NULL != s1ap->xml_node, "xmlCopyNode Failed"); + // see http://www.xmlsoft.org/html/libxml-tree.html#xmlCopyNode + cur_node = xmlCopyNode(s1ap_node, 1); + AssertFatal(NULL != cur_node, "xmlCopyNode Failed"); + s1ap->doc = xmlNewDoc(BAD_CAST "1.0"); + xmlDocSetRootElement(s1ap->doc, cur_node); + for (cur_node = (xmlNode *)s1ap_node; cur_node; cur_node = cur_node->next) { go_deeper_in_tree = 1; if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"field"))) { 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 3533ee086e..87ffe29e32 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c @@ -40,6 +40,10 @@ #include #include #include +#include +#include +#include +#include #include "tree.h" #include "queue.h" @@ -452,353 +456,146 @@ asn_comp_rval_t * et_s1ap_ies_is_matching(const S1AP_PDU_PR present, s1ap_messag return ret; } + +static void update_xpath_node_mme_ue_s1ap_id(et_s1ap_t * const s1ap, xmlNode *node, xmlChar *new_id_hex, xmlChar *new_id_dec, xmlChar *showname) +{ + xmlNode *cur_node = NULL; + xmlAttrPtr attr = NULL; + xmlChar *xml_char = NULL; + int size = 0; + int pos = 0; + int go_deeper_in_tree = 1; + // modify + for (cur_node = (xmlNode *)node; cur_node; cur_node = cur_node->next) { + go_deeper_in_tree = 1; + if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"field"))) { + // do not get hidden fields + xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"hide"); + if (NULL != xml_char) { + if ((!xmlStrcmp(xml_char, (const xmlChar *)"yes"))) { + go_deeper_in_tree = 0; + } + xmlFree(xml_char); + } + if (0 < go_deeper_in_tree) { + // first get size + xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"pos"); + if (NULL != xml_char) { + pos = strtoul((const char *)xml_char, NULL, 0); + xmlFree(xml_char); + xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"size"); + if (NULL != xml_char) { + size = strtoul((const char *)xml_char, NULL, 0); + xmlFree(xml_char); + // second: try to set value (always hex) + attr = xmlSetProp((xmlNode *)cur_node, (const xmlChar *)"value", new_id_hex); + attr = xmlSetProp((xmlNode *)cur_node, (const xmlChar *)"show", new_id_dec); + attr = xmlSetProp((xmlNode *)cur_node, (const xmlChar *)"showname", showname); + //TODO update s1ap->binary_stream @pos with new_id_hex, size + } + } + } + } + if (0 < go_deeper_in_tree) { + update_xpath_node_mme_ue_s1ap_id(s1ap, cur_node->children, new_id_hex, new_id_dec, showname); + } + } +} + +/** + * update_xpath_nodes: + * @nodes: the nodes set. + * @value: the new value for the node(s) + * + * Prints the @nodes content to @output. + * From http://www.xmlsoft.org/examples/#xpath2.c + */ +static void update_xpath_nodes_mme_ue_s1ap_id(et_s1ap_t * const s1ap_payload, xmlNodeSetPtr nodes, const S1ap_MME_UE_S1AP_ID_t new_id) +{ + int size = 0; + int i = 0; + int ret = 0; + const xmlChar value_d[32]; + const xmlChar value_h[20]; + const xmlChar showname[64]; + xmlNode *s1ap_node = NULL; + + size = (nodes) ? nodes->nodeNr : 0; + + ret = snprintf((char *)value_d, 32, "%ld", new_id); + AssertFatal((ret < 0) || (ret > 32), "Could not convert int to dec str"); + ret = snprintf((char *)value_h, 20, "C0%X", new_id); + AssertFatal((ret < 0) || (ret > 20), "Could not convert int to hex str"); + ret = snprintf((char *)showname, 64, "MME-UE-S1AP-ID: %d", new_id); + AssertFatal((ret < 0) || (ret > 64), "Could not convert int to dec str"); + /* + * NOTE: the nodes are processed in reverse order, i.e. reverse document + * order because xmlNodeSetContent can actually free up descendant + * of the node and such nodes may have been selected too ! Handling + * in reverse order ensure that descendant are accessed first, before + * they get removed. Mixing XPath and modifications on a tree must be + * done carefully ! + */ + for(i = size - 1; i >= 0; i--) { + s1ap_node = nodes->nodeTab[i]; + AssertFatal(NULL != s1ap_node, "One element of resultset of XPATH expression is NULL\n"); + update_xpath_node_mme_ue_s1ap_id(s1ap_payload, s1ap_node, value_d, value_h, showname); + /* + * All the elements returned by an XPath query are pointers to + * elements from the tree *except* namespace nodes where the XPath + * semantic is different from the implementation in libxml2 tree. + * As a result when a returned node set is freed when + * xmlXPathFreeObject() is called, that routine must check the + * element type. But node from the returned set may have been removed + * by xmlNodeSetContent() resulting in access to freed data. + * This can be exercised by running valgrind + * There is 2 ways around it: + * - make a copy of the pointers to the nodes from the result set + * then call xmlXPathFreeObject() and then modify the nodes + * or + * - remove the reference to the modified nodes from the node set + * as they are processed, if they are not namespace nodes. + */ + if (nodes->nodeTab[i]->type != XML_NAMESPACE_DECL) { + nodes->nodeTab[i] = NULL; + } + } +} //------------------------------------------------------------------------------ int et_s1ap_update_mme_ue_s1ap_id(et_packet_t * const packet, const S1ap_MME_UE_S1AP_ID_t old_id, const S1ap_MME_UE_S1AP_ID_t new_id) { - S1ap_MME_UE_S1AP_ID_t mme_ue_s1ap_id = 0; - S1AP_PDU_PR present; - ssize_t encoded; - present = packet->sctp_hdr.u.data_hdr.payload.pdu.present; - S1AP_DEBUG("Updating mme_ue_s1ap_id of packet num %d...\n", packet->packet_number); + xmlNode *cur_node = NULL; + xmlChar xpath_expression[ET_XPATH_EXPRESSION_MAX_LENGTH]; + int ret = 0; + xmlDocPtr doc = NULL; + xmlXPathContextPtr xpath_ctx = NULL; + xmlXPathObjectPtr xpath_obj = NULL; - switch (packet->sctp_hdr.u.data_hdr.payload.message.procedureCode) { - case S1ap_ProcedureCode_id_HandoverPreparation: - if (present == S1AP_PDU_PR_initiatingMessage) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequiredIEs.mme_ue_s1ap_id; - if (old_id == mme_ue_s1ap_id) { - packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequiredIEs.mme_ue_s1ap_id = new_id; - // re-encode - S1ap_HandoverRequired_t msg; - S1ap_HandoverRequired_t *msg_p = &msg; - memset((void *)msg_p, 0, sizeof(msg)); + ret = snprintf(xpath_expression, ET_XPATH_EXPRESSION_MAX_LENGTH, "//field[@name=\"s1ap.MME_UE_S1AP_ID\"][@show=\"%d\"]", old_id); + AssertFatal((ret < 0) || (ret > ET_XPATH_EXPRESSION_MAX_LENGTH), "Could not build XPATH expression"); - if (s1ap_encode_s1ap_handoverrequiredies( - msg_p, &packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequiredIEs) < 0) { - AssertFatal(0, "Re-encoding handoverrequiredies failed"); - } + doc = packet->sctp_hdr.u.data_hdr.payload.doc; - ANY_fromType_aper(&packet->sctp_hdr.u.data_hdr.payload.pdu.choice.initiatingMessage.value, - &asn_DEF_S1ap_HandoverRequired, - &packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequiredIEs); - - packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequiredIEs; - encoded = aper_encode_to_new_buffer(&asn_DEF_S1AP_PDU, 0, &packet->sctp_hdr.u.data_hdr.payload.pdu, - (void **)&packet->sctp_hdr.u.data_hdr.payload.binary_stream); - AssertFatal(encoded < 0, "Re-encoding PDU failed"); - } - } else { - mme_ue_s1ap_id = packet->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) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequestIEs.mme_ue_s1ap_id; - } else if (present == S1AP_PDU_PR_successfulOutcome) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequestAcknowledgeIEs.mme_ue_s1ap_id; - } else if (present == S1AP_PDU_PR_unsuccessfulOutcome) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverFailureIEs.mme_ue_s1ap_id; - } - break; - - case S1ap_ProcedureCode_id_HandoverNotification: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverNotifyIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_PathSwitchRequest: - //mme_ue_s1ap_id = 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: - mme_ue_s1ap_id = packet->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) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABSetupRequestIEs.mme_ue_s1ap_id; - } else { - mme_ue_s1ap_id = packet->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) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABModifyRequestIEs.mme_ue_s1ap_id; - } else { - mme_ue_s1ap_id = packet->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) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABReleaseCommandIEs.mme_ue_s1ap_id; - } else { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABReleaseResponseIEs.mme_ue_s1ap_id; - } - break; - - case S1ap_ProcedureCode_id_E_RABReleaseIndication: - mme_ue_s1ap_id = packet->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) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_InitialContextSetupRequestIEs.mme_ue_s1ap_id; - } else { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_InitialContextSetupResponseIEs.mme_ue_s1ap_id; - } - break; - - case S1ap_ProcedureCode_id_Paging: - //mme_ue_s1ap_id = 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: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkNASTransportIEs.mme_ue_s1ap_id; - if (old_id == mme_ue_s1ap_id) { - packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkNASTransportIEs.mme_ue_s1ap_id = new_id; - // re-encode - S1ap_DownlinkNASTransport_t msg; - S1ap_DownlinkNASTransport_t *msg_p = &msg; - memset((void *)msg_p, 0, sizeof(msg)); - - if (s1ap_encode_s1ap_downlinknastransporties( - msg_p, &packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkNASTransportIEs) < 0) { - AssertFatal(0, "Re-encoding downlinknastransporties failed"); - } - - ANY_fromType_aper(&packet->sctp_hdr.u.data_hdr.payload.pdu.choice.initiatingMessage.value, - &asn_DEF_S1ap_DownlinkNASTransport, - &packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkNASTransportIEs); - - encoded = aper_encode_to_new_buffer(&asn_DEF_S1AP_PDU, 0, &packet->sctp_hdr.u.data_hdr.payload.pdu, - (void **)&packet->sctp_hdr.u.data_hdr.payload.binary_stream); - AssertFatal(encoded < 0, "Re-encoding PDU failed"); - } - break; - - case S1ap_ProcedureCode_id_initialUEMessage: - //mme_ue_s1ap_id = 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: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkNASTransportIEs.mme_ue_s1ap_id; - if (old_id == mme_ue_s1ap_id) { - packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkNASTransportIEs.mme_ue_s1ap_id = new_id; - // re-encode - S1ap_UplinkNASTransport_t msg; - S1ap_UplinkNASTransport_t *msg_p = &msg; - memset((void *)msg_p, 0, sizeof(msg)); - - if (s1ap_encode_s1ap_uplinknastransporties( - msg_p, &packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkNASTransportIEs) < 0) { - AssertFatal(0, "Re-encoding uplinknastransporties failed"); - } - - ANY_fromType_aper(&packet->sctp_hdr.u.data_hdr.payload.pdu.choice.initiatingMessage.value, - &asn_DEF_S1ap_DownlinkNASTransport, - &packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkNASTransportIEs); - - encoded = aper_encode_to_new_buffer(&asn_DEF_S1AP_PDU, 0, &packet->sctp_hdr.u.data_hdr.payload.pdu, - (void **)&packet->sctp_hdr.u.data_hdr.payload.binary_stream); - AssertFatal(encoded < 0, "Re-encoding PDU failed"); - } - break; - - case S1ap_ProcedureCode_id_Reset: - //mme_ue_s1ap_id = 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: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ErrorIndicationIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_NASNonDeliveryIndication: - mme_ue_s1ap_id = packet->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) { - mme_ue_s1ap_id = 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) { - mme_ue_s1ap_id = 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) { - mme_ue_s1ap_id = 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: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextReleaseRequestIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_DownlinkS1cdma2000tunneling: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkS1cdma2000tunnelingIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_UplinkS1cdma2000tunneling: - mme_ue_s1ap_id = packet->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) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextModificationRequestIEs.mme_ue_s1ap_id; - } else if (present == S1AP_PDU_PR_successfulOutcome) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextModificationResponseIEs.mme_ue_s1ap_id; - } else if (present == S1AP_PDU_PR_unsuccessfulOutcome) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextModificationFailureIEs.mme_ue_s1ap_id; - } - break; - - case S1ap_ProcedureCode_id_UECapabilityInfoIndication: - mme_ue_s1ap_id = packet->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) { - //mme_ue_s1ap_id = 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 { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextReleaseCompleteIEs.mme_ue_s1ap_id; - } - break; - - case S1ap_ProcedureCode_id_eNBStatusTransfer: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ENBStatusTransferIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_MMEStatusTransfer: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_MMEStatusTransferIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_DeactivateTrace: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DeactivateTraceIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_TraceStart: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_TraceStartIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_TraceFailureIndication: - mme_ue_s1ap_id = packet->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) { - mme_ue_s1ap_id = 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) { - mme_ue_s1ap_id = 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 { - mme_ue_s1ap_id = 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) { - mme_ue_s1ap_id = 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) { - mme_ue_s1ap_id = 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 { - mme_ue_s1ap_id = 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: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_LocationReportingControlIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_LocationReportingFailureIndication: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_LocationReportingFailureIndicationIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_LocationReport: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_LocationReportIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_OverloadStart: - //mme_ue_s1ap_id = 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: - //mme_ue_s1ap_id = 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) { - mme_ue_s1ap_id = 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 { - mme_ue_s1ap_id = 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: - //mme_ue_s1ap_id = 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: - //mme_ue_s1ap_id = 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: - mme_ue_s1ap_id = packet->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) { - mme_ue_s1ap_id = 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 { - mme_ue_s1ap_id = 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: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkUEAssociatedLPPaTransport_IEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_uplinkUEAssociatedLPPaTransport: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkUEAssociatedLPPaTransport_IEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_downlinkNonUEAssociatedLPPaTransport: - //mme_ue_s1ap_id = 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: - //mme_ue_s1ap_id = 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", packet->sctp_hdr.u.data_hdr.payload.message.procedureCode); + // Create xpath evaluation context + xpath_ctx = xmlXPathNewContext(doc); + if(xpath_ctx == NULL) { + fprintf(stderr,"Error: unable to create new XPath context\n"); + xmlFreeDoc(doc); + return(-1); } + + // Evaluate xpath expression + xpath_obj = xmlXPathEvalExpression(xpath_expression, xpath_ctx); + AssertFatal(xpath_obj != NULL, "Unable to evaluate XPATH expression \"%s\"\n", xpath_expression); + + // update selected nodes + update_xpath_nodes_mme_ue_s1ap_id(&packet->sctp_hdr.u.data_hdr.payload, xpath_obj->nodesetval, new_id); + + // Cleanup of XPath data + xmlXPathFreeObject(xpath_obj); + xmlXPathFreeContext(xpath_ctx); + return 0; } From ed26845480fc401e9c994ae958f4e4f515df54ff Mon Sep 17 00:00:00 2001 From: gauthier Date: Thu, 17 Dec 2015 16:22:08 +0100 Subject: [PATCH 21/47] TODO transport layer address, play scenario max speed --- cmake_targets/tools/build_helper | 178 ------------------ openair3/TEST/EPC_TEST/generate_scenario.c | 4 +- openair3/TEST/EPC_TEST/play_scenario.c | 12 +- openair3/TEST/EPC_TEST/play_scenario.h | 4 + openair3/TEST/EPC_TEST/play_scenario_fsm.c | 19 +- openair3/TEST/EPC_TEST/play_scenario_parse.c | 16 +- openair3/TEST/EPC_TEST/play_scenario_s1ap.c | 33 ++-- .../EPC_TEST/play_scenario_s1ap_compare_ie.c | 54 ++++-- openair3/TEST/EPC_TEST/play_scenario_sctp.c | 19 +- 9 files changed, 112 insertions(+), 227 deletions(-) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 0a0118581e..534c4e0907 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -301,184 +301,6 @@ install_nas_tools() { fi } -################################################# -# 3. Network interfaces utilities -################################################ - -cidr2mask(){ - local i mask="" - local full_octets=$(($1/8)) - local partial_octet=$(($1%8)) - - for ((i=0;i<4;i+=1)); do - if [ $i -lt $full_octets ]; then - mask+=255 - elif [ $i -eq $full_octets ]; then - mask+=$((256 - 2**(8-$partial_octet))) - else - mask+=0 - fi - test $i -lt 3 && mask+=. - done - - echo $mask -} - -# example: netcalc 192.168.12.100 255.255.255.0 -netcalc(){ - local IFS='.' ip i - local -a oct msk - - read -ra oct <<<"$1" - read -ra msk <<<"$2" - - for i in ${!oct[@]}; do - ip+=( "$(( oct[i] & msk[i] ))" ) - done - - echo "${ip[*]}" -} - -# example: -bcastcalc(){ - local IFS='.' ip i - local -a oct msk - - read -ra oct <<<"$1" - read -ra msk <<<"$2" - - for i in ${!oct[@]}; do - ip+=( "$(( oct[i] + ( 255 - ( oct[i] | msk[i] ) ) ))" ) - done - echo "${ip[*]}" -} - - -is_real_interface(){ - my_bool=1 - for var in "$@" - do - if [ "a$var" == "a" ]; then - return 0 - fi - if [ "a$var" == "anone" ]; then - return 0 - fi - IF=`cat /etc/udev/rules.d/70-persistent-net.rules | grep $var | sed 's/^.*NAME=//' | tr -d '"'` - if [ "$IF" == "$var" ]; then - if [ "a${var:0:3}" != "aeth" ]; then - if [ "a${var:0:4}" != "awlan" ]; then - if [ "a${var:0:4}" != "awifi" ]; then - my_bool=0; - fi - fi - fi - fi - done - return $my_bool -} - -is_virtual_interface(){ - my_bool=1 - for var in "$@" - do - if [ "a$var" == "a" ]; then - return 0 - fi - if [ "a$var" == "anone" ]; then - return 0 - fi - num=`expr index "$var" :` - - if [ $num -eq 0 ]; then - my_bool=0; - fi - done - return $my_bool -} - -# arg1 = interface name -# arg2 = ipv4 addr cidr -set_interface_up(){ - interface=$1 - address=${2%/*} #part before '/' - cidr_netmask=${2#*/} # part after '/' - - if [ "a${interface:0:4}" == "anone" ]; then - return; - fi - echo "ifconfig $interface up" - $SUDO ifconfig $interface up - sync - netmask=`cidr2mask $cidr_netmask` - broadcast=`bcastcalc $address $netmask` - echo "ip -4 addr add $address/$cidr_netmask broadcast $broadcast dev $interface" - $SUDO ip -4 addr add $address/$cidr_netmask broadcast $broadcast dev $interface - sync -} - -# arg1 = interface name -# arg2 = ipv4 addr cidr -set_virtual_interface_up(){ - interface=$1 - address=${2%/*} #part before '/' - cidr_netmask=${2#*/} # part after '/' - - if [ "a${interface:0:4}" == "anone" ]; then - return; - fi - $SUDO ifconfig $interface down > /dev/null 2>&1 - sync - echo "ifconfig $interface $address up" - $SUDO ifconfig $interface $address up - sync -} - -#arg1 is interface name -#arg2 is IP address (CIDR) -set_network_interface(){ - local interface_name=$1 - local ip_cidr=$2 - - is_virtual_interface $interface_name - if [ $? -eq 1 ]; then - echo "$interface_name is virtual interface" - set_virtual_interface_up $interface_name $ip_cidr - else - is_real_interface $interface_name - if [ $? -eq 1 ]; then - echo "$interface_name is real interface" - set_interface_up $interface_name $ip_cidr - else - echo_warning "$interface_name not handled, not configuring it" - return - fi - fi -} - -# arg1 is a 'libconfig-like' config file -set_epc_network_interfaces(){ - value="`cat $1 | cut -d "#" -f1 | grep 'ADDRESS\|INTERFACE' | tr -d " " | grep "="`" - eval $value - - # check all var names are correct - list_var_name="\ - ENB_INTERFACE_NAME_FOR_S1_MME ENB_IPV4_ADDRESS_FOR_S1_MME \ - ENB_INTERFACE_NAME_FOR_S1U ENB_IPV4_ADDRESS_FOR_S1U " - for var_name in $list_var_name - do - if [ -n "$${var_name}" ]; then - echo_success "Found ${var_name} = ${!var_name}" - else - echo_fatal "${var_name} does does not exist in your config file $1" - fi - done - - # configure interfaces - set_network_interface $ENB_INTERFACE_NAME_FOR_S1_MME $ENB_IPV4_ADDRESS_FOR_S1_MME - set_network_interface $ENB_INTERFACE_NAME_FOR_S1U $ENB_IPV4_ADDRESS_FOR_S1U -} - ################################ diff --git a/openair3/TEST/EPC_TEST/generate_scenario.c b/openair3/TEST/EPC_TEST/generate_scenario.c index 238ba0ff11..69e707dcf9 100644 --- a/openair3/TEST/EPC_TEST/generate_scenario.c +++ b/openair3/TEST/EPC_TEST/generate_scenario.c @@ -142,7 +142,7 @@ int strip_extension(char *in_filename) if (NULL != in_filename) { /* Check chars starting at end of string to find last '.' */ - for (ssize_t i = strlen(in_filename); i > (name_min_len + max_ext_len); i--) { + for (ssize_t i = strlen(in_filename); i >= name_min_len; i--) { if (in_filename[i] == '.') { in_filename[i] = '\0'; return i; @@ -662,7 +662,7 @@ config_parse_opt_line ( fprintf(stderr, "Error: eNB config file name %s is not found in dir %s\n", enb_config_file_name, g_test_dir); } enb_config_init(enb_config_file_name); - enb_config_display(); + //enb_config_display(); if (NULL == pdml_in_file_name) { fprintf(stderr, "Error: please provide the PDML file name that should be in %s\n", g_test_dir); diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c index a801d2cf23..21aca820c2 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.c +++ b/openair3/TEST/EPC_TEST/play_scenario.c @@ -69,6 +69,7 @@ #define GS_IS_DIR 2 //------------------------------------------------------------------------------ Enb_properties_array_t g_enb_properties; +int g_max_speed = 0; //------------------------------------------------------------------------------ extern et_scenario_t *g_scenario; extern int xmlLoadExtDtdDefaultValue; @@ -118,7 +119,7 @@ int et_strip_extension(char *in_filename) if (NULL != in_filename) { /* Check chars starting at end of string to find last '.' */ - for (ssize_t i = strlen(in_filename); i > (name_min_len + max_ext_len); i--) { + for (ssize_t i = strlen(in_filename); i > name_min_len; i--) { if (in_filename[i] == '.') { in_filename[i] = '\0'; return i; @@ -833,6 +834,7 @@ et_config_parse_opt_line ( LONG_OPTION_START = 0x100, /* Start after regular single char options */ LONG_OPTION_ENB_CONF_FILE, LONG_OPTION_SCENARIO_FILE, + LONG_OPTION_MAX_SPEED, LONG_OPTION_TEST_DIR, LONG_OPTION_HELP, LONG_OPTION_VERSION @@ -841,6 +843,7 @@ et_config_parse_opt_line ( static struct option long_options[] = { {"enb-conf-file", required_argument, 0, LONG_OPTION_ENB_CONF_FILE}, {"scenario ", required_argument, 0, LONG_OPTION_SCENARIO_FILE}, + {"max-speed ", no_argument, 0, LONG_OPTION_MAX_SPEED}, {"test-dir", required_argument, 0, LONG_OPTION_TEST_DIR}, {"help", no_argument, 0, LONG_OPTION_HELP}, {"version", no_argument, 0, LONG_OPTION_VERSION}, @@ -850,7 +853,7 @@ et_config_parse_opt_line ( /* * Parsing command line */ - while ((option = getopt_long (argc, argv, "vhc:s:d:", long_options, NULL)) != -1) { + while ((option = getopt_long (argc, argv, "vhmc:s:d:", long_options, NULL)) != -1) { switch (option) { case LONG_OPTION_ENB_CONF_FILE: case 'c': @@ -882,6 +885,11 @@ et_config_parse_opt_line ( } break; + case LONG_OPTION_MAX_SPEED: + case 'm': + g_max_speed = 1; + break; + case LONG_OPTION_VERSION: case 'v': printf("Version %s\n", PACKAGE_VERSION); diff --git a/openair3/TEST/EPC_TEST/play_scenario.h b/openair3/TEST/EPC_TEST/play_scenario.h index 4ac46e84b5..0391ac5c47 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.h +++ b/openair3/TEST/EPC_TEST/play_scenario.h @@ -40,6 +40,7 @@ # include # include # include +# include # include #include "S1AP-PDU.h" @@ -460,6 +461,9 @@ et_packet_t* et_parse_xml_packet(xmlDocPtr doc, xmlNodePtr node); et_scenario_t* et_generate_scenario(const char * const et_scenario_filename ); //------------------------- 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); +void update_xpath_node_mme_ue_s1ap_id(et_s1ap_t * const s1ap, xmlNode *node, const S1ap_MME_UE_S1AP_ID_t new_id); +void update_xpath_nodes_mme_ue_s1ap_id(et_s1ap_t * const s1ap_payload, xmlNodeSetPtr nodes, const S1ap_MME_UE_S1AP_ID_t new_id); +int et_s1ap_update_mme_ue_s1ap_id(et_packet_t * const packet, const S1ap_MME_UE_S1AP_ID_t old_id, const S1ap_MME_UE_S1AP_ID_t new_id); //------------------------- 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); diff --git a/openair3/TEST/EPC_TEST/play_scenario_fsm.c b/openair3/TEST/EPC_TEST/play_scenario_fsm.c index b76d2240f5..a8f7e7331f 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_fsm.c +++ b/openair3/TEST/EPC_TEST/play_scenario_fsm.c @@ -46,6 +46,8 @@ #include "play_scenario_s1ap_eNB_defs.h" #include "timer.h" +//------------------------------------------------------------------------------ +extern int g_max_speed; //------------------------------------------------------------------------------ et_scenario_t *g_scenario = NULL; pthread_mutex_t g_fsm_lock = PTHREAD_MUTEX_INITIALIZER; @@ -86,13 +88,13 @@ int timeval_subtract (struct timeval * const result, struct timeval * const a, s //------------------------------------------------------------------------------ void et_scenario_wait_rx_packet(et_packet_t * const packet) { + packet->status = ET_PACKET_STATUS_SCHEDULED_FOR_RECEIVING; + g_fsm_state = ET_FSM_STATE_WAITING_RX_EVENT; if (timer_setup (ET_FSM_STATE_WAITING_RX_EVENT_DELAY_SEC, 0, TASK_S1AP, INSTANCE_DEFAULT, TIMER_ONE_SHOT, - NULL, &packet->timer_id) < 0) { + packet, &packet->timer_id) < 0) { AssertFatal(0, " Can not start waiting RX event timer\n"); } LOG_D(ENB_APP, "Waiting RX packet num %d\n", packet->packet_number); - g_fsm_state = ET_FSM_STATE_WAITING_RX_EVENT; - packet->status = ET_PACKET_STATUS_SCHEDULED_FOR_RECEIVING; } //------------------------------------------------------------------------------ void et_scenario_schedule_tx_packet(et_packet_t * const packet) @@ -133,14 +135,19 @@ void et_scenario_schedule_tx_packet(et_packet_t * const packet) we_are_too_early = timeval_subtract(&offset,&offset_last_rx_packet,&packet->time_relative_to_last_received_packet); LOG_D(ENB_APP, "we_are_too_early=%d, offset=%ld.%06d\n", we_are_too_early, offset.tv_sec, offset.tv_usec); } - if (we_are_too_early > 0) { + if ((0 < we_are_too_early) && (0 == g_max_speed)){ // set timer + if (offset.tv_sec < 0) offset.tv_sec = -offset.tv_sec; + if (offset.tv_usec < 0) { + offset.tv_usec = offset.tv_usec + 1000000; + offset.tv_sec -= 1; + } + LOG_D(ENB_APP, "Send packet num %u original frame number %u in %ld.%06d sec\n", packet->packet_number, packet->original_frame_number, offset.tv_sec, offset.tv_usec); packet->status = ET_PACKET_STATUS_SCHEDULED_FOR_SENDING; - if (timer_setup (offset.tv_sec, offset.tv_usec, TASK_S1AP, INSTANCE_DEFAULT, TIMER_ONE_SHOT, - NULL, &packet->timer_id) < 0) { + if (timer_setup (offset.tv_sec, offset.tv_usec, TASK_S1AP, INSTANCE_DEFAULT, TIMER_ONE_SHOT,packet, &packet->timer_id) < 0) { AssertFatal(0, " Can not start TX event timer\n"); } // Done g_fsm_state = ET_FSM_STATE_WAITING_TX_EVENT; diff --git a/openair3/TEST/EPC_TEST/play_scenario_parse.c b/openair3/TEST/EPC_TEST/play_scenario_parse.c index b9d24f366c..4004dd5074 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_parse.c +++ b/openair3/TEST/EPC_TEST/play_scenario_parse.c @@ -359,7 +359,7 @@ et_packet_t* et_parse_xml_packet(xmlDocPtr doc, xmlNodePtr node) { afloat = atof((const char*)xml_char); xmlFree(xml_char); packet->time_relative_to_first_packet.tv_sec = (int)afloat; - packet->time_relative_to_first_packet.tv_usec = (int)((afloat - packet->time_relative_to_first_packet.tv_sec)*1000000); + packet->time_relative_to_first_packet.tv_usec = (int)((afloat - packet->time_relative_to_first_packet.tv_sec)*1000000.0); if (first_packet > 0) { initial_time = packet->time_relative_to_first_packet; @@ -381,6 +381,13 @@ et_packet_t* et_parse_xml_packet(xmlDocPtr doc, xmlNodePtr node) { &packet->time_relative_to_last_sent_packet); relative_last_sent_packet = packet->time_relative_to_first_packet; } + if (first_received_packet > 0) { + packet->time_relative_to_last_received_packet.tv_sec = 0; + packet->time_relative_to_last_received_packet.tv_usec = 0; + } else { + timersub(&packet->time_relative_to_first_packet, &relative_last_received_packet, + &packet->time_relative_to_last_received_packet); + } } else if (packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { if (first_received_packet > 0) { relative_last_received_packet.tv_sec = packet->time_relative_to_first_packet.tv_sec; @@ -393,6 +400,13 @@ et_packet_t* et_parse_xml_packet(xmlDocPtr doc, xmlNodePtr node) { &packet->time_relative_to_last_received_packet); relative_last_received_packet = packet->time_relative_to_first_packet; } + if (first_sent_packet > 0) { + packet->time_relative_to_last_sent_packet.tv_sec = 0; + packet->time_relative_to_last_sent_packet.tv_usec = 0; + } else { + timersub(&packet->time_relative_to_first_packet, &relative_last_sent_packet, + &packet->time_relative_to_last_sent_packet); + } } } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"frame.number"))) { diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c index f5afebd786..6a39397f19 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c @@ -682,6 +682,11 @@ int et_s1ap_process_rx_packet(et_event_s1ap_data_ind_t * const s1ap_data_ind) packet->timestamp_packet.tv_usec = rx_packet->timestamp_packet.tv_usec; return et_scenario_set_packet_received(packet); } + } else if (strcmp(comp_results->name, "S1ap-TransportLayerAddress") == 0) { + S1AP_WARN("Some work needed there for %s, TODO in generic_scenario.xsl, add epc conf file in the process\n",comp_results->name); + 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"); } @@ -1109,18 +1114,22 @@ void *et_s1ap_eNB_task(void *arg) { et_packet_t * packet = (et_packet_t*)TIMER_HAS_EXPIRED (received_msg).arg; et_event_t event; - if (packet->status == ET_PACKET_STATUS_SCHEDULED_FOR_RECEIVING) { - memset((void*)&event, 0, sizeof(event)); - event.code = ET_EVENT_RX_PACKET_TIME_OUT; - event.u.rx_packet_time_out = packet; - et_scenario_fsm_notify_event(event); - } else if (packet->status == ET_PACKET_STATUS_SCHEDULED_FOR_SENDING) { - memset((void*)&event, 0, sizeof(event)); - event.code = ET_EVENT_TX_TIMED_PACKET; - event.u.tx_timed_packet = packet; - et_scenario_fsm_notify_event(event); - } else if ((packet->status != ET_PACKET_STATUS_SENT) && ((packet->status != ET_PACKET_STATUS_RECEIVED))) { - AssertFatal (0, "Bad status %d of packet timed out!\n", packet->status); + if (NULL != packet) { + if (packet->status == ET_PACKET_STATUS_SCHEDULED_FOR_RECEIVING) { + memset((void*)&event, 0, sizeof(event)); + event.code = ET_EVENT_RX_PACKET_TIME_OUT; + event.u.rx_packet_time_out = packet; + et_scenario_fsm_notify_event(event); + } else if (packet->status == ET_PACKET_STATUS_SCHEDULED_FOR_SENDING) { + memset((void*)&event, 0, sizeof(event)); + event.code = ET_EVENT_TX_TIMED_PACKET; + event.u.tx_timed_packet = packet; + et_scenario_fsm_notify_event(event); + } else if ((packet->status != ET_PACKET_STATUS_SENT) && ((packet->status != ET_PACKET_STATUS_RECEIVED))) { + AssertFatal (0, "Bad status %d of packet timed out!\n", packet->status); + } + } else { + LOG_W(S1AP, " Received TIMER_HAS_EXPIRED: timer_id %d, no packet attached to timer\n", TIMER_HAS_EXPIRED(received_msg).timer_id); } } if (TIMER_HAS_EXPIRED (received_msg).timer_id == g_scenario->enb_register_retry_timer_id) { 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 87ffe29e32..31d784b2bd 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c @@ -38,8 +38,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -457,7 +459,7 @@ asn_comp_rval_t * et_s1ap_ies_is_matching(const S1AP_PDU_PR present, s1ap_messag } -static void update_xpath_node_mme_ue_s1ap_id(et_s1ap_t * const s1ap, xmlNode *node, xmlChar *new_id_hex, xmlChar *new_id_dec, xmlChar *showname) +void update_xpath_node_mme_ue_s1ap_id(et_s1ap_t * const s1ap, xmlNode *node, const S1ap_MME_UE_S1AP_ID_t new_id) { xmlNode *cur_node = NULL; xmlAttrPtr attr = NULL; @@ -485,19 +487,47 @@ static void update_xpath_node_mme_ue_s1ap_id(et_s1ap_t * const s1ap, xmlNode *no xmlFree(xml_char); xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"size"); if (NULL != xml_char) { + const xmlChar value_d[32]; + const xmlChar value_h[20]; + const xmlChar showname[64]; + int ret = 0; + int pos2 = 0; + char val = NULL; + char hex[3] = {0,0,0};; + size = strtoul((const char *)xml_char, NULL, 0); xmlFree(xml_char); // second: try to set value (always hex) - attr = xmlSetProp((xmlNode *)cur_node, (const xmlChar *)"value", new_id_hex); - attr = xmlSetProp((xmlNode *)cur_node, (const xmlChar *)"show", new_id_dec); + ret = snprintf((char *)value_d, 32, "%ld", new_id); + AssertFatal((ret < 0) || (ret > 32), "Could not convert int to dec str"); + ret = snprintf((char *)value_h, 20, "C0%08X", new_id); + AssertFatal((ret < 0) || (ret > 20), "Could not convert int to hex str"); + ret = snprintf((char *)showname, 64, "MME-UE-S1AP-ID: %d", new_id); + AssertFatal((ret < 0) || (ret > 64), "Could not convert int to dec str"); + + attr = xmlSetProp((xmlNode *)cur_node, (const xmlChar *)"value", value_h); + attr = xmlSetProp((xmlNode *)cur_node, (const xmlChar *)"show", value_d); attr = xmlSetProp((xmlNode *)cur_node, (const xmlChar *)"showname", showname); //TODO update s1ap->binary_stream @pos with new_id_hex, size + AssertFatal((pos+size) < s1ap->binary_stream_allocated_size, "Rewrite of mme_ue_s1ap_id out of bounds of binary_stream"); + //avoid endianess issues + do { + hex[0] = value_h[pos2++]; + hex[1] = value_h[pos2++]; + hex[2] = 0; + val = (unsigned char)strtoul(hex, NULL, 16); + AssertFatal(errno != 0, "Conversion of hexstring %s failed", hex); + s1ap->binary_stream[pos++] = val; + } while (pos2 < (2*5)); + // update ASN1 + et_decode_s1ap(s1ap); + S1AP_DEBUG("Updated ASN1 for %s\n", showname); } } } } if (0 < go_deeper_in_tree) { - update_xpath_node_mme_ue_s1ap_id(s1ap, cur_node->children, new_id_hex, new_id_dec, showname); + update_xpath_node_mme_ue_s1ap_id(s1ap, cur_node->children, new_id); } } } @@ -510,24 +540,14 @@ static void update_xpath_node_mme_ue_s1ap_id(et_s1ap_t * const s1ap, xmlNode *no * Prints the @nodes content to @output. * From http://www.xmlsoft.org/examples/#xpath2.c */ -static void update_xpath_nodes_mme_ue_s1ap_id(et_s1ap_t * const s1ap_payload, xmlNodeSetPtr nodes, const S1ap_MME_UE_S1AP_ID_t new_id) +void update_xpath_nodes_mme_ue_s1ap_id(et_s1ap_t * const s1ap_payload, xmlNodeSetPtr nodes, const S1ap_MME_UE_S1AP_ID_t new_id) { int size = 0; int i = 0; - int ret = 0; - const xmlChar value_d[32]; - const xmlChar value_h[20]; - const xmlChar showname[64]; xmlNode *s1ap_node = NULL; size = (nodes) ? nodes->nodeNr : 0; - ret = snprintf((char *)value_d, 32, "%ld", new_id); - AssertFatal((ret < 0) || (ret > 32), "Could not convert int to dec str"); - ret = snprintf((char *)value_h, 20, "C0%X", new_id); - AssertFatal((ret < 0) || (ret > 20), "Could not convert int to hex str"); - ret = snprintf((char *)showname, 64, "MME-UE-S1AP-ID: %d", new_id); - AssertFatal((ret < 0) || (ret > 64), "Could not convert int to dec str"); /* * NOTE: the nodes are processed in reverse order, i.e. reverse document * order because xmlNodeSetContent can actually free up descendant @@ -539,7 +559,7 @@ static void update_xpath_nodes_mme_ue_s1ap_id(et_s1ap_t * const s1ap_payload, xm for(i = size - 1; i >= 0; i--) { s1ap_node = nodes->nodeTab[i]; AssertFatal(NULL != s1ap_node, "One element of resultset of XPATH expression is NULL\n"); - update_xpath_node_mme_ue_s1ap_id(s1ap_payload, s1ap_node, value_d, value_h, showname); + update_xpath_node_mme_ue_s1ap_id(s1ap_payload, s1ap_node, new_id); /* * All the elements returned by an XPath query are pointers to * elements from the tree *except* namespace nodes where the XPath @@ -574,7 +594,7 @@ int et_s1ap_update_mme_ue_s1ap_id(et_packet_t * const packet, const S1ap_MME_UE_ xmlXPathObjectPtr xpath_obj = NULL; ret = snprintf(xpath_expression, ET_XPATH_EXPRESSION_MAX_LENGTH, "//field[@name=\"s1ap.MME_UE_S1AP_ID\"][@show=\"%d\"]", old_id); - AssertFatal((ret < 0) || (ret > ET_XPATH_EXPRESSION_MAX_LENGTH), "Could not build XPATH expression"); + AssertFatal((ret > 0) && (ret < ET_XPATH_EXPRESSION_MAX_LENGTH), "Could not build XPATH expression err=%d", ret); doc = packet->sctp_hdr.u.data_hdr.payload.doc; diff --git a/openair3/TEST/EPC_TEST/play_scenario_sctp.c b/openair3/TEST/EPC_TEST/play_scenario_sctp.c index 181009c2c9..5d5489089b 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_sctp.c +++ b/openair3/TEST/EPC_TEST/play_scenario_sctp.c @@ -69,15 +69,16 @@ asn_comp_rval_t * et_sctp_data_is_matching(sctp_datahdr_t * const sctp1, sctp_da 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) { - 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); - } - } + // We do not have SSN from lower layers +// if (sctp1->ssn != sctp2->ssn) { +// if (constraints & ET_BIT_MASK_MATCH_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); +// } +// } return et_s1ap_is_matching(&sctp1->payload, &sctp2->payload, constraints); } From 64df39d1bf706a1206fe8239defb9217589d8a6b Mon Sep 17 00:00:00 2001 From: gauthier Date: Fri, 18 Dec 2015 21:11:45 +0100 Subject: [PATCH 22/47] Sync --- openair3/TEST/EPC_TEST/play_scenario.c | 277 +++++++++++++++++- openair3/TEST/EPC_TEST/play_scenario.h | 18 +- openair3/TEST/EPC_TEST/play_scenario_fsm.c | 58 ++-- openair3/TEST/EPC_TEST/play_scenario_parse.c | 52 +++- openair3/TEST/EPC_TEST/play_scenario_s1ap.c | 2 - .../EPC_TEST/play_scenario_s1ap_compare_ie.c | 1 - 6 files changed, 346 insertions(+), 62 deletions(-) diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c index 21aca820c2..d85faf4c2c 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.c +++ b/openair3/TEST/EPC_TEST/play_scenario.c @@ -130,6 +130,54 @@ int et_strip_extension(char *in_filename) } //------------------------------------------------------------------------------ // return number of splitted items +void et_get_shift_arg( char * line_argument, shift_packet_t * const shift) +{ + int len = strlen(line_argument); + int i = 0; + int j = 0; + int num_milli = 0; + char my_num[64]; + int negative = 0; + + + while ((line_argument[i] != ':') && (i < len)) { + my_num[i] = line_argument[i]; + i += 1; + } + my_num[i++] = '\0'; + shift->frame_number = atoi(my_num); + AssertFatal(ishift_seconds = atoi(my_num); + // may omit .mmm, accept .m or .mm or .mmm or ... + while ((i < len) && (num_milli++ < 3)){ + my_num[j++] = line_argument[i++]; + } + while (num_milli++ < 6){ + my_num[j++] = '0'; + } + my_num[j] = '\0'; + shift->shift_microseconds = atoi(my_num); + if (negative == 1) { + shift->shift_seconds = - shift->shift_seconds; + shift->shift_microseconds = - shift->shift_microseconds; + } +} +//------------------------------------------------------------------------------ +// return number of splitted items int split_path( char * pathP, char *** resP) { char * saveptr1; @@ -764,9 +812,168 @@ void *et_eNB_app_task(void *args_p) } //------------------------------------------------------------------------------ -int et_play_scenario(et_scenario_t* const scenario) +int et_play_scenario(et_scenario_t* const scenario, const struct shift_packet_s *shifts) { - et_event_t event; + et_event_t event; + struct shift_packet_s *shift = shifts; + et_packet_t *packet = NULL; + et_packet_t *next_packet = NULL; + struct timeval shift_all_packets = { .tv_sec = 0, .tv_usec = 0 }; + struct timeval relative_last_sent_packet = { .tv_sec = 0, .tv_usec = 0 }; + struct timeval relative_last_received_packet = { .tv_sec = 0, .tv_usec = 0 }; + struct timeval initial_time = { .tv_sec = 0, .tv_usec = 0 }; + char first_packet = 1; + char first_sent_packet = 1; + char first_received_packet = 1; + + // first apply timing shifts if requested + while (shift) { + packet = scenario->list_packet; + while (packet) { + fprintf(stdout, "*shift: %p\n", shift); + fprintf(stdout, "\tframe_number: %p\n", shift->frame_number); + fprintf(stdout, "\tshift_seconds: %ld\n", shift->shift_seconds); + fprintf(stdout, "\tshift_microseconds: %ld\n", shift->shift_microseconds); + fprintf(stdout, "\tsingle: %d\n\n", shift->single); + fprintf(stdout, "\tshift_all_packets_seconds: %ld\n", shift_all_packets.tv_sec); + fprintf(stdout, "\tshift_all_packets_microseconds: %ld\n", shift_all_packets.tv_usec); + + AssertFatal((packet->time_relative_to_first_packet.tv_sec >= 0) && (packet->time_relative_to_first_packet.tv_usec >= 0), + "Bad timing result time_relative_to_first_packet=%d.%d packet num %u, original frame number %u", + packet->time_relative_to_first_packet.tv_sec, + packet->time_relative_to_first_packet.tv_usec, + packet->packet_number, + packet->original_frame_number); + AssertFatal((packet->time_relative_to_last_received_packet.tv_sec >= 0) && (packet->time_relative_to_last_received_packet.tv_usec >= 0), + "Bad timing result time_relative_to_last_received_packet=%d.%d packet num %u, original frame number %u", + packet->time_relative_to_last_received_packet.tv_sec, + packet->time_relative_to_last_received_packet.tv_usec, + packet->packet_number, + packet->original_frame_number); + AssertFatal((packet->time_relative_to_last_sent_packet.tv_sec >= 0) && (packet->time_relative_to_last_sent_packet.tv_usec >= 0), + "Bad timing result time_relative_to_last_sent_packet=%d.%d packet num %u, original frame number %u", + packet->time_relative_to_last_sent_packet.tv_sec, + packet->time_relative_to_last_sent_packet.tv_usec, + packet->packet_number, + packet->original_frame_number); + fprintf(stdout, "\tpacket num %u, original frame number %u time_relative_to_first_packet=%d.%d\n", + packet->packet_number, + packet->original_frame_number, + packet->time_relative_to_first_packet.tv_sec, + packet->time_relative_to_first_packet.tv_usec); + fprintf(stdout, "\tpacket num %u, original frame number %u time_relative_to_last_received_packet=%d.%d\n", + packet->packet_number, + packet->original_frame_number, + packet->time_relative_to_last_received_packet.tv_sec, + packet->time_relative_to_last_received_packet.tv_usec); + fprintf(stdout, "\tpacket num %u, original frame number %u time_relative_to_last_sent_packet=%d.%d\n", + packet->packet_number, + packet->original_frame_number, + packet->time_relative_to_last_sent_packet.tv_sec, + packet->time_relative_to_last_sent_packet.tv_usec); + + if ((shift->single) && (shift->frame_number == packet->original_frame_number)) { + struct timeval t_offset = { .tv_sec = shift->shift_seconds, .tv_usec = shift->shift_microseconds }; + et_packet_shift_timing(packet, &t_offset); + next_packet = packet->next; + if (next_packet) { + t_offset.tv_sec = -t_offset.tv_sec; + t_offset.tv_usec = -t_offset.tv_usec; + + if (packet->action == ET_PACKET_ACTION_S1C_SEND) { + timeval_add(&next_packet->time_relative_to_last_sent_packet, &next_packet->time_relative_to_last_sent_packet, &t_offset); + } else if (packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { + timeval_add(&next_packet->time_relative_to_last_received_packet, &next_packet->time_relative_to_last_received_packet, &t_offset); + } + } + } + if ((0 == shift->single) && (shift->frame_number == packet->original_frame_number)) { + shift_all_packets.tv_sec = shift->shift_seconds; + shift_all_packets.tv_usec = shift->shift_microseconds; + timeval_add(&packet->time_relative_to_first_packet, &packet->time_relative_to_first_packet, &shift_all_packets); + fprintf(stdout, "\tpacket num %u, now original frame number %u time_relative_to_first_packet=%d.%d\n", + packet->packet_number, + packet->original_frame_number, + packet->time_relative_to_first_packet.tv_sec, + packet->time_relative_to_first_packet.tv_usec); + AssertFatal((packet->time_relative_to_first_packet.tv_sec >= 0) && (packet->time_relative_to_first_packet.tv_usec >= 0), + "Bad timing result time_relative_to_first_packet=%d.%d packet num %u, original frame number %u", + packet->time_relative_to_first_packet.tv_sec, + packet->time_relative_to_first_packet.tv_usec, + packet->packet_number, + packet->original_frame_number); + } else if ((0 == shift->single) && (shift->frame_number < packet->original_frame_number)) { + timeval_add(&packet->time_relative_to_first_packet, &packet->time_relative_to_first_packet, &shift_all_packets); + fprintf(stdout, "\tpacket num %u, now original frame number %u time_relative_to_first_packet=%d.%d\n", + packet->packet_number, + packet->original_frame_number, + packet->time_relative_to_first_packet.tv_sec, + packet->time_relative_to_first_packet.tv_usec); + AssertFatal((packet->time_relative_to_first_packet.tv_sec >= 0) && (packet->time_relative_to_first_packet.tv_usec >= 0), + "Bad timing result time_relative_to_first_packet=%d.%d packet num %u, original frame number %u", + packet->time_relative_to_first_packet.tv_sec, + packet->time_relative_to_first_packet.tv_usec, + packet->packet_number, + packet->original_frame_number); + } + packet = packet->next; + } + shift = shift->next; + } + // now recompute time_relative_to_last_received_packet, time_relative_to_last_sent_packet + if (shifts) { + packet = scenario->list_packet; + while (packet) { + if (first_packet > 0) { + initial_time = packet->time_relative_to_first_packet; + packet->time_relative_to_first_packet.tv_sec = 0; + packet->time_relative_to_first_packet.tv_usec = 0; + first_packet = 0; + } else { + timersub(&packet->time_relative_to_first_packet, &initial_time, + &packet->time_relative_to_first_packet); + } + if (packet->action == ET_PACKET_ACTION_S1C_SEND) { + if (first_sent_packet > 0) { + relative_last_sent_packet = packet->time_relative_to_first_packet; + packet->time_relative_to_last_sent_packet.tv_sec = 0; + packet->time_relative_to_last_sent_packet.tv_usec = 0; + first_sent_packet = 0; + } else { + timersub(&packet->time_relative_to_first_packet, &relative_last_sent_packet, + &packet->time_relative_to_last_sent_packet); + relative_last_sent_packet = packet->time_relative_to_first_packet; + } + if (first_received_packet > 0) { + packet->time_relative_to_last_received_packet.tv_sec = 0; + packet->time_relative_to_last_received_packet.tv_usec = 0; + } else { + timersub(&packet->time_relative_to_first_packet, &relative_last_received_packet, + &packet->time_relative_to_last_received_packet); + } + } else if (packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { + if (first_received_packet > 0) { + relative_last_received_packet.tv_sec = packet->time_relative_to_first_packet.tv_sec; + relative_last_received_packet.tv_usec = packet->time_relative_to_first_packet.tv_usec; + packet->time_relative_to_last_received_packet.tv_sec = 0; + packet->time_relative_to_last_received_packet.tv_usec = 0; + first_received_packet = 0; + } else { + timersub(&packet->time_relative_to_first_packet, &relative_last_received_packet, + &packet->time_relative_to_last_received_packet); + relative_last_received_packet = packet->time_relative_to_first_packet; + } + if (first_sent_packet > 0) { + packet->time_relative_to_last_sent_packet.tv_sec = 0; + packet->time_relative_to_last_sent_packet.tv_usec = 0; + } else { + timersub(&packet->time_relative_to_first_packet, &relative_last_sent_packet, + &packet->time_relative_to_last_sent_packet); + } + } + packet = packet->next; + } + } et_display_scenario(scenario); // create SCTP ITTI task: same as eNB code @@ -804,16 +1011,16 @@ 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 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 Directory where a set of files related to a particular test are located\n"); - fprintf (stdout, "\t-c | --enb-conf-file Provide an eNB config file, valid for the testbed\n"); - fprintf (stdout, "\t-s | --scenario File name (with no path) of a test scenario that has to be replayed ()\n"); + fprintf (stdout, "\t-d | --test-dir Directory where a set of files related to a particular test are located\n"); + fprintf (stdout, "\t-c | --enb-conf-file Provide an eNB config file, valid for the testbed\n"); + fprintf (stdout, "\t-f | --shift-packet Shift the timing of a packet'\n"); + fprintf (stdout, "\t-F | --shift-packets Shift the timing of packets starting at frame 'frame' included\n"); + fprintf (stdout, "\t-m | --max-speed Play scenario as fast as possible without respecting frame timings\n"); + fprintf (stdout, "\t-s | --scenario File name (with no path) of a test scenario that has to be replayed ()\n"); fprintf (stdout, "\n"); fprintf (stdout, "Other options:\n"); - fprintf (stdout, "\t-h | --help Print this help and return\n"); - fprintf (stdout, "\t-v | --version Print informations about the version of this executable\n"); + fprintf (stdout, "\t-h | --help Print this help and return\n"); + fprintf (stdout, "\t-v | --version Print informations about the version of this executable\n"); fprintf (stdout, "\n"); } @@ -824,11 +1031,13 @@ et_config_parse_opt_line ( char *argv[], char **et_dir_name, char **scenario_file_name, - char **enb_config_file_name) + char **enb_config_file_name, + shift_packet_t **shifts) //------------------------------------------------------------------------------ { - int option; - int rv = 0; + int option = 0; + int rv = 0; + shift_packet_t *shift = NULL; enum long_option_e { LONG_OPTION_START = 0x100, /* Start after regular single char options */ @@ -836,6 +1045,8 @@ et_config_parse_opt_line ( LONG_OPTION_SCENARIO_FILE, LONG_OPTION_MAX_SPEED, LONG_OPTION_TEST_DIR, + LONG_OPTION_SHIFT_PACKET, + LONG_OPTION_SHIFT_PACKETS, LONG_OPTION_HELP, LONG_OPTION_VERSION }; @@ -845,6 +1056,8 @@ et_config_parse_opt_line ( {"scenario ", required_argument, 0, LONG_OPTION_SCENARIO_FILE}, {"max-speed ", no_argument, 0, LONG_OPTION_MAX_SPEED}, {"test-dir", required_argument, 0, LONG_OPTION_TEST_DIR}, + {"shift-packet", required_argument, 0, LONG_OPTION_SHIFT_PACKET}, + {"shift-packets", required_argument, 0, LONG_OPTION_SHIFT_PACKETS}, {"help", no_argument, 0, LONG_OPTION_HELP}, {"version", no_argument, 0, LONG_OPTION_VERSION}, {NULL, 0, NULL, 0} @@ -853,7 +1066,7 @@ et_config_parse_opt_line ( /* * Parsing command line */ - while ((option = getopt_long (argc, argv, "vhmc:s:d:", long_options, NULL)) != -1) { + while ((option = getopt_long (argc, argv, "vhmc:s:d:f:F", long_options, NULL)) != -1) { switch (option) { case LONG_OPTION_ENB_CONF_FILE: case 'c': @@ -885,6 +1098,37 @@ et_config_parse_opt_line ( } break; + case LONG_OPTION_SHIFT_PACKET: + case 'f': + if (optarg) { + if (NULL == *shifts) { + shift = calloc(1, sizeof (*shift)); + *shifts = shift; + } else { + shift->next = calloc(1, sizeof (*shift)); + shift = shift->next; + } + shift->single = 1; + et_get_shift_arg(optarg, shift); + printf("Arg Shift packet %s\n", optarg); + } + break; + + case LONG_OPTION_SHIFT_PACKETS: + case 'F': + if (optarg) { + if (NULL == *shifts) { + shift = calloc(1, sizeof (*shift)); + *shifts = shift; + } else { + shift->next = calloc(1, sizeof (*shift)); + shift = shift->next; + } + et_get_shift_arg(optarg, shift); + printf("Arg Shift packets %s\n", optarg); + } + break; + case LONG_OPTION_MAX_SPEED: case 'm': g_max_speed = 1; @@ -938,6 +1182,7 @@ int main( int argc, char **argv ) char *et_dir_name = NULL; char *scenario_file_name = NULL; char *enb_config_file_name = NULL; + struct shift_packet_s *shifts = NULL; int ret = 0; et_scenario_t *scenario = NULL; char play_scenario_filename[NAME_MAX]; @@ -957,11 +1202,11 @@ int main( int argc, char **argv ) asn1_xer_print = 1; //parameters - actions = et_config_parse_opt_line (argc, argv, &et_dir_name, &scenario_file_name, &enb_config_file_name); //Command-line options + actions = et_config_parse_opt_line (argc, argv, &et_dir_name, &scenario_file_name, &enb_config_file_name, &shifts); //Command-line options if (actions & PLAY_SCENARIO) { if (et_generate_xml_scenario(et_dir_name, scenario_file_name,enb_config_file_name, play_scenario_filename) == 0) { if (NULL != (scenario = et_generate_scenario(play_scenario_filename))) { - ret = et_play_scenario(scenario); + ret = et_play_scenario(scenario, shifts); } else { fprintf(stderr, "ERROR: Could not generate scenario from tsml file\n"); ret = -1; diff --git a/openair3/TEST/EPC_TEST/play_scenario.h b/openair3/TEST/EPC_TEST/play_scenario.h index 0391ac5c47..ca569e5141 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.h +++ b/openair3/TEST/EPC_TEST/play_scenario.h @@ -89,6 +89,15 @@ #define ENB_CONFIG_STRING_ENB_PORT_FOR_S1U "ENB_PORT_FOR_S1U" +typedef struct shift_packet_s { + unsigned int frame_number; + int shift_seconds; + int shift_microseconds; + int single; // only this packet + struct shift_packet_s *next; +} shift_packet_t; + + typedef struct mme_ip_address_s { unsigned ipv4:1; unsigned ipv6:1; @@ -445,6 +454,10 @@ int et_generate_xml_scenario( const char const * enb_config_filename, char const * tsml_out_scenario_filename); //------------------------- +void timeval_add (struct timeval * const result, const struct timeval * const a, const struct timeval * const b); +int timeval_subtract (struct timeval * const result, struct timeval * const a, struct timeval * const b); +void et_scenario_wait_rx_packet(et_packet_t * const packet); +void et_scenario_schedule_tx_packet(et_packet_t * const packet); et_fsm_state_t et_scenario_fsm_notify_event_state_running(et_event_t event); et_fsm_state_t et_scenario_fsm_notify_event_state_waiting_tx(et_event_t event); et_fsm_state_t et_scenario_fsm_notify_event_state_waiting_rx(et_event_t event); @@ -458,7 +471,7 @@ void et_parse_sctp_init_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sct void et_parse_sctp_init_ack_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_initackhdr_t * const sctp_hdr); void et_parse_sctp(xmlDocPtr doc, const xmlNode const *sctp_node, et_sctp_hdr_t * const sctp_hdr); et_packet_t* et_parse_xml_packet(xmlDocPtr doc, xmlNodePtr node); -et_scenario_t* et_generate_scenario(const char * const et_scenario_filename ); +et_scenario_t* et_generate_scenario(const char * const et_scenario_filename); //------------------------- 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); void update_xpath_node_mme_ue_s1ap_id(et_s1ap_t * const s1ap, xmlNode *node, const S1ap_MME_UE_S1AP_ID_t new_id); @@ -471,6 +484,7 @@ asn_comp_rval_t * et_sctp_is_matching(et_sctp_hdr_t * const sctp1, et_sctp_hdr_t 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); int et_strip_extension( char *in_filename); +void et_get_shift_arg( char * line_argument, shift_packet_t * const shift); int et_split_path ( char * pathP, char *** resP); void et_display_node ( xmlNodePtr node, unsigned int indent); void et_display_tree ( xmlNodePtr node, unsigned int indent); @@ -486,6 +500,6 @@ void et_enb_config_init(const char const * lib_config_file_name_pP); const Enb_properties_array_t *et_enb_config_get(void); void et_eNB_app_register(const Enb_properties_array_t *enb_properties); void *et_eNB_app_task(void *args_p); -int et_play_scenario(et_scenario_t* const scenario); +int et_play_scenario(et_scenario_t* const scenario, const struct shift_packet_s *shifts); #endif /* PLAY_SCENARIO_H_ */ diff --git a/openair3/TEST/EPC_TEST/play_scenario_fsm.c b/openair3/TEST/EPC_TEST/play_scenario_fsm.c index a8f7e7331f..dece907dee 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_fsm.c +++ b/openair3/TEST/EPC_TEST/play_scenario_fsm.c @@ -54,36 +54,35 @@ pthread_mutex_t g_fsm_lock = PTHREAD_MUTEX_INITIALIZER; et_fsm_state_t g_fsm_state = ET_FSM_STATE_NULL; uint32_t g_constraints = ET_BIT_MASK_MATCH_SCTP_STREAM | ET_BIT_MASK_MATCH_SCTP_SSN; //------------------------------------------------------------------------------ -int timeval_subtract (struct timeval * const result, struct timeval * const a, struct timeval * const b) +// it is assumed that if a time is negative tv_sec and tv_usec are both negative +void timeval_add (struct timeval * const result, const struct timeval * const a, const struct timeval * const b) { - struct timeval b2; - int nsec = 0; - b2.tv_sec = b->tv_sec; - b2.tv_usec = b->tv_usec; - - - /* Perform the carry for the later subtraction by updating y. */ - if (a->tv_usec < b2.tv_usec) { - nsec = (b2.tv_usec - a->tv_usec) / 1000000 + 1; - b2.tv_usec -= 1000000 * nsec; - b2.tv_sec += nsec; + AssertFatal(((a->tv_sec <= 0) && (a->tv_usec <= 0)) || ((a->tv_sec >= 0) && (a->tv_usec >= 0)), " Bad time format arg a\n"); + AssertFatal(((b->tv_sec <= 0) && (b->tv_usec <= 0)) || ((b->tv_sec >= 0) && (b->tv_usec >= 0)), " Bad time format arg b\n"); + // may happen overflows but were are not dealing with very large timings + long long int r = a->tv_usec + b->tv_usec + (a->tv_sec + b->tv_sec) * 1000000; + result->tv_sec = r / (long long int)1000000; + result->tv_usec = r % (long long int)1000000; + if ((result != a) && (result != b)) { + LOG_D(ENB_APP, "timeval_add(%ld.%06d, %ld.%06d)=%ld.%06d\n", a->tv_sec, a->tv_usec, b->tv_sec, b->tv_usec, result->tv_sec, result->tv_usec); } - if (a->tv_usec - b2.tv_usec > 1000000) { - nsec = (a->tv_usec - b2.tv_usec) / 1000000; - b2.tv_usec += 1000000 * nsec; - b2.tv_sec -= nsec; - } - - /* Compute the time remaining to wait. - tv_usec is certainly positive. */ - result->tv_sec = a->tv_sec - b2.tv_sec; - result->tv_usec = a->tv_usec - b2.tv_usec; - - LOG_D(ENB_APP, "timeval_subtract(%ld.%06d, %ld.%06d)=%ld.%06d\n", a->tv_sec, a->tv_usec, b->tv_sec, b->tv_usec, result->tv_sec, result->tv_usec); - - return a->tv_sec < b2.tv_sec; } +//------------------------------------------------------------------------------ +// it is assumed that if a time is negative tv_sec and tv_usec are both negative +int timeval_subtract (struct timeval * const result, struct timeval * const a, struct timeval * const b) +{ + AssertFatal(((a->tv_sec <= 0) && (a->tv_usec <= 0)) || ((a->tv_sec >= 0) && (a->tv_usec >= 0)), " Bad time format arg a\n"); + AssertFatal(((b->tv_sec <= 0) && (b->tv_usec <= 0)) || ((b->tv_sec >= 0) && (b->tv_usec >= 0)), " Bad time format arg b\n"); + // may happen overflows but were are not dealing with very large timings + long long int r = a->tv_usec - b->tv_usec + (a->tv_sec - b->tv_sec) * 1000000; + result->tv_sec = r / (long long int)1000000; + result->tv_usec = r % (long long int)1000000; + if ((result != a) && (result != b)) { + LOG_D(ENB_APP, "timeval_subtract(%ld.%06d, %ld.%06d)=%ld.%06d\n", a->tv_sec, a->tv_usec, b->tv_sec, b->tv_usec, result->tv_sec, result->tv_usec); + } + return result->tv_sec < 0; +} //------------------------------------------------------------------------------ void et_scenario_wait_rx_packet(et_packet_t * const packet) @@ -137,10 +136,9 @@ void et_scenario_schedule_tx_packet(et_packet_t * const packet) } if ((0 < we_are_too_early) && (0 == g_max_speed)){ // set timer - if (offset.tv_sec < 0) offset.tv_sec = -offset.tv_sec; - if (offset.tv_usec < 0) { - offset.tv_usec = offset.tv_usec + 1000000; - offset.tv_sec -= 1; + if (offset.tv_sec < 0) { + offset.tv_sec = -offset.tv_sec; + offset.tv_usec = -offset.tv_usec; } LOG_D(ENB_APP, "Send packet num %u original frame number %u in %ld.%06d sec\n", diff --git a/openair3/TEST/EPC_TEST/play_scenario_parse.c b/openair3/TEST/EPC_TEST/play_scenario_parse.c index 4004dd5074..11dac34f0a 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_parse.c +++ b/openair3/TEST/EPC_TEST/play_scenario_parse.c @@ -62,7 +62,7 @@ extern Enb_properties_array_t g_enb_properties; //------------------------------------------------------------------------------ void et_parse_s1ap(xmlDocPtr doc, const xmlNode const *s1ap_node, et_s1ap_t * const s1ap) { - xmlNode *cur_node = NULL; + xmlNodePtr cur_node = NULL; xmlChar *xml_char = NULL; xmlChar *xml_char2 = NULL; unsigned int size = 0; @@ -329,9 +329,38 @@ 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) { +void et_packet_shift_timing(et_packet_t * const packet, const struct timeval * const shift) +{ + timeval_add(&packet->time_relative_to_first_packet, &packet->time_relative_to_first_packet, shift); + AssertFatal((packet->time_relative_to_first_packet.tv_sec >= 0) && (packet->time_relative_to_first_packet.tv_usec >= 0), + "Bad timing result time_relative_to_first_packet=%d.%d packet num %u, original frame number %u", + packet->time_relative_to_first_packet.tv_sec, + packet->time_relative_to_first_packet.tv_usec, + packet->packet_number, + packet->original_frame_number); - et_packet_t *packet = NULL; + timeval_add(&packet->time_relative_to_last_received_packet, &packet->time_relative_to_last_received_packet, shift); + AssertFatal((packet->time_relative_to_last_received_packet.tv_sec >= 0) && (packet->time_relative_to_last_received_packet.tv_usec >= 0), + "Bad timing result time_relative_to_last_received_packet=%d.%d packet num %u, original frame number %u", + packet->time_relative_to_last_received_packet.tv_sec, + packet->time_relative_to_last_received_packet.tv_usec, + packet->packet_number, + packet->original_frame_number); + + timeval_add(&packet->time_relative_to_last_sent_packet, &packet->time_relative_to_last_sent_packet, shift); + AssertFatal((packet->time_relative_to_last_sent_packet.tv_sec >= 0) && (packet->time_relative_to_last_sent_packet.tv_usec >= 0), + "Bad timing result time_relative_to_last_sent_packet=%d.%d packet num %u, original frame number %u", + packet->time_relative_to_last_sent_packet.tv_sec, + packet->time_relative_to_last_sent_packet.tv_usec, + packet->packet_number, + packet->original_frame_number); +} + +//------------------------------------------------------------------------------ +et_packet_t* et_parse_xml_packet(xmlDocPtr doc, xmlNodePtr node) +{ + + et_packet_t *packet = NULL; xmlNode *cur_node = NULL; xmlChar *xml_char = NULL; float afloat = (float)0.0; @@ -343,6 +372,7 @@ et_packet_t* et_parse_xml_packet(xmlDocPtr doc, xmlNodePtr node) { static char first_received_packet = 1; static unsigned int packet_number = 1; + if (NULL != node) { packet = calloc(1, sizeof(*packet)); @@ -441,15 +471,15 @@ et_packet_t* et_parse_xml_packet(xmlDocPtr doc, xmlNodePtr node) { } //------------------------------------------------------------------------------ et_scenario_t* et_generate_scenario( - const char * const tsml_out_scenario_filename ) + const char * const tsml_out_scenario_filename) { - xmlDocPtr doc = NULL; - xmlNodePtr root = NULL; - xmlNodePtr node = NULL; - xmlChar *xml_char = NULL; - et_scenario_t *scenario = NULL; - et_packet_t *packet = NULL; - et_packet_t **next_packet = NULL; + xmlDocPtr doc = NULL; + xmlNodePtr root = NULL; + xmlNodePtr node = NULL; + xmlChar *xml_char = NULL; + et_scenario_t *scenario = NULL; + et_packet_t *packet = NULL; + et_packet_t **next_packet = NULL; doc = xmlParseFile(tsml_out_scenario_filename); if (NULL == doc) { diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c index 6a39397f19..285b883ded 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c @@ -68,7 +68,6 @@ int et_s1ap_eNB_compare_assoc_id( if (p1->cnx_id < p2->cnx_id) { return -1; } - if (p1->cnx_id > p2->cnx_id) { return 1; } @@ -76,7 +75,6 @@ int et_s1ap_eNB_compare_assoc_id( if (p1->assoc_id < p2->assoc_id) { return -1; } - if (p1->assoc_id > p2->assoc_id) { return 1; } 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 31d784b2bd..32b571f823 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c @@ -586,7 +586,6 @@ int et_s1ap_update_mme_ue_s1ap_id(et_packet_t * const packet, const S1ap_MME_UE_ { - xmlNode *cur_node = NULL; xmlChar xpath_expression[ET_XPATH_EXPRESSION_MAX_LENGTH]; int ret = 0; xmlDocPtr doc = NULL; From ea7c5d5e6d694dc119010753c61aa449319cd116 Mon Sep 17 00:00:00 2001 From: gauthier Date: Tue, 22 Dec 2015 16:18:51 +0100 Subject: [PATCH 23/47] Ok, replay scenario, to be tested with more scenarios --- openair3/TEST/EPC_TEST/play_scenario.c | 64 +++++----- openair3/TEST/EPC_TEST/play_scenario.h | 9 +- openair3/TEST/EPC_TEST/play_scenario_fsm.c | 100 ++++++++++------ openair3/TEST/EPC_TEST/play_scenario_parse.c | 110 ++++++++---------- openair3/TEST/EPC_TEST/play_scenario_s1ap.c | 28 ++++- .../EPC_TEST/play_scenario_s1ap_compare_ie.c | 13 ++- 6 files changed, 184 insertions(+), 140 deletions(-) diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c index d85faf4c2c..e7cb8ef848 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.c +++ b/openair3/TEST/EPC_TEST/play_scenario.c @@ -830,13 +830,13 @@ int et_play_scenario(et_scenario_t* const scenario, const struct shift_packet_s while (shift) { packet = scenario->list_packet; while (packet) { - fprintf(stdout, "*shift: %p\n", shift); - fprintf(stdout, "\tframe_number: %p\n", shift->frame_number); - fprintf(stdout, "\tshift_seconds: %ld\n", shift->shift_seconds); - fprintf(stdout, "\tshift_microseconds: %ld\n", shift->shift_microseconds); - fprintf(stdout, "\tsingle: %d\n\n", shift->single); - fprintf(stdout, "\tshift_all_packets_seconds: %ld\n", shift_all_packets.tv_sec); - fprintf(stdout, "\tshift_all_packets_microseconds: %ld\n", shift_all_packets.tv_usec); +// fprintf(stdout, "*shift: %p\n", shift); +// fprintf(stdout, "\tframe_number: %p\n", shift->frame_number); +// fprintf(stdout, "\tshift_seconds: %ld\n", shift->shift_seconds); +// fprintf(stdout, "\tshift_microseconds: %ld\n", shift->shift_microseconds); +// fprintf(stdout, "\tsingle: %d\n\n", shift->single); +// fprintf(stdout, "\tshift_all_packets_seconds: %ld\n", shift_all_packets.tv_sec); +// fprintf(stdout, "\tshift_all_packets_microseconds: %ld\n", shift_all_packets.tv_usec); AssertFatal((packet->time_relative_to_first_packet.tv_sec >= 0) && (packet->time_relative_to_first_packet.tv_usec >= 0), "Bad timing result time_relative_to_first_packet=%d.%d packet num %u, original frame number %u", @@ -856,21 +856,21 @@ int et_play_scenario(et_scenario_t* const scenario, const struct shift_packet_s packet->time_relative_to_last_sent_packet.tv_usec, packet->packet_number, packet->original_frame_number); - fprintf(stdout, "\tpacket num %u, original frame number %u time_relative_to_first_packet=%d.%d\n", - packet->packet_number, - packet->original_frame_number, - packet->time_relative_to_first_packet.tv_sec, - packet->time_relative_to_first_packet.tv_usec); - fprintf(stdout, "\tpacket num %u, original frame number %u time_relative_to_last_received_packet=%d.%d\n", - packet->packet_number, - packet->original_frame_number, - packet->time_relative_to_last_received_packet.tv_sec, - packet->time_relative_to_last_received_packet.tv_usec); - fprintf(stdout, "\tpacket num %u, original frame number %u time_relative_to_last_sent_packet=%d.%d\n", - packet->packet_number, - packet->original_frame_number, - packet->time_relative_to_last_sent_packet.tv_sec, - packet->time_relative_to_last_sent_packet.tv_usec); +// fprintf(stdout, "\tpacket num %u, original frame number %u time_relative_to_first_packet=%d.%d\n", +// packet->packet_number, +// packet->original_frame_number, +// packet->time_relative_to_first_packet.tv_sec, +// packet->time_relative_to_first_packet.tv_usec); +// fprintf(stdout, "\tpacket num %u, original frame number %u time_relative_to_last_received_packet=%d.%d\n", +// packet->packet_number, +// packet->original_frame_number, +// packet->time_relative_to_last_received_packet.tv_sec, +// packet->time_relative_to_last_received_packet.tv_usec); +// fprintf(stdout, "\tpacket num %u, original frame number %u time_relative_to_last_sent_packet=%d.%d\n", +// packet->packet_number, +// packet->original_frame_number, +// packet->time_relative_to_last_sent_packet.tv_sec, +// packet->time_relative_to_last_sent_packet.tv_usec); if ((shift->single) && (shift->frame_number == packet->original_frame_number)) { struct timeval t_offset = { .tv_sec = shift->shift_seconds, .tv_usec = shift->shift_microseconds }; @@ -891,11 +891,11 @@ int et_play_scenario(et_scenario_t* const scenario, const struct shift_packet_s shift_all_packets.tv_sec = shift->shift_seconds; shift_all_packets.tv_usec = shift->shift_microseconds; timeval_add(&packet->time_relative_to_first_packet, &packet->time_relative_to_first_packet, &shift_all_packets); - fprintf(stdout, "\tpacket num %u, now original frame number %u time_relative_to_first_packet=%d.%d\n", - packet->packet_number, - packet->original_frame_number, - packet->time_relative_to_first_packet.tv_sec, - packet->time_relative_to_first_packet.tv_usec); +// fprintf(stdout, "\tpacket num %u, now original frame number %u time_relative_to_first_packet=%d.%d\n", +// packet->packet_number, +// packet->original_frame_number, +// packet->time_relative_to_first_packet.tv_sec, +// packet->time_relative_to_first_packet.tv_usec); AssertFatal((packet->time_relative_to_first_packet.tv_sec >= 0) && (packet->time_relative_to_first_packet.tv_usec >= 0), "Bad timing result time_relative_to_first_packet=%d.%d packet num %u, original frame number %u", packet->time_relative_to_first_packet.tv_sec, @@ -904,11 +904,11 @@ int et_play_scenario(et_scenario_t* const scenario, const struct shift_packet_s packet->original_frame_number); } else if ((0 == shift->single) && (shift->frame_number < packet->original_frame_number)) { timeval_add(&packet->time_relative_to_first_packet, &packet->time_relative_to_first_packet, &shift_all_packets); - fprintf(stdout, "\tpacket num %u, now original frame number %u time_relative_to_first_packet=%d.%d\n", - packet->packet_number, - packet->original_frame_number, - packet->time_relative_to_first_packet.tv_sec, - packet->time_relative_to_first_packet.tv_usec); +// fprintf(stdout, "\tpacket num %u, now original frame number %u time_relative_to_first_packet=%d.%d\n", +// packet->packet_number, +// packet->original_frame_number, +// packet->time_relative_to_first_packet.tv_sec, +// packet->time_relative_to_first_packet.tv_usec); AssertFatal((packet->time_relative_to_first_packet.tv_sec >= 0) && (packet->time_relative_to_first_packet.tv_usec >= 0), "Bad timing result time_relative_to_first_packet=%d.%d packet num %u, original frame number %u", packet->time_relative_to_first_packet.tv_sec, diff --git a/openair3/TEST/EPC_TEST/play_scenario.h b/openair3/TEST/EPC_TEST/play_scenario.h index ca569e5141..c1458047bd 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.h +++ b/openair3/TEST/EPC_TEST/play_scenario.h @@ -90,10 +90,10 @@ typedef struct shift_packet_s { - unsigned int frame_number; + unsigned int frame_number; // original frame number int shift_seconds; int shift_microseconds; - int single; // only this packet + int single; // shift timing only for this packet (not also following packets) struct shift_packet_s *next; } shift_packet_t; @@ -261,6 +261,7 @@ typedef enum { typedef struct et_s1ap_s { //et_s1ap_pdu_type_t pdu_type; S1AP_PDU_t pdu; // decoded ASN1 C type: choice of initiatingMessage, successfulOutcome, unsuccessfulOutcome + uint16_t xml_stream_pos_offset; uint16_t binary_stream_pos; uint16_t binary_stream_allocated_size; uint8_t *binary_stream; @@ -366,6 +367,8 @@ typedef struct et_scenario_s { et_packet_t *last_rx_packet; // Last packet received with all previous scenario RX packet received. et_packet_t *last_tx_packet; // Last sent packet et_packet_t *next_packet; // Next packet to be handled in the scenario (RX or TX packet) + + int timer_count; } et_scenario_t; @@ -457,7 +460,7 @@ int et_generate_xml_scenario( void timeval_add (struct timeval * const result, const struct timeval * const a, const struct timeval * const b); int timeval_subtract (struct timeval * const result, struct timeval * const a, struct timeval * const b); void et_scenario_wait_rx_packet(et_packet_t * const packet); -void et_scenario_schedule_tx_packet(et_packet_t * const packet); +void et_scenario_schedule_tx_packet(et_packet_t * packet); et_fsm_state_t et_scenario_fsm_notify_event_state_running(et_event_t event); et_fsm_state_t et_scenario_fsm_notify_event_state_waiting_tx(et_event_t event); et_fsm_state_t et_scenario_fsm_notify_event_state_waiting_rx(et_event_t event); diff --git a/openair3/TEST/EPC_TEST/play_scenario_fsm.c b/openair3/TEST/EPC_TEST/play_scenario_fsm.c index dece907dee..5dee83afc9 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_fsm.c +++ b/openair3/TEST/EPC_TEST/play_scenario_fsm.c @@ -70,6 +70,7 @@ void timeval_add (struct timeval * const result, const struct timeval * const a, //------------------------------------------------------------------------------ // it is assumed that if a time is negative tv_sec and tv_usec are both negative +// return true if result is positive int timeval_subtract (struct timeval * const result, struct timeval * const a, struct timeval * const b) { AssertFatal(((a->tv_sec <= 0) && (a->tv_usec <= 0)) || ((a->tv_sec >= 0) && (a->tv_usec >= 0)), " Bad time format arg a\n"); @@ -81,7 +82,7 @@ int timeval_subtract (struct timeval * const result, struct timeval * const a, s if ((result != a) && (result != b)) { LOG_D(ENB_APP, "timeval_subtract(%ld.%06d, %ld.%06d)=%ld.%06d\n", a->tv_sec, a->tv_usec, b->tv_sec, b->tv_usec, result->tv_sec, result->tv_usec); } - return result->tv_sec < 0; + return (result->tv_sec >= 0) && (result->tv_usec >= 0); } //------------------------------------------------------------------------------ @@ -93,10 +94,11 @@ void et_scenario_wait_rx_packet(et_packet_t * const packet) packet, &packet->timer_id) < 0) { AssertFatal(0, " Can not start waiting RX event timer\n"); } - LOG_D(ENB_APP, "Waiting RX packet num %d\n", packet->packet_number); + g_scenario->timer_count++; + LOG_D(ENB_APP, "Waiting RX packet num %d original frame number %u\n", packet->packet_number, packet->original_frame_number); } //------------------------------------------------------------------------------ -void et_scenario_schedule_tx_packet(et_packet_t * const packet) +void et_scenario_schedule_tx_packet(et_packet_t * packet) { s1ap_eNB_instance_t *s1ap_eNB_instance = NULL; struct timeval now = { .tv_sec = 0, .tv_usec = 0 }; @@ -104,8 +106,9 @@ void et_scenario_schedule_tx_packet(et_packet_t * const packet) struct timeval offset_last_rx_packet = { .tv_sec = 0, .tv_usec = 0 }; struct timeval offset_tx_rx = { .tv_sec = 0, .tv_usec = 0 }; struct timeval offset = { .tv_sec = 0, .tv_usec = 0 }; - int last_packet_was_tx = 0; - int we_are_too_early = 0; + int last_packet_was_rx = 0; + int we_are_too_late = 0; + int original_frame_number = -1; AssertFatal(NULL != packet, "packet argument is NULL"); s1ap_eNB_instance = et_s1ap_eNB_get_instance(packet->enb_instance); @@ -124,19 +127,19 @@ void et_scenario_schedule_tx_packet(et_packet_t * const packet) LOG_D(ENB_APP, "offset_last_tx_packet=%ld.%06d\n", offset_last_tx_packet.tv_sec, offset_last_tx_packet.tv_usec); LOG_D(ENB_APP, "offset_last_rx_packet=%ld.%06d\n", offset_last_rx_packet.tv_sec, offset_last_rx_packet.tv_usec); - last_packet_was_tx = timeval_subtract(&offset_tx_rx,&offset_last_tx_packet,&offset_last_rx_packet); - if (last_packet_was_tx) { - LOG_D(ENB_APP, "last_packet_was_tx\n"); - we_are_too_early = timeval_subtract(&offset,&offset_last_tx_packet,&packet->time_relative_to_last_sent_packet); - LOG_D(ENB_APP, "we_are_too_early=%d, offset=%ld.%06d\n", we_are_too_early, offset.tv_sec, offset.tv_usec); - } else { + last_packet_was_rx = timeval_subtract(&offset_tx_rx,&offset_last_tx_packet,&offset_last_rx_packet); + if (last_packet_was_rx) { LOG_D(ENB_APP, "last_packet_was_rx\n"); - we_are_too_early = timeval_subtract(&offset,&offset_last_rx_packet,&packet->time_relative_to_last_received_packet); - LOG_D(ENB_APP, "we_are_too_early=%d, offset=%ld.%06d\n", we_are_too_early, offset.tv_sec, offset.tv_usec); + we_are_too_late = timeval_subtract(&offset,&offset_last_rx_packet,&packet->time_relative_to_last_received_packet); + LOG_D(ENB_APP, "we_are_too_late=%d, offset=%ld.%06d\n", we_are_too_late, offset.tv_sec, offset.tv_usec); + } else { + LOG_D(ENB_APP, "last_packet_was_tx\n"); + we_are_too_late = timeval_subtract(&offset,&offset_last_tx_packet,&packet->time_relative_to_last_sent_packet); + LOG_D(ENB_APP, "we_are_too_early=%d, offset=%ld.%06d\n", we_are_too_late, offset.tv_sec, offset.tv_usec); } - if ((0 < we_are_too_early) && (0 == g_max_speed)){ + if ((0 == we_are_too_late) && (0 == g_max_speed)){ // set timer - if (offset.tv_sec < 0) { + if ((offset.tv_sec <= 0) || (offset.tv_usec <= 0)){ offset.tv_sec = -offset.tv_sec; offset.tv_usec = -offset.tv_usec; } @@ -148,23 +151,27 @@ void et_scenario_schedule_tx_packet(et_packet_t * const packet) if (timer_setup (offset.tv_sec, offset.tv_usec, TASK_S1AP, INSTANCE_DEFAULT, TIMER_ONE_SHOT,packet, &packet->timer_id) < 0) { AssertFatal(0, " Can not start TX event timer\n"); } + g_scenario->timer_count++; // Done g_fsm_state = ET_FSM_STATE_WAITING_TX_EVENT; } else { - LOG_D(ENB_APP, "Send packet num %u original frame number %u immediately\n", packet->packet_number, packet->original_frame_number); // send immediately AssertFatal(0 == gettimeofday(&packet->timestamp_packet, NULL), "gettimeofday() Failed"); + original_frame_number = packet->original_frame_number; + do { + g_scenario->time_last_tx_packet.tv_sec = packet->timestamp_packet.tv_sec; + g_scenario->time_last_tx_packet.tv_usec = packet->timestamp_packet.tv_usec; - g_scenario->time_last_tx_packet.tv_sec = packet->timestamp_packet.tv_sec; - g_scenario->time_last_tx_packet.tv_usec = packet->timestamp_packet.tv_usec; - - et_s1ap_eNB_itti_send_sctp_data_req( + LOG_D(ENB_APP, "Sending packet num %d original frame number %u immediately\n",packet->packet_number, packet->original_frame_number); + et_s1ap_eNB_itti_send_sctp_data_req( packet->enb_instance, packet->sctp_hdr.u.data_hdr.assoc_id, packet->sctp_hdr.u.data_hdr.payload.binary_stream, packet->sctp_hdr.u.data_hdr.payload.binary_stream_allocated_size, packet->sctp_hdr.u.data_hdr.stream); - packet->status = ET_PACKET_STATUS_SENT; - g_scenario->next_packet = g_scenario->next_packet->next; + packet->status = ET_PACKET_STATUS_SENT; + g_scenario->next_packet = g_scenario->next_packet->next; + packet = packet->next; + } while ((NULL != packet) && (packet->original_frame_number == original_frame_number)); g_fsm_state = ET_FSM_STATE_RUNNING; } break; @@ -183,7 +190,7 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_running(et_event_t event) switch (event.code){ case ET_EVENT_TICK: while (NULL != g_scenario->next_packet) { - LOG_D(ENB_APP, "EVENT_TICK: Considering packet num %d:\n", g_scenario->next_packet->packet_number); + LOG_D(ENB_APP, "EVENT_TICK: Considering packet num %d original frame number %u\n", g_scenario->next_packet->packet_number, g_scenario->next_packet->original_frame_number); switch (g_scenario->next_packet->sctp_hdr.chunk_type) { case SCTP_CID_DATA : // no init in this scenario, may be sub-scenario @@ -251,6 +258,13 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_running(et_event_t event) fprintf(stderr, "No Packet found in this scenario: %s\n", g_scenario->name); g_fsm_state = ET_FSM_STATE_NULL; pthread_mutex_unlock(&g_fsm_lock); + if (0 == g_scenario->timer_count) { + fprintf(stderr, "End of scenario: %s\n", g_scenario->name); + fflush(stderr); + fflush(stdout); + exit(0); + } + fprintf(stderr, "Remaining timers running: %d\n", g_scenario->timer_count); return g_fsm_state; break; case ET_EVENT_RX_PACKET_TIME_OUT: @@ -272,7 +286,10 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_running(et_event_t event) //------------------------------------------------------------------------------ et_fsm_state_t et_scenario_fsm_notify_event_state_waiting_tx(et_event_t event) { - int rv = 0; + int rv = 0; + int original_frame_number = -1; + et_packet_t *packet = NULL; + switch (event.code){ case ET_EVENT_TICK: fprintf(stdout, "EVENT_TICK: waiting for tx event\n"); @@ -284,19 +301,25 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_waiting_tx(et_event_t event) case ET_EVENT_TX_TIMED_PACKET: // send immediately - AssertFatal(0 == gettimeofday(&event.u.tx_timed_packet->timestamp_packet, NULL), "gettimeofday() Failed"); + packet = event.u.tx_timed_packet; + AssertFatal(0 == gettimeofday(&packet->timestamp_packet, NULL), "gettimeofday() Failed"); - g_scenario->time_last_tx_packet.tv_sec = event.u.tx_timed_packet->timestamp_packet.tv_sec; - g_scenario->time_last_tx_packet.tv_usec = event.u.tx_timed_packet->timestamp_packet.tv_usec; + original_frame_number = packet->original_frame_number; + do { + g_scenario->time_last_tx_packet.tv_sec = packet->timestamp_packet.tv_sec; + g_scenario->time_last_tx_packet.tv_usec = packet->timestamp_packet.tv_usec; - et_s1ap_eNB_itti_send_sctp_data_req( - event.u.tx_timed_packet->enb_instance, - event.u.tx_timed_packet->sctp_hdr.u.data_hdr.assoc_id, - event.u.tx_timed_packet->sctp_hdr.u.data_hdr.payload.binary_stream, - event.u.tx_timed_packet->sctp_hdr.u.data_hdr.payload.binary_stream_allocated_size, - event.u.tx_timed_packet->sctp_hdr.u.data_hdr.stream); - event.u.tx_timed_packet->status = ET_PACKET_STATUS_SENT; - g_scenario->next_packet = event.u.tx_timed_packet->next; + LOG_D(ENB_APP, "Sending packet num %d original frame number %u immediately\n",packet->packet_number, packet->original_frame_number); + et_s1ap_eNB_itti_send_sctp_data_req( + packet->enb_instance, + packet->sctp_hdr.u.data_hdr.assoc_id, + packet->sctp_hdr.u.data_hdr.payload.binary_stream, + packet->sctp_hdr.u.data_hdr.payload.binary_stream_allocated_size, + packet->sctp_hdr.u.data_hdr.stream); + packet->status = ET_PACKET_STATUS_SENT; + packet = packet->next; + g_scenario->next_packet = packet; + } while ( (NULL != packet) && (packet->original_frame_number == original_frame_number)); g_fsm_state = ET_FSM_STATE_RUNNING; break; @@ -411,6 +434,13 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_connecting_s1c(et_event_t even fprintf(stderr, "No Packet found in this scenario: %s\n", g_scenario->name); g_fsm_state = ET_FSM_STATE_NULL; pthread_mutex_unlock(&g_fsm_lock); + if (0 == g_scenario->timer_count) { + fprintf(stderr, "End of scenario: %s\n", g_scenario->name); + fflush(stderr); + fflush(stdout); + exit(0); + } + fprintf(stderr, "Remaining timers running: %d\n", g_scenario->timer_count); return g_fsm_state; break; diff --git a/openair3/TEST/EPC_TEST/play_scenario_parse.c b/openair3/TEST/EPC_TEST/play_scenario_parse.c index 11dac34f0a..aedc021f73 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_parse.c +++ b/openair3/TEST/EPC_TEST/play_scenario_parse.c @@ -71,10 +71,15 @@ void et_parse_s1ap(xmlDocPtr doc, const xmlNode const *s1ap_node, et_s1ap_t * co if ((NULL != s1ap_node) && (NULL != s1ap)) { // see http://www.xmlsoft.org/html/libxml-tree.html#xmlCopyNode - cur_node = xmlCopyNode(s1ap_node, 1); - AssertFatal(NULL != cur_node, "xmlCopyNode Failed"); - s1ap->doc = xmlNewDoc(BAD_CAST "1.0"); - xmlDocSetRootElement(s1ap->doc, cur_node); + if (NULL == s1ap->doc) { + xmlUnlinkNode(s1ap_node); + //cur_node = xmlCopyNodeList(s1ap_node); + // arg2: if 1 do a recursive copy (properties, namespaces and children when applicable) if 2 copy properties and namespaces (when applicable) + //cur_node = xmlCopyNode(s1ap_node, 1); + //AssertFatal(NULL != cur_node, "xmlCopyNode Failed"); + s1ap->doc = xmlNewDoc(BAD_CAST "1.0"); + xmlDocSetRootElement(s1ap->doc, s1ap_node); + } for (cur_node = (xmlNode *)s1ap_node; cur_node; cur_node = cur_node->next) { go_deeper_in_tree = 1; @@ -97,17 +102,17 @@ void et_parse_s1ap(xmlDocPtr doc, const xmlNode const *s1ap_node, et_s1ap_t * co xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"value"); if (NULL != xml_char) { xml_char2 = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"name"); - fprintf(stdout, "s1ap %p field %s size %d value %s\n",s1ap, xml_char2, size, xml_char); + fprintf(stdout, "s1ap %p field name %s size %d value %s\n",s1ap, xml_char2, size, xml_char); xmlFree(xml_char2); // if success to get value, do not parse children //AssertFatal ((xmlStrlen(xml_char) == size), "ERROR %s() mismatch in size %d and strlen %d\n", __FUNCTION__, size, xmlStrlen(xml_char)); //if (xmlStrlen(xml_char) == size) { AssertFatal ((s1ap->binary_stream_pos+xmlStrlen(xml_char)/2) <= s1ap->binary_stream_allocated_size, - "ERROR %s() in buffer size: binary_stream_pos %d xmlStrlen(xml_char)/2=%d\n", __FUNCTION__, s1ap->binary_stream_pos, xmlStrlen(xml_char)/2); + "ERROR in buffer size: binary_stream_pos %d xmlStrlen(xml_char)/2=%d\n", s1ap->binary_stream_pos, xmlStrlen(xml_char)/2); rc = et_hex2data( &s1ap->binary_stream[s1ap->binary_stream_pos], xml_char, xmlStrlen(xml_char)); s1ap->binary_stream_pos += xmlStrlen(xml_char)/2; - et_display_node(cur_node, 0); - AssertFatal (rc >= 0, "ERROR %s() in converting hex string %s len %d size %d rc %d\n", __FUNCTION__, xml_char, xmlStrlen(xml_char), size, rc); + //et_display_node(cur_node, 0); + AssertFatal (rc >= 0, "ERROR in converting hex string %s len %d size %d rc %d\n", xml_char, xmlStrlen(xml_char), size, rc); go_deeper_in_tree = 0; //} xmlFree(xml_char); @@ -274,15 +279,23 @@ void et_parse_sctp(xmlDocPtr doc, const xmlNode const *sctp_node, et_sctp_hdr_t if (NULL != xml_char) { if ((!xmlStrcmp(xml_char, (const xmlChar *)"s1ap"))) { xmlFree(xml_char); - xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"size"); - if (NULL != xml_char2) { - sctp_hdr->u.data_hdr.payload.binary_stream_allocated_size = strtoul((const char *)xml_char2, NULL, 0); - sctp_hdr->u.data_hdr.payload.binary_stream = calloc(1, sctp_hdr->u.data_hdr.payload.binary_stream_allocated_size); - xmlFree(xml_char2); + xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"pos"); + if (NULL != xml_char) { + sctp_hdr->u.data_hdr.payload.xml_stream_pos_offset = strtoul((const char *)xml_char, NULL, 0); + xmlFree(xml_char); + + xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"size"); + if (NULL != xml_char2) { + sctp_hdr->u.data_hdr.payload.binary_stream_allocated_size = strtoul((const char *)xml_char2, NULL, 0); + sctp_hdr->u.data_hdr.payload.binary_stream = calloc(1, sctp_hdr->u.data_hdr.payload.binary_stream_allocated_size); + sctp_hdr->u.data_hdr.payload.binary_stream_pos = 0; + fprintf(stdout, "Allocating payload of sctp_hdr %p %u bytes\n", sctp_hdr, sctp_hdr->u.data_hdr.payload.binary_stream_allocated_size); + xmlFree(xml_char2); + } + et_parse_s1ap(doc, sctp_node, &sctp_hdr->u.data_hdr.payload); + et_decode_s1ap(&sctp_hdr->u.data_hdr.payload); + return; } - et_parse_s1ap(doc, sctp_node, &sctp_hdr->u.data_hdr.payload); - et_decode_s1ap(&sctp_hdr->u.data_hdr.payload); - return; } xmlFree(xml_char); } @@ -388,6 +401,7 @@ et_packet_t* et_parse_xml_packet(xmlDocPtr doc, xmlNodePtr node) xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"value"); afloat = atof((const char*)xml_char); xmlFree(xml_char); + fprintf(stdout, "Parsing packet frame.time_relative: %f\n", afloat); packet->time_relative_to_first_packet.tv_sec = (int)afloat; packet->time_relative_to_first_packet.tv_usec = (int)((afloat - packet->time_relative_to_first_packet.tv_sec)*1000000.0); @@ -400,48 +414,10 @@ et_packet_t* et_parse_xml_packet(xmlDocPtr doc, xmlNodePtr node) timersub(&packet->time_relative_to_first_packet, &initial_time, &packet->time_relative_to_first_packet); } - if (packet->action == ET_PACKET_ACTION_S1C_SEND) { - if (first_sent_packet > 0) { - relative_last_sent_packet = packet->time_relative_to_first_packet; - packet->time_relative_to_last_sent_packet.tv_sec = 0; - packet->time_relative_to_last_sent_packet.tv_usec = 0; - first_sent_packet = 0; - } else { - timersub(&packet->time_relative_to_first_packet, &relative_last_sent_packet, - &packet->time_relative_to_last_sent_packet); - relative_last_sent_packet = packet->time_relative_to_first_packet; - } - if (first_received_packet > 0) { - packet->time_relative_to_last_received_packet.tv_sec = 0; - packet->time_relative_to_last_received_packet.tv_usec = 0; - } else { - timersub(&packet->time_relative_to_first_packet, &relative_last_received_packet, - &packet->time_relative_to_last_received_packet); - } - } else if (packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { - if (first_received_packet > 0) { - relative_last_received_packet.tv_sec = packet->time_relative_to_first_packet.tv_sec; - relative_last_received_packet.tv_usec = packet->time_relative_to_first_packet.tv_usec; - packet->time_relative_to_last_received_packet.tv_sec = 0; - packet->time_relative_to_last_received_packet.tv_usec = 0; - first_received_packet = 0; - } else { - timersub(&packet->time_relative_to_first_packet, &relative_last_received_packet, - &packet->time_relative_to_last_received_packet); - relative_last_received_packet = packet->time_relative_to_first_packet; - } - if (first_sent_packet > 0) { - packet->time_relative_to_last_sent_packet.tv_sec = 0; - packet->time_relative_to_last_sent_packet.tv_usec = 0; - } else { - timersub(&packet->time_relative_to_first_packet, &relative_last_sent_packet, - &packet->time_relative_to_last_sent_packet); - } - } - } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"frame.number"))) { xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"value"); packet->original_frame_number = strtoul((const char *)xml_char, NULL, 0); + fprintf(stdout, "Parsing packet frame.number: %u\n", packet->original_frame_number); xmlFree(xml_char); } else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"ip.src"))) { xml_char = xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1); @@ -473,13 +449,14 @@ et_packet_t* et_parse_xml_packet(xmlDocPtr doc, xmlNodePtr node) et_scenario_t* et_generate_scenario( const char * const tsml_out_scenario_filename) { - xmlDocPtr doc = NULL; - xmlNodePtr root = NULL; - xmlNodePtr node = NULL; - xmlChar *xml_char = NULL; - et_scenario_t *scenario = NULL; - et_packet_t *packet = NULL; - et_packet_t **next_packet = NULL; + xmlDocPtr doc = NULL; + xmlNodePtr root = NULL; + xmlNodePtr node = NULL; + xmlChar *xml_char = NULL; + et_scenario_t *scenario = NULL; + et_packet_t *last_packet = NULL; + et_packet_t *packet = NULL; + et_packet_t **next_packet = NULL; doc = xmlParseFile(tsml_out_scenario_filename); if (NULL == doc) { @@ -503,6 +480,14 @@ et_scenario_t* et_generate_scenario( if ((!xmlStrcmp(node->name, (const xmlChar *)"packet"))) { packet = et_parse_xml_packet(doc, node); if (NULL != packet) { + // special case: S1AP same frame for 2 packets + if (NULL != last_packet) { + if (last_packet->original_frame_number == packet->original_frame_number) { + // updating because these informations are not in 2nd sctp header (same IP packet) + packet->sctp_hdr.dst_port = last_packet->sctp_hdr.dst_port; + packet->sctp_hdr.src_port = last_packet->sctp_hdr.src_port; + } + } *next_packet = packet; next_packet = &packet->next; } else { @@ -510,6 +495,7 @@ et_scenario_t* et_generate_scenario( et_display_node(node, 0); } } + last_packet = packet; } } } else { diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c index 285b883ded..5d5a3672d3 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c @@ -362,8 +362,16 @@ int et_handle_s1ap_mismatch_mme_ue_s1ap_id(et_packet_t * const spacket, et_packe 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; + switch (rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextReleaseCommandIEs.uE_S1AP_IDs.present) { + case S1ap_UE_S1AP_IDs_PR_uE_S1AP_ID_pair: + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextReleaseCommandIEs.uE_S1AP_IDs.choice.uE_S1AP_ID_pair.mME_UE_S1AP_ID; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextReleaseCommandIEs.uE_S1AP_IDs.choice.uE_S1AP_ID_pair.mME_UE_S1AP_ID; + break; + case S1ap_UE_S1AP_IDs_PR_mME_UE_S1AP_ID: + rx_mme_ue_s1ap_id = rx_packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextReleaseCommandIEs.uE_S1AP_IDs.choice.mME_UE_S1AP_ID; + scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextReleaseCommandIEs.uE_S1AP_IDs.choice.mME_UE_S1AP_ID; + break; + } } 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; @@ -511,6 +519,7 @@ int et_handle_s1ap_mismatch_mme_ue_s1ap_id(et_packet_t * const spacket, et_packe AssertFatal(0, "Unknown procedure code %ld", rx_packet->sctp_hdr.u.data_hdr.payload.message.procedureCode); } if (scenario_mme_ue_s1ap_id != rx_mme_ue_s1ap_id) { + S1AP_DEBUG("%s() Updating mme_ue_s1ap_id %u -> %u \n", __FUNCTION__, scenario_mme_ue_s1ap_id, rx_mme_ue_s1ap_id); et_packet_t * p = spacket; while (p) { et_s1ap_update_mme_ue_s1ap_id(p, scenario_mme_ue_s1ap_id, rx_mme_ue_s1ap_id); @@ -615,6 +624,7 @@ int et_scenario_set_packet_received(et_packet_t * const packet) if (0 != packet->timer_id) { rc = timer_remove(packet->timer_id); AssertFatal(rc == 0, "TODO: Debug Timer on Rx packet num %d unknown", packet->packet_number); + g_scenario->timer_count--; return rc; } return 1; @@ -656,7 +666,8 @@ int et_s1ap_process_rx_packet(et_event_s1ap_data_ind_t * const s1ap_data_ind) packet = g_scenario->last_rx_packet->next; } // not_found threshold may sure depend on number of mme, may be not sure on number of UE - while ((NULL != packet) && (not_found < 5)) { + while ((NULL != packet) && (not_found < 7)) { + S1AP_DEBUG("%s() Considering packet num %d original frame number %u\n", __FUNCTION__, packet->packet_number, packet->original_frame_number); if (packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { comp_results = et_sctp_is_matching(&packet->sctp_hdr, &rx_packet->sctp_hdr, g_constraints); if (NULL == comp_results) { @@ -681,11 +692,15 @@ int et_s1ap_process_rx_packet(et_event_s1ap_data_ind_t * const s1ap_data_ind) return et_scenario_set_packet_received(packet); } } else if (strcmp(comp_results->name, "S1ap-TransportLayerAddress") == 0) { - S1AP_WARN("Some work needed there for %s, TODO in generic_scenario.xsl, add epc conf file in the process\n",comp_results->name); + S1AP_WARN("Some work needed there for %s, TODO in generic_scenario.xsl, add epc conf file in the process, anyway continuing...\n",comp_results->name); 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_WARN("\n\nRX PACKET:\n"); + et_display_packet_sctp(&rx_packet->sctp_hdr); + S1AP_WARN("\n\nWAITED PACKET:\n"); + et_display_packet_sctp(&packet->sctp_hdr); AssertFatal(0,"Some work needed there"); } } @@ -1112,6 +1127,7 @@ void *et_s1ap_eNB_task(void *arg) { et_packet_t * packet = (et_packet_t*)TIMER_HAS_EXPIRED (received_msg).arg; et_event_t event; + g_scenario->timer_count--; if (NULL != packet) { if (packet->status == ET_PACKET_STATUS_SCHEDULED_FOR_RECEIVING) { memset((void*)&event, 0, sizeof(event)); @@ -1123,6 +1139,10 @@ void *et_s1ap_eNB_task(void *arg) event.code = ET_EVENT_TX_TIMED_PACKET; event.u.tx_timed_packet = packet; et_scenario_fsm_notify_event(event); + + et_event_t continue_event; + continue_event.code = ET_EVENT_TICK; + et_scenario_fsm_notify_event(continue_event); } else if ((packet->status != ET_PACKET_STATUS_SENT) && ((packet->status != ET_PACKET_STATUS_RECEIVED))) { AssertFatal (0, "Bad status %d of packet timed out!\n", packet->status); } 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 32b571f823..ad720ab7dc 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c @@ -467,6 +467,8 @@ void update_xpath_node_mme_ue_s1ap_id(et_s1ap_t * const s1ap, xmlNode *node, con int size = 0; int pos = 0; int go_deeper_in_tree = 1; + S1AP_DEBUG("%s() mme_ue_s1ap_id %u\n", __FUNCTION__, new_id); + // modify for (cur_node = (xmlNode *)node; cur_node; cur_node = cur_node->next) { go_deeper_in_tree = 1; @@ -484,6 +486,8 @@ void update_xpath_node_mme_ue_s1ap_id(et_s1ap_t * const s1ap, xmlNode *node, con xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"pos"); if (NULL != xml_char) { pos = strtoul((const char *)xml_char, NULL, 0); + pos -= s1ap->xml_stream_pos_offset; + AssertFatal(pos >= 0, "Bad pos %d xml_stream_pos_offset %d", pos, s1ap->xml_stream_pos_offset); xmlFree(xml_char); xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"size"); if (NULL != xml_char) { @@ -499,11 +503,11 @@ void update_xpath_node_mme_ue_s1ap_id(et_s1ap_t * const s1ap, xmlNode *node, con xmlFree(xml_char); // second: try to set value (always hex) ret = snprintf((char *)value_d, 32, "%ld", new_id); - AssertFatal((ret < 0) || (ret > 32), "Could not convert int to dec str"); + AssertFatal((ret > 0) && (ret < 32), "Could not convert int to dec str"); ret = snprintf((char *)value_h, 20, "C0%08X", new_id); - AssertFatal((ret < 0) || (ret > 20), "Could not convert int to hex str"); + AssertFatal((ret > 0) && (ret < 20), "Could not convert int to hex str"); ret = snprintf((char *)showname, 64, "MME-UE-S1AP-ID: %d", new_id); - AssertFatal((ret < 0) || (ret > 64), "Could not convert int to dec str"); + AssertFatal((ret > 0) && (ret < 64), "Could not convert int to dec str"); attr = xmlSetProp((xmlNode *)cur_node, (const xmlChar *)"value", value_h); attr = xmlSetProp((xmlNode *)cur_node, (const xmlChar *)"show", value_d); @@ -592,11 +596,12 @@ int et_s1ap_update_mme_ue_s1ap_id(et_packet_t * const packet, const S1ap_MME_UE_ xmlXPathContextPtr xpath_ctx = NULL; xmlXPathObjectPtr xpath_obj = NULL; + S1AP_DEBUG("%s() packet num %u original frame number %u, mme_ue_s1ap_id %u -> %u\n", __FUNCTION__, packet->packet_number, packet->original_frame_number, old_id, new_id); + ret = snprintf(xpath_expression, ET_XPATH_EXPRESSION_MAX_LENGTH, "//field[@name=\"s1ap.MME_UE_S1AP_ID\"][@show=\"%d\"]", old_id); AssertFatal((ret > 0) && (ret < ET_XPATH_EXPRESSION_MAX_LENGTH), "Could not build XPATH expression err=%d", ret); doc = packet->sctp_hdr.u.data_hdr.payload.doc; - // Create xpath evaluation context xpath_ctx = xmlXPathNewContext(doc); if(xpath_ctx == NULL) { From b14a2212fda1cff45267144085a1faad437ea8b8 Mon Sep 17 00:00:00 2001 From: gauthier Date: Tue, 5 Jan 2016 11:38:39 +0100 Subject: [PATCH 24/47] Correct timming issues --- openair3/TEST/EPC_TEST/play_scenario.c | 100 +++++++++--------- openair3/TEST/EPC_TEST/play_scenario_fsm.c | 2 +- .../EPC_TEST/play_scenario_s1ap_compare_ie.c | 18 ++-- 3 files changed, 60 insertions(+), 60 deletions(-) diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c index e7cb8ef848..c633cedfa7 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.c +++ b/openair3/TEST/EPC_TEST/play_scenario.c @@ -921,58 +921,56 @@ int et_play_scenario(et_scenario_t* const scenario, const struct shift_packet_s shift = shift->next; } // now recompute time_relative_to_last_received_packet, time_relative_to_last_sent_packet - if (shifts) { - packet = scenario->list_packet; - while (packet) { - if (first_packet > 0) { - initial_time = packet->time_relative_to_first_packet; - packet->time_relative_to_first_packet.tv_sec = 0; - packet->time_relative_to_first_packet.tv_usec = 0; - first_packet = 0; - } else { - timersub(&packet->time_relative_to_first_packet, &initial_time, - &packet->time_relative_to_first_packet); - } - if (packet->action == ET_PACKET_ACTION_S1C_SEND) { - if (first_sent_packet > 0) { - relative_last_sent_packet = packet->time_relative_to_first_packet; - packet->time_relative_to_last_sent_packet.tv_sec = 0; - packet->time_relative_to_last_sent_packet.tv_usec = 0; - first_sent_packet = 0; - } else { - timersub(&packet->time_relative_to_first_packet, &relative_last_sent_packet, - &packet->time_relative_to_last_sent_packet); - relative_last_sent_packet = packet->time_relative_to_first_packet; - } - if (first_received_packet > 0) { - packet->time_relative_to_last_received_packet.tv_sec = 0; - packet->time_relative_to_last_received_packet.tv_usec = 0; - } else { - timersub(&packet->time_relative_to_first_packet, &relative_last_received_packet, - &packet->time_relative_to_last_received_packet); - } - } else if (packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { - if (first_received_packet > 0) { - relative_last_received_packet.tv_sec = packet->time_relative_to_first_packet.tv_sec; - relative_last_received_packet.tv_usec = packet->time_relative_to_first_packet.tv_usec; - packet->time_relative_to_last_received_packet.tv_sec = 0; - packet->time_relative_to_last_received_packet.tv_usec = 0; - first_received_packet = 0; - } else { - timersub(&packet->time_relative_to_first_packet, &relative_last_received_packet, - &packet->time_relative_to_last_received_packet); - relative_last_received_packet = packet->time_relative_to_first_packet; - } - if (first_sent_packet > 0) { - packet->time_relative_to_last_sent_packet.tv_sec = 0; - packet->time_relative_to_last_sent_packet.tv_usec = 0; - } else { - timersub(&packet->time_relative_to_first_packet, &relative_last_sent_packet, - &packet->time_relative_to_last_sent_packet); - } - } - packet = packet->next; + packet = scenario->list_packet; + while (packet) { + if (first_packet > 0) { + initial_time = packet->time_relative_to_first_packet; + packet->time_relative_to_first_packet.tv_sec = 0; + packet->time_relative_to_first_packet.tv_usec = 0; + first_packet = 0; + } else { + timersub(&packet->time_relative_to_first_packet, &initial_time, + &packet->time_relative_to_first_packet); } + if (packet->action == ET_PACKET_ACTION_S1C_SEND) { + if (first_sent_packet > 0) { + relative_last_sent_packet = packet->time_relative_to_first_packet; + packet->time_relative_to_last_sent_packet.tv_sec = 0; + packet->time_relative_to_last_sent_packet.tv_usec = 0; + first_sent_packet = 0; + } else { + timersub(&packet->time_relative_to_first_packet, &relative_last_sent_packet, + &packet->time_relative_to_last_sent_packet); + relative_last_sent_packet = packet->time_relative_to_first_packet; + } + if (first_received_packet > 0) { + packet->time_relative_to_last_received_packet.tv_sec = 0; + packet->time_relative_to_last_received_packet.tv_usec = 0; + } else { + timersub(&packet->time_relative_to_first_packet, &relative_last_received_packet, + &packet->time_relative_to_last_received_packet); + } + } else if (packet->action == ET_PACKET_ACTION_S1C_RECEIVE) { + if (first_received_packet > 0) { + relative_last_received_packet.tv_sec = packet->time_relative_to_first_packet.tv_sec; + relative_last_received_packet.tv_usec = packet->time_relative_to_first_packet.tv_usec; + packet->time_relative_to_last_received_packet.tv_sec = 0; + packet->time_relative_to_last_received_packet.tv_usec = 0; + first_received_packet = 0; + } else { + timersub(&packet->time_relative_to_first_packet, &relative_last_received_packet, + &packet->time_relative_to_last_received_packet); + relative_last_received_packet = packet->time_relative_to_first_packet; + } + if (first_sent_packet > 0) { + packet->time_relative_to_last_sent_packet.tv_sec = 0; + packet->time_relative_to_last_sent_packet.tv_usec = 0; + } else { + timersub(&packet->time_relative_to_first_packet, &relative_last_sent_packet, + &packet->time_relative_to_last_sent_packet); + } + } + packet = packet->next; } et_display_scenario(scenario); diff --git a/openair3/TEST/EPC_TEST/play_scenario_fsm.c b/openair3/TEST/EPC_TEST/play_scenario_fsm.c index 5dee83afc9..d253e5cd5f 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_fsm.c +++ b/openair3/TEST/EPC_TEST/play_scenario_fsm.c @@ -135,7 +135,7 @@ void et_scenario_schedule_tx_packet(et_packet_t * packet) } else { LOG_D(ENB_APP, "last_packet_was_tx\n"); we_are_too_late = timeval_subtract(&offset,&offset_last_tx_packet,&packet->time_relative_to_last_sent_packet); - LOG_D(ENB_APP, "we_are_too_early=%d, offset=%ld.%06d\n", we_are_too_late, offset.tv_sec, offset.tv_usec); + LOG_D(ENB_APP, "we_are_too_late=%d, offset=%ld.%06d\n", we_are_too_late, offset.tv_sec, offset.tv_usec); } if ((0 == we_are_too_late) && (0 == g_max_speed)){ // set timer 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 ad720ab7dc..2242a63bd6 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c @@ -494,10 +494,11 @@ void update_xpath_node_mme_ue_s1ap_id(et_s1ap_t * const s1ap, xmlNode *node, con const xmlChar value_d[32]; const xmlChar value_h[20]; const xmlChar showname[64]; - int ret = 0; - int pos2 = 0; - char val = NULL; - char hex[3] = {0,0,0};; + int ret = 0; + int pos2 = 0; + unsigned long int uli = 0; + char hex[3] = {0,0,0}; + char *end_ptr = NULL; size = strtoul((const char *)xml_char, NULL, 0); xmlFree(xml_char); @@ -518,10 +519,11 @@ void update_xpath_node_mme_ue_s1ap_id(et_s1ap_t * const s1ap, xmlNode *node, con do { hex[0] = value_h[pos2++]; hex[1] = value_h[pos2++]; - hex[2] = 0; - val = (unsigned char)strtoul(hex, NULL, 16); - AssertFatal(errno != 0, "Conversion of hexstring %s failed", hex); - s1ap->binary_stream[pos++] = val; + hex[2] = '\0'; + end_ptr = hex; + uli = strtoul(hex, &end_ptr, 16); + AssertFatal((uli != ULONG_MAX) && (end_ptr != NULL) && (*end_ptr == '\0'), "Conversion of hexstring %s failed returned %ld errno %d", hex, uli, errno); + s1ap->binary_stream[pos++] = (unsigned char)uli; } while (pos2 < (2*5)); // update ASN1 et_decode_s1ap(s1ap); From 10a764c4727693520f9822a6e581940906367cae Mon Sep 17 00:00:00 2001 From: gauthier Date: Tue, 26 Jan 2016 16:45:48 +0100 Subject: [PATCH 25/47] Traces + shift timing bug --- openair3/TEST/EPC_TEST/play_scenario.c | 45 ++++++++++--------- .../EPC_TEST/play_scenario_s1ap_compare_ie.c | 12 +++-- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c index c633cedfa7..cafdd93d31 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.c +++ b/openair3/TEST/EPC_TEST/play_scenario.c @@ -141,10 +141,14 @@ void et_get_shift_arg( char * line_argument, shift_packet_t * const shift) while ((line_argument[i] != ':') && (i < len)) { - my_num[i] = line_argument[i]; + if (isdigit(line_argument[i])) { // may occur '\"' + my_num[j++] = line_argument[i]; + } i += 1; } - my_num[i++] = '\0'; + AssertFatal(':' == line_argument[i], "Bad format"); + i += 1; // ':' + my_num[j++] = '\0'; shift->frame_number = atoi(my_num); AssertFatal(ilist_packet; while (packet) { -// fprintf(stdout, "*shift: %p\n", shift); -// fprintf(stdout, "\tframe_number: %p\n", shift->frame_number); -// fprintf(stdout, "\tshift_seconds: %ld\n", shift->shift_seconds); -// fprintf(stdout, "\tshift_microseconds: %ld\n", shift->shift_microseconds); -// fprintf(stdout, "\tsingle: %d\n\n", shift->single); -// fprintf(stdout, "\tshift_all_packets_seconds: %ld\n", shift_all_packets.tv_sec); -// fprintf(stdout, "\tshift_all_packets_microseconds: %ld\n", shift_all_packets.tv_usec); + fprintf(stdout, "*shift: %p\n", shift); + fprintf(stdout, "\tframe_number: %d\n", shift->frame_number); + fprintf(stdout, "\tshift_seconds: %ld\n", shift->shift_seconds); + fprintf(stdout, "\tshift_microseconds: %ld\n", shift->shift_microseconds); + fprintf(stdout, "\tsingle: %d\n\n", shift->single); + fprintf(stdout, "\tshift_all_packets_seconds: %ld\n", shift_all_packets.tv_sec); + fprintf(stdout, "\tshift_all_packets_microseconds: %ld\n", shift_all_packets.tv_usec); AssertFatal((packet->time_relative_to_first_packet.tv_sec >= 0) && (packet->time_relative_to_first_packet.tv_usec >= 0), "Bad timing result time_relative_to_first_packet=%d.%d packet num %u, original frame number %u", @@ -891,11 +896,11 @@ int et_play_scenario(et_scenario_t* const scenario, const struct shift_packet_s shift_all_packets.tv_sec = shift->shift_seconds; shift_all_packets.tv_usec = shift->shift_microseconds; timeval_add(&packet->time_relative_to_first_packet, &packet->time_relative_to_first_packet, &shift_all_packets); -// fprintf(stdout, "\tpacket num %u, now original frame number %u time_relative_to_first_packet=%d.%d\n", -// packet->packet_number, -// packet->original_frame_number, -// packet->time_relative_to_first_packet.tv_sec, -// packet->time_relative_to_first_packet.tv_usec); + fprintf(stdout, "\tpacket num %u, now original frame number %u time_relative_to_first_packet=%d.%d\n", + packet->packet_number, + packet->original_frame_number, + packet->time_relative_to_first_packet.tv_sec, + packet->time_relative_to_first_packet.tv_usec); AssertFatal((packet->time_relative_to_first_packet.tv_sec >= 0) && (packet->time_relative_to_first_packet.tv_usec >= 0), "Bad timing result time_relative_to_first_packet=%d.%d packet num %u, original frame number %u", packet->time_relative_to_first_packet.tv_sec, @@ -904,11 +909,11 @@ int et_play_scenario(et_scenario_t* const scenario, const struct shift_packet_s packet->original_frame_number); } else if ((0 == shift->single) && (shift->frame_number < packet->original_frame_number)) { timeval_add(&packet->time_relative_to_first_packet, &packet->time_relative_to_first_packet, &shift_all_packets); -// fprintf(stdout, "\tpacket num %u, now original frame number %u time_relative_to_first_packet=%d.%d\n", -// packet->packet_number, -// packet->original_frame_number, -// packet->time_relative_to_first_packet.tv_sec, -// packet->time_relative_to_first_packet.tv_usec); + fprintf(stdout, "\tpacket num %u, now original frame number %u time_relative_to_first_packet=%d.%d\n", + packet->packet_number, + packet->original_frame_number, + packet->time_relative_to_first_packet.tv_sec, + packet->time_relative_to_first_packet.tv_usec); AssertFatal((packet->time_relative_to_first_packet.tv_sec >= 0) && (packet->time_relative_to_first_packet.tv_usec >= 0), "Bad timing result time_relative_to_first_packet=%d.%d packet num %u, original frame number %u", packet->time_relative_to_first_packet.tv_sec, @@ -1107,8 +1112,8 @@ et_config_parse_opt_line ( shift = shift->next; } shift->single = 1; - et_get_shift_arg(optarg, shift); printf("Arg Shift packet %s\n", optarg); + et_get_shift_arg(optarg, shift); } break; 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 2242a63bd6..1e79c38963 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c @@ -467,7 +467,7 @@ void update_xpath_node_mme_ue_s1ap_id(et_s1ap_t * const s1ap, xmlNode *node, con int size = 0; int pos = 0; int go_deeper_in_tree = 1; - S1AP_DEBUG("%s() mme_ue_s1ap_id %u\n", __FUNCTION__, new_id); + S1AP_INFO("%s() mme_ue_s1ap_id %u\n", __FUNCTION__, new_id); // modify for (cur_node = (xmlNode *)node; cur_node; cur_node = cur_node->next) { @@ -527,7 +527,7 @@ void update_xpath_node_mme_ue_s1ap_id(et_s1ap_t * const s1ap, xmlNode *node, con } while (pos2 < (2*5)); // update ASN1 et_decode_s1ap(s1ap); - S1AP_DEBUG("Updated ASN1 for %s\n", showname); + S1AP_INFO("Updated ASN1 for %s\n", showname); } } } @@ -553,6 +553,7 @@ void update_xpath_nodes_mme_ue_s1ap_id(et_s1ap_t * const s1ap_payload, xmlNodeSe xmlNode *s1ap_node = NULL; size = (nodes) ? nodes->nodeNr : 0; + S1AP_DEBUG("%s() num nodes %u\n", __FUNCTION__, size); /* * NOTE: the nodes are processed in reverse order, i.e. reverse document @@ -614,14 +615,19 @@ int et_s1ap_update_mme_ue_s1ap_id(et_packet_t * const packet, const S1ap_MME_UE_ // Evaluate xpath expression xpath_obj = xmlXPathEvalExpression(xpath_expression, xpath_ctx); + xmlXPathFreeContext(xpath_ctx); AssertFatal(xpath_obj != NULL, "Unable to evaluate XPATH expression \"%s\"\n", xpath_expression); + if(xmlXPathNodeSetIsEmpty(xpath_obj->nodesetval)){ + xmlXPathFreeObject(xpath_obj); + S1AP_DEBUG("%s() No match packet num %u original frame number %u, mme_ue_s1ap_id %u -> %u\n", __FUNCTION__, packet->packet_number, packet->original_frame_number, old_id, new_id); + return -1; + } // update selected nodes update_xpath_nodes_mme_ue_s1ap_id(&packet->sctp_hdr.u.data_hdr.payload, xpath_obj->nodesetval, new_id); // Cleanup of XPath data xmlXPathFreeObject(xpath_obj); - xmlXPathFreeContext(xpath_ctx); return 0; } From 5319fcba38008b1c99c2eab6e82926471b965a19 Mon Sep 17 00:00:00 2001 From: gauthier Date: Wed, 27 Jan 2016 08:39:44 +0100 Subject: [PATCH 26/47] Bug, needed unsigned instead of signed --- openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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 1e79c38963..f9c7d9c822 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c @@ -601,7 +601,7 @@ int et_s1ap_update_mme_ue_s1ap_id(et_packet_t * const packet, const S1ap_MME_UE_ S1AP_DEBUG("%s() packet num %u original frame number %u, mme_ue_s1ap_id %u -> %u\n", __FUNCTION__, packet->packet_number, packet->original_frame_number, old_id, new_id); - ret = snprintf(xpath_expression, ET_XPATH_EXPRESSION_MAX_LENGTH, "//field[@name=\"s1ap.MME_UE_S1AP_ID\"][@show=\"%d\"]", old_id); + ret = snprintf(xpath_expression, ET_XPATH_EXPRESSION_MAX_LENGTH, "//field[@name=\"s1ap.MME_UE_S1AP_ID\"][@show=\"%u\"]", old_id); AssertFatal((ret > 0) && (ret < ET_XPATH_EXPRESSION_MAX_LENGTH), "Could not build XPATH expression err=%d", ret); doc = packet->sctp_hdr.u.data_hdr.payload.doc; @@ -620,7 +620,8 @@ int et_s1ap_update_mme_ue_s1ap_id(et_packet_t * const packet, const S1ap_MME_UE_ if(xmlXPathNodeSetIsEmpty(xpath_obj->nodesetval)){ xmlXPathFreeObject(xpath_obj); - S1AP_DEBUG("%s() No match packet num %u original frame number %u, mme_ue_s1ap_id %u -> %u\n", __FUNCTION__, packet->packet_number, packet->original_frame_number, old_id, new_id); + S1AP_DEBUG("%s() No match \"%s\"packet num %u original frame number %u, mme_ue_s1ap_id %u -> %u\n", + __FUNCTION__, xpath_expression, packet->packet_number, packet->original_frame_number, old_id, new_id); return -1; } // update selected nodes From c32e5544e2339d6fd683247d290c7680cd043b8f Mon Sep 17 00:00:00 2001 From: gauthier Date: Sat, 20 Feb 2016 18:20:44 +0100 Subject: [PATCH 27/47] Make it compile on 15.10 (problem with gcc-xml not resolved, may be do as in openair-cn: disable it, it is only needed for ITTI ANALYZER) --- cmake_targets/CMakeLists.txt | 1 - openair2/COMMON/commonDef.h | 19 ++++++++++++------- openair2/LAYER2/RLC/rlc.h | 2 ++ openair2/UTIL/OCG/OCG_parse_XML.c | 4 ---- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index a88eb69991..1c8f3d221e 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1110,7 +1110,6 @@ add_library(CN_UTILS ${OPENAIR3_DIR}/UTILS/conversions.c ${OPENAIR3_DIR}/UTILS/enum_string.c ${OPENAIR3_DIR}/UTILS/log.c - ${OPENAIR3_DIR}/UTILS/mme_config.c ${OPENAIR3_DIR}/UTILS/mcc_mnc_itu.c ) diff --git a/openair2/COMMON/commonDef.h b/openair2/COMMON/commonDef.h index e33e64ec06..64216b0094 100644 --- a/openair2/COMMON/commonDef.h +++ b/openair2/COMMON/commonDef.h @@ -48,7 +48,19 @@ Description Contains global common definitions #include #include +#include +typedef signed char boolean_t; + +#if !defined(TRUE) +#define TRUE (boolean_t)0x01 +#endif + +#if !defined(FALSE) +#define FALSE (boolean_t)0x00 +#endif + +#define BOOL_NOT(b) (b^TRUE) #define NAS_UE_ID_FMT "0x%06x" @@ -59,13 +71,6 @@ Description Contains global common definitions #define RETURNok (0) #define RETURNerror (-1) -#ifndef FALSE -#define FALSE (0) -#endif -#ifndef TRUE -#define TRUE (1) -#endif - /* * Name of the environment variable which defines the default directory * where the NAS application is executed and where are located files diff --git a/openair2/LAYER2/RLC/rlc.h b/openair2/LAYER2/RLC/rlc.h index 392ae88cf8..72fde0b746 100755 --- a/openair2/LAYER2/RLC/rlc.h +++ b/openair2/LAYER2/RLC/rlc.h @@ -60,6 +60,8 @@ # include "DRB-ToAddModList.h" # include "SRB-ToAddMod.h" # include "SRB-ToAddModList.h" +# include "DRB-ToReleaseList.h" + #ifdef Rel10 #include "PMCH-InfoList-r9.h" #endif diff --git a/openair2/UTIL/OCG/OCG_parse_XML.c b/openair2/UTIL/OCG/OCG_parse_XML.c index 5397cdbd98..0100d742e1 100644 --- a/openair2/UTIL/OCG/OCG_parse_XML.c +++ b/openair2/UTIL/OCG/OCG_parse_XML.c @@ -51,10 +51,6 @@ #include "UTIL/OPT/opt.h" /*----------------------------------------------------------------------------*/ -#ifndef HAVE_STRNDUP -char * strndup (const char *s, size_t size); -#endif - static int oai_emulation_; /*!< \brief indicating that the parsing position is now within OAI_Emulation_*/ static int environment_system_config_; /*!< \brief indicating that the parsing position is now within Envi_Config_*/ From 0c017f692272666fdb5eca3bd37bb0355adb05df Mon Sep 17 00:00:00 2001 From: gauthier Date: Tue, 1 Mar 2016 22:53:47 +0100 Subject: [PATCH 28/47] Added delay on exit option --- openair3/TEST/EPC_TEST/play_scenario.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c index cafdd93d31..876691cfcc 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.c +++ b/openair3/TEST/EPC_TEST/play_scenario.c @@ -1016,6 +1016,7 @@ static void et_usage ( fprintf (stdout, "\n"); fprintf (stdout, "\t-d | --test-dir Directory where a set of files related to a particular test are located\n"); fprintf (stdout, "\t-c | --enb-conf-file Provide an eNB config file, valid for the testbed\n"); + fprintf (stdout, "\t-D | --delay-on-exit Wait delay-in-sec before exiting\n"); fprintf (stdout, "\t-f | --shift-packet Shift the timing of a packet'\n"); fprintf (stdout, "\t-F | --shift-packets Shift the timing of packets starting at frame 'frame' included\n"); fprintf (stdout, "\t-m | --max-speed Play scenario as fast as possible without respecting frame timings\n"); @@ -1035,7 +1036,8 @@ et_config_parse_opt_line ( char **et_dir_name, char **scenario_file_name, char **enb_config_file_name, - shift_packet_t **shifts) + shift_packet_t **shifts, + int *delay_on_exit) //------------------------------------------------------------------------------ { int option = 0; @@ -1048,6 +1050,7 @@ et_config_parse_opt_line ( LONG_OPTION_SCENARIO_FILE, LONG_OPTION_MAX_SPEED, LONG_OPTION_TEST_DIR, + LONG_OPTION_DELAY_EXIT, LONG_OPTION_SHIFT_PACKET, LONG_OPTION_SHIFT_PACKETS, LONG_OPTION_HELP, @@ -1059,6 +1062,7 @@ et_config_parse_opt_line ( {"scenario ", required_argument, 0, LONG_OPTION_SCENARIO_FILE}, {"max-speed ", no_argument, 0, LONG_OPTION_MAX_SPEED}, {"test-dir", required_argument, 0, LONG_OPTION_TEST_DIR}, + {"delay-on-exit", required_argument, 0, LONG_OPTION_DELAY_EXIT}, {"shift-packet", required_argument, 0, LONG_OPTION_SHIFT_PACKET}, {"shift-packets", required_argument, 0, LONG_OPTION_SHIFT_PACKETS}, {"help", no_argument, 0, LONG_OPTION_HELP}, @@ -1101,6 +1105,19 @@ et_config_parse_opt_line ( } break; + case LONG_OPTION_DELAY_EXIT: + case 'D': + if (optarg) { + delay_on_exit = atoi(optarg); + if (0 > delay_on_exit) { + fprintf(stderr, "Please provide a valid -D/--delay-on-exit argument, %s is not a valid value\n", delay_on_exit); + exit(1); + } + printf("Delay on exit is %d\n", delay_on_exit); + } + break; + + case LONG_OPTION_SHIFT_PACKET: case 'f': if (optarg) { @@ -1187,6 +1204,7 @@ int main( int argc, char **argv ) char *enb_config_file_name = NULL; struct shift_packet_s *shifts = NULL; int ret = 0; + int delay_on_exit = 0; et_scenario_t *scenario = NULL; char play_scenario_filename[NAME_MAX]; @@ -1205,7 +1223,7 @@ int main( int argc, char **argv ) asn1_xer_print = 1; //parameters - actions = et_config_parse_opt_line (argc, argv, &et_dir_name, &scenario_file_name, &enb_config_file_name, &shifts); //Command-line options + actions = et_config_parse_opt_line (argc, argv, &et_dir_name, &scenario_file_name, &enb_config_file_name, &shifts, &delay_on_exit); //Command-line options if (actions & PLAY_SCENARIO) { if (et_generate_xml_scenario(et_dir_name, scenario_file_name,enb_config_file_name, play_scenario_filename) == 0) { if (NULL != (scenario = et_generate_scenario(play_scenario_filename))) { @@ -1223,5 +1241,8 @@ int main( int argc, char **argv ) et_free_pointer(enb_config_file_name); } itti_wait_tasks_end(); + if (0 < delay_on_exit) { + sleep(delay_on_exit); + } return ret; } From d33d2f5ed5ea76a3d8d4a533f07717c3ab6d47f6 Mon Sep 17 00:00:00 2001 From: Rohit Gupta Date: Thu, 3 Mar 2016 10:41:49 +0100 Subject: [PATCH 29/47] install libxslt --- cmake_targets/tools/build_helper | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 0d68c5d8d7..810b7349d2 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -269,7 +269,9 @@ check_install_oai_software() { pydb \ wvdial \ python-numpy \ - sshpass + sshpass \ + libxslt1-dev + $SUDO update-alternatives --set liblapack.so /usr/lib/atlas-base/atlas/liblapack.so if [ `lsb_release -rs` = '12.04' ] ; then install_nettle_from_source @@ -398,4 +400,4 @@ if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then fi return $stat -} \ No newline at end of file +} From 85d010d9872751275fb45c09eb60d2040c2c9d91 Mon Sep 17 00:00:00 2001 From: trilyrak Date: Thu, 10 Mar 2016 15:47:04 +0100 Subject: [PATCH 30/47] update run_enb_s1_usrp script --- cmake_targets/tools/run_enb_s1_usrp | 7 +++++++ .../GENERIC-LTE-EPC/CONF/enb.band13.tm1.lmssdr.conf | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/cmake_targets/tools/run_enb_s1_usrp b/cmake_targets/tools/run_enb_s1_usrp index f003faf5c9..5bb7ef151f 100755 --- a/cmake_targets/tools/run_enb_s1_usrp +++ b/cmake_targets/tools/run_enb_s1_usrp @@ -56,6 +56,7 @@ function help() echo_error "Mandatory arguments to long options are mandatory for short options too." echo_error " -g, --gdb Run with GDB." echo_error " -h, --help Print this help." + echo_error " -e, --ulsch-max-errors num-errs maximum allowed number of uplink errors" echo_error " -f, --rf-config-file filename RF specific configuration file" echo_error " -K, --itti-dump-file filename ITTI dump file containing all ITTI events occuring during EPC runtime.(can omit file name if last argument)" echo_error " -M, --target-dl-mcs mcs Downlink target MCS." @@ -138,6 +139,12 @@ function main() shift; exit 0 ;; + -e | --ulsch-max-errors) + ulsch_max_errors=$2 + echo "setting --ulsch-max-errors to $ulsch_max_errors" + exe_arguments="$exe_arguments --ulsch-max-errors=$ulsch_max_errors" + shift 2; + ;; -f | --rf-config-file) rf_config_file=$2 # can omit file name if last arg on the line diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.lmssdr.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.lmssdr.conf index df5ea1f1d2..266e5aae25 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.lmssdr.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.lmssdr.conf @@ -36,7 +36,7 @@ eNBs = nb_antennas_tx = 1; nb_antennas_rx = 1; tx_gain = 90; - rx_gain = 125; + rx_gain = 107; prach_root = 0; prach_config_index = 0; prach_high_speed = "DISABLE"; From 7c016904d1eb5cb02038dfb8070ca61661bce531 Mon Sep 17 00:00:00 2001 From: Rohit Gupta Date: Tue, 15 Mar 2016 10:50:45 +0100 Subject: [PATCH 31/47] add sudo to deleting asn1 tmp dir --- cmake_targets/tools/build_helper | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index c8adf45257..82602b8cee 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -288,7 +288,7 @@ install_asn1c_from_source(){ asn1_install_dir=$OPENAIR_DIR/cmake_targets/log/asn1c_install_log.txt echo_info "\nInstalling ASN1. The log file for ASN1 installation is here: $asn1_install_dir " ( - rm -rf /tmp/asn1c-r1516 + $SUDO rm -rf /tmp/asn1c-r1516 mkdir -p /tmp/asn1c-r1516 cd /tmp/asn1c-r1516 svn co https://github.com/vlm/asn1c/trunk /tmp/asn1c-r1516 -r 1516 @@ -397,4 +397,4 @@ if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then fi return $stat -} \ No newline at end of file +} From 902f70ae5eba918e0d1ba822135b4edefb42684b Mon Sep 17 00:00:00 2001 From: gauthier Date: Tue, 15 Mar 2016 13:41:09 +0100 Subject: [PATCH 32/47] Remove some traces in --- openair3/TEST/EPC_TEST/play_scenario.c | 43 ++++++++++++++----- openair3/TEST/EPC_TEST/play_scenario_fsm.c | 5 ++- openair3/TEST/EPC_TEST/play_scenario_parse.c | 3 +- .../EPC_TEST/play_scenario_s1ap_compare_ie.c | 8 ++-- 4 files changed, 41 insertions(+), 18 deletions(-) diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c index cafdd93d31..b2207d39d7 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.c +++ b/openair3/TEST/EPC_TEST/play_scenario.c @@ -835,13 +835,13 @@ int et_play_scenario(et_scenario_t* const scenario, const struct shift_packet_s while (shift) { packet = scenario->list_packet; while (packet) { - fprintf(stdout, "*shift: %p\n", shift); - fprintf(stdout, "\tframe_number: %d\n", shift->frame_number); - fprintf(stdout, "\tshift_seconds: %ld\n", shift->shift_seconds); - fprintf(stdout, "\tshift_microseconds: %ld\n", shift->shift_microseconds); - fprintf(stdout, "\tsingle: %d\n\n", shift->single); - fprintf(stdout, "\tshift_all_packets_seconds: %ld\n", shift_all_packets.tv_sec); - fprintf(stdout, "\tshift_all_packets_microseconds: %ld\n", shift_all_packets.tv_usec); + //fprintf(stdout, "*shift: %p\n", shift); + //fprintf(stdout, "\tframe_number: %d\n", shift->frame_number); + //fprintf(stdout, "\tshift_seconds: %ld\n", shift->shift_seconds); + //fprintf(stdout, "\tshift_microseconds: %ld\n", shift->shift_microseconds); + //fprintf(stdout, "\tsingle: %d\n\n", shift->single); + //fprintf(stdout, "\tshift_all_packets_seconds: %ld\n", shift_all_packets.tv_sec); + //fprintf(stdout, "\tshift_all_packets_microseconds: %ld\n", shift_all_packets.tv_usec); AssertFatal((packet->time_relative_to_first_packet.tv_sec >= 0) && (packet->time_relative_to_first_packet.tv_usec >= 0), "Bad timing result time_relative_to_first_packet=%d.%d packet num %u, original frame number %u", @@ -977,7 +977,7 @@ int et_play_scenario(et_scenario_t* const scenario, const struct shift_packet_s } packet = packet->next; } - et_display_scenario(scenario); + //et_display_scenario(scenario); // create SCTP ITTI task: same as eNB code if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) { @@ -1016,6 +1016,7 @@ static void et_usage ( fprintf (stdout, "\n"); fprintf (stdout, "\t-d | --test-dir Directory where a set of files related to a particular test are located\n"); fprintf (stdout, "\t-c | --enb-conf-file Provide an eNB config file, valid for the testbed\n"); + fprintf (stdout, "\t-D | --delay-on-exit Wait delay-in-sec before exiting\n"); fprintf (stdout, "\t-f | --shift-packet Shift the timing of a packet'\n"); fprintf (stdout, "\t-F | --shift-packets Shift the timing of packets starting at frame 'frame' included\n"); fprintf (stdout, "\t-m | --max-speed Play scenario as fast as possible without respecting frame timings\n"); @@ -1035,7 +1036,8 @@ et_config_parse_opt_line ( char **et_dir_name, char **scenario_file_name, char **enb_config_file_name, - shift_packet_t **shifts) + shift_packet_t **shifts, + int *delay_on_exit) //------------------------------------------------------------------------------ { int option = 0; @@ -1048,6 +1050,7 @@ et_config_parse_opt_line ( LONG_OPTION_SCENARIO_FILE, LONG_OPTION_MAX_SPEED, LONG_OPTION_TEST_DIR, + LONG_OPTION_DELAY_EXIT, LONG_OPTION_SHIFT_PACKET, LONG_OPTION_SHIFT_PACKETS, LONG_OPTION_HELP, @@ -1059,6 +1062,7 @@ et_config_parse_opt_line ( {"scenario ", required_argument, 0, LONG_OPTION_SCENARIO_FILE}, {"max-speed ", no_argument, 0, LONG_OPTION_MAX_SPEED}, {"test-dir", required_argument, 0, LONG_OPTION_TEST_DIR}, + {"delay-on-exit", required_argument, 0, LONG_OPTION_DELAY_EXIT}, {"shift-packet", required_argument, 0, LONG_OPTION_SHIFT_PACKET}, {"shift-packets", required_argument, 0, LONG_OPTION_SHIFT_PACKETS}, {"help", no_argument, 0, LONG_OPTION_HELP}, @@ -1101,6 +1105,19 @@ et_config_parse_opt_line ( } break; + case LONG_OPTION_DELAY_EXIT: + case 'D': + if (optarg) { + delay_on_exit = atoi(optarg); + if (0 > delay_on_exit) { + fprintf(stderr, "Please provide a valid -D/--delay-on-exit argument, %s is not a valid value\n", delay_on_exit); + exit(1); + } + printf("Delay on exit is %d\n", delay_on_exit); + } + break; + + case LONG_OPTION_SHIFT_PACKET: case 'f': if (optarg) { @@ -1187,6 +1204,7 @@ int main( int argc, char **argv ) char *enb_config_file_name = NULL; struct shift_packet_s *shifts = NULL; int ret = 0; + int delay_on_exit = 0; et_scenario_t *scenario = NULL; char play_scenario_filename[NAME_MAX]; @@ -1205,7 +1223,7 @@ int main( int argc, char **argv ) asn1_xer_print = 1; //parameters - actions = et_config_parse_opt_line (argc, argv, &et_dir_name, &scenario_file_name, &enb_config_file_name, &shifts); //Command-line options + actions = et_config_parse_opt_line (argc, argv, &et_dir_name, &scenario_file_name, &enb_config_file_name, &shifts, &delay_on_exit); //Command-line options if (actions & PLAY_SCENARIO) { if (et_generate_xml_scenario(et_dir_name, scenario_file_name,enb_config_file_name, play_scenario_filename) == 0) { if (NULL != (scenario = et_generate_scenario(play_scenario_filename))) { @@ -1223,5 +1241,10 @@ int main( int argc, char **argv ) et_free_pointer(enb_config_file_name); } itti_wait_tasks_end(); + if (0 < delay_on_exit) { + sleep(delay_on_exit); + } return ret; } + + diff --git a/openair3/TEST/EPC_TEST/play_scenario_fsm.c b/openair3/TEST/EPC_TEST/play_scenario_fsm.c index d253e5cd5f..f5b142d2fd 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_fsm.c +++ b/openair3/TEST/EPC_TEST/play_scenario_fsm.c @@ -262,7 +262,8 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_running(et_event_t event) fprintf(stderr, "End of scenario: %s\n", g_scenario->name); fflush(stderr); fflush(stdout); - exit(0); + return 0; + //exit(0); } fprintf(stderr, "Remaining timers running: %d\n", g_scenario->timer_count); return g_fsm_state; @@ -342,7 +343,7 @@ et_fsm_state_t et_scenario_fsm_notify_event_state_waiting_rx(et_event_t event) case ET_EVENT_RX_PACKET_TIME_OUT: fprintf(stderr, "Error The following packet is not received:\n"); - et_display_packet(event.u.rx_packet_time_out); + //et_display_packet(event.u.rx_packet_time_out); AssertFatal(0, "Waited packet not received"); break; diff --git a/openair3/TEST/EPC_TEST/play_scenario_parse.c b/openair3/TEST/EPC_TEST/play_scenario_parse.c index aedc021f73..e4f7b48c51 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_parse.c +++ b/openair3/TEST/EPC_TEST/play_scenario_parse.c @@ -491,8 +491,7 @@ et_scenario_t* et_generate_scenario( *next_packet = packet; next_packet = &packet->next; } else { - fprintf(stdout, "WARNING omitted packet:\n"); - et_display_node(node, 0); + fprintf(stdout, "WARNING omitted packet\n"); } } last_packet = packet; 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 f9c7d9c822..5d43b211ee 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c @@ -467,7 +467,7 @@ void update_xpath_node_mme_ue_s1ap_id(et_s1ap_t * const s1ap, xmlNode *node, con int size = 0; int pos = 0; int go_deeper_in_tree = 1; - S1AP_INFO("%s() mme_ue_s1ap_id %u\n", __FUNCTION__, new_id); + //S1AP_INFO("%s() mme_ue_s1ap_id %u\n", __FUNCTION__, new_id); // modify for (cur_node = (xmlNode *)node; cur_node; cur_node = cur_node->next) { @@ -527,7 +527,7 @@ void update_xpath_node_mme_ue_s1ap_id(et_s1ap_t * const s1ap, xmlNode *node, con } while (pos2 < (2*5)); // update ASN1 et_decode_s1ap(s1ap); - S1AP_INFO("Updated ASN1 for %s\n", showname); + //S1AP_INFO("Updated ASN1 for %s\n", showname); } } } @@ -553,7 +553,7 @@ void update_xpath_nodes_mme_ue_s1ap_id(et_s1ap_t * const s1ap_payload, xmlNodeSe xmlNode *s1ap_node = NULL; size = (nodes) ? nodes->nodeNr : 0; - S1AP_DEBUG("%s() num nodes %u\n", __FUNCTION__, size); + //S1AP_DEBUG("%s() num nodes %u\n", __FUNCTION__, size); /* * NOTE: the nodes are processed in reverse order, i.e. reverse document @@ -599,7 +599,7 @@ int et_s1ap_update_mme_ue_s1ap_id(et_packet_t * const packet, const S1ap_MME_UE_ xmlXPathContextPtr xpath_ctx = NULL; xmlXPathObjectPtr xpath_obj = NULL; - S1AP_DEBUG("%s() packet num %u original frame number %u, mme_ue_s1ap_id %u -> %u\n", __FUNCTION__, packet->packet_number, packet->original_frame_number, old_id, new_id); + //S1AP_DEBUG("%s() packet num %u original frame number %u, mme_ue_s1ap_id %u -> %u\n", __FUNCTION__, packet->packet_number, packet->original_frame_number, old_id, new_id); ret = snprintf(xpath_expression, ET_XPATH_EXPRESSION_MAX_LENGTH, "//field[@name=\"s1ap.MME_UE_S1AP_ID\"][@show=\"%u\"]", old_id); AssertFatal((ret > 0) && (ret < ET_XPATH_EXPRESSION_MAX_LENGTH), "Could not build XPATH expression err=%d", ret); From e3a7edb0a2e08a59c31a919d688417b09aadd875 Mon Sep 17 00:00:00 2001 From: Rohit Gupta Date: Tue, 15 Mar 2016 18:47:36 +0100 Subject: [PATCH 33/47] RRH Tests for USRP b210 --- cmake_targets/autotests/README.txt | 16 + cmake_targets/autotests/test_case_list.xml | 336 ++++++++++++--------- 2 files changed, 212 insertions(+), 140 deletions(-) diff --git a/cmake_targets/autotests/README.txt b/cmake_targets/autotests/README.txt index d3b72edf46..6e9cbbd581 100644 --- a/cmake_targets/autotests/README.txt +++ b/cmake_targets/autotests/README.txt @@ -189,6 +189,22 @@ Obj.# Case# Test# Description 01 75 04 Band 7 FDD 10MHz DL Throughput for 300 sec for 1TX/1RX 01 75 05 Band 7 FDD 20MHz DL Throughput for 300 sec for 1TX/1RX +01 80 00 lte-softmodem + RRH tests with BladeRF RF as eNB and ALU EPC w/ Bandrich COTS UE for TX/1RX +01 80 00 Band 7 FDD 5MHz UL Throughput for 300 sec for 1TX/1RX +01 80 01 Band 7 FDD 10MHz UL Throughput for 300 sec for 1TX/1RX +01 80 02 Band 7 FDD 20MHz UL Throughput for 300 sec for 1TX/1RX +01 80 03 Band 7 FDD 5MHz DL Throughput for 300 sec for 1TX/1RX +01 80 04 Band 7 FDD 10MHz DL Throughput for 300 sec for 1TX/1RX +01 80 05 Band 7 FDD 20MHz DL Throughput for 300 sec for 1TX/1RX + +01 85 00 lte-softmodem + RRH tests with USRP X310 RF as eNB and ALU EPC w/ Bandrich COTS UE for TX/1RX +01 85 00 Band 7 FDD 5MHz UL Throughput for 300 sec for 1TX/1RX +01 85 01 Band 7 FDD 10MHz UL Throughput for 300 sec for 1TX/1RX +01 85 02 Band 7 FDD 20MHz UL Throughput for 300 sec for 1TX/1RX +01 85 03 Band 7 FDD 5MHz DL Throughput for 300 sec for 1TX/1RX +01 85 04 Band 7 FDD 10MHz DL Throughput for 300 sec for 1TX/1RX +01 85 05 Band 7 FDD 20MHz DL Throughput for 300 sec for 1TX/1RX + 01 64 lte-softmodem-noS1 tests diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 4e6ca873cb..d2afaa3469 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -10,7 +10,7 @@ sudo -S -E /opt/ltebox/tools/stop_ltebox $OPENAIR_DIR/cmake_targets/build_oai -w EXMIMO -c; sudo -S -E $OPENAIR_DIR/cmake_targets/tools/stop_exmimo2; uname -a; dmesg|tail 36000 - 0102+ 010304 010305 0104+ 015502 015505 015506 015507 015508 015509 015510 015511 015602 015605 015702 015705 015802 015805 0159+ 0160+ 0161+ 0162+ 0163+ 0165+ 0170+ 0175+ + 0102+ 010304 010305 0104+ 015502 015505 015506 015507 015508 015509 015510 015511 015602 015605 015702 015705 015802 015805 0159+ 0160+ 0161+ 0162+ 0163+ 0165+ 0170+ 017502 017505 3 mozart calisson stevens nano amerique @@ -5521,44 +5521,46 @@ mozart 390 /tmp - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf tracking_area_code \"1\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf mobile_country_code \"208\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf mobile_network_code \"92\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf N_RB_DL 25 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf mme_ip_address "ipv4=\"192.168.12.26\";ipv6=\"192:168:30::17\";active=\"yes\";preference=\"ipv4\";" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf downlink_frequency 2660000000L - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf uplink_frequency_offset -120000000 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf tx_gain 90 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf rx_gain 125 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf frame_type \"FDD\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf nb_antennas_rx 1 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf nb_antennas_tx 1 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_INTERFACE_NAME_FOR_S1_MME \"eth6\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_IPV4_ADDRESS_FOR_S1_MME \"192.168.12.111/24\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_INTERFACE_NAME_FOR_S1U \"eth6\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_IPV4_ADDRESS_FOR_S1U \"192.168.12.111/24\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_PORT_FOR_S1U 2152 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf rrh_gw_config "local_if_name=\"eth0\";remote_address=\"10:60:4b:75:80:83\";local_address=\"98:90:96:df:66:07\";local_port=50000;remote_port=50000;tr_preference=\"raw\";rf_preference=\"usrp_b200\";iq_txshift=5;tx_sample_advance=70;tx_scheduling_advance=9;" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf tracking_area_code \"1\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf mobile_country_code \"208\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf mobile_network_code \"92\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf N_RB_DL 25 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf mme_ip_address "ipv4=\"192.168.12.26\";ipv6=\"192:168:30::17\";active=\"yes\";preference=\"ipv4\";" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf downlink_frequency 2660000000L + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf uplink_frequency_offset -120000000 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf tx_gain 90 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf rx_gain 125 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf pdsch_referenceSignalPower -26 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf frame_type \"FDD\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf nb_antennas_rx 1 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf nb_antennas_tx 1 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_INTERFACE_NAME_FOR_S1_MME \"eth6\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_IPV4_ADDRESS_FOR_S1_MME \"192.168.12.111/24\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_INTERFACE_NAME_FOR_S1U \"eth6\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_IPV4_ADDRESS_FOR_S1U \"192.168.12.111/24\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_PORT_FOR_S1U 2152 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf rrh_gw_config "local_if_name=\"eth0\";remote_address=\"10:60:4b:75:80:83\";local_address=\"98:90:96:df:66:07\";local_port=50000;remote_port=50000;tr_preference=\"raw\";rf_preference=\"usrp_b200\";iq_txshift=4;tx_sample_advance=70;tx_scheduling_advance=9;rrh_gw_active=\"yes\";" + $OPENAIR_DIR/cmake_targets/build_oai + --eNB -w None -t ETHERNET -x -c --disable-deadline + + + sleep 5; $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf -W + + + + + False $OPENAIR_DIR/cmake_targets/build_oai --RRH -w USRP -t ETHERNET -c --disable-deadline sudo -E chrt -f 99 $OPENAIR_DIR/cmake_targets/rrh_gw/build/rrh_gw - -n1 -g3 -x -i eth1 + -n1 -x -m1 -i eth1 False - $OPENAIR_DIR/cmake_targets/build_oai - --eNB -w None -t ETHERNET -x -c --disable-deadline - - - sleep 5; $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem - -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf -W - - - - - False + /tmp @@ -5601,39 +5603,50 @@ lte-softmodem - calisson + calisson + mozart stevens amerique 390 /tmp - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf tracking_area_code \"1\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf mobile_country_code \"208\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf mobile_network_code \"92\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf N_RB_DL 50 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf mme_ip_address "ipv4=\"192.168.12.26\";ipv6=\"192:168:30::17\";active=\"yes\";preference=\"ipv4\";" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf downlink_frequency 2660000000L - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf uplink_frequency_offset -120000000 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf tx_gain 90 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf rx_gain 125 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf frame_type \"FDD\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf nb_antennas_rx 1 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf nb_antennas_tx 1 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_INTERFACE_NAME_FOR_S1_MME \"eth5\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_IPV4_ADDRESS_FOR_S1_MME \"192.168.12.82/24\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_INTERFACE_NAME_FOR_S1U \"eth5\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_IPV4_ADDRESS_FOR_S1U \"192.168.12.82/24\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_PORT_FOR_S1U 2152 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf tracking_area_code \"1\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf mobile_country_code \"208\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf mobile_network_code \"92\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf N_RB_DL 50 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf mme_ip_address "ipv4=\"192.168.12.26\";ipv6=\"192:168:30::17\";active=\"yes\";preference=\"ipv4\";" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf downlink_frequency 2660000000L + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf uplink_frequency_offset -120000000 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf tx_gain 90 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf rx_gain 125 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf pdsch_referenceSignalPower -29 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf frame_type \"FDD\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf nb_antennas_rx 1 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf nb_antennas_tx 1 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_INTERFACE_NAME_FOR_S1_MME \"eth6\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_IPV4_ADDRESS_FOR_S1_MME \"192.168.12.111/24\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_INTERFACE_NAME_FOR_S1U \"eth6\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_IPV4_ADDRESS_FOR_S1U \"192.168.12.111/24\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_PORT_FOR_S1U 2152 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf rrh_gw_config "local_if_name=\"eth0\";remote_address=\"10:60:4b:75:80:83\";local_address=\"98:90:96:df:66:07\";local_port=50000;remote_port=50000;tr_preference=\"raw\";rf_preference=\"usrp_b200\";iq_txshift=4;tx_sample_advance=113;tx_scheduling_advance=9;rrh_gw_active=\"yes\";" $OPENAIR_DIR/cmake_targets/build_oai - --eNB -w USRP -x -c + --eNB -w None -t ETHERNET -x -c --disable-deadline - $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem - -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf -W + sleep 5; $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf -W - True + False + + $OPENAIR_DIR/cmake_targets/build_oai + --RRH -w USRP -t ETHERNET -c --disable-deadline + + + sudo -E chrt -f 99 $OPENAIR_DIR/cmake_targets/rrh_gw/build/rrh_gw + -n1 -x -m1 -i eth1 + False /tmp @@ -5675,39 +5688,50 @@ lte-softmodem - calisson + calisson + mozart stevens amerique 390 /tmp - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf tracking_area_code \"1\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf mobile_country_code \"208\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf mobile_network_code \"92\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf N_RB_DL 100 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf mme_ip_address "ipv4=\"192.168.12.26\";ipv6=\"192:168:30::17\";active=\"yes\";preference=\"ipv4\";" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf downlink_frequency 2660000000L - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf uplink_frequency_offset -120000000 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf tx_gain 90 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf rx_gain 125 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf frame_type \"FDD\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf nb_antennas_rx 1 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf nb_antennas_tx 1 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_INTERFACE_NAME_FOR_S1_MME \"eth5\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_IPV4_ADDRESS_FOR_S1_MME \"192.168.12.82/24\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_INTERFACE_NAME_FOR_S1U \"eth5\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_IPV4_ADDRESS_FOR_S1U \"192.168.12.82/24\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_PORT_FOR_S1U 2152 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf tracking_area_code \"1\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf mobile_country_code \"208\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf mobile_network_code \"92\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf N_RB_DL 100 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf mme_ip_address "ipv4=\"192.168.12.26\";ipv6=\"192:168:30::17\";active=\"yes\";preference=\"ipv4\";" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf downlink_frequency 2660000000L + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf uplink_frequency_offset -120000000 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf tx_gain 90 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf rx_gain 125 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf pdsch_referenceSignalPower -32 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf frame_type \"FDD\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf nb_antennas_rx 1 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf nb_antennas_tx 1 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_INTERFACE_NAME_FOR_S1_MME \"eth6\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_IPV4_ADDRESS_FOR_S1_MME \"192.168.12.111/24\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_INTERFACE_NAME_FOR_S1U \"eth6\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_IPV4_ADDRESS_FOR_S1U \"192.168.12.111/24\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_PORT_FOR_S1U 2152 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf rrh_gw_config "local_if_name=\"eth0\";remote_address=\"10:60:4b:75:80:83\";local_address=\"98:90:96:df:66:07\";local_port=50000;remote_port=50000;tr_preference=\"raw\";rf_preference=\"usrp_b200\";iq_txshift=4;tx_sample_advance=115;tx_scheduling_advance=11;rrh_gw_active=\"yes\";" $OPENAIR_DIR/cmake_targets/build_oai - --eNB -w USRP -x -c + --eNB -w None -t ETHERNET -x -c --disable-deadline - $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem - -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf -W + sleep 5; $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf -W - True + False + + $OPENAIR_DIR/cmake_targets/build_oai + --RRH -w USRP -t ETHERNET -c --disable-deadline + + + sudo -E chrt -f 99 $OPENAIR_DIR/cmake_targets/rrh_gw/build/rrh_gw + -n1 -x -m1 -i eth1 + False /tmp @@ -5749,39 +5773,50 @@ lte-softmodem - calisson + calisson + mozart stevens amerique 390 /tmp - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf tracking_area_code \"1\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf mobile_country_code \"208\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf mobile_network_code \"92\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf N_RB_DL 25 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf mme_ip_address "ipv4=\"192.168.12.26\";ipv6=\"192:168:30::17\";active=\"yes\";preference=\"ipv4\";" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf downlink_frequency 2660000000L - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf uplink_frequency_offset -120000000 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf tx_gain 90 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf rx_gain 125 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf frame_type \"FDD\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf nb_antennas_rx 1 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf nb_antennas_tx 1 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_INTERFACE_NAME_FOR_S1_MME \"eth5\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_IPV4_ADDRESS_FOR_S1_MME \"192.168.12.82/24\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_INTERFACE_NAME_FOR_S1U \"eth5\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_IPV4_ADDRESS_FOR_S1U \"192.168.12.82/24\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_PORT_FOR_S1U 2152 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf tracking_area_code \"1\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf mobile_country_code \"208\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf mobile_network_code \"92\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf N_RB_DL 25 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf mme_ip_address "ipv4=\"192.168.12.26\";ipv6=\"192:168:30::17\";active=\"yes\";preference=\"ipv4\";" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf downlink_frequency 2660000000L + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf uplink_frequency_offset -120000000 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf tx_gain 90 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf rx_gain 125 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf pdsch_referenceSignalPower -26 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf frame_type \"FDD\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf nb_antennas_rx 1 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf nb_antennas_tx 1 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_INTERFACE_NAME_FOR_S1_MME \"eth6\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_IPV4_ADDRESS_FOR_S1_MME \"192.168.12.111/24\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_INTERFACE_NAME_FOR_S1U \"eth6\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_IPV4_ADDRESS_FOR_S1U \"192.168.12.111/24\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_PORT_FOR_S1U 2152 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf rrh_gw_config "local_if_name=\"eth0\";remote_address=\"10:60:4b:75:80:83\";local_address=\"98:90:96:df:66:07\";local_port=50000;remote_port=50000;tr_preference=\"raw\";rf_preference=\"usrp_b200\";iq_txshift=4;tx_sample_advance=70;tx_scheduling_advance=9;rrh_gw_active=\"yes\";" $OPENAIR_DIR/cmake_targets/build_oai - --eNB -w USRP -x -c + --eNB -w None -t ETHERNET -x -c --disable-deadline - $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem - -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf -W + sleep 5; $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf -W - True + False + + $OPENAIR_DIR/cmake_targets/build_oai + --RRH -w USRP -t ETHERNET -c --disable-deadline + + + sudo -E chrt -f 99 $OPENAIR_DIR/cmake_targets/rrh_gw/build/rrh_gw + -n1 -x -m1 -i eth1 + False /tmp @@ -5827,34 +5862,44 @@ amerique 390 /tmp - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf tracking_area_code \"1\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf mobile_country_code \"208\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf mobile_network_code \"92\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf N_RB_DL 50 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf mme_ip_address "ipv4=\"192.168.12.26\";ipv6=\"192:168:30::17\";active=\"yes\";preference=\"ipv4\";" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf downlink_frequency 2660000000L - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf uplink_frequency_offset -120000000 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf tx_gain 90 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf rx_gain 125 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf frame_type \"FDD\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf nb_antennas_rx 1 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf nb_antennas_tx 1 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_INTERFACE_NAME_FOR_S1_MME \"eth5\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_IPV4_ADDRESS_FOR_S1_MME \"192.168.12.82/24\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_INTERFACE_NAME_FOR_S1U \"eth5\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_IPV4_ADDRESS_FOR_S1U \"192.168.12.82/24\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_PORT_FOR_S1U 2152 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf tracking_area_code \"1\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf mobile_country_code \"208\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf mobile_network_code \"92\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf N_RB_DL 50 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf mme_ip_address "ipv4=\"192.168.12.26\";ipv6=\"192:168:30::17\";active=\"yes\";preference=\"ipv4\";" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf downlink_frequency 2660000000L + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf uplink_frequency_offset -120000000 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf tx_gain 90 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf rx_gain 125 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf pdsch_referenceSignalPower -29 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf frame_type \"FDD\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf nb_antennas_rx 1 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf nb_antennas_tx 1 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_INTERFACE_NAME_FOR_S1_MME \"eth6\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_IPV4_ADDRESS_FOR_S1_MME \"192.168.12.111/24\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_INTERFACE_NAME_FOR_S1U \"eth6\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_IPV4_ADDRESS_FOR_S1U \"192.168.12.111/24\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_PORT_FOR_S1U 2152 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf rrh_gw_config "local_if_name=\"eth0\";remote_address=\"10:60:4b:75:80:83\";local_address=\"98:90:96:df:66:07\";local_port=50000;remote_port=50000;tr_preference=\"raw\";rf_preference=\"usrp_b200\";iq_txshift=4;tx_sample_advance=113;tx_scheduling_advance=9;rrh_gw_active=\"yes\";" $OPENAIR_DIR/cmake_targets/build_oai - --eNB -w USRP -x -c + --eNB -w None -t ETHERNET -x -c --disable-deadline - $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem - -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf -W + sleep 5; $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf -W - True + False + + $OPENAIR_DIR/cmake_targets/build_oai + --RRH -w USRP -t ETHERNET -c --disable-deadline + + + sudo -E chrt -f 99 $OPENAIR_DIR/cmake_targets/rrh_gw/build/rrh_gw + -n1 -x -m1 -i eth1 + False /tmp @@ -5895,39 +5940,50 @@ lte-softmodem - calisson + calisson + mozart stevens amerique 390 /tmp - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf tracking_area_code \"1\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf mobile_country_code \"208\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf mobile_network_code \"92\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf N_RB_DL 100 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf mme_ip_address "ipv4=\"192.168.12.26\";ipv6=\"192:168:30::17\";active=\"yes\";preference=\"ipv4\";" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf downlink_frequency 2660000000L - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf uplink_frequency_offset -120000000 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf tx_gain 90 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf rx_gain 125 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf frame_type \"FDD\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf nb_antennas_rx 1 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf nb_antennas_tx 1 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_INTERFACE_NAME_FOR_S1_MME \"eth5\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_IPV4_ADDRESS_FOR_S1_MME \"192.168.12.82/24\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_INTERFACE_NAME_FOR_S1U \"eth5\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_IPV4_ADDRESS_FOR_S1U \"192.168.12.82/24\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf ENB_PORT_FOR_S1U 2152 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf tracking_area_code \"1\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf mobile_country_code \"208\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf mobile_network_code \"92\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf N_RB_DL 100 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf mme_ip_address "ipv4=\"192.168.12.26\";ipv6=\"192:168:30::17\";active=\"yes\";preference=\"ipv4\";" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf downlink_frequency 2660000000L + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf uplink_frequency_offset -120000000 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf tx_gain 90 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf rx_gain 125 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf pdsch_referenceSignalPower -32 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf frame_type \"FDD\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf nb_antennas_rx 1 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf nb_antennas_tx 1 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_INTERFACE_NAME_FOR_S1_MME \"eth6\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_IPV4_ADDRESS_FOR_S1_MME \"192.168.12.111/24\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_INTERFACE_NAME_FOR_S1U \"eth6\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_IPV4_ADDRESS_FOR_S1U \"192.168.12.111/24\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf ENB_PORT_FOR_S1U 2152 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf rrh_gw_config "local_if_name=\"eth0\";remote_address=\"10:60:4b:75:80:83\";local_address=\"98:90:96:df:66:07\";local_port=50000;remote_port=50000;tr_preference=\"raw\";rf_preference=\"usrp_b200\";iq_txshift=4;tx_sample_advance=115;tx_scheduling_advance=11;rrh_gw_active=\"yes\";" $OPENAIR_DIR/cmake_targets/build_oai - --eNB -w USRP -x -c + --eNB -w None -t ETHERNET -x -c --disable-deadline - $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem - -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.remote.conf -W + sleep 5; $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf -W - True + False + + $OPENAIR_DIR/cmake_targets/build_oai + --RRH -w USRP -t ETHERNET -c --disable-deadline + + + sudo -E chrt -f 99 $OPENAIR_DIR/cmake_targets/rrh_gw/build/rrh_gw + -n1 -x -m1 -i eth1 + False /tmp From 665b33ce5bc496aa992b2dcacad2e77e867b8330 Mon Sep 17 00:00:00 2001 From: Rohit Gupta Date: Tue, 15 Mar 2016 19:08:17 +0100 Subject: [PATCH 34/47] minor fix in RRH testcase 017504 --- cmake_targets/autotests/test_case_list.xml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index d2afaa3469..59e6783c23 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -5544,7 +5544,7 @@ --eNB -w None -t ETHERNET -x -c --disable-deadline - sleep 5; $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem + sleep 5; sudo -E chrt -f 99 $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf -W @@ -5632,7 +5632,7 @@ --eNB -w None -t ETHERNET -x -c --disable-deadline - sleep 5; $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem + sleep 5; sudo -E chrt -f 99 $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf -W @@ -5717,7 +5717,7 @@ --eNB -w None -t ETHERNET -x -c --disable-deadline - sleep 5; $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem + sleep 5; sudo -E chrt -f 99 $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf -W @@ -5802,7 +5802,7 @@ --eNB -w None -t ETHERNET -x -c --disable-deadline - sleep 5; $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem + sleep 5; sudo -E chrt -f 99 $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf -W @@ -5857,7 +5857,8 @@ lte-softmodem - calisson + calisson + mozart stevens amerique 390 @@ -5885,7 +5886,7 @@ --eNB -w None -t ETHERNET -x -c --disable-deadline - sleep 5; $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem + sleep 5; sudo -E chrt -f 99 $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf -W From ef6f2e2a17d37a5fca76afe8e7b51777798b9195 Mon Sep 17 00:00:00 2001 From: Rohit Gupta Date: Wed, 16 Mar 2016 12:06:42 +0100 Subject: [PATCH 35/47] minor stability fixes for Gitlab test setup --- .../autotests/run_exec_lte-softmodem_tests.py | 2 +- cmake_targets/autotests/test_case_list.xml | 120 +++++++++--------- 2 files changed, 61 insertions(+), 61 deletions(-) diff --git a/cmake_targets/autotests/run_exec_lte-softmodem_tests.py b/cmake_targets/autotests/run_exec_lte-softmodem_tests.py index 3418798954..9997d89cd7 100755 --- a/cmake_targets/autotests/run_exec_lte-softmodem_tests.py +++ b/cmake_targets/autotests/run_exec_lte-softmodem_tests.py @@ -216,7 +216,7 @@ def sftp_module (username, password, hostname, ports, paramList,logfile): # \brief bash script stub put at the end of scripts to terminate it # \param timeout_cmd terminate script after timeout_cmd seconds # \param terminate_missing_procs if True terminate all the processes launched by script if one of them terminates prematurely (due to error) -def finalize_deploy_script (timeout_cmd, terminate_missing_procs='True'): +def finalize_deploy_script (timeout_cmd, terminate_missing_procs='False'): cmd = 'declare -i timeout_cmd='+str(timeout_cmd) + '\n' if terminate_missing_procs == 'True': cmd = cmd + """ diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 59e6783c23..382127b1d6 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -981,7 +981,7 @@ - True + False /tmp @@ -995,7 +995,7 @@ - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue /tmp @@ -1015,7 +1015,7 @@ throughput_test min=1.0Mbits/sec max=1.0Mbits/sec average=1.0Mbits/sec - True + False USRPb210.ALU_EPC.Bandrich.10MHz.FDD.Band_7.UL.1TX.1RX 10 @@ -1055,7 +1055,7 @@ - True + False /tmp @@ -1069,7 +1069,7 @@ - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue /tmp @@ -1089,7 +1089,7 @@ throughput_test min=1.0Mbits/sec max=1.0Mbits/sec average=1.0Mbits/sec - True + False USRPb210.ALU_EPC.Bandrich.20MHz.FDD.Band_7.UL.1TX.1RX 10 @@ -1129,7 +1129,7 @@ - True + False /tmp @@ -1141,7 +1141,7 @@ $OPENAIR_DIR/cmake_targets/autotests/tools/iperf_script 1 ppp0 -s -i 1 -u -f m -B 192.172.0.2 - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue throughput_test min=4.0Mbits/sec max=5.0Mbits/sec average=4.0Mbits/sec @@ -1162,7 +1162,7 @@ $OPENAIRCN_DIR/TEST/autotests/tools/iperf_script 60 lo -u -c 192.172.0.2 -b 10Mbits/s -B 192.172.0.1 - True + False USRPb210.ALU_EPC.Bandrich.5MHz.FDD.Band_7.DL.1TX.1RX 10 @@ -1202,7 +1202,7 @@ - True + False /tmp @@ -1215,7 +1215,7 @@ throughput_test min=8.0Mbits/sec max=9.0Mbits/sec average=8.5Mbits/sec - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue @@ -1235,7 +1235,7 @@ $OPENAIRCN_DIR/TEST/autotests/tools/iperf_script 60 lo -u -c 192.172.0.2 -b 10Mbits/s -B 192.172.0.1 - True + False USRPb210.ALU_EPC.Bandrich.10MHz.FDD.Band_7.DL.1TX.1RX 10 @@ -1275,7 +1275,7 @@ - True + False /tmp @@ -1289,7 +1289,7 @@ throughput_test min=15.0Mbits/sec max=15.0Mbits/sec average=15.0Mbits/sec - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue @@ -1309,7 +1309,7 @@ $OPENAIRCN_DIR/TEST/autotests/tools/iperf_script 60 lo -u -c 192.172.0.2 -b 10Mbits/s -B 192.172.0.1 - True + False USRPb210.ALU_EPC.Bandrich.20MHz.FDD.Band_7.DL.1TX.1RX 10 @@ -1350,7 +1350,7 @@ - True + False /tmp @@ -1364,7 +1364,7 @@ - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue /tmp @@ -1384,7 +1384,7 @@ throughput_test min=1.0Mbits/sec max=1.0Mbits/sec average=1.0Mbits/sec - True + False USRPb210.ALU_EPC.Bandrich.5MHz.FDD.Band_7.UL.2TX.2RX 10 @@ -1425,7 +1425,7 @@ - True + False /tmp > @@ -1438,7 +1438,7 @@ - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue /tmp @@ -1458,7 +1458,7 @@ throughput_test min=2.0Mbits/sec max=2.0Mbits/sec average=2.0Mbits/sec - True + False USRPb210.ALU_EPC.Bandrich.10MHz.FDD.Band_7.UL.2TX.2RX 10 @@ -1498,7 +1498,7 @@ - True + False /tmp @@ -1512,7 +1512,7 @@ - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue /tmp @@ -1532,7 +1532,7 @@ throughput_test min=4.0Mbits/sec max=4.0Mbits/sec average=4.0Mbits/sec - True + False USRPb210.ALU_EPC.Bandrich.20MHz.FDD.Band_7.UL.2TX.2RX 10 @@ -1572,7 +1572,7 @@ - True + False /tmp @@ -1586,7 +1586,7 @@ throughput_test min=4.0Mbits/sec max=5.0Mbits/sec average=4.0Mbits/sec - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue @@ -1606,7 +1606,7 @@ $OPENAIRCN_DIR/TEST/autotests/tools/iperf_script 60 lo -u -c 192.172.0.2 -b 10Mbits/s -B 192.172.0.1 - True + False USRPb210.ALU_EPC.Bandrich.5MHz.FDD.Band_7.DL.2TX.2RX 10 @@ -1646,7 +1646,7 @@ - True + False /tmp @@ -1660,7 +1660,7 @@ throughput_test min=8.0Mbits/sec max=9.0Mbits/sec average=8.5Mbits/sec - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue @@ -1680,7 +1680,7 @@ $OPENAIRCN_DIR/TEST/autotests/tools/iperf_script 60 lo -u -c 192.172.0.2 -b 10Mbits/s -B 192.172.0.1 - True + False USRPb210.ALU_EPC.Bandrich.10MHz.FDD.Band_7.DL.2TX.2RX 10 @@ -1720,7 +1720,7 @@ - True + False /tmp @@ -1734,7 +1734,7 @@ throughput_test min=15.0Mbits/sec max=15.0Mbits/sec average=15.0Mbits/sec - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue @@ -1754,7 +1754,7 @@ $OPENAIRCN_DIR/TEST/autotests/tools/iperf_script 60 lo -u -c 192.172.0.2 -b 10Mbits/s -B 192.172.0.1 - True + False USRPb210.ALU_EPC.Bandrich.20MHz.FDD.Band_7.DL.2TX.2RX 10 @@ -2836,7 +2836,7 @@ throughput_test min=1.0Mbits/sec max=1.0Mbits/sec average=1.0Mbits/sec - True + False USRPx310.ALU_EPC.Bandrich.5MHz.FDD.Band_7.UL.1TX.1RX 10 @@ -2908,7 +2908,7 @@ throughput_test min=1.0Mbits/sec max=1.0Mbits/sec average=1.0Mbits/sec - True + False USRPx310.ALU_EPC.Bandrich.10MHz.FDD.Band_7.UL.1TX.1RX 10 @@ -2980,7 +2980,7 @@ throughput_test min=1.0Mbits/sec max=1.0Mbits/sec average=1.0Mbits/sec - True + False USRPx310.ALU_EPC.Bandrich.20MHz.FDD.Band_7.UL.1TX.1RX 10 @@ -3051,7 +3051,7 @@ $OPENAIRCN_DIR/TEST/autotests/tools/iperf_script 60 lo -u -c 192.172.0.2 -b 10Mbits/s -B 192.172.0.1 - True + False USRPx310.ALU_EPC.Bandrich.5MHz.FDD.Band_7.DL.1TX.1RX 10 @@ -3122,7 +3122,7 @@ $OPENAIRCN_DIR/TEST/autotests/tools/iperf_script 60 lo -u -c 192.172.0.2 -b 10Mbits/s -B 192.172.0.1 - True + False USRPx310.ALU_EPC.Bandrich.10MHz.FDD.Band_7.DL.1TX.1RX 10 @@ -3193,7 +3193,7 @@ $OPENAIRCN_DIR/TEST/autotests/tools/iperf_script 60 lo -u -c 192.172.0.2 -b 10Mbits/s -B 192.172.0.1 - True + False USRPx310.ALU_EPC.Bandrich.20MHz.FDD.Band_7.DL.1TX.1RX 10 @@ -3755,7 +3755,7 @@ throughput_test min=1.0Mbits/sec max=1.0Mbits/sec average=1.0Mbits/sec - True + False EXMIMO.ALU_EPC.Bandrich.5MHz.FDD.Band_7.UL.1TX.1RX 10 @@ -3828,7 +3828,7 @@ throughput_test min=1.0Mbits/sec max=1.0Mbits/sec average=1.0Mbits/sec - True + False EXMIMO.ALU_EPC.Bandrich.10MHz.FDD.Band_7.UL.1TX.1RX 10 @@ -3904,7 +3904,7 @@ throughput_test min=1.0Mbits/sec max=1.0Mbits/sec average=1.0Mbits/sec - True + False EXMIMO.ALU_EPC.Bandrich.20MHz.FDD.Band_7.UL.1TX.1RX 10 @@ -3975,7 +3975,7 @@ $OPENAIRCN_DIR/TEST/autotests/tools/iperf_script 60 lo -u -c 192.172.0.2 -b 10Mbits/s -B 192.172.0.1 - True + False EXMIMO.ALU_EPC.Bandrich.5MHz.FDD.Band_7.DL.1TX.1RX 10 @@ -4046,7 +4046,7 @@ $OPENAIRCN_DIR/TEST/autotests/tools/iperf_script 60 lo -u -c 192.172.0.2 -b 10Mbits/s -B 192.172.0.1 - True + False EXMIMO.ALU_EPC.Bandrich.10MHz.FDD.Band_7.DL.1TX.1RX 10 @@ -4117,7 +4117,7 @@ $OPENAIRCN_DIR/TEST/autotests/tools/iperf_script 60 lo -u -c 192.172.0.2 -b 10Mbits/s -B 192.172.0.1 - True + False EXMIMO.ALU_EPC.Bandrich.20MHz.FDD.Band_7.DL.1TX.1RX 10 @@ -4760,7 +4760,7 @@ throughput_test min=1.0Mbits/sec max=1.0Mbits/sec average=1.0Mbits/sec - True + False BladeRF.ALU_EPC.Bandrich.10MHz.FDD.Band_7.UL.1TX.1RX 10 @@ -4835,7 +4835,7 @@ throughput_test min=1.0Mbits/sec max=1.0Mbits/sec average=1.0Mbits/sec - True + False BladeRF.ALU_EPC.Bandrich.20MHz.FDD.Band_7.UL.1TX.1RX 10 @@ -4909,7 +4909,7 @@ $OPENAIRCN_DIR/TEST/autotests/tools/iperf_script 60 lo -u -c 192.172.0.2 -b 10Mbits/s -B 192.172.0.1 - True + False BladeRF.ALU_EPC.Bandrich.5MHz.FDD.Band_7.DL.1TX.1RX 10 @@ -4983,7 +4983,7 @@ $OPENAIRCN_DIR/TEST/autotests/tools/iperf_script 60 lo -u -c 192.172.0.2 -b 10Mbits/s -B 192.172.0.1 - True + False BladeRF.ALU_EPC.Bandrich.10MHz.FDD.Band_7.DL.1TX.1RX 10 @@ -5058,7 +5058,7 @@ $OPENAIRCN_DIR/TEST/autotests/tools/iperf_script 60 lo -u -c 192.172.0.2 -b 10Mbits/s -B 192.172.0.1 - True + False BladeRF.ALU_EPC.Bandrich.20MHz.FDD.Band_7.DL.1TX.1RX 10 @@ -5209,7 +5209,7 @@ throughput_test min=1.0Mbits/sec max=1.0Mbits/sec average=1.0Mbits/sec - True + False SoDeRa.ALU_EPC.Bandrich.10MHz.FDD.Band_7.UL.1TX.1RX 10 @@ -5284,7 +5284,7 @@ throughput_test min=1.0Mbits/sec max=1.0Mbits/sec average=1.0Mbits/sec - True + False SoDeRa.ALU_EPC.Bandrich.20MHz.FDD.Band_7.UL.1TX.1RX 10 @@ -5358,7 +5358,7 @@ $OPENAIRCN_DIR/TEST/autotests/tools/iperf_script 60 lo -u -c 192.172.0.2 -b 10Mbits/s -B 192.172.0.1 - True + False BladeRF.ALU_EPC.Bandrich.5MHz.FDD.Band_7.DL.1TX.1RX 10 @@ -5432,7 +5432,7 @@ $OPENAIRCN_DIR/TEST/autotests/tools/iperf_script 60 lo -u -c 192.172.0.2 -b 10Mbits/s -B 192.172.0.1 - True + False SoDeRa.ALU_EPC.Bandrich.10MHz.FDD.Band_7.DL.1TX.1RX 10 @@ -5507,7 +5507,7 @@ $OPENAIRCN_DIR/TEST/autotests/tools/iperf_script 60 lo -u -c 192.172.0.2 -b 10Mbits/s -B 192.172.0.1 - True + False SoDeRa.ALU_EPC.Bandrich.20MHz.FDD.Band_7.DL.1TX.1RX 10 @@ -5680,7 +5680,7 @@ throughput_test min=1.0Mbits/sec max=1.0Mbits/sec average=1.0Mbits/sec - True + False USRPb210.RRH.ALU_EPC.Bandrich.10MHz.FDD.Band_7.UL.1TX.1RX 10 @@ -5765,7 +5765,7 @@ throughput_test min=1.0Mbits/sec max=1.0Mbits/sec average=1.0Mbits/sec - True + False USRPb210.RRH.ALU_EPC.Bandrich.20MHz.FDD.Band_7.UL.1TX.1RX 10 @@ -5849,7 +5849,7 @@ $OPENAIRCN_DIR/TEST/autotests/tools/iperf_script 60 lo -u -c 192.172.0.2 -b 10Mbits/s -B 192.172.0.1 - True + False USRPb210.RRH.ALU_EPC.Bandrich.5MHz.FDD.Band_7.DL.1TX.1RX 10 @@ -5933,7 +5933,7 @@ $OPENAIRCN_DIR/TEST/autotests/tools/iperf_script 60 lo -u -c 192.172.0.2 -b 10Mbits/s -B 192.172.0.1 - True + False USRPb210.RRH.ALU_EPC.Bandrich.10MHz.FDD.Band_7.DL.1TX.1RX 10 @@ -6018,7 +6018,7 @@ $OPENAIRCN_DIR/TEST/autotests/tools/iperf_script 60 lo -u -c 192.172.0.2 -b 10Mbits/s -B 192.172.0.1 - True + False USRPb210.RRH.ALU_EPC.Bandrich.20MHz.FDD.Band_7.DL.1TX.1RX 10 From 9b82047c43ed40676ae4325c946a6e3b1007a35a Mon Sep 17 00:00:00 2001 From: Rohit Gupta Date: Wed, 16 Mar 2016 12:18:50 +0100 Subject: [PATCH 36/47] minor fix for Gitlab CI stability --- cmake_targets/autotests/test_case_list.xml | 28 +++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 382127b1d6..6ea12c1fcb 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -2803,7 +2803,7 @@ - True + False /tmp @@ -2875,7 +2875,7 @@ - True + False /tmp @@ -2946,7 +2946,7 @@ - True + False /tmp @@ -3018,7 +3018,7 @@ - True + False /tmp @@ -3089,7 +3089,7 @@ - True + False /tmp @@ -3160,7 +3160,7 @@ - True + False /tmp @@ -3317,7 +3317,7 @@ - True + False /tmp @@ -3641,7 +3641,7 @@ - True + False /tmp @@ -3722,7 +3722,7 @@ - True + False /tmp @@ -3794,7 +3794,7 @@ - True + False /tmp @@ -3866,7 +3866,7 @@ - True + False /tmp @@ -3942,7 +3942,7 @@ - True + False /tmp @@ -4013,7 +4013,7 @@ - True + False /tmp @@ -4084,7 +4084,7 @@ - True + False /tmp From 138380e97a3d535b62011a370062af976ae50147 Mon Sep 17 00:00:00 2001 From: Rohit Gupta Date: Wed, 16 Mar 2016 12:21:10 +0100 Subject: [PATCH 37/47] minor fix for Gitlab CI stability --- cmake_targets/autotests/test_case_list.xml | 54 +++++++++++----------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 6ea12c1fcb..50bdd93344 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -2816,7 +2816,7 @@ - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue /tmp @@ -2888,7 +2888,7 @@ - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue /tmp @@ -2960,7 +2960,7 @@ - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue /tmp @@ -3030,7 +3030,7 @@ $OPENAIR_DIR/cmake_targets/autotests/tools/iperf_script 1 ppp0 -s -i 1 -u -f m -B 192.172.0.2 - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue throughput_test min=4.0Mbits/sec max=5.0Mbits/sec average=4.0Mbits/sec @@ -3101,7 +3101,7 @@ $OPENAIR_DIR/cmake_targets/autotests/tools/iperf_script 1 ppp0 -s -i 1 -u -f m -B 192.172.0.2 - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue throughput_test min=8.0Mbits/sec max=9.0Mbits/sec average=8.5Mbits/sec @@ -3172,7 +3172,7 @@ $OPENAIR_DIR/cmake_targets/autotests/tools/iperf_script 1 ppp0 -s -i 1 -u -f m -B 192.172.0.2 - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue throughput_test min=15.0Mbits/sec max=15.0Mbits/sec average=15.0Mbits/sec @@ -3735,7 +3735,7 @@ - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue /tmp @@ -3808,7 +3808,7 @@ - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue /tmp @@ -3880,7 +3880,7 @@ - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue /tmp @@ -3954,7 +3954,7 @@ $OPENAIR_DIR/cmake_targets/autotests/tools/iperf_script 1 ppp0 -s -i 1 -u -f m -B 192.172.0.2 - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue throughput_test min=4.0Mbits/sec max=5.0Mbits/sec average=4.0Mbits/sec @@ -4025,7 +4025,7 @@ $OPENAIR_DIR/cmake_targets/autotests/tools/iperf_script 1 ppp0 -s -i 1 -u -f m -B 192.172.0.2 - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue throughput_test min=8.0Mbits/sec max=9.0Mbits/sec average=8.5Mbits/sec @@ -4096,7 +4096,7 @@ $OPENAIR_DIR/cmake_targets/autotests/tools/iperf_script 1 ppp0 -s -i 1 -u -f m -B 192.172.0.2 - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue throughput_test min=15.0Mbits/sec max=15.0Mbits/sec average=15.0Mbits/sec @@ -4740,7 +4740,7 @@ - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue /tmp @@ -4815,7 +4815,7 @@ - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue /tmp @@ -4888,7 +4888,7 @@ $OPENAIR_DIR/cmake_targets/autotests/tools/iperf_script 1 ppp0 -s -i 1 -u -f m -B 192.172.0.2 - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue throughput_test min=4.0Mbits/sec max=5.0Mbits/sec average=4.0Mbits/sec @@ -4963,7 +4963,7 @@ throughput_test min=8.0Mbits/sec max=9.0Mbits/sec average=8.5Mbits/sec - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue @@ -5038,7 +5038,7 @@ throughput_test min=15.0Mbits/sec max=15.0Mbits/sec average=15.0Mbits/sec - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue @@ -5189,7 +5189,7 @@ - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue /tmp @@ -5264,7 +5264,7 @@ - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue /tmp @@ -5337,7 +5337,7 @@ $OPENAIR_DIR/cmake_targets/autotests/tools/iperf_script 1 ppp0 -s -i 1 -u -f m -B 192.172.0.2 - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue throughput_test min=4.0Mbits/sec max=5.0Mbits/sec average=4.0Mbits/sec @@ -5412,7 +5412,7 @@ throughput_test min=8.0Mbits/sec max=9.0Mbits/sec average=8.5Mbits/sec - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue @@ -5487,7 +5487,7 @@ throughput_test min=15.0Mbits/sec max=15.0Mbits/sec average=15.0Mbits/sec - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue @@ -5660,7 +5660,7 @@ - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue /tmp @@ -5745,7 +5745,7 @@ - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue /tmp @@ -5828,7 +5828,7 @@ $OPENAIR_DIR/cmake_targets/autotests/tools/iperf_script 1 ppp0 -s -i 1 -u -f m -B 192.172.0.2 - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue throughput_test min=4.0Mbits/sec max=5.0Mbits/sec average=4.0Mbits/sec @@ -5913,7 +5913,7 @@ throughput_test min=8.0Mbits/sec max=9.0Mbits/sec average=8.5Mbits/sec - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue @@ -5998,7 +5998,7 @@ throughput_test min=15.0Mbits/sec max=15.0Mbits/sec average=15.0Mbits/sec - True + False sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue From b2bbd720a6fb478d7e25ee019a0891f30a8e38d1 Mon Sep 17 00:00:00 2001 From: Rohit Gupta Date: Wed, 16 Mar 2016 14:12:29 +0100 Subject: [PATCH 38/47] syntax fix for test setup xml file --- cmake_targets/autotests/test_case_list.xml | 28 +++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 50bdd93344..394feda359 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -2803,7 +2803,7 @@ - False + False /tmp @@ -2875,7 +2875,7 @@ - False + False /tmp @@ -2946,7 +2946,7 @@ - False + False /tmp @@ -3018,7 +3018,7 @@ - False + False /tmp @@ -3089,7 +3089,7 @@ - False + False /tmp @@ -3160,7 +3160,7 @@ - False + False /tmp @@ -3317,7 +3317,7 @@ - False + False /tmp @@ -3641,7 +3641,7 @@ - False + False /tmp @@ -3722,7 +3722,7 @@ - False + False /tmp @@ -3794,7 +3794,7 @@ - False + False /tmp @@ -3866,7 +3866,7 @@ - False + False /tmp @@ -3942,7 +3942,7 @@ - False + False /tmp @@ -4013,7 +4013,7 @@ - False + False /tmp @@ -4084,7 +4084,7 @@ - False + False /tmp From 91d8c8920b11312fdd68db6f29bf3583b779ed0d Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 16 Mar 2016 15:10:06 +0100 Subject: [PATCH 39/47] Modifications to test system to download from the right repository when doing a merge request from oai-internal to oai. --- .gitlab-ci.yml | 5 +++-- cmake_targets/autotests/run_exec_lte-softmodem_tests.py | 9 ++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c75f8fa464..8947453454 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,6 +8,7 @@ job1: - echo $EXTERNAL_SHARE_DIR - echo $SHELL - git rev-parse --abbrev-ref HEAD + - git_repo=`git config --get remote.origin.url` - git_head=`git rev-parse HEAD` - echo $git_head - tmp=`git show-ref --head | grep $git_head` @@ -23,8 +24,8 @@ job1: - echo $NRUNS_LTE_SOFTMODEM - echo $TIMEOUT_CMD - mkdir -p $OPENAIR_DIR/cmake_targets/autotests/log - - python $OPENAIR_DIR/cmake_targets/autotests/run_exec_lte-softmodem_tests.py -c -5GRepoHeadVersion $git_head -n $NFS_SHARE_DIR -u $OAI_USER -p $OAI_PASS $OAI_EXTRA_ARGS -g "$OAI_TEST_CASE_GROUP">& $OPENAIR_DIR/cmake_targets/autotests/python_autotest_cleanup.log - - python $OPENAIR_DIR/cmake_targets/autotests/run_exec_lte-softmodem_tests.py -r -5GRepoHeadVersion $git_head -n $NFS_SHARE_DIR -u $OAI_USER -p $OAI_PASS `echo $OAI_EXTRA_ARGS` -g "$OAI_TEST_CASE_GROUP" --nrun_lte_softmodem $NRUNS_LTE_SOFTMODEM --timeout_cmd $TIMEOUT_CMD >& $OPENAIR_DIR/cmake_targets/autotests/python_autotest.log + - python $OPENAIR_DIR/cmake_targets/autotests/run_exec_lte-softmodem_tests.py -c -5GRepo $git_repo -5GRepoHeadVersion $git_head -n $NFS_SHARE_DIR -u $OAI_USER -p $OAI_PASS $OAI_EXTRA_ARGS -g "$OAI_TEST_CASE_GROUP">& $OPENAIR_DIR/cmake_targets/autotests/python_autotest_cleanup.log + - python $OPENAIR_DIR/cmake_targets/autotests/run_exec_lte-softmodem_tests.py -r -5GRepo $git_repo -5GRepoHeadVersion $git_head -n $NFS_SHARE_DIR -u $OAI_USER -p $OAI_PASS `echo $OAI_EXTRA_ARGS` -g "$OAI_TEST_CASE_GROUP" --nrun_lte_softmodem $NRUNS_LTE_SOFTMODEM --timeout_cmd $TIMEOUT_CMD >& $OPENAIR_DIR/cmake_targets/autotests/python_autotest.log - mv $OPENAIR_DIR/cmake_targets/autotests/python_autotest.log $OPENAIR_DIR/cmake_targets/autotests/log/python_autotest.log - mv $OPENAIR_DIR/cmake_targets/autotests/python_autotest_cleanup.log $OPENAIR_DIR/cmake_targets/autotests/log/python_autotest_cleanup.log - sshpass -p "$OAI_PASS" rsync -az -e "ssh -o StrictHostKeyChecking=no " --rsync-path="mkdir -p $NFS_TEST_RESULTS_DIR && rsync" $OPENAIR_DIR/cmake_targets/autotests/log $OAI_USER@localhost:$NFS_TEST_RESULTS_DIR diff --git a/cmake_targets/autotests/run_exec_lte-softmodem_tests.py b/cmake_targets/autotests/run_exec_lte-softmodem_tests.py index 9997d89cd7..ace214bb53 100755 --- a/cmake_targets/autotests/run_exec_lte-softmodem_tests.py +++ b/cmake_targets/autotests/run_exec_lte-softmodem_tests.py @@ -1105,6 +1105,7 @@ pw ='' i = 0 dlsim=0 localshell=0 +GitOAI5GRepo='' GitOAI5GRepoBranch='' GitOAI5GHeadVersion='' user='' @@ -1141,6 +1142,9 @@ while i < len (sys.argv): i = i +1 elif arg == '-c': cleanUpRemoteMachines=True + elif arg == '-5GRepo': + GitOAI5GRepo = sys.argv[i+1] + i = i +1 elif arg == '-5GRepoBranch': GitOAI5GRepoBranch = sys.argv[i+1] i = i +1 @@ -1190,6 +1194,7 @@ while i < len (sys.argv): print "-r: Remove the log directory in autotests" print "-g: Run test cases in a group" print "-c: Run cleanup scripts on remote machines and exit" + print "-5GRepo: Repository for OAI 5G to use to run tests (overrides GitOAI5GRepo in test_case_list.xml)" print "-5GRepoBranch: Branch for OAI 5G Repository to run tests (overrides the branch in test_case_list.xml)" print "-5GRepoHeadVersion: Head commit on which to run tests (overrides the branch in test_case_list.xml)" print "-u: use the user name passed as argument" @@ -1278,7 +1283,9 @@ if MachineList =='': MachineList = xmlRoot.findtext('MachineList',default='') NFSResultsShare = xmlRoot.findtext('NFSResultsShare',default='') GitOpenaircnRepo = xmlRoot.findtext('GitOpenair-cnRepo',default='') -GitOAI5GRepo = xmlRoot.findtext('GitOAI5GRepo',default='') + +if GitOAI5GRepo == '': + GitOAI5GRepo = xmlRoot.findtext('GitOAI5GRepo',default='') if GitOAI5GRepoBranch == '': GitOAI5GRepoBranch = xmlRoot.findtext('GitOAI5GRepoBranch',default='') From ede2d8e672ea86c3ba41457cc86446509b2d1b67 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 16 Mar 2016 15:51:42 +0100 Subject: [PATCH 40/47] small bug in scope --- openair1/PHY/TOOLS/lte_phy_scope.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c index 843a77fe62..a1478c45ab 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -719,13 +719,13 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, // PDSCH LLRs if (pdsch_llr != NULL) { - for (i=0; ipdsch_llr,0,coded_bits_per_codeword/4); - fl_set_xyplot_data(form->pdsch_llr,bit,llr,coded_bits_per_codeword/4,"","",""); + fl_set_xyplot_xbounds(form->pdsch_llr,0,coded_bits_per_codeword); + fl_set_xyplot_data(form->pdsch_llr,bit,llr,coded_bits_per_codeword,"","",""); } // PDSCH I/Q of MF Output From 4f9b32aa2bb3c9e145ed88ff242065b571be5ce5 Mon Sep 17 00:00:00 2001 From: Rohit Gupta Date: Wed, 16 Mar 2016 16:12:30 +0100 Subject: [PATCH 41/47] updates for OAI EPC Local test cases --- cmake_targets/autotests/test_case_list.xml | 254 ++++++++++----------- 1 file changed, 125 insertions(+), 129 deletions(-) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 394feda359..4dc402c024 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1768,30 +1768,30 @@ calisson 390 /tmp - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf tracking_area_code \"1\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf mobile_country_code \"208\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf mobile_network_code \"92\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf N_RB_DL 25 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf pdsch_referenceSignalPower -26 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf mme_ip_address "ipv4=\"192.170.0.1\";ipv6=\"192:168:30::17\";active=\"yes\";preference=\"ipv4\";" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf downlink_frequency 2660000000L - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf uplink_frequency_offset -120000000 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf tx_gain 90 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf rx_gain 125 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf frame_type \"FDD\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf nb_antennas_rx 1 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf nb_antennas_tx 1 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_INTERFACE_NAME_FOR_S1_MME \"eth5:3\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_IPV4_ADDRESS_FOR_S1_MME \"192.170.0.2/24\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_INTERFACE_NAME_FOR_S1U \"eth5:4\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_IPV4_ADDRESS_FOR_S1U \"192.170.1.2/24\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_PORT_FOR_S1U 2152 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf tracking_area_code \"1\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf mobile_country_code \"208\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf mobile_network_code \"92\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf N_RB_DL 25 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf pdsch_referenceSignalPower -26 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf mme_ip_address "ipv4=\"192.170.0.1\";ipv6=\"192:168:30::17\";active=\"yes\";preference=\"ipv4\";" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf downlink_frequency 2660000000L + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf uplink_frequency_offset -120000000 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf tx_gain 90 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf rx_gain 125 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf frame_type \"FDD\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf nb_antennas_rx 1 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf nb_antennas_tx 1 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_INTERFACE_NAME_FOR_S1_MME \"eth5:3\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_IPV4_ADDRESS_FOR_S1_MME \"192.170.0.2/24\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_INTERFACE_NAME_FOR_S1U \"eth5:4\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_IPV4_ADDRESS_FOR_S1U \"192.170.1.2/24\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_PORT_FOR_S1U 2152 $OPENAIR_DIR/cmake_targets/build_oai --eNB -w USRP -c - sleep 15; sudo -E bash -c 'echo 3 > /proc/sys/vm/drop_caches' ; sudo -E ifconfig eth5:3 192.170.0.2 up ; sudo -E ifconfig eth5:4 192.170.1.2 up; ifconfig ; cp $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf $OPENAIR_TESTDIR/enb.conf + sleep 15; sudo -E bash -c 'echo 3 > /proc/sys/vm/drop_caches' ; sudo -E ifconfig eth5:3 192.170.0.2 up ; sudo -E ifconfig eth5:4 192.170.1.2 up; ifconfig ; cp $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf $OPENAIR_TESTDIR/enb.conf $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem - -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf -W + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf -W @@ -1852,30 +1852,30 @@ calisson 390 /tmp - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf tracking_area_code \"1\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf mobile_country_code \"208\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf mobile_network_code \"92\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf N_RB_DL 50 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf pdsch_referenceSignalPower -29 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf mme_ip_address "ipv4=\"192.170.0.1\";ipv6=\"192:168:30::17\";active=\"yes\";preference=\"ipv4\";" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf downlink_frequency 2660000000L - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf uplink_frequency_offset -120000000 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf tx_gain 90 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf rx_gain 125 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf frame_type \"FDD\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf nb_antennas_rx 1 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf nb_antennas_tx 1 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_INTERFACE_NAME_FOR_S1_MME \"eth5:3\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_IPV4_ADDRESS_FOR_S1_MME \"192.170.0.2/24\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_INTERFACE_NAME_FOR_S1U \"eth5:4\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_IPV4_ADDRESS_FOR_S1U \"192.170.1.2/24\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_PORT_FOR_S1U 2152 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf tracking_area_code \"1\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf mobile_country_code \"208\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf mobile_network_code \"92\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf N_RB_DL 50 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf pdsch_referenceSignalPower -29 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf mme_ip_address "ipv4=\"192.170.0.1\";ipv6=\"192:168:30::17\";active=\"yes\";preference=\"ipv4\";" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf downlink_frequency 2660000000L + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf uplink_frequency_offset -120000000 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf tx_gain 90 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf rx_gain 125 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf frame_type \"FDD\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf nb_antennas_rx 1 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf nb_antennas_tx 1 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_INTERFACE_NAME_FOR_S1_MME \"eth5:3\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_IPV4_ADDRESS_FOR_S1_MME \"192.170.0.2/24\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_INTERFACE_NAME_FOR_S1U \"eth5:4\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_IPV4_ADDRESS_FOR_S1U \"192.170.1.2/24\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_PORT_FOR_S1U 2152 $OPENAIR_DIR/cmake_targets/build_oai --eNB -w USRP -c - sleep 15; sudo -E bash -c 'echo 3 > /proc/sys/vm/drop_caches' ;sudo -E ifconfig eth5:3 192.170.0.2 up ; sudo -E ifconfig eth5:4 192.170.1.2 up; ifconfig ; cp $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf $OPENAIR_TESTDIR/enb.conf + sleep 15; sudo -E bash -c 'echo 3 > /proc/sys/vm/drop_caches' ;sudo -E ifconfig eth5:3 192.170.0.2 up ; sudo -E ifconfig eth5:4 192.170.1.2 up; ifconfig ; cp $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf $OPENAIR_TESTDIR/enb.conf $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem - -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf -W + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf -W @@ -1936,30 +1936,30 @@ calisson 390 /tmp - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf tracking_area_code \"1\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf mobile_country_code \"208\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf mobile_network_code \"92\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf N_RB_DL 100 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf pdsch_referenceSignalPower -29 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf mme_ip_address "ipv4=\"192.170.0.1\";ipv6=\"192:168:30::17\";active=\"yes\";preference=\"ipv4\";" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf downlink_frequency 2660000000L - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf uplink_frequency_offset -120000000 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf tx_gain 90 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf rx_gain 125 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf frame_type \"FDD\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf nb_antennas_rx 1 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf nb_antennas_tx 1 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_INTERFACE_NAME_FOR_S1_MME \"eth5:3\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_IPV4_ADDRESS_FOR_S1_MME \"192.170.0.2/24\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_INTERFACE_NAME_FOR_S1U \"eth5:4\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_IPV4_ADDRESS_FOR_S1U \"192.170.1.2/24\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_PORT_FOR_S1U 2152 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf tracking_area_code \"1\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf mobile_country_code \"208\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf mobile_network_code \"92\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf N_RB_DL 100 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf pdsch_referenceSignalPower -29 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf mme_ip_address "ipv4=\"192.170.0.1\";ipv6=\"192:168:30::17\";active=\"yes\";preference=\"ipv4\";" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf downlink_frequency 2660000000L + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf uplink_frequency_offset -120000000 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf tx_gain 90 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf rx_gain 125 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf frame_type \"FDD\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf nb_antennas_rx 1 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf nb_antennas_tx 1 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_INTERFACE_NAME_FOR_S1_MME \"eth5:3\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_IPV4_ADDRESS_FOR_S1_MME \"192.170.0.2/24\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_INTERFACE_NAME_FOR_S1U \"eth5:4\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_IPV4_ADDRESS_FOR_S1U \"192.170.1.2/24\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_PORT_FOR_S1U 2152 $OPENAIR_DIR/cmake_targets/build_oai --eNB -w USRP -c - sleep 15; sudo -E bash -c 'echo 3 > /proc/sys/vm/drop_caches' ;sudo -E ifconfig eth5:3 192.170.0.2 up ; sudo -E ifconfig eth5:4 192.170.1.2 up; ifconfig ; cp $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf $OPENAIR_TESTDIR/enb.conf + sleep 15; sudo -E bash -c 'echo 3 > /proc/sys/vm/drop_caches' ;sudo -E ifconfig eth5:3 192.170.0.2 up ; sudo -E ifconfig eth5:4 192.170.1.2 up; ifconfig ; cp $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf $OPENAIR_TESTDIR/enb.conf $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem - -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf -W + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf -W @@ -2020,30 +2020,30 @@ calisson 390 /tmp - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf tracking_area_code \"1\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf mobile_country_code \"208\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf mobile_network_code \"92\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf N_RB_DL 25 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf pdsch_referenceSignalPower -26 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf mme_ip_address "ipv4=\"192.170.0.1\";ipv6=\"192:168:30::17\";active=\"yes\";preference=\"ipv4\";" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf downlink_frequency 2660000000L - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf uplink_frequency_offset -120000000 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf tx_gain 90 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf rx_gain 125 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf frame_type \"FDD\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf nb_antennas_rx 1 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf nb_antennas_tx 1 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_INTERFACE_NAME_FOR_S1_MME \"eth5:3\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_IPV4_ADDRESS_FOR_S1_MME \"192.170.0.2/24\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_INTERFACE_NAME_FOR_S1U \"eth5:4\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_IPV4_ADDRESS_FOR_S1U \"192.170.1.2/24\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_PORT_FOR_S1U 2152 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf tracking_area_code \"1\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf mobile_country_code \"208\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf mobile_network_code \"92\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf N_RB_DL 25 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf pdsch_referenceSignalPower -26 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf mme_ip_address "ipv4=\"192.170.0.1\";ipv6=\"192:168:30::17\";active=\"yes\";preference=\"ipv4\";" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf downlink_frequency 2660000000L + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf uplink_frequency_offset -120000000 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf tx_gain 90 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf rx_gain 125 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf frame_type \"FDD\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf nb_antennas_rx 1 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf nb_antennas_tx 1 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_INTERFACE_NAME_FOR_S1_MME \"eth5:3\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_IPV4_ADDRESS_FOR_S1_MME \"192.170.0.2/24\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_INTERFACE_NAME_FOR_S1U \"eth5:4\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_IPV4_ADDRESS_FOR_S1U \"192.170.1.2/24\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_PORT_FOR_S1U 2152 $OPENAIR_DIR/cmake_targets/build_oai --eNB -w USRP -c - sleep 15; sudo -E bash -c 'echo 3 > /proc/sys/vm/drop_caches' ;sudo -E ifconfig eth5:3 192.170.0.2 up ; sudo -E ifconfig eth5:4 192.170.1.2 up; ifconfig ; cp $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf $OPENAIR_TESTDIR/enb.conf + sleep 15; sudo -E bash -c 'echo 3 > /proc/sys/vm/drop_caches' ;sudo -E ifconfig eth5:3 192.170.0.2 up ; sudo -E ifconfig eth5:4 192.170.1.2 up; ifconfig ; cp $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf $OPENAIR_TESTDIR/enb.conf $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem - -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf -W + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf -W @@ -2104,30 +2104,30 @@ calisson 390 /tmp - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf tracking_area_code \"1\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf mobile_country_code \"208\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf mobile_network_code \"92\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf N_RB_DL 50 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf pdsch_referenceSignalPower -29 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf mme_ip_address "ipv4=\"192.170.0.1\";ipv6=\"192:168:30::17\";active=\"yes\";preference=\"ipv4\";" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf downlink_frequency 2660000000L - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf uplink_frequency_offset -120000000 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf tx_gain 90 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf rx_gain 125 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf frame_type \"FDD\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf nb_antennas_rx 1 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf nb_antennas_tx 1 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_INTERFACE_NAME_FOR_S1_MME \"eth5:3\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_IPV4_ADDRESS_FOR_S1_MME \"192.170.0.2/24\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_INTERFACE_NAME_FOR_S1U \"eth5:4\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_IPV4_ADDRESS_FOR_S1U \"192.170.1.2/24\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_PORT_FOR_S1U 2152 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf tracking_area_code \"1\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf mobile_country_code \"208\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf mobile_network_code \"92\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf N_RB_DL 50 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf pdsch_referenceSignalPower -29 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf mme_ip_address "ipv4=\"192.170.0.1\";ipv6=\"192:168:30::17\";active=\"yes\";preference=\"ipv4\";" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf downlink_frequency 2660000000L + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf uplink_frequency_offset -120000000 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf tx_gain 90 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf rx_gain 125 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf frame_type \"FDD\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf nb_antennas_rx 1 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf nb_antennas_tx 1 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_INTERFACE_NAME_FOR_S1_MME \"eth5:3\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_IPV4_ADDRESS_FOR_S1_MME \"192.170.0.2/24\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_INTERFACE_NAME_FOR_S1U \"eth5:4\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_IPV4_ADDRESS_FOR_S1U \"192.170.1.2/24\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_PORT_FOR_S1U 2152 $OPENAIR_DIR/cmake_targets/build_oai --eNB -w USRP -c - sleep 15; sudo -E bash -c 'echo 3 > /proc/sys/vm/drop_caches' ;sudo -E ifconfig eth5:3 192.170.0.2 up ; sudo -E ifconfig eth5:4 192.170.1.2 up; ifconfig ; cp $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf $OPENAIR_TESTDIR/enb.conf + sleep 15; sudo -E bash -c 'echo 3 > /proc/sys/vm/drop_caches' ;sudo -E ifconfig eth5:3 192.170.0.2 up ; sudo -E ifconfig eth5:4 192.170.1.2 up; ifconfig ; cp $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf $OPENAIR_TESTDIR/enb.conf $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem - -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf -W + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf -W @@ -2188,30 +2188,30 @@ calisson 390 /tmp - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf tracking_area_code \"1\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf mobile_country_code \"208\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf mobile_network_code \"92\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf N_RB_DL 100 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf pdsch_referenceSignalPower -29 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf mme_ip_address "ipv4=\"192.170.0.1\";ipv6=\"192:168:30::17\";active=\"yes\";preference=\"ipv4\";" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf downlink_frequency 2660000000L - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf uplink_frequency_offset -120000000 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf tx_gain 90 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf rx_gain 125 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf frame_type \"FDD\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf nb_antennas_rx 1 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf nb_antennas_tx 1 - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_INTERFACE_NAME_FOR_S1_MME \"eth5:3\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_IPV4_ADDRESS_FOR_S1_MME \"192.170.0.2/24\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_INTERFACE_NAME_FOR_S1U \"eth5:4\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_IPV4_ADDRESS_FOR_S1U \"192.170.1.2/24\" - targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf ENB_PORT_FOR_S1U 2152 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf tracking_area_code \"1\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf mobile_country_code \"208\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf mobile_network_code \"92\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf N_RB_DL 100 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf pdsch_referenceSignalPower -29 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf mme_ip_address "ipv4=\"192.170.0.1\";ipv6=\"192:168:30::17\";active=\"yes\";preference=\"ipv4\";" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf downlink_frequency 2660000000L + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf uplink_frequency_offset -120000000 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf tx_gain 90 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf rx_gain 125 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf frame_type \"FDD\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf nb_antennas_rx 1 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf nb_antennas_tx 1 + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_INTERFACE_NAME_FOR_S1_MME \"eth5:3\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_IPV4_ADDRESS_FOR_S1_MME \"192.170.0.2/24\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_INTERFACE_NAME_FOR_S1U \"eth5:4\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_IPV4_ADDRESS_FOR_S1U \"192.170.1.2/24\" + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf ENB_PORT_FOR_S1U 2152 $OPENAIR_DIR/cmake_targets/build_oai --eNB -w USRP -c - sleep 15; sudo -E bash -c 'echo 3 > /proc/sys/vm/drop_caches' ;sudo -E ifconfig eth5:3 192.170.0.2 up ; sudo -E ifconfig eth5:4 192.170.1.2 up; ifconfig ; cp $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf $OPENAIR_TESTDIR/enb.conf + sleep 15; sudo -E bash -c 'echo 3 > /proc/sys/vm/drop_caches' ;sudo -E ifconfig eth5:3 192.170.0.2 up ; sudo -E ifconfig eth5:4 192.170.1.2 up; ifconfig ; cp $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf $OPENAIR_TESTDIR/enb.conf $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem - -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.epc.local.conf -W + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf -W @@ -3884,15 +3884,11 @@ sudo -S -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --stop-ue /tmp - BUILD/EPC/epc.local.enb.conf.in MCC \"208\" - BUILD/EPC/epc.local.enb.conf.in MNC \"92\" - BUILD/EPC/epc.local.enb.conf.in TAC \"1\" - BUILD/EPC/epc.local.enb.conf.in PGW_INTERFACE_NAME_FOR_SGI \"eth5\" - BUILD/EPC/epc.local.enb.conf.in PGW_IPV4_ADDRESS_FOR_SGI \"192.168.12.82/24\" - SCRIPTS/build_epc - -c -l - SCRIPTS/build_hss - -c -l + + + + + From 1459ca123768ef791df29f6352a0509e07e53303 Mon Sep 17 00:00:00 2001 From: Rohit Gupta Date: Wed, 16 Mar 2016 17:17:52 +0100 Subject: [PATCH 42/47] remove testcases from exclusion which are working --- cmake_targets/autotests/test_case_list.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 4dc402c024..5212b62995 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -10,7 +10,7 @@ sudo -S -E /opt/ltebox/tools/stop_ltebox $OPENAIR_DIR/cmake_targets/build_oai -w EXMIMO -c; sudo -S -E $OPENAIR_DIR/cmake_targets/tools/stop_exmimo2; uname -a; dmesg|tail 36000 - 0102+ 010304 010305 0104+ 015502 015505 015506 015507 015508 015509 015510 015511 015602 015605 015702 015705 015802 015805 0159+ 0160+ 0161+ 0162+ 0163+ 0165+ 0170+ 017502 017505 + 0102+ 010304 010305 0104+ 015502 015505 015506 015507 015508 015509 015510 015511 015602 015605 015702 015705 015802 015805 0170+ 017502 017505 3 mozart calisson stevens nano amerique From 4eed6a1a472f74a8da19c53dde44933e778a11d0 Mon Sep 17 00:00:00 2001 From: Rohit Gupta Date: Wed, 16 Mar 2016 17:24:50 +0100 Subject: [PATCH 43/47] fix for segmentation fault in BaldeRF --- targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c b/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c index 065b0bbad2..d9b7bfa905 100644 --- a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c +++ b/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c @@ -1080,6 +1080,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { device->trx_set_freq_func = trx_brf_set_freq; device->trx_set_gains_func = trx_brf_set_gains; device->openair0_cfg = openair0_cfg; + device->priv = (void *)brf; calibrate_rf(device); From 1db6299616f6ed3e561bfcb862d8da6fafe9cc2b Mon Sep 17 00:00:00 2001 From: Rohit Gupta Date: Thu, 17 Mar 2016 19:35:45 +0100 Subject: [PATCH 44/47] change to exclusion test case list --- cmake_targets/autotests/test_case_list.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 5212b62995..c4b0fc75e6 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -10,7 +10,7 @@ sudo -S -E /opt/ltebox/tools/stop_ltebox $OPENAIR_DIR/cmake_targets/build_oai -w EXMIMO -c; sudo -S -E $OPENAIR_DIR/cmake_targets/tools/stop_exmimo2; uname -a; dmesg|tail 36000 - 0102+ 010304 010305 0104+ 015502 015505 015506 015507 015508 015509 015510 015511 015602 015605 015702 015705 015802 015805 0170+ 017502 017505 + 0102+ 010304 010305 0104+ 015502 015505 015506 015507 015508 015509 015510 015511 015602 015605 015702 015705 015802 015805 016502 016505 0170+ 017502 017505 018002 018005 018502 018505 3 mozart calisson stevens nano amerique From c031cfe84e525a79d8c759cff1955d31cb996932 Mon Sep 17 00:00:00 2001 From: Rohit Gupta Date: Mon, 21 Mar 2016 10:28:37 +0100 Subject: [PATCH 45/47] minor fix for bug in Gitlab CI for checking out code --- cmake_targets/autotests/run_exec_lte-softmodem_tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake_targets/autotests/run_exec_lte-softmodem_tests.py b/cmake_targets/autotests/run_exec_lte-softmodem_tests.py index ace214bb53..086ec12080 100755 --- a/cmake_targets/autotests/run_exec_lte-softmodem_tests.py +++ b/cmake_targets/autotests/run_exec_lte-softmodem_tests.py @@ -1401,8 +1401,8 @@ for oai in oai_list: #cmd = cmd + 'mkdir -p ' + logdir + '\n' cmd = cmd + 'cd '+ logdir + '\n' cmd = cmd + 'git config --global http.sslVerify false \n' - cmd = cmd + 'git clone --depth 1 '+ GitOAI5GRepo + ' -b ' + GitOAI5GRepoBranch +' \n' - cmd = cmd + 'git clone '+ GitOpenaircnRepo + ' -b ' +GitOpenaircnRepoBranch + ' \n' + cmd = cmd + 'git clone '+ GitOAI5GRepo +' \n' + cmd = cmd + 'git clone '+ GitOpenaircnRepo + ' \n' cmd = cmd + 'cd ' + logdirOAI5GRepo + '\n' cmd = cmd + 'git checkout ' + GitOAI5GRepoBranch + '\n' #cmd = cmd + 'git checkout ' + GitOAI5GHeadVersion + '\n' From 3a419bd4eaf14d804257d12a1895b62afb48a5b5 Mon Sep 17 00:00:00 2001 From: Rohit Gupta Date: Mon, 21 Mar 2016 10:42:28 +0100 Subject: [PATCH 46/47] minor fix for Gitlab CI logging --- cmake_targets/autotests/run_exec_lte-softmodem_tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake_targets/autotests/run_exec_lte-softmodem_tests.py b/cmake_targets/autotests/run_exec_lte-softmodem_tests.py index 086ec12080..f1c165acbf 100755 --- a/cmake_targets/autotests/run_exec_lte-softmodem_tests.py +++ b/cmake_targets/autotests/run_exec_lte-softmodem_tests.py @@ -1409,7 +1409,7 @@ for oai in oai_list: cmd = cmd + 'git_head=`git ls-remote |grep \'' + GitOAI5GRepoBranch + '\'` \n' cmd = cmd + 'git_head=($git_head) \n' cmd = cmd + 'git_head=${git_head[0]} \n' - cmd = cmd + 'echo \"GitOAI5GHeadVersion_remote = $git_head\"' + cmd = cmd + 'echo \"GitOAI5GHeadVersion_remote = $git_head\" \n' cmd = cmd + 'echo \"GitOAI5GHeadVersion_local = ' + GitOAI5GHeadVersion + '\" \n' if flag_skip_git_head_check==True: cmd = cmd + 'echo \"skipping GitHead check...\" \n ' From 28dae90984b71d169f620da3d3fff2889a843462 Mon Sep 17 00:00:00 2001 From: Rohit Gupta Date: Mon, 21 Mar 2016 11:29:02 +0100 Subject: [PATCH 47/47] fix for excluding tests listed in xml file --- .../autotests/run_exec_autotests.bash | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/cmake_targets/autotests/run_exec_autotests.bash b/cmake_targets/autotests/run_exec_autotests.bash index a98a071bae..1029acc1e6 100755 --- a/cmake_targets/autotests/run_exec_autotests.bash +++ b/cmake_targets/autotests/run_exec_autotests.bash @@ -388,6 +388,7 @@ until [ -z "$1" ] -g | --run-group) RUN_GROUP=1 test_case_group=$2 + test_case_group=`sed "s/\+/\*/g" <<< "${test_case_group}"` # Replace + with * for bash string substituion echo_info "Will execute test cases only in group $test_case_group" shift 2;; -p) @@ -423,9 +424,17 @@ rm -fr $tmpfile xml_conf="$OPENAIR_DIR/cmake_targets/autotests/test_case_list.xml" test_case_list=`xmlstarlet sel -T -t -m /testCaseList/testCase -s A:N:- "@id" -v "@id" -n $xml_conf` +test_case_excl_list=`xmlstarlet sel -t -v "/testCaseList/TestCaseExclusionList" $xml_conf` +echo "Test Case Exclusion List = $test_case_excl_list " + +test_case_excl_list=`sed "s/\+/\*/g" <<< "$test_case_excl_list" ` # Replace + with * for bash string substituion + +read -a test_case_excl_array <<< "$test_case_excl_list" echo "test_case_list = $test_case_list" +echo "Test Case Exclusion List = $test_case_excl_list \n" + readarray -t test_case_array <<<"$test_case_list" read -a test_case_group_array <<< "$test_case_group" @@ -447,6 +456,15 @@ for search_expr in "${test_case_array[@]}" flag_run_test_case=1 fi + for search_excl in "${test_case_excl_array[@]}" + do + if [[ $search_expr == $search_excl ]];then + flag_run_test_case=0 + echo_info "Test case $search_expr match found in test case excl group. Will skip the test case for execution..." + break + fi + done + #We skip this test case if it is not in the group list if [ "$flag_run_test_case" -ne "1" ]; then