diff --git a/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf index bae8dcfd97..ec968e8cef 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf @@ -13,10 +13,8 @@ eNBs = 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 = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: diff --git a/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf index 673d5a7957..c2f69cb1b9 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf @@ -13,10 +13,8 @@ eNBs = 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 = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: diff --git a/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf index fd9de112dc..6bdbd4e39b 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf @@ -13,10 +13,8 @@ eNBs = 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 = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: diff --git a/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf index 3d79fd0986..1a566e9579 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf @@ -13,11 +13,8 @@ eNBs = 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 = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); tr_s_preference = "local_mac" diff --git a/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf index b4c20ba644..fd49fe9d83 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf @@ -13,11 +13,8 @@ eNBs = 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 = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); tr_s_preference = "local_mac" diff --git a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf index a6ac1f8c14..1613dd4c32 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf @@ -13,11 +13,8 @@ eNBs = 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 = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); tr_s_preference = "local_mac" diff --git a/ci-scripts/conf_files/lte-fdd-basic-sim.conf b/ci-scripts/conf_files/lte-fdd-basic-sim.conf index 0b02e8f871..0211e126a1 100644 --- a/ci-scripts/conf_files/lte-fdd-basic-sim.conf +++ b/ci-scripts/conf_files/lte-fdd-basic-sim.conf @@ -13,11 +13,8 @@ eNBs = 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 = "93"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } ); tr_s_preference = "local_mac" diff --git a/ci-scripts/conf_files/lte-tdd-basic-sim.conf b/ci-scripts/conf_files/lte-tdd-basic-sim.conf index fe9b8a3601..a7bc31eed8 100644 --- a/ci-scripts/conf_files/lte-tdd-basic-sim.conf +++ b/ci-scripts/conf_files/lte-tdd-basic-sim.conf @@ -13,10 +13,8 @@ eNBs = 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 = "93"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } ); ////////// Physical parameters: diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf index 08eb76e09d..398b763888 100644 --- a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf @@ -13,11 +13,8 @@ eNBs = 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 = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf index eff42040ad..46b6484737 100644 --- a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf @@ -13,11 +13,8 @@ eNBs = 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 = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf index 8eb66d4643..93b82773e6 100644 --- a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf @@ -13,11 +13,8 @@ eNBs = 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 = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf index dc3b3bc4f0..b412b00e52 100644 --- a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf @@ -13,11 +13,8 @@ eNBs = 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 = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf index 6af71831f5..f0d688903a 100644 --- a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf @@ -13,11 +13,8 @@ eNBs = 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 = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf index 077b6e4ead..929c91fffb 100644 --- a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf @@ -13,11 +13,8 @@ eNBs = 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 = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf index e2f5981418..98358eb269 100644 --- a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf +++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf @@ -13,11 +13,8 @@ eNBs = 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 = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf index 9e08414ab3..bc31e051e5 100644 --- a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf +++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf @@ -13,11 +13,8 @@ eNBs = 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 = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf index 2a598c31d3..2cfc227e67 100644 --- a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf +++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf @@ -13,11 +13,8 @@ eNBs = 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 = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf index 4966108d03..9b135a9498 100644 --- a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf +++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf @@ -13,11 +13,8 @@ eNBs = 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 = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf index 4f3b25349a..9f84057299 100644 --- a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf +++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf @@ -13,11 +13,8 @@ eNBs = 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 = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf index 54e5a327cd..7197e93322 100644 --- a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf +++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf @@ -13,11 +13,8 @@ eNBs = 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 = "92"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c index 57a680044b..0ec2e23790 100644 --- a/common/config/config_userapi.c +++ b/common/config/config_userapi.c @@ -29,6 +29,9 @@ * \note * \warning */ + +#define _GNU_SOURCE + #include #include #include @@ -210,6 +213,36 @@ configmodule_interface_t *cfgif = config_get_if(); return ret; } +int config_getlist(paramlist_def_t *ParamList, paramdef_t *params, int numparams, char *prefix) +{ + if (CONFIG_ISFLAGSET(CONFIG_ABORT)) { + fprintf(stderr,"[CONFIG] config_get skipped, config module not properly initialized\n"); + return -1; + } + if (!config_get_if()) + return -1; + + const int ret = config_get_if()->getlist(ParamList, params, numparams, prefix); + if (ret >= 0 && params) { + char *newprefix; + if (prefix) { + int rc = asprintf(&newprefix, "%s.%s", prefix, ParamList->listname); + if (rc < 0) newprefix = NULL; + } else { + newprefix = ParamList->listname; + } + char cfgpath[MAX_OPTNAME_SIZE*2 + 6]; /* prefix.listname.[listindex] */ + for (int i = 0; i < ParamList->numelt; ++i) { + // TODO config_process_cmdline? + sprintf(cfgpath, "%s.[%i]", newprefix, i); + config_execcheck(ParamList->paramarray[i], numparams, cfgpath); + } + if (prefix) + free(newprefix); + } + return ret; +} + int config_isparamset(paramdef_t *params,int paramidx) { if ((params[paramidx].paramflags & PARAMFLAG_PARAMSET) != 0) { diff --git a/common/config/config_userapi.h b/common/config/config_userapi.h index 25306b8778..2b40f8401b 100644 --- a/common/config/config_userapi.h +++ b/common/config/config_userapi.h @@ -57,7 +57,7 @@ extern int config_assign_ipv4addr(paramdef_t *cfgoptions, char *ipv4addr); /* apis to get parameters, to be used by oai modules, at configuration time */ extern int config_get(paramdef_t *params,int numparams, char *prefix); -#define config_getlist config_get_if()->getlist +extern int config_getlist(paramlist_def_t *ParamList, paramdef_t *params, int numparams, char *prefix); /* apis to retrieve parameters info after calling get or getlist functions */ extern int config_isparamset(paramdef_t *params,int paramidx); diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 4a0137d4b6..12a06f7c65 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -97,9 +97,10 @@ typedef struct RrcConfigurationReq_s { uint16_t tac; - uint16_t mcc; - uint16_t mnc; - uint8_t mnc_digit_length; + uint16_t mcc[PLMN_LIST_MAX_SIZE]; + uint16_t mnc[PLMN_LIST_MAX_SIZE]; + uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE]; + uint8_t num_plmn; paging_drx_t default_drx; diff --git a/openair2/COMMON/s1ap_messages_types.h b/openair2/COMMON/s1ap_messages_types.h index 4a5f492b0b..f56a340cb2 100644 --- a/openair2/COMMON/s1ap_messages_types.h +++ b/openair2/COMMON/s1ap_messages_types.h @@ -325,12 +325,14 @@ typedef struct s1ap_register_enb_req_s { /* Tracking area code */ uint16_t tac; +#define PLMN_LIST_MAX_SIZE 6 /* Mobile Country Code * Mobile Network Code */ - uint16_t mcc; - uint16_t mnc; - uint8_t mnc_digit_length; + uint16_t mcc[PLMN_LIST_MAX_SIZE]; + uint16_t mnc[PLMN_LIST_MAX_SIZE]; + uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE]; + uint8_t num_plmn; /* Default Paging DRX of the eNB as defined in TS 36.304 */ paging_drx_t default_drx; @@ -342,6 +344,8 @@ typedef struct s1ap_register_enb_req_s { uint8_t nb_mme; /* List of MME to connect to */ net_ip_address_t mme_ip_address[S1AP_MAX_NB_MME_IP_ADDRESS]; + uint8_t broadcast_plmn_num[S1AP_MAX_NB_MME_IP_ADDRESS]; + uint8_t broadcast_plmn_index[S1AP_MAX_NB_MME_IP_ADDRESS][PLMN_LIST_MAX_SIZE]; /* Number of SCTP streams used for a mme association */ uint16_t sctp_in_streams; @@ -372,6 +376,10 @@ typedef struct s1ap_nas_first_req_s { /* UE id for initial connection to S1AP */ uint16_t ue_initial_id; + /* the chosen PLMN identity as index, see TS 36.331 6.2.2 RRC Connection + * Setup Complete. This index here is zero-based, unlike the standard! */ + int selected_plmn_identity; + /* Establishment cause as sent by UE */ rrc_establishment_cause_t establishment_cause; diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 8caf72251e..3be7e2999e 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -570,31 +570,46 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { for (k=0; k cell_type = CELL_MACRO_ENB; - } else if (strcmp(cell_type, "CELL_HOME_ENB") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cell_type = CELL_HOME_ENB; - } else { - AssertFatal (0, - "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); - } + RRC_CONFIGURATION_REQ(msg_p).tac = *ENBParamList.paramarray[i][ENB_TRACKING_AREA_CODE_IDX].uptr; + AssertFatal(!ENBParamList.paramarray[i][ENB_MOBILE_COUNTRY_CODE_IDX_OLD].strptr + && !ENBParamList.paramarray[i][ENB_MOBILE_NETWORK_CODE_IDX_OLD].strptr, + "It seems that you use an old configuration file. Please change the existing\n" + " tracking_area_code = \"1\";\n" + " mobile_country_code = \"208\";\n" + " mobile_network_code = \"93\";\n" + "to\n" + " tracking_area_code = 1; // no string!!\n" + " plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } )\n"); + config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), enbpath); + + if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6) + AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n", + PLMNParamList.numelt); + + RRC_CONFIGURATION_REQ(msg_p).num_plmn = PLMNParamList.numelt; + + for (int l = 0; l < PLMNParamList.numelt; ++l) { + RRC_CONFIGURATION_REQ(msg_p).mcc[l] = *PLMNParamList.paramarray[l][ENB_MOBILE_COUNTRY_CODE_IDX].uptr; + RRC_CONFIGURATION_REQ(msg_p).mnc[l] = *PLMNParamList.paramarray[l][ENB_MOBILE_NETWORK_CODE_IDX].uptr; + RRC_CONFIGURATION_REQ(msg_p).mnc_digit_length[l] = *PLMNParamList.paramarray[l][ENB_MNC_DIGIT_LENGTH].u8ptr; + AssertFatal(RRC_CONFIGURATION_REQ(msg_p).mnc_digit_length[l] == 3 + || RRC_CONFIGURATION_REQ(msg_p).mnc[l] < 100, + "MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n", + RRC_CONFIGURATION_REQ(msg_p).mnc[l]); + } - enb_properties_loc.properties[enb_properties_loc_index]->eNB_name = strdup(enb_name); - */ - RRC_CONFIGURATION_REQ (msg_p).tac = (uint16_t)atoi( *(ENBParamList.paramarray[i][ENB_TRACKING_AREA_CODE_IDX].strptr) ); - RRC_CONFIGURATION_REQ (msg_p).mcc = (uint16_t)atoi( *(ENBParamList.paramarray[i][ENB_MOBILE_COUNTRY_CODE_IDX].strptr) ); - RRC_CONFIGURATION_REQ (msg_p).mnc = (uint16_t)atoi( *(ENBParamList.paramarray[i][ENB_MOBILE_NETWORK_CODE_IDX].strptr) ); - RRC_CONFIGURATION_REQ (msg_p).mnc_digit_length = strlen(*(ENBParamList.paramarray[i][ENB_MOBILE_NETWORK_CODE_IDX].strptr)); - AssertFatal((RRC_CONFIGURATION_REQ (msg_p).mnc_digit_length == 2) || - (RRC_CONFIGURATION_REQ (msg_p).mnc_digit_length == 3), - "BAD MNC DIGIT LENGTH %d", - RRC_CONFIGURATION_REQ (msg_p).mnc_digit_length); // Parse optional physical parameters - sprintf(enbpath,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k), - config_getlist( &CCsParamList,NULL,0,enbpath); + config_getlist( &CCsParamList,NULL,0,enbpath); LOG_I(RRC,"num component carriers %d \n",CCsParamList.numelt); if ( CCsParamList.numelt> 0) { @@ -1984,35 +1999,6 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t8; } - /* - // Network Controller - subsetting = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_NETWORK_CONTROLLER_CONFIG); - - if (subsetting != NULL) { - if ( ( - config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_INTERFACE_NAME, - (const char **)&flexran_agent_interface_name) - && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_IPV4_ADDRESS, - (const char **)&flexran_agent_ipv4_address) - && config_setting_lookup_int(subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_PORT, - &flexran_agent_port) - && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_CACHE, - (const char **)&flexran_agent_cache) - ) - ) { - enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_interface_name = strdup(flexran_agent_interface_name); - cidr = flexran_agent_ipv4_address; - address = strtok(cidr, "/"); - //enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_ipv4_address = strdup(address); - if (address) { - IPV4_STR_ADDR_TO_INT_NWBO (address, enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_ipv4_address, "BAD IP ADDRESS FORMAT FOR eNB Agent !\n" ); - } - - enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_port = flexran_agent_port; - enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_cache = strdup(flexran_agent_cache); - } - } - */ break; } } @@ -2097,11 +2083,20 @@ int RCconfig_S1(MessageDef *msg_p, uint32_t i) { // search if in active list for (j=0; j < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; j++) { if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[j], *(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)) == 0) { + paramdef_t PLMNParams[] = PLMNPARAMS_DESC; + paramlist_def_t PLMNParamList = {ENB_CONFIG_STRING_PLMN_LIST, NULL, 0}; + /* map parameter checking array instances to parameter definition array instances */ + checkedparam_t config_check_PLMNParams [] = PLMNPARAMS_CHECK; + + for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I) + PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]); + paramdef_t S1Params[] = S1PARAMS_DESC; paramlist_def_t S1ParamList = {ENB_CONFIG_STRING_MME_IP_ADDRESS,NULL,0}; paramdef_t SCTPParams[] = SCTPPARAMS_DESC; paramdef_t NETParams[] = NETPARAMS_DESC; char aprefix[MAX_OPTNAME_SIZE*2 + 8]; + sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k); S1AP_REGISTER_ENB_REQ (msg_p).eNB_id = enb_id; if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_ENB") == 0) { @@ -2115,16 +2110,35 @@ int RCconfig_S1(MessageDef *msg_p, uint32_t i) { } S1AP_REGISTER_ENB_REQ (msg_p).eNB_name = strdup(*(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)); - S1AP_REGISTER_ENB_REQ (msg_p).tac = (uint16_t)atoi(*(ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].strptr)); - S1AP_REGISTER_ENB_REQ (msg_p).mcc = (uint16_t)atoi(*(ENBParamList.paramarray[k][ENB_MOBILE_COUNTRY_CODE_IDX].strptr)); - S1AP_REGISTER_ENB_REQ (msg_p).mnc = (uint16_t)atoi(*(ENBParamList.paramarray[k][ENB_MOBILE_NETWORK_CODE_IDX].strptr)); - S1AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length = strlen(*(ENBParamList.paramarray[k][ENB_MOBILE_NETWORK_CODE_IDX].strptr)); - S1AP_REGISTER_ENB_REQ (msg_p).default_drx = 0; - AssertFatal((S1AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length == 2) || - (S1AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length == 3), - "BAD MNC DIGIT LENGTH %d", - S1AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length); - sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k); + S1AP_REGISTER_ENB_REQ(msg_p).tac = *ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].uptr; + AssertFatal(!ENBParamList.paramarray[k][ENB_MOBILE_COUNTRY_CODE_IDX_OLD].strptr + && !ENBParamList.paramarray[k][ENB_MOBILE_NETWORK_CODE_IDX_OLD].strptr, + "It seems that you use an old configuration file. Please change the existing\n" + " tracking_area_code = \"1\";\n" + " mobile_country_code = \"208\";\n" + " mobile_network_code = \"93\";\n" + "to\n" + " tracking_area_code = 1; // no string!!\n" + " plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } )\n"); + config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix); + + if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6) + AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n", + PLMNParamList.numelt); + + S1AP_REGISTER_ENB_REQ(msg_p).num_plmn = PLMNParamList.numelt; + + for (int l = 0; l < PLMNParamList.numelt; ++l) { + S1AP_REGISTER_ENB_REQ(msg_p).mcc[l] = *PLMNParamList.paramarray[l][ENB_MOBILE_COUNTRY_CODE_IDX].uptr; + S1AP_REGISTER_ENB_REQ(msg_p).mnc[l] = *PLMNParamList.paramarray[l][ENB_MOBILE_NETWORK_CODE_IDX].uptr; + S1AP_REGISTER_ENB_REQ(msg_p).mnc_digit_length[l] = *PLMNParamList.paramarray[l][ENB_MNC_DIGIT_LENGTH].u8ptr; + AssertFatal(S1AP_REGISTER_ENB_REQ(msg_p).mnc_digit_length[l] == 3 + || S1AP_REGISTER_ENB_REQ(msg_p).mnc[l] < 100, + "MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n", + S1AP_REGISTER_ENB_REQ(msg_p).mnc[l]); + } + + S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 0; config_getlist( &S1ParamList,S1Params,sizeof(S1Params)/sizeof(paramdef_t),aprefix); S1AP_REGISTER_ENB_REQ (msg_p).nb_mme = 0; @@ -2141,6 +2155,35 @@ int RCconfig_S1(MessageDef *msg_p, uint32_t i) { S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4 = 1; S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6 = 1; } + + if (S1ParamList.paramarray[l][ENB_MME_BROADCAST_PLMN_INDEX].iptr) + S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] = S1ParamList.paramarray[l][ENB_MME_BROADCAST_PLMN_INDEX].numelt; + else + S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] = 0; + + AssertFatal(S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] <= S1AP_REGISTER_ENB_REQ(msg_p).num_plmn, + "List of broadcast PLMN to be sent to MME can not be longer than actual " + "PLMN list (max %d, but is %d)\n", + S1AP_REGISTER_ENB_REQ(msg_p).num_plmn, + S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l]); + + for (int el = 0; el < S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l]; ++el) { + /* UINTARRAY gets mapped to int, see config_libconfig.c:223 */ + S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] = S1ParamList.paramarray[l][ENB_MME_BROADCAST_PLMN_INDEX].iptr[el]; + AssertFatal(S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] >= 0 + && S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] < S1AP_REGISTER_ENB_REQ(msg_p).num_plmn, + "index for MME's MCC/MNC (%d) is an invalid index for the registered PLMN IDs (%d)\n", + S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el], + S1AP_REGISTER_ENB_REQ(msg_p).num_plmn); + } + + /* if no broadcasst_plmn array is defined, fill default values */ + if (S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] == 0) { + S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] = S1AP_REGISTER_ENB_REQ(msg_p).num_plmn; + + for (int el = 0; el < S1AP_REGISTER_ENB_REQ(msg_p).num_plmn; ++el) + S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] = el; + } } // SCTP SETTING @@ -2300,6 +2343,14 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) { // search if in active list for (j = 0; j < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; j++) { if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[j], *(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)) == 0) { + paramdef_t PLMNParams[] = PLMNPARAMS_DESC; + paramlist_def_t PLMNParamList = {ENB_CONFIG_STRING_PLMN_LIST, NULL, 0}; + /* map parameter checking array instances to parameter definition array instances */ + checkedparam_t config_check_PLMNParams [] = PLMNPARAMS_CHECK; + + for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I) + PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]); + paramdef_t X2Params[] = X2PARAMS_DESC; paramlist_def_t X2ParamList = {ENB_CONFIG_STRING_TARGET_ENB_X2_IP_ADDRESS,NULL,0}; paramdef_t SCTPParams[] = SCTPPARAMS_DESC; @@ -2307,6 +2358,7 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) { /* TODO: fix the size - if set lower we have a crash (MAX_OPTNAME_SIZE was 64 when this code was written) */ /* this is most probably a problem with the config module */ char aprefix[MAX_OPTNAME_SIZE*80 + 8]; + sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k); /* Some default/random parameters */ X2AP_REGISTER_ENB_REQ (msg_p).eNB_id = enb_id; @@ -2321,17 +2373,31 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) { } X2AP_REGISTER_ENB_REQ (msg_p).eNB_name = strdup(*(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)); - X2AP_REGISTER_ENB_REQ (msg_p).tac = (uint16_t)atoi(*(ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].strptr)); - X2AP_REGISTER_ENB_REQ (msg_p).mcc = (uint16_t)atoi(*(ENBParamList.paramarray[k][ENB_MOBILE_COUNTRY_CODE_IDX].strptr)); - X2AP_REGISTER_ENB_REQ (msg_p).mnc = (uint16_t)atoi(*(ENBParamList.paramarray[k][ENB_MOBILE_NETWORK_CODE_IDX].strptr)); - X2AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length = strlen(*(ENBParamList.paramarray[k][ENB_MOBILE_NETWORK_CODE_IDX].strptr)); - AssertFatal((X2AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length == 2) || - (X2AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length == 3), - "BAD MNC DIGIT LENGTH %d", - X2AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length); + X2AP_REGISTER_ENB_REQ (msg_p).tac = *ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].uptr; + config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix); + + if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6) + AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n", + PLMNParamList.numelt); + + if (PLMNParamList.numelt > 1) + LOG_W(X2AP, "X2AP currently handles only one PLMN, ignoring the others!\n"); + + X2AP_REGISTER_ENB_REQ (msg_p).mcc = *PLMNParamList.paramarray[0][ENB_MOBILE_COUNTRY_CODE_IDX].uptr; + X2AP_REGISTER_ENB_REQ (msg_p).mnc = *PLMNParamList.paramarray[0][ENB_MOBILE_NETWORK_CODE_IDX].uptr; + X2AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length = *PLMNParamList.paramarray[0][ENB_MNC_DIGIT_LENGTH].u8ptr; + AssertFatal(X2AP_REGISTER_ENB_REQ(msg_p).mnc_digit_length == 3 + || X2AP_REGISTER_ENB_REQ(msg_p).mnc < 100, + "MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n", + X2AP_REGISTER_ENB_REQ(msg_p).mnc); + config_getlist( &X2ParamList,X2Params,sizeof(X2Params)/sizeof(paramdef_t),aprefix); + AssertFatal(X2ParamList.numelt <= X2AP_MAX_NB_ENB_IP_ADDRESS, + "value of X2ParamList.numelt %d must be lower than X2AP_MAX_NB_ENB_IP_ADDRESS %d value: reconsider to increase X2AP_MAX_NB_ENB_IP_ADDRESS\n", + X2ParamList.numelt,X2AP_MAX_NB_ENB_IP_ADDRESS); + /* CC params */ - sprintf(aprefix, "%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, k); config_getlist(&CCsParamList, NULL, 0, aprefix); + X2AP_REGISTER_ENB_REQ (msg_p).num_cc = CCsParamList.numelt; if (CCsParamList.numelt > 0) { @@ -2376,11 +2442,6 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) { sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k); config_getlist( &X2ParamList,X2Params,sizeof(X2Params)/sizeof(paramdef_t),aprefix); - if(X2ParamList.numelt>X2AP_MAX_NB_ENB_IP_ADDRESS) { - LOG_E(RRC,"value of X2ParamList.numelt %d must be lower than X2AP_MAX_NB_ENB_IP_ADDRESS %d value: reconsider to increase X2AP_MAX_NB_ENB_IP_ADDRESS\n",X2ParamList.numelt,X2AP_MAX_NB_ENB_IP_ADDRESS); - exit(1); - } - X2AP_REGISTER_ENB_REQ (msg_p).nb_x2 = 0; for (l = 0; l < X2ParamList.numelt; l++) { diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index fa622ce5d7..524daac43d 100755 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -185,8 +185,8 @@ typedef enum { #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_MOBILE_COUNTRY_CODE_OLD "mobile_country_code" +#define ENB_CONFIG_STRING_MOBILE_NETWORK_CODE_OLD "mobile_network_code" #define ENB_CONFIG_STRING_TRANSPORT_S_PREFERENCE "tr_s_preference" #define ENB_CONFIG_STRING_LOCAL_S_IF_NAME "local_s_if_name" #define ENB_CONFIG_STRING_LOCAL_S_ADDRESS "local_s_address" @@ -204,9 +204,9 @@ typedef enum { {ENB_CONFIG_STRING_ENB_ID, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ {ENB_CONFIG_STRING_CELL_TYPE, NULL, 0, strptr:NULL, defstrval:"CELL_MACRO_ENB", TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_ENB_NAME, NULL, 0, strptr:NULL, defstrval:"OAIeNodeB", TYPE_STRING, 0}, \ -{ENB_CONFIG_STRING_TRACKING_AREA_CODE, NULL, 0, strptr:NULL, defstrval:"0", TYPE_STRING, 0}, \ -{ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE, NULL, 0, strptr:NULL, defstrval:"0", TYPE_STRING, 0}, \ -{ENB_CONFIG_STRING_MOBILE_NETWORK_CODE, NULL, 0, strptr:NULL, defstrval:"0", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_TRACKING_AREA_CODE, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE_OLD, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_MOBILE_NETWORK_CODE_OLD, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_TRANSPORT_S_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"local_mac", TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_LOCAL_S_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_LOCAL_S_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ @@ -220,8 +220,8 @@ typedef enum { #define ENB_CELL_TYPE_IDX 1 #define ENB_ENB_NAME_IDX 2 #define ENB_TRACKING_AREA_CODE_IDX 3 -#define ENB_MOBILE_COUNTRY_CODE_IDX 4 -#define ENB_MOBILE_NETWORK_CODE_IDX 5 +#define ENB_MOBILE_COUNTRY_CODE_IDX_OLD 4 +#define ENB_MOBILE_NETWORK_CODE_IDX_OLD 5 #define ENB_TRANSPORT_S_PREFERENCE_IDX 6 #define ENB_LOCAL_S_IF_NAME_IDX 7 #define ENB_LOCAL_S_ADDRESS_IDX 8 @@ -230,9 +230,56 @@ typedef enum { #define ENB_REMOTE_S_PORTC_IDX 11 #define ENB_LOCAL_S_PORTD_IDX 12 #define ENB_REMOTE_S_PORTD_IDX 13 + +#define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD} +#define ENBPARAMS_CHECK { \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s2 = { config_check_intrange, TRACKING_AREA_CODE_OKRANGE } },\ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ +} + /*-------------------------------------------------------------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* PLMN ID configuration */ + +#define ENB_CONFIG_STRING_PLMN_LIST "plmn_list" + +#define ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE "mcc" +#define ENB_CONFIG_STRING_MOBILE_NETWORK_CODE "mnc" +#define ENB_CONFIG_STRING_MNC_DIGIT_LENGTH "mnc_length" + +#define ENB_MOBILE_COUNTRY_CODE_IDX 0 +#define ENB_MOBILE_NETWORK_CODE_IDX 1 +#define ENB_MNC_DIGIT_LENGTH 2 + +#define PLMNPARAMS_DESC { \ +/* optname helpstr paramflags XXXptr def val type numelt */ \ + {ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE, "mobile country code", 0, uptr:NULL, defuintval:1000, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_MOBILE_NETWORK_CODE, "mobile network code", 0, uptr:NULL, defuintval:1000, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_MNC_DIGIT_LENGTH, "length of the MNC (2 or 3)", 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ +} + +#define MCC_MNC_OKRANGES {0,999} +#define MNC_DIGIT_LENGTH_OKVALUES {2,3} + +#define PLMNPARAMS_CHECK { \ + { .s2 = { config_check_intrange, MCC_MNC_OKRANGES } }, \ + { .s2 = { config_check_intrange, MCC_MNC_OKRANGES } }, \ + { .s1 = { config_check_intval, MNC_DIGIT_LENGTH_OKVALUES, 2 } }, \ +} + /* component carries configuration parameters name */ @@ -681,6 +728,7 @@ typedef enum { #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_MME_BROADCAST_PLMN_INDEX "broadcast_plmn_index" /*-------------------------------------------------------------------------------------------------------------------------------------*/ @@ -692,12 +740,14 @@ typedef enum { {ENB_CONFIG_STRING_MME_IPV6_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_MME_BROADCAST_PLMN_INDEX, NULL, 0, uptr:NULL, defintarrayval:NULL,TYPE_UINTARRAY, 6} \ } #define ENB_MME_IPV4_ADDRESS_IDX 0 #define ENB_MME_IPV6_ADDRESS_IDX 1 #define ENB_MME_IP_ADDRESS_ACTIVE_IDX 2 #define ENB_MME_IP_ADDRESS_PREFERENCE_IDX 3 +#define ENB_MME_BROADCAST_PLMN_INDEX 4 /*---------------------------------------------------------------------------------------------------------------------------------------*/ /* X2 configuration parameters section name */ diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 5e07d9e936..9ab2351b44 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -345,8 +345,13 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, { // SystemInformation_t systemInformation; - PLMN_IdentityInfo_t PLMN_identity_info; - MCC_MNC_Digit_t dummy_mcc[3],dummy_mnc[3]; +#if defined(ENABLE_ITTI) + int num_plmn = configuration->num_plmn; +#else + int num_plmn = 1; +#endif + PLMN_IdentityInfo_t PLMN_identity_info[num_plmn]; + MCC_MNC_Digit_t dummy_mcc[num_plmn][3], dummy_mnc[num_plmn][3]; asn_enc_rval_t enc_rval; SchedulingInfo_t schedulingInfo; SIB_Type_t sib_type; @@ -354,6 +359,7 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, uint8_t *buffer = carrier->SIB1; BCCH_DL_SCH_Message_t *bcch_message = &carrier->siblock1; SystemInformationBlockType1_t **sib1 = &carrier->sib1; + int i; memset(bcch_message,0,sizeof(BCCH_DL_SCH_Message_t)); @@ -363,67 +369,68 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, *sib1 = &bcch_message->message.choice.c1.choice.systemInformationBlockType1; - memset(&PLMN_identity_info,0,sizeof(PLMN_IdentityInfo_t)); + memset(PLMN_identity_info,0,num_plmn * sizeof(PLMN_IdentityInfo_t)); memset(&schedulingInfo,0,sizeof(SchedulingInfo_t)); memset(&sib_type,0,sizeof(SIB_Type_t)); + /* as per TS 36.311, up to 6 PLMN_identity_info are allowed in list -> add one by one */ + for (i = 0; i < configuration->num_plmn; ++i) { + PLMN_identity_info[i].plmn_Identity.mcc = CALLOC(1,sizeof(*PLMN_identity_info[i].plmn_Identity.mcc)); + memset(PLMN_identity_info[i].plmn_Identity.mcc,0,sizeof(*PLMN_identity_info[i].plmn_Identity.mcc)); - - PLMN_identity_info.plmn_Identity.mcc = CALLOC(1,sizeof(*PLMN_identity_info.plmn_Identity.mcc)); - memset(PLMN_identity_info.plmn_Identity.mcc,0,sizeof(*PLMN_identity_info.plmn_Identity.mcc)); - - asn_set_empty(&PLMN_identity_info.plmn_Identity.mcc->list);//.size=0; + asn_set_empty(&PLMN_identity_info[i].plmn_Identity.mcc->list);//.size=0; #if defined(ENABLE_ITTI) - dummy_mcc[0] = (configuration->mcc / 100) % 10; - dummy_mcc[1] = (configuration->mcc / 10) % 10; - dummy_mcc[2] = (configuration->mcc / 1) % 10; + dummy_mcc[i][0] = (configuration->mcc[i] / 100) % 10; + dummy_mcc[i][1] = (configuration->mcc[i] / 10) % 10; + dummy_mcc[i][2] = (configuration->mcc[i] / 1) % 10; #else - dummy_mcc[0] = 0; - dummy_mcc[1] = 0; - dummy_mcc[2] = 1; + dummy_mcc[i][0] = 0; + dummy_mcc[i][1] = 0; + dummy_mcc[i][2] = 1; #endif - ASN_SEQUENCE_ADD(&PLMN_identity_info.plmn_Identity.mcc->list,&dummy_mcc[0]); - ASN_SEQUENCE_ADD(&PLMN_identity_info.plmn_Identity.mcc->list,&dummy_mcc[1]); - ASN_SEQUENCE_ADD(&PLMN_identity_info.plmn_Identity.mcc->list,&dummy_mcc[2]); + ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mcc->list,&dummy_mcc[i][0]); + ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mcc->list,&dummy_mcc[i][1]); + ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mcc->list,&dummy_mcc[i][2]); - PLMN_identity_info.plmn_Identity.mnc.list.size=0; - PLMN_identity_info.plmn_Identity.mnc.list.count=0; + PLMN_identity_info[i].plmn_Identity.mnc.list.size=0; + PLMN_identity_info[i].plmn_Identity.mnc.list.count=0; #if defined(ENABLE_ITTI) - if (configuration->mnc >= 100) { - dummy_mnc[0] = (configuration->mnc / 100) % 10; - dummy_mnc[1] = (configuration->mnc / 10) % 10; - dummy_mnc[2] = (configuration->mnc / 1) % 10; - } else { - if (configuration->mnc_digit_length == 2) { - dummy_mnc[0] = (configuration->mnc / 10) % 10; - dummy_mnc[1] = (configuration->mnc / 1) % 10; - dummy_mnc[2] = 0xf; + if (configuration->mnc[i] >= 100) { + dummy_mnc[i][0] = (configuration->mnc[i] / 100) % 10; + dummy_mnc[i][1] = (configuration->mnc[i] / 10) % 10; + dummy_mnc[i][2] = (configuration->mnc[i] / 1) % 10; } else { - dummy_mnc[0] = (configuration->mnc / 100) % 100; - dummy_mnc[1] = (configuration->mnc / 10) % 10; - dummy_mnc[2] = (configuration->mnc / 1) % 10; + if (configuration->mnc_digit_length[i] == 2) { + dummy_mnc[i][0] = (configuration->mnc[i] / 10) % 10; + dummy_mnc[i][1] = (configuration->mnc[i] / 1) % 10; + dummy_mnc[i][2] = 0xf; + } else { + dummy_mnc[i][0] = (configuration->mnc[i] / 100) % 100; + dummy_mnc[i][1] = (configuration->mnc[i] / 10) % 10; + dummy_mnc[i][2] = (configuration->mnc[i] / 1) % 10; + } } - } #else - dummy_mnc[0] = 0; - dummy_mnc[1] = 1; - dummy_mnc[2] = 0xf; + dummy_mnc[i][0] = 0; + dummy_mnc[i][1] = 1; + dummy_mnc[i][2] = 0xf; #endif - ASN_SEQUENCE_ADD(&PLMN_identity_info.plmn_Identity.mnc.list,&dummy_mnc[0]); - ASN_SEQUENCE_ADD(&PLMN_identity_info.plmn_Identity.mnc.list,&dummy_mnc[1]); + ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mnc.list,&dummy_mnc[i][0]); + ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mnc.list,&dummy_mnc[i][1]); - if (dummy_mnc[2] != 0xf) { - ASN_SEQUENCE_ADD(&PLMN_identity_info.plmn_Identity.mnc.list,&dummy_mnc[2]); + if (dummy_mnc[i][2] != 0xf) { + ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mnc.list,&dummy_mnc[i][2]); + } + + //assign_enum(&PLMN_identity_info.cellReservedForOperatorUse,PLMN_IdentityInfo__cellReservedForOperatorUse_notReserved); + PLMN_identity_info[i].cellReservedForOperatorUse=PLMN_IdentityInfo__cellReservedForOperatorUse_notReserved; + + ASN_SEQUENCE_ADD(&(*sib1)->cellAccessRelatedInfo.plmn_IdentityList.list,&PLMN_identity_info[i]); } - //assign_enum(&PLMN_identity_info.cellReservedForOperatorUse,PLMN_IdentityInfo__cellReservedForOperatorUse_notReserved); - PLMN_identity_info.cellReservedForOperatorUse=PLMN_IdentityInfo__cellReservedForOperatorUse_notReserved; - - ASN_SEQUENCE_ADD(&(*sib1)->cellAccessRelatedInfo.plmn_IdentityList.list,&PLMN_identity_info); - // 16 bits (*sib1)->cellAccessRelatedInfo.trackingAreaCode.buf = MALLOC(2); diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index e21cb9255a..ae87075489 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -699,13 +699,6 @@ typedef struct eNB_RRC_INST_s { #if defined(ENABLE_ITTI) RrcConfigurationReq configuration; #endif - // other PLMN parameters - /// Mobile country code - int mcc; - /// Mobile network code - int mnc; - /// number of mnc digits - int mnc_digit_length; // other RAN parameters int srb1_timer_poll_retransmit; diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 7d24228602..d225b6eae0 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -755,17 +755,20 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ( ue_context_pP->ue_context.rnti); } + /* selected_plmn_identity: IE is 1-based, convert to 0-based (C array) */ + int selected_plmn_identity = rrcConnectionSetupComplete->selectedPLMN_Identity - 1; + S1AP_NAS_FIRST_REQ(message_p).selected_plmn_identity = selected_plmn_identity; + if (rrcConnectionSetupComplete->registeredMME != NULL) { /* Fill GUMMEI */ struct RegisteredMME *r_mme = rrcConnectionSetupComplete->registeredMME; - //int selected_plmn_identity = rrcConnectionSetupComplete->selectedPLMN_Identity; S1AP_NAS_FIRST_REQ (message_p).ue_identity.presenceMask |= UE_IDENTITIES_gummei; if (r_mme->plmn_Identity != NULL) { if ((r_mme->plmn_Identity->mcc != NULL) && (r_mme->plmn_Identity->mcc->list.count > 0)) { /* Use first indicated PLMN MCC if it is defined */ - S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = *r_mme->plmn_Identity->mcc->list.array[0]; + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = *r_mme->plmn_Identity->mcc->list.array[selected_plmn_identity]; LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MCC %u ue %x\n", ctxt_pP->module_id, S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc, @@ -774,20 +777,16 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ( if (r_mme->plmn_Identity->mnc.list.count > 0) { /* Use first indicated PLMN MNC if it is defined */ - S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = *r_mme->plmn_Identity->mnc.list.array[0]; + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = *r_mme->plmn_Identity->mnc.list.array[selected_plmn_identity]; LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u ue %x\n", ctxt_pP->module_id, S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc, ue_context_pP->ue_context.rnti); } } else { - // const Enb_properties_array_t *enb_properties_p = NULL; - // enb_properties_p = enb_config_get(); - - // actually the eNB configuration contains only one PLMN (can be up to 6) - S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = rrc->mcc; - S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = rrc->mnc; - S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len = rrc->mnc_digit_length; + S1AP_NAS_FIRST_REQ(message_p).ue_identity.gummei.mcc = rrc->configuration.mcc[selected_plmn_identity]; + S1AP_NAS_FIRST_REQ(message_p).ue_identity.gummei.mnc = rrc->configuration.mnc[selected_plmn_identity]; + S1AP_NAS_FIRST_REQ(message_p).ue_identity.gummei.mnc_len = rrc->configuration.mnc_digit_length[selected_plmn_identity]; } S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_code = BIT_STRING_to_uint8 (&r_mme->mmec); @@ -1850,125 +1849,127 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance for (uint16_t tai_size = 0; tai_size < S1AP_PAGING_IND(msg_p).tai_size; tai_size++) { LOG_D(RRC,"[eNB %d] In S1AP_PAGING_IND: MCC %d, MNC %d, TAC %d\n", instance, S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc, S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc, S1AP_PAGING_IND(msg_p).tac[tai_size]); - if (RC.rrc[instance]->configuration.mcc == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc - && RC.rrc[instance]->configuration.mnc == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc - && RC.rrc[instance]->configuration.tac == S1AP_PAGING_IND(msg_p).tac[tai_size]) { - for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - lte_frame_type_t frame_type = RC.eNB[instance][CC_id]->frame_parms.frame_type; - /* get nB from configuration */ - /* get default DRX cycle from configuration */ - Tc = (uint8_t)RC.rrc[instance]->configuration.pcch_defaultPagingCycle[CC_id]; - if (Tc < PCCH_Config__defaultPagingCycle_rf32 || Tc > PCCH_Config__defaultPagingCycle_rf256) { - continue; - } - Tue = (uint8_t)S1AP_PAGING_IND(msg_p).paging_drx; - /* set T = min(Tc,Tue) */ - T = Tc < Tue ? Ttab[Tc] : Ttab[Tue]; - /* set pcch_nB = PCCH-Config->nB */ - pcch_nB = (uint32_t)RC.rrc[instance]->configuration.pcch_nB[CC_id]; - switch (pcch_nB) { - case PCCH_Config__nB_fourT: - Ns = 4; - break; - case PCCH_Config__nB_twoT: - Ns = 2; - break; - default: - Ns = 1; - break; - } - /* set N = min(T,nB) */ - if (pcch_nB > PCCH_Config__nB_oneT) { - switch (pcch_nB) { - case PCCH_Config__nB_halfT: - N = T/2; - break; - case PCCH_Config__nB_quarterT: - N = T/4; - break; - case PCCH_Config__nB_oneEighthT: - N = T/8; - break; - case PCCH_Config__nB_oneSixteenthT: - N = T/16; - break; - case PCCH_Config__nB_oneThirtySecondT: - N = T/32; - break; - default: - /* pcch_nB error */ - LOG_E(RRC, "[eNB %d] In S1AP_PAGING_IND: pcch_nB error (pcch_nB %d) \n", - instance, pcch_nB); - return (-1); - } - } else { - N = T; - } - - /* insert data to UE_PF_PO or update data in UE_PF_PO */ - pthread_mutex_lock(&ue_pf_po_mutex); - uint16_t i = 0; - for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { - if ((UE_PF_PO[CC_id][i].enable_flag == TRUE && UE_PF_PO[CC_id][i].ue_index_value == (uint16_t)(S1AP_PAGING_IND(msg_p).ue_index_value)) - || (UE_PF_PO[CC_id][i].enable_flag != TRUE)) { - /* set T = min(Tc,Tue) */ - UE_PF_PO[CC_id][i].T = T; - /* set UE_ID */ - UE_PF_PO[CC_id][i].ue_index_value = (uint16_t)S1AP_PAGING_IND(msg_p).ue_index_value; - /* calculate PF and PO */ - /* set PF_min : SFN mod T = (T div N)*(UE_ID mod N) */ - UE_PF_PO[CC_id][i].PF_min = (T / N) * (UE_PF_PO[CC_id][i].ue_index_value % N); - /* set PO */ - /* i_s = floor(UE_ID/N) mod Ns */ - i_s = (uint8_t)((UE_PF_PO[CC_id][i].ue_index_value / N) % Ns); - if (Ns == 1) { - UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? 9 : 0; - } else if (Ns==2) { - UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4+(5*i_s)) : (5*i_s); - } else if (Ns==4) { - UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4*(i_s&1)+(5*(i_s>>1))) : ((i_s&1)+(5*(i_s>>1))); + for (uint8_t j = 0; j < RC.rrc[instance]->configuration.num_plmn; j++) { + if (RC.rrc[instance]->configuration.mcc[j] == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc + && RC.rrc[instance]->configuration.mnc[j] == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc + && RC.rrc[instance]->configuration.tac == S1AP_PAGING_IND(msg_p).tac[tai_size]) { + for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + lte_frame_type_t frame_type = RC.eNB[instance][CC_id]->frame_parms.frame_type; + /* get nB from configuration */ + /* get default DRX cycle from configuration */ + Tc = (uint8_t)RC.rrc[instance]->configuration.pcch_defaultPagingCycle[CC_id]; + if (Tc < PCCH_Config__defaultPagingCycle_rf32 || Tc > PCCH_Config__defaultPagingCycle_rf256) { + continue; + } + Tue = (uint8_t)S1AP_PAGING_IND(msg_p).paging_drx; + /* set T = min(Tc,Tue) */ + T = Tc < Tue ? Ttab[Tc] : Ttab[Tue]; + /* set pcch_nB = PCCH-Config->nB */ + pcch_nB = (uint32_t)RC.rrc[instance]->configuration.pcch_nB[CC_id]; + switch (pcch_nB) { + case PCCH_Config__nB_fourT: + Ns = 4; + break; + case PCCH_Config__nB_twoT: + Ns = 2; + break; + default: + Ns = 1; + break; + } + /* set N = min(T,nB) */ + if (pcch_nB > PCCH_Config__nB_oneT) { + switch (pcch_nB) { + case PCCH_Config__nB_halfT: + N = T/2; + break; + case PCCH_Config__nB_quarterT: + N = T/4; + break; + case PCCH_Config__nB_oneEighthT: + N = T/8; + break; + case PCCH_Config__nB_oneSixteenthT: + N = T/16; + break; + case PCCH_Config__nB_oneThirtySecondT: + N = T/32; + break; + default: + /* pcch_nB error */ + LOG_E(RRC, "[eNB %d] In S1AP_PAGING_IND: pcch_nB error (pcch_nB %d) \n", + instance, pcch_nB); + return (-1); } - if (UE_PF_PO[CC_id][i].enable_flag == TRUE) { - //paging exist UE log - LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Update exist UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO); - } else { - /* set enable_flag */ - UE_PF_PO[CC_id][i].enable_flag = TRUE; - //paging new UE log - LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Insert a new UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO); - } - break; - } - } - pthread_mutex_unlock(&ue_pf_po_mutex); + } else { + N = T; + } - uint32_t length; - uint8_t buffer[RRC_BUF_SIZE]; - uint8_t *message_buffer; - /* Transfer data to PDCP */ - MessageDef *message_p; - message_p = itti_alloc_new_message (TASK_RRC_ENB, RRC_PCCH_DATA_REQ); - /* Create message for PDCP (DLInformationTransfer_t) */ - length = do_Paging (instance, - buffer, - S1AP_PAGING_IND(msg_p).ue_paging_identity, - S1AP_PAGING_IND(msg_p).cn_domain); - if(length == -1) - { - LOG_I(RRC, "do_Paging error"); - return -1; + /* insert data to UE_PF_PO or update data in UE_PF_PO */ + pthread_mutex_lock(&ue_pf_po_mutex); + uint8_t i = 0; + for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { + if ((UE_PF_PO[CC_id][i].enable_flag == TRUE && UE_PF_PO[CC_id][i].ue_index_value == (uint16_t)(S1AP_PAGING_IND(msg_p).ue_index_value)) + || (UE_PF_PO[CC_id][i].enable_flag != TRUE)) { + /* set T = min(Tc,Tue) */ + UE_PF_PO[CC_id][i].T = T; + /* set UE_ID */ + UE_PF_PO[CC_id][i].ue_index_value = (uint16_t)S1AP_PAGING_IND(msg_p).ue_index_value; + /* calculate PF and PO */ + /* set PF_min : SFN mod T = (T div N)*(UE_ID mod N) */ + UE_PF_PO[CC_id][i].PF_min = (T / N) * (UE_PF_PO[CC_id][i].ue_index_value % N); + /* set PO */ + /* i_s = floor(UE_ID/N) mod Ns */ + i_s = (uint8_t)((UE_PF_PO[CC_id][i].ue_index_value / N) % Ns); + if (Ns == 1) { + UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? 9 : 0; + } else if (Ns==2) { + UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4+(5*i_s)) : (5*i_s); + } else if (Ns==4) { + UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4*(i_s&1)+(5*(i_s>>1))) : ((i_s&1)+(5*(i_s>>1))); + } + if (UE_PF_PO[CC_id][i].enable_flag == TRUE) { + //paging exist UE log + LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Update exist UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO); + } else { + /* set enable_flag */ + UE_PF_PO[CC_id][i].enable_flag = TRUE; + //paging new UE log + LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Insert a new UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO); + } + break; + } + } + pthread_mutex_unlock(&ue_pf_po_mutex); + + uint32_t length; + uint8_t buffer[RRC_BUF_SIZE]; + uint8_t *message_buffer; + /* Transfer data to PDCP */ + MessageDef *message_p; + message_p = itti_alloc_new_message (TASK_RRC_ENB, RRC_PCCH_DATA_REQ); + /* Create message for PDCP (DLInformationTransfer_t) */ + length = do_Paging (instance, + buffer, + S1AP_PAGING_IND(msg_p).ue_paging_identity, + S1AP_PAGING_IND(msg_p).cn_domain); + if(length == -1) + { + LOG_I(RRC, "do_Paging error"); + return -1; + } + message_buffer = itti_malloc (TASK_RRC_ENB, TASK_PDCP_ENB, length); + /* Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). */ + memcpy (message_buffer, buffer, length); + RRC_PCCH_DATA_REQ (message_p).sdu_size = length; + RRC_PCCH_DATA_REQ (message_p).sdu_p = message_buffer; + RRC_PCCH_DATA_REQ (message_p).mode = PDCP_TRANSMISSION_MODE_TRANSPARENT; /* not used */ + RRC_PCCH_DATA_REQ (message_p).rnti = P_RNTI; + RRC_PCCH_DATA_REQ (message_p).ue_index = i; + RRC_PCCH_DATA_REQ (message_p).CC_id = CC_id; + LOG_D(RRC, "[eNB %d] CC_id %d In S1AP_PAGING_IND: send encdoed buffer to PDCP buffer_size %d\n", instance, CC_id, length); + itti_send_msg_to_task (TASK_PDCP_ENB, instance, message_p); } - message_buffer = itti_malloc (TASK_RRC_ENB, TASK_PDCP_ENB, length); - /* Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). */ - memcpy (message_buffer, buffer, length); - RRC_PCCH_DATA_REQ (message_p).sdu_size = length; - RRC_PCCH_DATA_REQ (message_p).sdu_p = message_buffer; - RRC_PCCH_DATA_REQ (message_p).mode = PDCP_TRANSMISSION_MODE_TRANSPARENT; /* not used */ - RRC_PCCH_DATA_REQ (message_p).rnti = P_RNTI; - RRC_PCCH_DATA_REQ (message_p).ue_index = i; - RRC_PCCH_DATA_REQ (message_p).CC_id = CC_id; - LOG_D(RRC, "[eNB %d] CC_id %d In S1AP_PAGING_IND: send encdoed buffer to PDCP buffer_size %d\n", instance, CC_id, length); - itti_send_msg_to_task (TASK_PDCP_ENB, instance, message_p); } } } diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index a617963686..3edc5be0d5 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -97,7 +97,9 @@ static void 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) + uint16_t out_streams, + uint8_t broadcast_plmn_num, + uint8_t broadcast_plmn_index[PLMN_LIST_MAX_SIZE]) { MessageDef *message_p = NULL; sctp_new_association_req_t *sctp_new_association_req_p = NULL; @@ -126,8 +128,8 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, sizeof(*local_ip_addr)); S1AP_INFO("[eNB %d] check the mme registration state\n",instance_p->instance); - - mme = s1ap_eNB_get_MME_from_instance(instance_p); + + mme = NULL; if ( mme == NULL ) { @@ -139,6 +141,9 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, 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->broadcast_plmn_num = broadcast_plmn_num; + for (int i = 0; i < broadcast_plmn_num; ++i) + s1ap_mme_data_p->broadcast_plmn_index[i] = broadcast_plmn_index[i]; s1ap_mme_data_p->s1ap_eNB_instance = instance_p; STAILQ_INIT(&s1ap_mme_data_p->served_gummei); @@ -190,10 +195,14 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * /* 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->num_plmn == s1ap_register_eNB->num_plmn, new_instance->num_plmn, s1ap_register_eNB->num_plmn, 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); + for (int i = 0; i < new_instance->num_plmn; i++) + { + DevCheck(new_instance->mcc[i] == s1ap_register_eNB->mcc[i], new_instance->mcc[i], s1ap_register_eNB->mcc[i], 0); + DevCheck(new_instance->mnc[i] == s1ap_register_eNB->mnc[i], new_instance->mnc[i], s1ap_register_eNB->mnc[i], 0); + DevCheck(new_instance->mnc_digit_length[i] == s1ap_register_eNB->mnc_digit_length[i], new_instance->mnc_digit_length[i], s1ap_register_eNB->mnc_digit_length[i], 0); + } DevCheck(new_instance->default_drx == s1ap_register_eNB->default_drx, new_instance->default_drx, s1ap_register_eNB->default_drx, 0); } else { new_instance = calloc(1, sizeof(s1ap_eNB_instance_t)); @@ -208,9 +217,13 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * 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; + for (int i = 0; i < s1ap_register_eNB->num_plmn; i++) + { + new_instance->mcc[i] = s1ap_register_eNB->mcc[i]; + new_instance->mnc[i] = s1ap_register_eNB->mnc[i]; + new_instance->mnc_digit_length[i] = s1ap_register_eNB->mnc_digit_length[i]; + } + new_instance->num_plmn = s1ap_register_eNB->num_plmn; new_instance->default_drx = s1ap_register_eNB->default_drx; /* Add the new instance to the list of eNB (meaningfull in virtual mode) */ @@ -231,7 +244,9 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * &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); + s1ap_register_eNB->sctp_out_streams, + s1ap_register_eNB->broadcast_plmn_num[index], + s1ap_register_eNB->broadcast_plmn_index[index]); } } @@ -459,7 +474,9 @@ static int s1ap_eNB_generate_s1_setup_request( ie->id = S1AP_ProtocolIE_ID_id_Global_ENB_ID; ie->criticality = S1AP_Criticality_reject; ie->value.present = S1AP_S1SetupRequestIEs__value_PR_Global_ENB_ID; - MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + MCC_MNC_TO_PLMNID(instance_p->mcc[s1ap_mme_data_p->broadcast_plmn_index[0]], + instance_p->mnc[s1ap_mme_data_p->broadcast_plmn_index[0]], + instance_p->mnc_digit_length[s1ap_mme_data_p->broadcast_plmn_index[0]], &ie->value.choice.Global_ENB_ID.pLMNidentity); ie->value.choice.Global_ENB_ID.eNB_ID.present = S1AP_ENB_ID_PR_macroENB_ID; MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id, @@ -490,9 +507,14 @@ static int s1ap_eNB_generate_s1_setup_request( ta = (S1AP_SupportedTAs_Item_t *)calloc(1, sizeof(S1AP_SupportedTAs_Item_t)); INT16_TO_OCTET_STRING(instance_p->tac, &ta->tAC); { - plmn = (S1AP_PLMNidentity_t *)calloc(1, sizeof(S1AP_PLMNidentity_t)); - MCC_MNC_TO_TBCD(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn); - ASN_SEQUENCE_ADD(&ta->broadcastPLMNs.list, plmn); + for (int i = 0; i < s1ap_mme_data_p->broadcast_plmn_num; ++i) { + plmn = (S1AP_PLMNidentity_t *)calloc(1, sizeof(S1AP_PLMNidentity_t)); + MCC_MNC_TO_TBCD(instance_p->mcc[s1ap_mme_data_p->broadcast_plmn_index[i]], + instance_p->mnc[s1ap_mme_data_p->broadcast_plmn_index[i]], + instance_p->mnc_digit_length[s1ap_mme_data_p->broadcast_plmn_index[i]], + plmn); + ASN_SEQUENCE_ADD(&ta->broadcastPLMNs.list, plmn); + } } ASN_SEQUENCE_ADD(&ie->value.choice.SupportedTAs.list, ta); } diff --git a/openair3/S1AP/s1ap_eNB_defs.h b/openair3/S1AP/s1ap_eNB_defs.h index 11e64703ec..5bffa0df0c 100644 --- a/openair3/S1AP/s1ap_eNB_defs.h +++ b/openair3/S1AP/s1ap_eNB_defs.h @@ -154,6 +154,11 @@ typedef struct s1ap_eNB_mme_data_s { /* SCTP association id */ int32_t assoc_id; + /* This is served PLMN IDs communicated to the MME via an index over the + * MCC/MNC array in s1ap_eNB_instance */ + uint8_t broadcast_plmn_num; + uint8_t broadcast_plmn_index[PLMN_LIST_MAX_SIZE]; + /* Only meaningfull in virtual mode */ struct s1ap_eNB_instance_s *s1ap_eNB_instance; } s1ap_eNB_mme_data_t; @@ -198,9 +203,10 @@ typedef struct s1ap_eNB_instance_s { /* Mobile Country Code * Mobile Network Code */ - uint16_t mcc; - uint16_t mnc; - uint8_t mnc_digit_length; + uint16_t mcc[PLMN_LIST_MAX_SIZE]; + uint16_t mnc[PLMN_LIST_MAX_SIZE]; + uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE]; + uint8_t num_plmn; /* Default Paging DRX of the eNB as defined in TS 36.304 */ paging_drx_t default_drx; diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.c b/openair3/S1AP/s1ap_eNB_nas_procedures.c index ebd5bab4fd..80266a4d9c 100644 --- a/openair3/S1AP/s1ap_eNB_nas_procedures.c +++ b/openair3/S1AP/s1ap_eNB_nas_procedures.c @@ -81,6 +81,16 @@ int s1ap_eNB_handle_nas_first_req( instance_p, s1ap_nas_first_req_p->establishment_cause, s1ap_nas_first_req_p->ue_identity.gummei); + if (mme_desc_p) { + S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through GUMMEI MCC %d MNC %d MMEGI %d MMEC %d\n", + instance, + mme_desc_p->mme_name, + mme_desc_p->assoc_id, + s1ap_nas_first_req_p->ue_identity.gummei.mcc, + s1ap_nas_first_req_p->ue_identity.gummei.mnc, + s1ap_nas_first_req_p->ue_identity.gummei.mme_group_id, + s1ap_nas_first_req_p->ue_identity.gummei.mme_code); + } } if (mme_desc_p == NULL) { @@ -89,18 +99,53 @@ int s1ap_eNB_handle_nas_first_req( mme_desc_p = s1ap_eNB_nnsf_select_mme_by_mme_code( instance_p, s1ap_nas_first_req_p->establishment_cause, + s1ap_nas_first_req_p->selected_plmn_identity, s1ap_nas_first_req_p->ue_identity.s_tmsi.mme_code); + if (mme_desc_p) { + S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through S-TMSI MMEC %d and selected PLMN Identity index %d MCC %d MNC %d\n", + instance, + mme_desc_p->mme_name, + mme_desc_p->assoc_id, + s1ap_nas_first_req_p->ue_identity.s_tmsi.mme_code, + s1ap_nas_first_req_p->selected_plmn_identity, + instance_p->mcc[s1ap_nas_first_req_p->selected_plmn_identity], + instance_p->mnc[s1ap_nas_first_req_p->selected_plmn_identity]); + } + } + } + + if (mme_desc_p == NULL) { + /* Select MME based on the selected PLMN identity, received through RRC + * Connection Setup Complete */ + mme_desc_p = s1ap_eNB_nnsf_select_mme_by_plmn_id( + instance_p, + s1ap_nas_first_req_p->establishment_cause, + s1ap_nas_first_req_p->selected_plmn_identity); + if (mme_desc_p) { + S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through selected PLMN Identity index %d MCC %d MNC %d\n", + instance, + mme_desc_p->mme_name, + mme_desc_p->assoc_id, + s1ap_nas_first_req_p->selected_plmn_identity, + instance_p->mcc[s1ap_nas_first_req_p->selected_plmn_identity], + instance_p->mnc[s1ap_nas_first_req_p->selected_plmn_identity]); } } if (mme_desc_p == NULL) { /* - * If no MME corresponds to the GUMMEI or the s-TMSI, selects the MME with the - * highest capacity. + * If no MME corresponds to the GUMMEI, the s-TMSI, or the selected PLMN + * identity, selects the MME with the highest capacity. */ mme_desc_p = s1ap_eNB_nnsf_select_mme( instance_p, s1ap_nas_first_req_p->establishment_cause); + if (mme_desc_p) { + S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through highest relative capacity\n", + instance, + mme_desc_p->mme_name, + mme_desc_p->assoc_id); + } } if (mme_desc_p == NULL) { @@ -124,6 +169,7 @@ int s1ap_eNB_handle_nas_first_req( ue_desc_p->mme_ref = mme_desc_p; ue_desc_p->ue_initial_id = s1ap_nas_first_req_p->ue_initial_id; ue_desc_p->eNB_instance = instance_p; + ue_desc_p->selected_plmn_identity = s1ap_nas_first_req_p->selected_plmn_identity; do { struct s1ap_eNB_ue_context_s *collision_p; @@ -172,9 +218,9 @@ int s1ap_eNB_handle_nas_first_req( ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_TAI; /* Assuming TAI is the TAI from the cell */ INT16_TO_OCTET_STRING(instance_p->tac, &ie->value.choice.TAI.tAC); - MCC_MNC_TO_PLMNID(instance_p->mcc, - instance_p->mnc, - instance_p->mnc_digit_length, + MCC_MNC_TO_PLMNID(instance_p->mcc[ue_desc_p->selected_plmn_identity], + instance_p->mnc[ue_desc_p->selected_plmn_identity], + instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity], &ie->value.choice.TAI.pLMNidentity); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); @@ -191,9 +237,9 @@ int s1ap_eNB_handle_nas_first_req( MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id, 0, // Cell ID &ie->value.choice.EUTRAN_CGI.cell_ID); - MCC_MNC_TO_TBCD(instance_p->mcc, - instance_p->mnc, - instance_p->mnc_digit_length, + MCC_MNC_TO_TBCD(instance_p->mcc[ue_desc_p->selected_plmn_identity], + instance_p->mnc[ue_desc_p->selected_plmn_identity], + instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity], &ie->value.choice.EUTRAN_CGI.pLMNidentity); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); @@ -608,9 +654,9 @@ int s1ap_eNB_nas_uplink(instance_t instance, s1ap_uplink_nas_t *s1ap_uplink_nas_ ie->criticality = S1AP_Criticality_ignore; ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_EUTRAN_CGI; MCC_MNC_TO_PLMNID( - s1ap_eNB_instance_p->mcc, - s1ap_eNB_instance_p->mnc, - s1ap_eNB_instance_p->mnc_digit_length, + s1ap_eNB_instance_p->mcc[ue_context_p->selected_plmn_identity], + s1ap_eNB_instance_p->mnc[ue_context_p->selected_plmn_identity], + s1ap_eNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity], &ie->value.choice.EUTRAN_CGI.pLMNidentity); //#warning "TODO get cell id from RRC" MACRO_ENB_ID_TO_CELL_IDENTITY(s1ap_eNB_instance_p->eNB_id, @@ -624,9 +670,9 @@ int s1ap_eNB_nas_uplink(instance_t instance, s1ap_uplink_nas_t *s1ap_uplink_nas_ ie->criticality = S1AP_Criticality_ignore; ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_TAI; MCC_MNC_TO_PLMNID( - s1ap_eNB_instance_p->mcc, - s1ap_eNB_instance_p->mnc, - s1ap_eNB_instance_p->mnc_digit_length, + s1ap_eNB_instance_p->mcc[ue_context_p->selected_plmn_identity], + s1ap_eNB_instance_p->mnc[ue_context_p->selected_plmn_identity], + s1ap_eNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity], &ie->value.choice.TAI.pLMNidentity); TAC_TO_ASN1(s1ap_eNB_instance_p->tac, &ie->value.choice.TAI.tAC); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); diff --git a/openair3/S1AP/s1ap_eNB_nnsf.c b/openair3/S1AP/s1ap_eNB_nnsf.c index 8b7d65cb01..63dc92b5e2 100644 --- a/openair3/S1AP/s1ap_eNB_nnsf.c +++ b/openair3/S1AP/s1ap_eNB_nnsf.c @@ -90,14 +90,83 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, } struct s1ap_eNB_mme_data_s * -s1ap_eNB_nnsf_select_mme_by_mme_code(s1ap_eNB_instance_t *instance_p, - rrc_establishment_cause_t cause, - uint8_t mme_code) +s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p, + rrc_establishment_cause_t cause, + int selected_plmn_identity) { struct s1ap_eNB_mme_data_s *mme_data_p = NULL; struct s1ap_eNB_mme_data_s *mme_highest_capacity_p = NULL; uint8_t current_capacity = 0; + RB_FOREACH(mme_data_p, s1ap_mme_map, &instance_p->s1ap_mme_head) { + struct served_gummei_s *gummei_p = NULL; + struct plmn_identity_s *served_plmn_p = NULL; + if (mme_data_p->state != S1AP_ENB_STATE_CONNECTED) { + /* The association between MME and eNB is not ready for the moment, + * go to the next known MME. + */ + if (mme_data_p->state == S1AP_ENB_OVERLOAD) { + /* MME is overloaded. We have to check the RRC establishment + * cause and take decision to the select this MME depending on + * the overload state. + */ + if ((cause == RRC_CAUSE_MO_DATA) + && (mme_data_p->overload_state == S1AP_OVERLOAD_REJECT_MO_DATA)) { + continue; + } + + if ((mme_data_p->overload_state == S1AP_OVERLOAD_REJECT_ALL_SIGNALLING) + && ((cause == RRC_CAUSE_MO_SIGNALLING) || (cause == RRC_CAUSE_MO_DATA))) { + continue; + } + + if ((mme_data_p->overload_state == S1AP_OVERLOAD_ONLY_EMERGENCY_AND_MT) + && ((cause == RRC_CAUSE_MO_SIGNALLING) || (cause == RRC_CAUSE_MO_DATA) + || (cause == RRC_CAUSE_HIGH_PRIO_ACCESS))) { + continue; + } + + /* At this point, the RRC establishment can be handled by the MME + * even if it is in overload state. + */ + } else { + /* The MME is not overloaded, association is simply not ready. */ + continue; + } + } + + /* Looking for served GUMMEI PLMN Identity selected matching the one provided by the UE */ + STAILQ_FOREACH(gummei_p, &mme_data_p->served_gummei, next) { + STAILQ_FOREACH(served_plmn_p, &gummei_p->served_plmns, next) { + if ((served_plmn_p->mcc == instance_p->mcc[selected_plmn_identity]) && + (served_plmn_p->mnc == instance_p->mnc[selected_plmn_identity])) { + break; + } + } + /* if found, we can stop the outer loop, too */ + if (served_plmn_p) break; + } + /* if we didn't find such a served PLMN, go on with the next MME */ + if (!served_plmn_p) continue; + + if (current_capacity < mme_data_p->relative_mme_capacity) { + /* We find a better MME, keep a reference to it */ + current_capacity = mme_data_p->relative_mme_capacity; + mme_highest_capacity_p = mme_data_p; + } + } + + return mme_highest_capacity_p; +} + +struct s1ap_eNB_mme_data_s * +s1ap_eNB_nnsf_select_mme_by_mme_code(s1ap_eNB_instance_t *instance_p, + rrc_establishment_cause_t cause, + int selected_plmn_identity, + uint8_t mme_code) +{ + struct s1ap_eNB_mme_data_s *mme_data_p = NULL; + RB_FOREACH(mme_data_p, s1ap_mme_map, &instance_p->s1ap_mme_head) { struct served_gummei_s *gummei_p = NULL; @@ -135,30 +204,37 @@ s1ap_eNB_nnsf_select_mme_by_mme_code(s1ap_eNB_instance_t *instance_p, } } - if (current_capacity < mme_data_p->relative_mme_capacity) { - /* We find a better MME, keep a reference to it */ - current_capacity = mme_data_p->relative_mme_capacity; - mme_highest_capacity_p = mme_data_p; - } - /* Looking for MME code matching the one provided by NAS */ STAILQ_FOREACH(gummei_p, &mme_data_p->served_gummei, next) { struct mme_code_s *mme_code_p = NULL; + struct plmn_identity_s *served_plmn_p = NULL; + STAILQ_FOREACH(served_plmn_p, &gummei_p->served_plmns, next) { + if ((served_plmn_p->mcc == instance_p->mcc[selected_plmn_identity]) && + (served_plmn_p->mnc == instance_p->mnc[selected_plmn_identity])) { + break; + } + } STAILQ_FOREACH(mme_code_p, &gummei_p->mme_codes, next) { if (mme_code_p->mme_code == mme_code) { - return mme_data_p; + break; } } + + /* The MME matches the parameters provided by the NAS layer -> + * the MME is knwown and the association is ready. + * Return the reference to the MME to use it for this UE. + */ + if (mme_code_p && served_plmn_p) { + return mme_data_p; + } } } - /* At this point no MME matches the provided GUMMEI. Select the one with the - * highest relative capacity. - * In case the list of known MME is empty, simply return NULL, that way the RRC - * layer should know about it and reject RRC connectivity. - */ - return mme_highest_capacity_p; + /* At this point no MME matches the selected PLMN and MME code. In this case, + * return NULL. That way the RRC layer should know about it and reject RRC + * connectivity. */ + return NULL; } struct s1ap_eNB_mme_data_s * @@ -167,8 +243,6 @@ s1ap_eNB_nnsf_select_mme_by_gummei(s1ap_eNB_instance_t *instance_p, s1ap_gummei_t gummei) { struct s1ap_eNB_mme_data_s *mme_data_p = NULL; - struct s1ap_eNB_mme_data_s *mme_highest_capacity_p = NULL; - uint8_t current_capacity = 0; RB_FOREACH(mme_data_p, s1ap_mme_map, &instance_p->s1ap_mme_head) { struct served_gummei_s *gummei_p = NULL; @@ -207,12 +281,6 @@ s1ap_eNB_nnsf_select_mme_by_gummei(s1ap_eNB_instance_t *instance_p, } } - if (current_capacity < mme_data_p->relative_mme_capacity) { - /* We find a better MME, keep a reference to it */ - current_capacity = mme_data_p->relative_mme_capacity; - mme_highest_capacity_p = mme_data_p; - } - /* Looking for MME gummei matching the one provided by NAS */ STAILQ_FOREACH(gummei_p, &mme_data_p->served_gummei, next) { struct served_group_id_s *group_id_p = NULL; @@ -248,10 +316,8 @@ s1ap_eNB_nnsf_select_mme_by_gummei(s1ap_eNB_instance_t *instance_p, } } - /* At this point no MME matches the provided GUMMEI. Select the one with the - * highest relative capacity. - * In case the list of known MME is empty, simply return NULL, that way the RRC - * layer should know about it and reject RRC connectivity. - */ - return mme_highest_capacity_p; + /* At this point no MME matches the provided GUMMEI. In this case, return + * NULL. That way the RRC layer should know about it and reject RRC + * connectivity. */ + return NULL; } diff --git a/openair3/S1AP/s1ap_eNB_nnsf.h b/openair3/S1AP/s1ap_eNB_nnsf.h index 78405f34d1..706f3ada6f 100644 --- a/openair3/S1AP/s1ap_eNB_nnsf.h +++ b/openair3/S1AP/s1ap_eNB_nnsf.h @@ -26,9 +26,15 @@ struct s1ap_eNB_mme_data_s * s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, rrc_establishment_cause_t cause); +struct s1ap_eNB_mme_data_s * +s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p, + rrc_establishment_cause_t cause, + int selected_plmn_identity); + struct s1ap_eNB_mme_data_s* s1ap_eNB_nnsf_select_mme_by_mme_code(s1ap_eNB_instance_t *instance_p, rrc_establishment_cause_t cause, + int selected_plmn_identity, uint8_t mme_code); struct s1ap_eNB_mme_data_s* diff --git a/openair3/S1AP/s1ap_eNB_ue_context.h b/openair3/S1AP/s1ap_eNB_ue_context.h index d78c6f7f1a..9adbc5fb2c 100644 --- a/openair3/S1AP/s1ap_eNB_ue_context.h +++ b/openair3/S1AP/s1ap_eNB_ue_context.h @@ -67,6 +67,11 @@ typedef struct s1ap_eNB_ue_context_s { /* Reference to MME data this UE is attached to */ struct s1ap_eNB_mme_data_s *mme_ref; + /* Signaled by the UE in RRC Connection Setup Complete and used in NAS Uplink + * to route NAS messages correctly. 0-based, not 1-based as in TS 36.331 + * 6.2.2 RRC Connection Setup Complete! */ + int selected_plmn_identity; + /* Reference to eNB data this UE is attached to */ s1ap_eNB_instance_t *eNB_instance; } s1ap_eNB_ue_context_t; 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 index 2571db70a0..85cee4dda0 100644 --- 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 @@ -13,11 +13,8 @@ eNBs = 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"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 95; mnc_length = 2; } ); ////////// Physical parameters: diff --git a/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb1.conf b/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb1.conf index e71e7e03f5..df06231e4a 100755 --- a/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb1.conf +++ b/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb1.conf @@ -13,10 +13,8 @@ eNBs = 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"; + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 95; mnc_length = 2; } ); ////////// Physical parameters: diff --git a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.calisson.conf b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.calisson.conf index 7ec670d568..86131b3e8e 100755 --- a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.calisson.conf +++ b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.calisson.conf @@ -15,12 +15,9 @@ eNBs = eNB_name = "eNB_Eurecom_LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "15"; - - mobile_country_code = "208"; - - mobile_network_code = "92"; - + tracking_area_code = 15; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); + ////////// Channel parameters: // Default Paging DRX of the eNB as defined in TS 36.304 default_paging_drx = "PAGING_DRX_256"; diff --git a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.memphis.conf b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.memphis.conf index e3a0ea3c56..e87a37f9fb 100755 --- a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.memphis.conf +++ b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.memphis.conf @@ -15,12 +15,9 @@ eNBs = eNB_name = "eNB_Eurecom_LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "15"; - - mobile_country_code = "208"; - - mobile_network_code = "92"; - + tracking_area_code = 15; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); + ////////// Channel parameters: // Default Paging DRX of the eNB as defined in TS 36.304 default_paging_drx = "PAGING_DRX_256"; diff --git a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.nord.conf b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.nord.conf index 591257ff71..af4f4236a7 100755 --- a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.nord.conf +++ b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.nord.conf @@ -14,12 +14,9 @@ eNBs = eNB_name = "eNB_Eurecom_LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "15"; - - mobile_country_code = "208"; - - mobile_network_code = "92"; - + tracking_area_code = 15; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); + ////////// Channel parameters: // Default Paging DRX of the eNB as defined in TS 36.304 default_paging_drx = "PAGING_DRX_256"; diff --git a/targets/PROJECTS/E-MBMS/enb.conf b/targets/PROJECTS/E-MBMS/enb.conf index 852f7bbf5f..ea256487b0 100755 --- a/targets/PROJECTS/E-MBMS/enb.conf +++ b/targets/PROJECTS/E-MBMS/enb.conf @@ -11,12 +11,9 @@ eNBs = eNB_name = "eNB_Eurecom_0"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = 1; - - mobile_country_code = 208; - - mobile_network_code = 10; - + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 10; mnc_length = 2; } ); + ////////// Channel parameters: // Default Paging DRX of the eNB as defined in TS 36.304 default_paging_drx = "PAGING_DRX_256"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf index 2761fe5fdb..8c080b7d10 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf @@ -13,10 +13,9 @@ eNBs = eNB_name = "eNB_Eurecom_LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; - mobile_country_code = "208"; - mobile_network_code = "92"; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf index 56b3c37c0a..83954a00d5 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf @@ -13,10 +13,9 @@ eNBs = eNB_name = "eNB_Eurecom_LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; - mobile_country_code = "208"; - mobile_network_code = "92"; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); ////////// Physical parameters: diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf index f088eda84f..60b47c5c49 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf @@ -13,11 +13,9 @@ eNBs = eNB_name = "eNB_Eurecom_LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; - mobile_country_code = "208"; - - mobile_network_code = "93"; + plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } ); tr_s_preference = "local_mac" diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf index 3bd4b1275a..823c5fb1c3 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf @@ -13,11 +13,9 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; - mobile_country_code = "208"; - - mobile_network_code = "92"; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); tr_s_preference = "local_mac" diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf index a419122846..476d4903f1 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf @@ -13,11 +13,9 @@ eNBs = eNB_name = "eNB_Eurecom_LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; - mobile_country_code = "208"; - - mobile_network_code = "93"; + plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } ); tr_s_preference = "local_mac" diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf index e08b83d58a..83834bfeca 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf @@ -13,11 +13,9 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; - mobile_country_code = "208"; - - mobile_network_code = "93"; + plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } ); tr_s_preference = "local_mac" diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf index f0a3cb524a..403e5f24f5 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf @@ -13,11 +13,9 @@ eNBs = eNB_name = "eNB_Eurecom_LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; - mobile_country_code = "208"; - - mobile_network_code = "93"; + plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } ); tr_s_preference = "local_mac" diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band38.tm1.if4p5.50PRB.lo.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band38.tm1.if4p5.50PRB.lo.conf index 039f0c39c1..7eb16a3b7a 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band38.tm1.if4p5.50PRB.lo.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band38.tm1.if4p5.50PRB.lo.conf @@ -16,11 +16,9 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; - mobile_country_code = "208"; - - mobile_network_code = "93"; + plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } ); tr_s_preference = "local_mac" diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf index 8f6aac632b..47047e5626 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf @@ -13,12 +13,9 @@ eNBs = eNB_name = "eNB_Eurecom_LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; - mobile_country_code = "208"; - - #mobile_network_code = "93"; - mobile_network_code = "92"; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); tr_s_preference = "local_mac" diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf index f4ac5a9aa3..ced031163d 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf @@ -13,11 +13,9 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; - mobile_country_code = "208"; - - mobile_network_code = "93"; + plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } ); tr_s_preference = "local_mac" diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf index ea205e44d1..d989ac8b10 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf @@ -16,11 +16,9 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; - mobile_country_code = "208"; - - mobile_network_code = "93"; + plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } ); tr_s_preference = "local_mac" diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf index a2e97648c9..79bd48cd0c 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf @@ -16,11 +16,9 @@ eNBs = eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; - mobile_country_code = "208"; - - mobile_network_code = "93"; + plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } ); tr_s_preference = "local_mac"