From 648c3f64832e4a517a380997fc70267454629d16 Mon Sep 17 00:00:00 2001 From: gauthier <gauthier@mycompany.com> Date: Wed, 30 Sep 2015 15:59:49 +0000 Subject: [PATCH] Sync home, in dev git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7864 818b1a75-f10b-46b9-bf7c-635c3b92a50f --- openair-cn/TEST/EPC_TEST/generate_scenario.c | 468 +++++++++++++++++++ 1 file changed, 468 insertions(+) create mode 100644 openair-cn/TEST/EPC_TEST/generate_scenario.c diff --git a/openair-cn/TEST/EPC_TEST/generate_scenario.c b/openair-cn/TEST/EPC_TEST/generate_scenario.c new file mode 100644 index 0000000000..99cb25d3d9 --- /dev/null +++ b/openair-cn/TEST/EPC_TEST/generate_scenario.c @@ -0,0 +1,468 @@ +/******************************************************************************* + 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 <http://www.gnu.org/licenses/>. + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@eurecom.fr + + Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE + + *******************************************************************************/ + +/* + generate_scenario.c + ------------------- + AUTHOR : Lionel GAUTHIER + COMPANY : EURECOM + EMAIL : Lionel.Gauthier@eurecom.fr + */ + +#include <string.h> +#include <libconfig.h> +#include <inttypes.h> + +#include "assertions.h" +#include "enb_config.h" +#if defined(ENABLE_ITTI) +# include "intertask_interface.h" +# if defined(ENABLE_USE_MME) +# include "s1ap_eNB.h" +# include "sctp_eNB_task.h" +# endif +#endif +#include "sctp_default_values.h" + +#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" + + + + +Enb_properties_array_t g_enb_properties; + +static void enb_config_display(void) +{ + int i,j; + + printf( "\n----------------------------------------------------------------------\n"); + printf( " ENB CONFIG FILE CONTENT LOADED (TBC):\n"); + printf( "----------------------------------------------------------------------\n"); + 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.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.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.properties[i]->mnc); + } + printf( "\n--------------------------------------------------------\n"); + } +} + + +#ifdef LIBCONFIG_LONG +#define libconfig_int long +#else +#define libconfig_int int +#endif +const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) +{ + 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; + int num_enb_properties = 0; + 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; + 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; + 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; + 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; + char *astring = NULL; + + memset((char*) (g_enb_properties.properties), 0 , MAX_ENB * sizeof(Enb_properties_t *)); + memset((char*)active_enb, 0 , 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 { + config_destroy(&cfg); + AssertFatal (0, "No eNB configuration file provided!\n"); + } + + // 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 = 0; + 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 = 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; +#if defined(ENABLE_USE_MME) + EPC_MODE_ENABLED = 1; +#endif + } // 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; + } + } + + // 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; +# if defined(ENABLE_USE_MME) + 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; + } + } +#endif + + // 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" ); + } + } + } + } + } + } + } + + g_enb_properties.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; +} + + +static void usage ( + int argc, + char *argv[]) +{ + 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, "Available options:\n"); + fprintf (stdout, "\t--help, -h Print this help and return\n"); + fprintf (stdout, "\t--test-dir <path>\n"); + fprintf (stdout, " Set the test directory where pdml and original enb(s) config files are located\n"); + fprintf (stdout, " See README in openair-cn/TEST/EPC_TEST\n"); + fprintf (stdout, "\t--new-enb-conf-file <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"); +} + + +int +config_parse_opt_line ( + int argc, + char *argv[]) +{ + 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_HELP, + }; + + static struct option long_options[] = { + {"test-dir", required_argument, 0, LONG_OPTION_TEST_DIR}, + {"new-enb-conf-file", required_argument, 0, LONG_OPTION_NEW_ENB_CONF_FILE}, + {"help", required_argument, 0, LONG_OPTION_HELP}, + {NULL, 0, NULL, 0} + }; + + /* + * Parsing command line + */ + while ((option = getopt_long (argc, argv, "h", long_options, NULL)) != -1) { + switch (option) { + case LONG_OPTION_TEST_DIR: + if (optarg) { + test_dir = strdup(optarg); + printf("TEST DIRECTORY IS %s\n", test_dir); + } + break; + + case LONG_OPTION_NEW_ENB_CONF_FILE: + if (optarg) { + enb_config_file_name = strdup(optarg); + printf("eNB config file name is %s\n", enb_config_file_name); + g_enb_properties = enb_config_init(conf_config_file_name); + } + break; + + if (optarg) { + test_dir = strdup(optarg); + printf("TEST DIRECTORY IS %s\n", test_dir); + } + break; + + case LONG_OPTION_HELP: + case 'h': /* Fall through */ + default: + usage (); + exit (0); + } + } + return 0; +} + +//------------------------------------------------------------------------------ +int main( int argc, char **argv ) +//------------------------------------------------------------------------------ +{ + memset((char*) (g_enb_properties.properties), 0 , MAX_ENB * sizeof(Enb_properties_t *)); + config_parse_opt_line (argc, argv); //Command-line options + + /* Read eNB configuration file */ + g_enb_properties = enb_config_init(conf_config_file_name); + + + return 0; +} -- GitLab