Commit e58be6bb authored by gauthier's avatar gauthier
Browse files

Remaining TODO fill assoc_id and mme_ue_id of packets

parent d27641a4
......@@ -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}
)
......
......@@ -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");
......
......@@ -8,30 +8,30 @@
/>
<!-- Ugly but no time to find a better way in XSLT 1.0 (map/list)-->
<xsl:param name="enb_s1c0" select="'0.0.0.0'"/>
<xsl:param name="enb_s1c1" select="'0.0.0.0'"/>
<xsl:param name="enb_s1c2" select="'0.0.0.0'"/>
<xsl:param name="enb_s1c3" select="'0.0.0.0'"/>
<xsl:param name="enb_s1c4" select="'0.0.0.0'"/>
<xsl:param name="enb_s1c5" select="'0.0.0.0'"/>
<xsl:param name="enb_s1c6" select="'0.0.0.0'"/>
<xsl:param name="enb_s1c7" select="'0.0.0.0'"/>
<xsl:param name="mme_s1c0_0" select="'0.0.0.0'"/>
<xsl:param name="mme_s1c0_1" select="'0.0.0.0'"/>
<xsl:param name="mme_s1c0_2" select="'0.0.0.0'"/>
<xsl:param name="mme_s1c0_3" select="'0.0.0.0'"/>
<xsl:param name="mme_s1c1_0" select="'0.0.0.0'"/>
<xsl:param name="mme_s1c1_1" select="'0.0.0.0'"/>
<xsl:param name="mme_s1c1_2" select="'0.0.0.0'"/>
<xsl:param name="mme_s1c1_3" select="'0.0.0.0'"/>
<xsl:param name="mme_s1c2_0" select="'0.0.0.0'"/>
<xsl:param name="mme_s1c2_1" select="'0.0.0.0'"/>
<xsl:param name="mme_s1c2_2" select="'0.0.0.0'"/>
<xsl:param name="mme_s1c2_3" select="'0.0.0.0'"/>
<xsl:param name="mme_s1c3_0" select="'0.0.0.0'"/>
<xsl:param name="mme_s1c3_1" select="'0.0.0.0'"/>
<xsl:param name="mme_s1c3_2" select="'0.0.0.0'"/>
<xsl:param name="mme_s1c3_3" select="'0.0.0.0'"/>
<xsl:param name="enb0_s1c" select="'0.0.0.0'"/>
<xsl:param name="enb1_s1c" select="'0.0.0.0'"/>
<xsl:param name="enb2_s1c" select="'0.0.0.0'"/>
<xsl:param name="enb3_s1c" select="'0.0.0.0'"/>
<xsl:param name="enb4_s1c" select="'0.0.0.0'"/>
<xsl:param name="enb5_s1c" select="'0.0.0.0'"/>
<xsl:param name="enb6_s1c" select="'0.0.0.0'"/>
<xsl:param name="enb7_s1c" select="'0.0.0.0'"/>
<xsl:param name="mme0_s1c_0" select="'0.0.0.0'"/>
<xsl:param name="mme0_s1c_1" select="'0.0.0.0'"/>
<xsl:param name="mme0_s1c_2" select="'0.0.0.0'"/>
<xsl:param name="mme0_s1c_3" select="'0.0.0.0'"/>
<xsl:param name="mme1_s1c_0" select="'0.0.0.0'"/>
<xsl:param name="mme1_s1c_1" select="'0.0.0.0'"/>
<xsl:param name="mme1_s1c_2" select="'0.0.0.0'"/>
<xsl:param name="mme1_s1c_3" select="'0.0.0.0'"/>
<xsl:param name="mme2_s1c_0" select="'0.0.0.0'"/>
<xsl:param name="mme2_s1c_1" select="'0.0.0.0'"/>
<xsl:param name="mme2_s1c_2" select="'0.0.0.0'"/>
<xsl:param name="mme2_s1c_3" select="'0.0.0.0'"/>
<xsl:param name="mme3_s1c_0" select="'0.0.0.0'"/>
<xsl:param name="mme3_s1c_1" select="'0.0.0.0'"/>
<xsl:param name="mme3_s1c_2" select="'0.0.0.0'"/>
<xsl:param name="mme3_s1c_3" select="'0.0.0.0'"/>
<xsl:param name="ip_address" select="'0.0.0.0'"/>
......@@ -39,30 +39,30 @@
<xsl:template name="reverse_ip">
<xsl:param name="ip_address"/>
<xsl:choose>
<xsl:when test="$ip_address=$enb_s1c0">enb_s1c0</xsl:when>
<xsl:when test="$ip_address=$enb_s1c1">enb_s1c1</xsl:when>
<xsl:when test="$ip_address=$enb_s1c2">enb_s1c2</xsl:when>
<xsl:when test="$ip_address=$enb_s1c3">enb_s1c3</xsl:when>
<xsl:when test="$ip_address=$enb_s1c4">enb_s1c4</xsl:when>
<xsl:when test="$ip_address=$enb_s1c5">enb_s1c5</xsl:when>
<xsl:when test="$ip_address=$enb_s1c6">enb_s1c6</xsl:when>
<xsl:when test="$ip_address=$enb_s1c7">enb_s1c7</xsl:when>
<xsl:when test="$ip_address=$mme_s1c0_0">mme_s1c0_0</xsl:when>
<xsl:when test="$ip_address=$mme_s1c0_1">mme_s1c0_1</xsl:when>
<xsl:when test="$ip_address=$mme_s1c0_2">mme_s1c0_2</xsl:when>
<xsl:when test="$ip_address=$mme_s1c0_3">mme_s1c0_3</xsl:when>
<xsl:when test="$ip_address=$mme_s1c1_0">mme_s1c1_0</xsl:when>
<xsl:when test="$ip_address=$mme_s1c1_1">mme_s1c1_1</xsl:when>
<xsl:when test="$ip_address=$mme_s1c1_2">mme_s1c1_2</xsl:when>
<xsl:when test="$ip_address=$mme_s1c1_3">mme_s1c1_3</xsl:when>
<xsl:when test="$ip_address=$mme_s1c2_0">mme_s1c2_0</xsl:when>
<xsl:when test="$ip_address=$mme_s1c2_1">mme_s1c2_1</xsl:when>
<xsl:when test="$ip_address=$mme_s1c2_2">mme_s1c2_2</xsl:when>
<xsl:when test="$ip_address=$mme_s1c2_3">mme_s1c2_3</xsl:when>
<xsl:when test="$ip_address=$mme_s1c3_0">mme_s1c3_0</xsl:when>
<xsl:when test="$ip_address=$mme_s1c3_1">mme_s1c3_1</xsl:when>
<xsl:when test="$ip_address=$mme_s1c3_2">mme_s1c3_2</xsl:when>
<xsl:when test="$ip_address=$mme_s1c3_3">mme_s1c3_3</xsl:when>
<xsl:when test="$ip_address=$enb0_s1c">enb0_s1c</xsl:when>
<xsl:when test="$ip_address=$enb1_s1c">enb1_s1c</xsl:when>
<xsl:when test="$ip_address=$enb2_s1c">enb2_s1c</xsl:when>
<xsl:when test="$ip_address=$enb3_s1c">enb3_s1c</xsl:when>
<xsl:when test="$ip_address=$enb4_s1c">enb4_s1c</xsl:when>
<xsl:when test="$ip_address=$enb5_s1c">enb5_s1c</xsl:when>
<xsl:when test="$ip_address=$enb6_s1c">enb6_s1c</xsl:when>
<xsl:when test="$ip_address=$enb7_s1c">enb7_s1c</xsl:when>
<xsl:when test="$ip_address=$mme0_s1c_0">mme0_s1c_0</xsl:when>
<xsl:when test="$ip_address=$mme0_s1c_1">mme0_s1c_1</xsl:when>
<xsl:when test="$ip_address=$mme0_s1c_2">mme0_s1c_2</xsl:when>
<xsl:when test="$ip_address=$mme0_s1c_3">mme0_s1c_3</xsl:when>
<xsl:when test="$ip_address=$mme1_s1c_0">mme1_s1c_0</xsl:when>
<xsl:when test="$ip_address=$mme1_s1c_1">mme1_s1c_1</xsl:when>
<xsl:when test="$ip_address=$mme1_s1c_2">mme1_s1c_2</xsl:when>
<xsl:when test="$ip_address=$mme1_s1c_3">mme1_s1c_3</xsl:when>
<xsl:when test="$ip_address=$mme2_s1c_0">mme2_s1c_0</xsl:when>
<xsl:when test="$ip_address=$mme2_s1c_1">mme2_s1c_1</xsl:when>
<xsl:when test="$ip_address=$mme2_s1c_2">mme2_s1c_2</xsl:when>
<xsl:when test="$ip_address=$mme2_s1c_3">mme2_s1c_3</xsl:when>
<xsl:when test="$ip_address=$mme3_s1c_0">mme3_s1c_0</xsl:when>
<xsl:when test="$ip_address=$mme3_s1c_1">mme3_s1c_1</xsl:when>
<xsl:when test="$ip_address=$mme3_s1c_2">mme3_s1c_2</xsl:when>
<xsl:when test="$ip_address=$mme3_s1c_3">mme3_s1c_3</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">ERROR: Cannot reverse resolv IP <xsl:value-of select="."/> !
</xsl:message>
......@@ -70,6 +70,26 @@
</xsl:choose>
</xsl:template>
<xsl:template name="enb_ip_2_enb_instance">
<xsl:param name="ip_address"/>
<xsl:choose>
<xsl:when test="$ip_address=$enb0_s1c">0</xsl:when>
<xsl:when test="$ip_address=$enb1_s1c">1</xsl:when>
<xsl:when test="$ip_address=$enb2_s1c">2</xsl:when>
<xsl:when test="$ip_address=$enb3_s1c">3</xsl:when>
<xsl:when test="$ip_address=$enb4_s1c">4</xsl:when>
<xsl:when test="$ip_address=$enb5_s1c">5</xsl:when>
<xsl:when test="$ip_address=$enb6_s1c">6</xsl:when>
<xsl:when test="$ip_address=$enb7_s1c">7</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">ERROR: Cannot set eNB instance <xsl:value-of select="."/> !
</xsl:message>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="chunktype2str">
<xsl:param name="chunk_type"/>
<xsl:choose>
......@@ -120,8 +140,26 @@
</xsl:variable>
<xsl:variable name="action">
<xsl:choose>
<xsl:when test="starts-with($ip_src,'enb_s1')">SEND</xsl:when>
<xsl:when test="starts-with($ip_src,'mme_s1c')">RECEIVE</xsl:when>
<xsl:when test="starts-with($ip_src,'enb')">SEND</xsl:when>
<xsl:when test="starts-with($ip_src,'mme')">RECEIVE</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">ERROR: UNKNOWN ACTION <xsl:value-of select="."/> !
</xsl:message>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="enb_instance">
<xsl:choose>
<xsl:when test="starts-with($ip_src,'enb')">
<xsl:call-template name="enb_ip_2_enb_instance">
<xsl:with-param name="ip_address" select="$ip/field[@name='ip.src']/@show"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="starts-with($ip_dst,'enb')">
<xsl:call-template name="enb_ip_2_enb_instance">
<xsl:with-param name="ip_address" select="$ip/field[@name='ip.dst']/@show"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">ERROR: UNKNOWN ACTION <xsl:value-of select="."/> !
</xsl:message>
......@@ -156,6 +194,7 @@
<pos_offset value="{$s1ap_pos_offset}"/>
<ip.src value="{$ip_src}"/>
<ip.dst value="{$ip_dst}"/>
<eNB.instance value="{$enb_instance}"/>
<!--sctp.data_sid value="{$sctp_data_sid}"/-->
<!--sctp.srcport value="{$sctp_srcport}"/-->
<!--sctp.dstport value="{$sctp_dstport}"/-->
......@@ -177,6 +216,7 @@
<pos_offset value="{$sctp_pos_offset}"/>
<ip.src value="{$ip_src}"/>
<ip.dst value="{$ip_dst}"/>
<eNB.instance value="{$enb_instance}"/>
<!--sctp.srcport value="{$sctp_srcport}"/-->
<!--sctp.dstport value="{$sctp_dstport}"/-->
<!--sctp.init_nr_in_streams value="{$sctp_init_nr_in_streams}"/-->
......@@ -197,6 +237,7 @@
<pos_offset value="{$sctp_pos_offset}"/>
<ip.src value="{$ip_src}"/>
<ip.dst value="{$ip_dst}"/>
<eNB.instance value="{$enb_instance}"/>
<!--sctp.data_sid value="{$sctp_data_sid}"/-->
<!--sctp.srcport value="{$sctp_srcport}"/-->
<!--sctp.dstport value="{$sctp_dstport}"/-->
......@@ -218,6 +259,7 @@
<pos_offset value="{$sctp_pos_offset}"/>
<ip.src value="{$ip_src}"/>
<ip.dst value="{$ip_dst}"/>
<eNB.instance value="{$enb_instance}"/>
<!--sctp.data_sid value="{$sctp_data_sid}"/-->
<!--sctp.srcport value="{$sctp_srcport}"/-->
<!--sctp.dstport value="{$sctp_dstport}"/-->
......@@ -233,6 +275,7 @@
<pos_offset value="{$sctp_pos_offset}"/>
<ip.src value="{$ip_src}"/>
<ip.dst value="{$ip_dst}"/>
<eNB.instance value="{$enb_instance}"/>
<!--sctp.data_sid value="{$sctp_data_sid}"/-->
<!--sctp.srcport value="{$sctp_srcport}"/-->
<!--sctp.dstport value="{$sctp_dstport}"/-->
......@@ -249,6 +292,7 @@
<pos_offset value="{$sctp_pos_offset}"/>
<ip.src value="{$ip_src}"/>
<ip.dst value="{$ip_dst}"/>
<eNB.instance value="{$enb_instance}"/>
<!--sctp.data_sid value="{$sctp_data_sid}"/-->
<!--sctp.srcport value="{$sctp_srcport}"/-->
<!--sctp.dstport value="{$sctp_dstport}"/-->
......
......@@ -48,6 +48,9 @@
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#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);