Merge branch 'feature-s1-flex' into develop_integration_2018_w_41
Introduction of S1-flex. It handles multiple PLMN IDs (up to 6) in the SIB as well as the selection of an MME based on the selected PLMN identity.
Major impact: changes on the eNB configuration files:
tracking_area_code = 1;
plmn_list = (
{ mcc = 208; mnc = 94; mnc_length = 2; },
{ mcc = 208; mnc = 95; mnc_length = 2; }
)
See https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/s1-flex-conf-nnsf for more details.
Signed-off-by: Raphael Defosseux <raphael.defosseux@eurecom.fr>
This commit is contained in:
@@ -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:
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
+136
-75
@@ -570,31 +570,46 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
|
||||
for (k=0; k <num_enbs ; k++) {
|
||||
if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[k], *(ENBParamList.paramarray[i][ENB_ENB_NAME_IDX].strptr) )== 0) {
|
||||
char enbpath[MAX_OPTNAME_SIZE + 8];
|
||||
sprintf(enbpath,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k);
|
||||
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]);
|
||||
|
||||
RRC_CONFIGURATION_REQ (msg_p).cell_identity = enb_id;
|
||||
/*
|
||||
if (strcmp(*(ENBParamList.paramarray[i][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_ENB") == 0) {
|
||||
enb_properties_loc.properties[enb_properties_loc_index]->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++) {
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
+127
-126
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+36
-14
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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*
|
||||
|
||||
@@ -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;
|
||||
|
||||
+2
-5
@@ -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:
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
+2
-4
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user