Files
openairinterface5g/openair2/ENB_APP/enb_config.c
T
Robert Schmidt 7c6c4fc7d3 Start E2 agent only if configuration present
This commit introduces an additional (implicit) option that signals if
the E2 agent is to be activated or not. When reading the configuration,
we now check if all fields are set, and activate the E2 agent only if
this is the case. If not, we only print a warning and start the gNB
without the agent.

Note that previously, if not all fields are set correctly, the gNB
stopped.

To implement this behavior, it is necessary to change the defaults of
the RIC IP and the directory for SMs to a (non-NULL) default value.
Otherwise, the configuration system would not consider the field to be
set to the default, and wrongly assumes the field is set, even though it
is not; at least, this change is necessary to make config_isparamset()
return NULL if the configuration is not set.
2023-11-30 08:06:16 +01:00

2966 lines
162 KiB
C

/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*
enb_config.c
-------------------
AUTHOR : Lionel GAUTHIER, navid nikaein, Laurent Winckel
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr, navid.nikaein@eurecom.fr
*/
#include <string.h>
#include <inttypes.h>
#include <dlfcn.h>
#include "common/utils/LOG/log.h"
#include "assertions.h"
#include "enb_config.h"
#include "UTIL/OTG/otg.h"
#include "UTIL/OTG/otg_externs.h"
#include "intertask_interface.h"
#include "s1ap_eNB.h"
#include "sctp_eNB_task.h"
#include "common/ran_context.h"
#include "sctp_default_values.h"
#include "LTE_SystemInformationBlockType2.h"
#include "uper_decoder.h"
#include "LAYER2/MAC/mac_extern.h"
#include "LAYER2/MAC/mac_proto.h"
#include "PHY/phy_extern.h"
#include "PHY/INIT/phy_init.h"
#include "radio/ETHERNET/ethernet_lib.h"
#include "nfapi_vnf.h"
#include "nfapi_pnf.h"
#include "executables/lte-softmodem.h"
#include "L1_paramdef.h"
#include "MACRLC_paramdef.h"
#include "common/config/config_userapi.h"
#include "RRC_config_tools.h"
#include "enb_paramdef.h"
#include "executables/thread-common.h"
#include <openair3/ocp-gtpu/gtp_itf.h>
extern uint32_t to_earfcn_DL(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw);
extern uint32_t to_earfcn_UL(int eutra_bandP, uint32_t ul_CarrierFreq, uint32_t bw);
extern char *parallel_config;
extern char *worker_config;
RAN_CONTEXT_t RC;
void RCconfig_L1(void) {
int i,j;
paramdef_t L1_Params[] = L1PARAMS_DESC;
paramlist_def_t L1_ParamList = {CONFIG_STRING_L1_LIST,NULL,0};
if (RC.eNB == NULL) {
RC.eNB = (PHY_VARS_eNB ** *)malloc((1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB **));
LOG_I(PHY,"RC.eNB = %p\n",RC.eNB);
memset(RC.eNB,0,(1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB **));
RC.nb_L1_CC = malloc((1+RC.nb_L1_inst)*sizeof(int));
}
config_getlist(config_get_if(), &L1_ParamList, L1_Params, sizeofArray(L1_Params), NULL);
if (L1_ParamList.numelt > 0) {
for (j = 0; j < RC.nb_L1_inst; j++) {
RC.nb_L1_CC[j] = *(L1_ParamList.paramarray[j][L1_CC_IDX].uptr);
if (RC.eNB[j] == NULL) {
RC.eNB[j] = (PHY_VARS_eNB **)malloc((1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB *));
LOG_I(PHY,"RC.eNB[%d] = %p\n",j,RC.eNB[j]);
memset(RC.eNB[j],0,(1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB *));
}
for (i=0; i<RC.nb_L1_CC[j]; i++) {
if (RC.eNB[j][i] == NULL) {
RC.eNB[j][i] = (PHY_VARS_eNB *)calloc(1, sizeof(PHY_VARS_eNB));
LOG_I(PHY,"RC.eNB[%d][%d] = %p\n",j,i,RC.eNB[j][i]);
RC.eNB[j][i]->Mod_id = j;
RC.eNB[j][i]->CC_id = i;
}
}
if (strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_mac") == 0) {
} else if (strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "nfapi") == 0) {
RC.eNB[j][0]->eth_params_n.local_if_name = strdup(*(L1_ParamList.paramarray[j][L1_LOCAL_N_IF_NAME_IDX].strptr));
RC.eNB[j][0]->eth_params_n.my_addr = strdup(*(L1_ParamList.paramarray[j][L1_LOCAL_N_ADDRESS_IDX].strptr));
RC.eNB[j][0]->eth_params_n.remote_addr = strdup(*(L1_ParamList.paramarray[j][L1_REMOTE_N_ADDRESS_IDX].strptr));
RC.eNB[j][0]->eth_params_n.my_portc = *(L1_ParamList.paramarray[j][L1_LOCAL_N_PORTC_IDX].iptr);
RC.eNB[j][0]->eth_params_n.remote_portc = *(L1_ParamList.paramarray[j][L1_REMOTE_N_PORTC_IDX].iptr);
RC.eNB[j][0]->eth_params_n.my_portd = *(L1_ParamList.paramarray[j][L1_LOCAL_N_PORTD_IDX].iptr);
RC.eNB[j][0]->eth_params_n.remote_portd = *(L1_ParamList.paramarray[j][L1_REMOTE_N_PORTD_IDX].iptr);
RC.eNB[j][0]->eth_params_n.transp_preference = ETH_UDP_MODE;
RC.nb_macrlc_inst = 1; // This is used by mac_top_init_eNB()
// This is used by init_eNB_afterRU()
RC.nb_CC = (int *)malloc((1+RC.nb_inst)*sizeof(int));
RC.nb_CC[0]=1;
RC.nb_inst =1; // feptx_prec uses num_eNB but phy_init_RU uses nb_inst
LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_inst=1 this is because phy_init_RU() uses that to index and not RC.num_eNB - why the 2 similar variables?\n", __FUNCTION__);
LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_CC[0]=%d for init_eNB_afterRU()\n", __FUNCTION__, RC.nb_CC[0]);
LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_macrlc_inst:%d because used by mac_top_init_eNB()\n", __FUNCTION__, RC.nb_macrlc_inst);
mac_top_init_eNB();
configure_nfapi_pnf(RC.eNB[j][0]->eth_params_n.remote_addr, RC.eNB[j][0]->eth_params_n.remote_portc, RC.eNB[j][0]->eth_params_n.my_addr, RC.eNB[j][0]->eth_params_n.my_portd,
RC.eNB[j][0]->eth_params_n .remote_portd);
} else { // other midhaul
}
// PRACH/PUCCH parameters
RC.eNB[j][0]->prach_DTX_threshold = *(L1_ParamList.paramarray[j][L1_PRACH_DTX_THRESHOLD_IDX].iptr);
RC.eNB[j][0]->pucch1_DTX_threshold = *(L1_ParamList.paramarray[j][L1_PUCCH1_DTX_THRESHOLD_IDX].iptr);
RC.eNB[j][0]->pucch1ab_DTX_threshold = *(L1_ParamList.paramarray[j][L1_PUCCH1AB_DTX_THRESHOLD_IDX].iptr);
for (int ce_level=0; ce_level<4; ce_level++) {
RC.eNB[j][0]->prach_DTX_threshold_emtc[ce_level] = *(L1_ParamList.paramarray[j][L1_PRACH_DTX_EMTC0_THRESHOLD_IDX+ce_level].iptr);
RC.eNB[j][0]->pucch1_DTX_threshold_emtc[ce_level] = *(L1_ParamList.paramarray[j][L1_PUCCH1_DTX_EMTC0_THRESHOLD_IDX+ce_level].iptr);
RC.eNB[j][0]->pucch1ab_DTX_threshold_emtc[ce_level] = *(L1_ParamList.paramarray[j][L1_PUCCH1AB_DTX_EMTC0_THRESHOLD_IDX+ce_level].iptr);
}
RC.eNB[j][0]->pusch_signal_threshold = *(L1_ParamList.paramarray[j][L1_PUSCH_SIGNAL_THRESHOLD_IDX].iptr);
LOG_I(ENB_APP,"PUSCH singal threshold = %d \n",RC.eNB[j][0]->pusch_signal_threshold);
}// j=0..num_inst
LOG_I(ENB_APP,"Initializing northbound interface for L1\n");
l1_north_init_eNB();
} else {
LOG_I(PHY,"No " CONFIG_STRING_L1_LIST " configuration found");
// need to create some structures for VNF
j = 0;
RC.nb_L1_CC = malloc((1+RC.nb_L1_inst)*sizeof(int));
RC.nb_L1_CC[j]=1;
if (RC.eNB[j] == NULL) {
RC.eNB[j] = (PHY_VARS_eNB **)malloc((1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB **));
LOG_I(PHY,"RC.eNB[%d] = %p\n",j,RC.eNB[j]);
memset(RC.eNB[j],0,(1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB***));
}
for (i=0; i<RC.nb_L1_CC[j]; i++) {
if (RC.eNB[j][i] == NULL) {
RC.eNB[j][i] = (PHY_VARS_eNB *)malloc(sizeof(PHY_VARS_eNB));
memset((void *)RC.eNB[j][i],0,sizeof(PHY_VARS_eNB));
LOG_I(PHY,"RC.eNB[%d][%d] = %p\n",j,i,RC.eNB[j][i]);
RC.eNB[j][i]->Mod_id = j;
RC.eNB[j][i]->CC_id = i;
}
}
}
}
void RCconfig_macrlc(void)
{
int j;
paramdef_t MacRLC_Params[] = MACRLCPARAMS_DESC;
paramlist_def_t MacRLC_ParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0};
config_getlist(config_get_if(), &MacRLC_ParamList, MacRLC_Params, sizeofArray(MacRLC_Params), NULL);
config_getlist(config_get_if(), &MacRLC_ParamList, MacRLC_Params, sizeofArray(MacRLC_Params), NULL);
if ( MacRLC_ParamList.numelt > 0) {
RC.nb_macrlc_inst=MacRLC_ParamList.numelt;
mac_top_init_eNB();
RC.nb_mac_CC = (int *)malloc(RC.nb_macrlc_inst*sizeof(int));
for (j = 0; j < RC.nb_macrlc_inst; j++) {
RC.mac[j]->puSch10xSnr = *(MacRLC_ParamList.paramarray[j][MACRLC_PUSCH10xSNR_IDX ].iptr);
RC.mac[j]->puCch10xSnr = *(MacRLC_ParamList.paramarray[j][MACRLC_PUCCH10xSNR_IDX ].iptr);
RC.mac[j]->ue_multiple_max = *(MacRLC_ParamList.paramarray[j][MACRLC_UE_MULTIPLE_MAX_IDX ].iptr);
RC.mac[j]->use_mcs_offset = *(MacRLC_ParamList.paramarray[j][MACRLC_USE_MCS_OFFSET_IDX ].iptr);
RC.mac[j]->bler_lower = *(MacRLC_ParamList.paramarray[j][MACRLC_BLER_TARGET_LOWER_IDX ].dblptr);
RC.mac[j]->bler_upper = *(MacRLC_ParamList.paramarray[j][MACRLC_BLER_TARGET_UPPER_IDX ].dblptr);
RC.mac[j]->max_ul_rb_index = *(MacRLC_ParamList.paramarray[j][MACRLC_MAX_UL_RB_INDEX_IDX ].iptr);
RC.nb_mac_CC[j] = *(MacRLC_ParamList.paramarray[j][MACRLC_CC_IDX].iptr);
LOG_I(ENB_APP,"MAC instance %d parameters : pusch_snr %lf, pucch_snr %lf, ue_multiple_max %d, use_mcs_offset %d, bler_lower %lf, bler_upper %lf,max_ul_rb_index %d\n",
j,
RC.mac[j]->puSch10xSnr/10.0,
RC.mac[j]->puCch10xSnr/10.0,
RC.mac[j]->ue_multiple_max,
RC.mac[j]->use_mcs_offset,
RC.mac[j]->bler_lower,
RC.mac[j]->bler_upper,
RC.mac[j]->max_ul_rb_index);
if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_RRC") == 0) {
// check number of instances is same as RRC/PDCP
LOG_I(ENB_APP,"Configuring local RRC for MACRLC\n");
} else { // other midhaul
AssertFatal(1==0,"MACRLC %d: %s unknown northbound midhaul\n",j, *(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr));
}
if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr), "local_L1") == 0) {
} else if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr), "nfapi") == 0) {
RC.mac[j]->eth_params_s.local_if_name = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_IF_NAME_IDX].strptr));
RC.mac[j]->eth_params_s.my_addr = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_ADDRESS_IDX].strptr));
RC.mac[j]->eth_params_s.remote_addr = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_ADDRESS_IDX].strptr));
RC.mac[j]->eth_params_s.my_portc = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_PORTC_IDX].iptr);
RC.mac[j]->eth_params_s.remote_portc = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTC_IDX].iptr);
RC.mac[j]->eth_params_s.my_portd = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_PORTD_IDX].iptr);
RC.mac[j]->eth_params_s.remote_portd = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTD_IDX].iptr);
RC.mac[j]->eth_params_s.transp_preference = ETH_UDP_MODE;
LOG_I(ENB_APP,"**************** vnf_port:%d\n", RC.mac[j]->eth_params_s.my_portc);
configure_nfapi_vnf(RC.mac[j]->eth_params_s.my_addr, RC.mac[j]->eth_params_s.my_portc,RC.mac[j]->eth_params_s.remote_addr,RC.mac[j]->eth_params_s.remote_portd,RC.mac[j]->eth_params_s.my_portd);
LOG_I(ENB_APP,"**************** RETURNED FROM configure_nfapi_vnf() vnf_port:%d\n", RC.mac[j]->eth_params_s.my_portc);
} else { // other midhaul
AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr));
}
if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr), "default") == 0) {
global_scheduler_mode=SCHED_MODE_DEFAULT;
LOG_I(ENB_APP,"sched mode = default %d [%s]\n",global_scheduler_mode,*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr));
} else if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr), "fairRR") == 0) {
global_scheduler_mode=SCHED_MODE_FAIR_RR;
printf("sched mode = fairRR %d [%s]\n",global_scheduler_mode,*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr));
} else {
global_scheduler_mode=SCHED_MODE_DEFAULT;
printf("sched mode = default %d [%s]\n",global_scheduler_mode,*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr));
}
char *s = *MacRLC_ParamList.paramarray[j][MACRLC_DEFAULT_SCHED_DL_ALGO_IDX].strptr;
void *d = dlsym(NULL, s);
AssertFatal(d, "%s(): no default scheduler DL algo '%s' found\n", __func__, s);
// release default, add new
pp_impl_param_t *dl_pp = &RC.mac[j]->pre_processor_dl;
dl_pp->dl_algo.unset(&dl_pp->dl_algo.data);
dl_pp->dl_algo = *(default_sched_dl_algo_t *) d;
dl_pp->dl_algo.data = dl_pp->dl_algo.setup();
LOG_I(ENB_APP, "using default scheduler DL algo '%s'\n", dl_pp->dl_algo.name);
}// j=0..num_inst
} /*else {// MacRLC_ParamList.numelt > 0 // ignore it
AssertFatal (0,
"No " CONFIG_STRING_MACRLC_LIST " configuration found");
}*/
}
int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc) {
int num_enbs = 0;
int j,k = 0;
int32_t enb_id = 0;
int32_t offsetMaxLimit = 0;
int32_t cycleNb = 0;
RrcConfigurationReq *RRCcfg = &rrc->configuration;
ccparams_lte_t ccparams_lte;
ccparams_sidelink_t SLconfig;
ccparams_eMTC_t eMTCconfig;
memset((void *)&ccparams_lte,0,sizeof(ccparams_lte_t));
memset((void *)&SLconfig,0,sizeof(ccparams_sidelink_t));
memset((void *)&eMTCconfig,0,sizeof(ccparams_eMTC_t));
paramdef_t ENBSParams[] = ENBSPARAMS_DESC;
paramdef_t ENBParams[] = ENBPARAMS_DESC;
paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST,NULL,0};
checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK;
paramdef_t CCsParams[] = CCPARAMS_DESC(ccparams_lte);
paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS,NULL,0};
paramdef_t eMTCParams[] = EMTCPARAMS_DESC((&eMTCconfig));
checkedparam_t config_check_eMTCparams[] = EMTCPARAMS_CHECK;
srb1_params_t srb1_params;
memset((void *)&srb1_params,0,sizeof(srb1_params_t));
paramdef_t SRB1Params[] = SRB1PARAMS_DESC(srb1_params);
paramdef_t SLParams[] = CCPARAMS_SIDELINK_DESC(SLconfig);
/* map parameter checking array instances to parameter definition array instances */
for (int I = 0; I < sizeofArray(CCsParams); I++) {
CCsParams[I].chkPptr = &(config_check_CCparams[I]);
}
for (int I = 0; I < sizeofArray(CCsParams); I++) {
eMTCParams[I].chkPptr = &(config_check_eMTCparams[I]);
}
/* get global parameters, defined outside any section in the config file */
config_get(config_get_if(), ENBSParams, sizeofArray(ENBSParams), NULL);
num_enbs = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt;
AssertFatal (i<num_enbs,
"Failed to parse config file no %uth element in %s \n",i, ENB_CONFIG_STRING_ACTIVE_ENBS);
if (num_enbs>0) {
// Output a list of all eNBs.
config_getlist(config_get_if(), &ENBParamList, ENBParams, sizeofArray(ENBParams), NULL);
if (ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr == NULL) {
// Calculate a default eNB ID
if (EPC_MODE_ENABLED) {
uint32_t hash;
hash = s1ap_generate_eNB_id ();
enb_id = i + (hash & 0xFFFF8);
} else {
enb_id = i;
}
} else {
enb_id = *(ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr);
}
LOG_I(RRC,"Instance %d: Southbound Transport %s\n",i,*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr));
rrc->nr_cellid = (uint64_t)*(ENBParamList.paramarray[i][ENB_NRCELLID_IDX].u64ptr);
// search if in active list
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 < sizeofArray(PLMNParams); ++I)
PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]);
// In the configuration file it is in seconds. For RRC it has to be in milliseconds
RRCcfg->rrc_inactivity_timer_thres = (*ENBParamList.paramarray[i][ENB_RRC_INACTIVITY_THRES_IDX].uptr) * 1000;
RRCcfg->cell_identity = enb_id;
RRCcfg->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(config_get_if(), &PLMNParamList, PLMNParams, sizeofArray(PLMNParams), 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);
RRCcfg->num_plmn = PLMNParamList.numelt;
for (int l = 0; l < PLMNParamList.numelt; ++l) {
RRCcfg->mcc[l] = *PLMNParamList.paramarray[l][ENB_MOBILE_COUNTRY_CODE_IDX].uptr;
RRCcfg->mnc[l] = *PLMNParamList.paramarray[l][ENB_MOBILE_NETWORK_CODE_IDX].uptr;
RRCcfg->mnc_digit_length[l] = *PLMNParamList.paramarray[l][ENB_MNC_DIGIT_LENGTH].u8ptr;
AssertFatal(RRCcfg->mnc_digit_length[l] == 3 || RRCcfg->mnc[l] < 100, "MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n", RRCcfg->mnc[l]);
}
/* measurement reports enabled? */
if (ENBParamList.paramarray[i][ENB_ENABLE_MEASUREMENT_REPORTS].strptr != NULL &&
*(ENBParamList.paramarray[i][ENB_ENABLE_MEASUREMENT_REPORTS].strptr) != NULL &&
!strcmp(*(ENBParamList.paramarray[i][ENB_ENABLE_MEASUREMENT_REPORTS].strptr), "yes"))
RRCcfg->enable_measurement_reports = 1;
else
RRCcfg->enable_measurement_reports = 0;
/* x2 enabled? */
if (ENBParamList.paramarray[i][ENB_ENABLE_X2].strptr != NULL &&
*(ENBParamList.paramarray[i][ENB_ENABLE_X2].strptr) != NULL &&
!strcmp(*(ENBParamList.paramarray[i][ENB_ENABLE_X2].strptr), "yes"))
RRCcfg->enable_x2 = 1;
else
RRCcfg->enable_x2 = 0;
/* m2 enabled */
if (ENBParamList.paramarray[i][ENB_ENABLE_ENB_M2].strptr != NULL &&
*(ENBParamList.paramarray[i][ENB_ENABLE_ENB_M2].strptr) != NULL &&
!strcmp(*(ENBParamList.paramarray[i][ENB_ENABLE_ENB_M2].strptr), "yes"))
RRCcfg->eMBMS_M2_configured = 1;
else
RRCcfg->eMBMS_M2_configured = 0;
// Parse optional physical parameters
config_getlist(config_get_if(), &CCsParamList, NULL, 0, enbpath);
LOG_I(RRC,"num component carriers %d \n",CCsParamList.numelt);
if ( CCsParamList.numelt> 0) {
char ccspath[MAX_OPTNAME_SIZE*2 + 16];
for (j = 0; j < CCsParamList.numelt ; j++) {
sprintf(ccspath,"%s.%s.[%i]",enbpath,ENB_CONFIG_STRING_COMPONENT_CARRIERS,j);
LOG_I(RRC,
"enb_config::RCconfig_RRC() parameter number: %d, total number of parameters: %zd, ccspath: %s \n \n",
j,
sizeofArray(CCsParams),
ccspath);
config_get(config_get_if(), CCsParams, sizeofArray(CCsParams), ccspath);
// printf("Component carrier %d\n",component_carrier);
// Cell params, MIB/SIB1
RRCcfg->tdd_config[j] = ccparams_lte.tdd_config;
AssertFatal (ccparams_lte.tdd_config <= LTE_TDD_Config__subframeAssignment_sa6,
"Failed to parse eNB configuration file %s, enb %u illegal tdd_config %d (should be 0-%d)!",
RC.config_file_name, i, ccparams_lte.tdd_config, LTE_TDD_Config__subframeAssignment_sa6);
RRCcfg->tdd_config_s[j] = ccparams_lte.tdd_config_s;
AssertFatal (ccparams_lte.tdd_config_s <= LTE_TDD_Config__specialSubframePatterns_ssp8,
"Failed to parse eNB configuration file %s, enb %u illegal tdd_config_s %d (should be 0-%d)!",
RC.config_file_name, i, ccparams_lte.tdd_config_s, LTE_TDD_Config__specialSubframePatterns_ssp8);
if (!ccparams_lte.prefix_type)
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u define %s: NORMAL,EXTENDED!\n",
RC.config_file_name, i, ENB_CONFIG_STRING_PREFIX_TYPE);
else if (strcmp(ccparams_lte.prefix_type, "NORMAL") == 0) {
RRCcfg->prefix_type[j] = NORMAL;
} else if (strcmp(ccparams_lte.prefix_type, "EXTENDED") == 0) {
RRCcfg->prefix_type[j] = EXTENDED;
} else {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for prefix_type choice: NORMAL or EXTENDED !\n",
RC.config_file_name, i, ccparams_lte.prefix_type);
}
if (!ccparams_lte.pbch_repetition)
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u define %s: TRUE,FALSE!\n",
RC.config_file_name, i, ENB_CONFIG_STRING_PBCH_REPETITION);
else if (strcmp(ccparams_lte.pbch_repetition, "TRUE") == 0) {
RRCcfg->pbch_repetition[j] = 1;
} else if (strcmp(ccparams_lte.pbch_repetition, "FALSE") == 0) {
RRCcfg->pbch_repetition[j] = 0;
} else {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pbch_repetition choice: TRUE or FALSE !\n",
RC.config_file_name, i, ccparams_lte.pbch_repetition);
}
RRCcfg->eutra_band[j] = ccparams_lte.eutra_band;
RRCcfg->downlink_frequency[j] = (uint32_t)ccparams_lte.downlink_frequency;
RRCcfg->uplink_frequency_offset[j] = (unsigned int)ccparams_lte.uplink_frequency_offset;
RRCcfg->Nid_cell[j] = ccparams_lte.Nid_cell;
if (ccparams_lte.Nid_cell>503) {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for Nid_cell choice: 0...503 !\n",
RC.config_file_name, i, ccparams_lte.Nid_cell);
}
RRCcfg->N_RB_DL[j] = ccparams_lte.N_RB_DL;
if ((ccparams_lte.N_RB_DL!=6) &&
(ccparams_lte.N_RB_DL!=15) &&
(ccparams_lte.N_RB_DL!=25) &&
(ccparams_lte.N_RB_DL!=50) &&
(ccparams_lte.N_RB_DL!=75) &&
(ccparams_lte.N_RB_DL!=100)) {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for N_RB_DL choice: 6,15,25,50,75,100 !\n",
RC.config_file_name, i, ccparams_lte.N_RB_DL);
}
if (strcmp(ccparams_lte.frame_type, "FDD") == 0) {
RRCcfg->frame_type[j] = FDD;
} else if (strcmp(ccparams_lte.frame_type, "TDD") == 0) {
RRCcfg->frame_type[j] = TDD;
} else {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for frame_type choice: FDD or TDD !\n",
RC.config_file_name, i, ccparams_lte.frame_type);
}
if (config_check_band_frequencies(j, RRCcfg->eutra_band[j], RRCcfg->downlink_frequency[j], RRCcfg->uplink_frequency_offset[j], RRCcfg->frame_type[j])) {
AssertFatal(0, "error calling enb_check_band_frequencies\n");
}
if ((ccparams_lte.nb_antenna_ports <1) || (ccparams_lte.nb_antenna_ports > 2))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for nb_antenna_ports choice: 1..2 !\n",
RC.config_file_name, i, ccparams_lte.nb_antenna_ports);
RRCcfg->nb_antenna_ports[j] = ccparams_lte.nb_antenna_ports;
// Radio Resource Configuration (SIB2)
RRCcfg->radioresourceconfig[j].prach_root = ccparams_lte.prach_root;
if ((ccparams_lte.prach_root <0) || (ccparams_lte.prach_root > 1023))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for prach_root choice: 0..1023 !\n",
RC.config_file_name, i, ccparams_lte.prach_root);
RRCcfg->radioresourceconfig[j].prach_config_index = ccparams_lte.prach_config_index;
if ((ccparams_lte.prach_config_index <0) || (ccparams_lte.prach_config_index > 63))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for prach_config_index choice: 0..1023 !\n",
RC.config_file_name, i, ccparams_lte.prach_config_index);
if (!ccparams_lte.prach_high_speed)
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u define %s: ENABLE,DISABLE!\n",
RC.config_file_name, i, ENB_CONFIG_STRING_PRACH_HIGH_SPEED);
else if (strcmp(ccparams_lte.prach_high_speed, "ENABLE") == 0) {
RRCcfg->radioresourceconfig[j].prach_high_speed = true;
} else if (strcmp(ccparams_lte.prach_high_speed, "DISABLE") == 0) {
RRCcfg->radioresourceconfig[j].prach_high_speed = false;
} else
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for prach_config choice: ENABLE,DISABLE !\n",
RC.config_file_name, i, ccparams_lte.prach_high_speed);
RRCcfg->radioresourceconfig[j].prach_zero_correlation = ccparams_lte.prach_zero_correlation;
if ((ccparams_lte.prach_zero_correlation <0) ||
(ccparams_lte.prach_zero_correlation > 15))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for prach_zero_correlation choice: 0..15!\n",
RC.config_file_name, i, ccparams_lte.prach_zero_correlation);
RRCcfg->radioresourceconfig[j].prach_freq_offset = ccparams_lte.prach_freq_offset;
if ((ccparams_lte.prach_freq_offset <0) ||
(ccparams_lte.prach_freq_offset > 94))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for prach_freq_offset choice: 0..94!\n",
RC.config_file_name, i, ccparams_lte.prach_freq_offset);
RRCcfg->radioresourceconfig[j].pucch_delta_shift = ccparams_lte.pucch_delta_shift - 1;
if ((ccparams_lte.pucch_delta_shift <1) ||
(ccparams_lte.pucch_delta_shift > 3))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for pucch_delta_shift choice: 1..3!\n",
RC.config_file_name, i, ccparams_lte.pucch_delta_shift);
RRCcfg->radioresourceconfig[j].pucch_nRB_CQI = ccparams_lte.pucch_nRB_CQI;
if ((ccparams_lte.pucch_nRB_CQI <0) ||
(ccparams_lte.pucch_nRB_CQI > 98))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for pucch_nRB_CQI choice: 0..98!\n",
RC.config_file_name, i, ccparams_lte.pucch_nRB_CQI);
RRCcfg->radioresourceconfig[j].pucch_nCS_AN = ccparams_lte.pucch_nCS_AN;
if ((ccparams_lte.pucch_nCS_AN <0) ||
(ccparams_lte.pucch_nCS_AN > 7))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for pucch_nCS_AN choice: 0..7!\n",
RC.config_file_name, i, ccparams_lte.pucch_nCS_AN);
RRCcfg->radioresourceconfig[j].pucch_n1_AN = ccparams_lte.pucch_n1_AN;
if ((ccparams_lte.pucch_n1_AN <0) ||
(ccparams_lte.pucch_n1_AN > 2047))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for pucch_n1_AN choice: 0..2047!\n",
RC.config_file_name, i, ccparams_lte.pucch_n1_AN);
RRCcfg->radioresourceconfig[j].pdsch_referenceSignalPower = ccparams_lte.pdsch_referenceSignalPower;
if ((ccparams_lte.pdsch_referenceSignalPower <-60) ||
(ccparams_lte.pdsch_referenceSignalPower > 50))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for pdsch_referenceSignalPower choice:-60..50!\n",
RC.config_file_name, i, ccparams_lte.pdsch_referenceSignalPower);
RRCcfg->radioresourceconfig[j].pdsch_p_b = ccparams_lte.pdsch_p_b;
if ((ccparams_lte.pdsch_p_b <0) ||
(ccparams_lte.pdsch_p_b > 3))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for pdsch_p_b choice: 0..3!\n",
RC.config_file_name, i, ccparams_lte.pdsch_p_b);
RRCcfg->radioresourceconfig[j].pusch_n_SB = ccparams_lte.pusch_n_SB;
if ((ccparams_lte.pusch_n_SB <1) ||
(ccparams_lte.pusch_n_SB > 4))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for pusch_n_SB choice: 1..4!\n",
RC.config_file_name, i, ccparams_lte.pusch_n_SB);
if (!ccparams_lte.pusch_hoppingMode)
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u define %s: interSubframe,intraAndInterSubframe!\n",
RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_HOPPINGMODE);
else if (strcmp(ccparams_lte.pusch_hoppingMode,"interSubFrame")==0) {
RRCcfg->radioresourceconfig[j].pusch_hoppingMode = LTE_PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_interSubFrame;
} else if (strcmp(ccparams_lte.pusch_hoppingMode,"intraAndInterSubFrame")==0) {
RRCcfg->radioresourceconfig[j].pusch_hoppingMode = LTE_PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_intraAndInterSubFrame;
} else
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pusch_hoppingMode choice: interSubframe,intraAndInterSubframe!\n",
RC.config_file_name, i, ccparams_lte.pusch_hoppingMode);
RRCcfg->radioresourceconfig[j].pusch_hoppingOffset = ccparams_lte.pusch_hoppingOffset;
if ((ccparams_lte.pusch_hoppingOffset<0) ||
(ccparams_lte.pusch_hoppingOffset>98))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pusch_hoppingOffset choice: 0..98!\n",
RC.config_file_name, i, ccparams_lte.pusch_hoppingMode);
if (!ccparams_lte.pusch_enable64QAM)
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u define %s: ENABLE,DISABLE!\n",
RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_ENABLE64QAM);
else if (strcmp(ccparams_lte.pusch_enable64QAM, "ENABLE") == 0) {
RRCcfg->radioresourceconfig[j].pusch_enable64QAM = true;
} else if (strcmp(ccparams_lte.pusch_enable64QAM, "DISABLE") == 0) {
RRCcfg->radioresourceconfig[j].pusch_enable64QAM = false;
} else
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pusch_enable64QAM choice: ENABLE,DISABLE!\n",
RC.config_file_name, i, ccparams_lte.pusch_enable64QAM);
if (!ccparams_lte.pusch_groupHoppingEnabled)
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u define %s: ENABLE,DISABLE!\n",
RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_GROUP_HOPPING_EN);
else if (strcmp(ccparams_lte.pusch_groupHoppingEnabled, "ENABLE") == 0) {
RRCcfg->radioresourceconfig[j].pusch_groupHoppingEnabled = true;
} else if (strcmp(ccparams_lte.pusch_groupHoppingEnabled, "DISABLE") == 0) {
RRCcfg->radioresourceconfig[j].pusch_groupHoppingEnabled = false;
} else
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pusch_groupHoppingEnabled choice: ENABLE,DISABLE!\n",
RC.config_file_name, i, ccparams_lte.pusch_groupHoppingEnabled);
RRCcfg->radioresourceconfig[j].pusch_groupAssignment = ccparams_lte.pusch_groupAssignment;
if ((ccparams_lte.pusch_groupAssignment<0)||
(ccparams_lte.pusch_groupAssignment>29))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for pusch_groupAssignment choice: 0..29!\n",
RC.config_file_name, i, ccparams_lte.pusch_groupAssignment);
if (!ccparams_lte.pusch_sequenceHoppingEnabled)
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u define %s: ENABLE,DISABLE!\n",
RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_SEQUENCE_HOPPING_EN);
else if (strcmp(ccparams_lte.pusch_sequenceHoppingEnabled, "ENABLE") == 0) {
RRCcfg->radioresourceconfig[j].pusch_sequenceHoppingEnabled = true;
} else if (strcmp(ccparams_lte.pusch_sequenceHoppingEnabled, "DISABLE") == 0) {
RRCcfg->radioresourceconfig[j].pusch_sequenceHoppingEnabled = false;
} else
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pusch_sequenceHoppingEnabled choice: ENABLE,DISABLE!\n",
RC.config_file_name, i, ccparams_lte.pusch_sequenceHoppingEnabled);
RRCcfg->radioresourceconfig[j].pusch_nDMRS1 = ccparams_lte.pusch_nDMRS1; // cyclic_shift in RRC!
if ((ccparams_lte.pusch_nDMRS1 <0) ||
(ccparams_lte.pusch_nDMRS1>7))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for pusch_nDMRS1 choice: 0..7!\n",
RC.config_file_name, i, ccparams_lte.pusch_nDMRS1);
if (strcmp(ccparams_lte.phich_duration,"NORMAL")==0) {
RRCcfg->radioresourceconfig[j].phich_duration = LTE_PHICH_Config__phich_Duration_normal;
} else if (strcmp(ccparams_lte.phich_duration,"EXTENDED")==0) {
RRCcfg->radioresourceconfig[j].phich_duration = LTE_PHICH_Config__phich_Duration_extended;
} else
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for phich_duration choice: NORMAL,EXTENDED!\n",
RC.config_file_name, i, ccparams_lte.phich_duration);
if (strcmp(ccparams_lte.phich_resource,"ONESIXTH")==0) {
RRCcfg->radioresourceconfig[j].phich_resource = LTE_PHICH_Config__phich_Resource_oneSixth;
} else if (strcmp(ccparams_lte.phich_resource,"HALF")==0) {
RRCcfg->radioresourceconfig[j].phich_resource = LTE_PHICH_Config__phich_Resource_half;
} else if (strcmp(ccparams_lte.phich_resource,"ONE")==0) {
RRCcfg->radioresourceconfig[j].phich_resource = LTE_PHICH_Config__phich_Resource_one;
} else if (strcmp(ccparams_lte.phich_resource,"TWO")==0) {
RRCcfg->radioresourceconfig[j].phich_resource = LTE_PHICH_Config__phich_Resource_two;
} else
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for phich_resource choice: ONESIXTH,HALF,ONE,TWO!\n",
RC.config_file_name, i, ccparams_lte.phich_resource);
printf("phich.resource %ld (%s), phich.duration %ld (%s)\n",
RRCcfg->radioresourceconfig[j].phich_resource,
ccparams_lte.phich_resource,
RRCcfg->radioresourceconfig[j].phich_duration,
ccparams_lte.phich_duration);
if (strcmp(ccparams_lte.srs_enable, "ENABLE") == 0) {
RRCcfg->radioresourceconfig[j].srs_enable = true;
} else if (strcmp(ccparams_lte.srs_enable, "DISABLE") == 0) {
RRCcfg->radioresourceconfig[j].srs_enable = false;
} else
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n",
RC.config_file_name, i, ccparams_lte.srs_enable);
if (RRCcfg->radioresourceconfig[j].srs_enable == true) {
RRCcfg->radioresourceconfig[j].srs_BandwidthConfig = ccparams_lte.srs_BandwidthConfig;
if ((ccparams_lte.srs_BandwidthConfig < 0) ||
(ccparams_lte.srs_BandwidthConfig >7))
AssertFatal (0, "Failed to parse eNB configuration file %s, enb %u unknown value %d for srs_BandwidthConfig choice: 0...7\n",
RC.config_file_name, i, ccparams_lte.srs_BandwidthConfig);
RRCcfg->radioresourceconfig[j].srs_SubframeConfig = ccparams_lte.srs_SubframeConfig;
if ((ccparams_lte.srs_SubframeConfig<0) ||
(ccparams_lte.srs_SubframeConfig>15))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for srs_SubframeConfig choice: 0..15 !\n",
RC.config_file_name, i, ccparams_lte.srs_SubframeConfig);
if (strcmp(ccparams_lte.srs_ackNackST, "ENABLE") == 0) {
RRCcfg->radioresourceconfig[j].srs_ackNackST = true;
} else if (strcmp(ccparams_lte.srs_ackNackST, "DISABLE") == 0) {
RRCcfg->radioresourceconfig[j].srs_ackNackST = false;
} else
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n",
RC.config_file_name, i, ccparams_lte.srs_ackNackST);
if (strcmp(ccparams_lte.srs_MaxUpPts, "ENABLE") == 0) {
RRCcfg->radioresourceconfig[j].srs_MaxUpPts = true;
} else if (strcmp(ccparams_lte.srs_MaxUpPts, "DISABLE") == 0) {
RRCcfg->radioresourceconfig[j].srs_MaxUpPts = false;
} else
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for srs_MaxUpPts choice: ENABLE,DISABLE !\n",
RC.config_file_name, i, ccparams_lte.srs_MaxUpPts);
}
RRCcfg->radioresourceconfig[j].pusch_p0_Nominal = ccparams_lte.pusch_p0_Nominal;
if ((ccparams_lte.pusch_p0_Nominal<-126) ||
(ccparams_lte.pusch_p0_Nominal>24))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for pusch_p0_Nominal choice: -126..24 !\n",
RC.config_file_name, i, ccparams_lte.pusch_p0_Nominal);
if (strcmp(ccparams_lte.pusch_alpha,"AL0")==0) {
RRCcfg->radioresourceconfig[j].pusch_alpha = LTE_Alpha_r12_al0;
} else if (strcmp(ccparams_lte.pusch_alpha,"AL04")==0) {
RRCcfg->radioresourceconfig[j].pusch_alpha = LTE_Alpha_r12_al04;
} else if (strcmp(ccparams_lte.pusch_alpha,"AL05")==0) {
RRCcfg->radioresourceconfig[j].pusch_alpha = LTE_Alpha_r12_al05;
} else if (strcmp(ccparams_lte.pusch_alpha,"AL06")==0) {
RRCcfg->radioresourceconfig[j].pusch_alpha = LTE_Alpha_r12_al06;
} else if (strcmp(ccparams_lte.pusch_alpha,"AL07")==0) {
RRCcfg->radioresourceconfig[j].pusch_alpha = LTE_Alpha_r12_al07;
} else if (strcmp(ccparams_lte.pusch_alpha,"AL08")==0) {
RRCcfg->radioresourceconfig[j].pusch_alpha = LTE_Alpha_r12_al08;
} else if (strcmp(ccparams_lte.pusch_alpha,"AL09")==0) {
RRCcfg->radioresourceconfig[j].pusch_alpha = LTE_Alpha_r12_al09;
} else if (strcmp(ccparams_lte.pusch_alpha,"AL1")==0) {
RRCcfg->radioresourceconfig[j].pusch_alpha = LTE_Alpha_r12_al1;
} else
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pucch_Alpha choice: AL0,AL04,AL05,AL06,AL07,AL08,AL09,AL1!\n",
RC.config_file_name, i, ccparams_lte.pusch_alpha);
RRCcfg->radioresourceconfig[j].pucch_p0_Nominal = ccparams_lte.pucch_p0_Nominal;
if ((ccparams_lte.pucch_p0_Nominal<-127) ||
(ccparams_lte.pucch_p0_Nominal>-96))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for pucch_p0_Nominal choice: -127..-96 !\n",
RC.config_file_name, i, ccparams_lte.pucch_p0_Nominal);
RRCcfg->radioresourceconfig[j].msg3_delta_Preamble = ccparams_lte.msg3_delta_Preamble;
if ((ccparams_lte.msg3_delta_Preamble<-1) ||
(ccparams_lte.msg3_delta_Preamble>6))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for msg3_delta_Preamble choice: -1..6 !\n",
RC.config_file_name, i, ccparams_lte.msg3_delta_Preamble);
if (strcmp(ccparams_lte.pucch_deltaF_Format1,"deltaF_2")==0) {
RRCcfg->radioresourceconfig[j].pucch_deltaF_Format1 = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF_2;
} else if (strcmp(ccparams_lte.pucch_deltaF_Format1,"deltaF0")==0) {
RRCcfg->radioresourceconfig[j].pucch_deltaF_Format1 = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF0;
} else if (strcmp(ccparams_lte.pucch_deltaF_Format1,"deltaF2")==0) {
RRCcfg->radioresourceconfig[j].pucch_deltaF_Format1 = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF2;
} else
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pucch_deltaF_Format1 choice: deltaF_2,dltaF0,deltaF2!\n",
RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format1);
if (strcmp(ccparams_lte.pucch_deltaF_Format1b,"deltaF1")==0) {
RRCcfg->radioresourceconfig[j].pucch_deltaF_Format1b = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF1;
} else if (strcmp(ccparams_lte.pucch_deltaF_Format1b,"deltaF3")==0) {
RRCcfg->radioresourceconfig[j].pucch_deltaF_Format1b = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF3;
} else if (strcmp(ccparams_lte.pucch_deltaF_Format1b,"deltaF5")==0) {
RRCcfg->radioresourceconfig[j].pucch_deltaF_Format1b = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF5;
} else
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pucch_deltaF_Format1b choice: deltaF1,dltaF3,deltaF5!\n",
RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format1b);
if (strcmp(ccparams_lte.pucch_deltaF_Format2,"deltaF_2")==0) {
RRCcfg->radioresourceconfig[j].pucch_deltaF_Format2 = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF_2;
} else if (strcmp(ccparams_lte.pucch_deltaF_Format2,"deltaF0")==0) {
RRCcfg->radioresourceconfig[j].pucch_deltaF_Format2 = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF0;
} else if (strcmp(ccparams_lte.pucch_deltaF_Format2,"deltaF1")==0) {
RRCcfg->radioresourceconfig[j].pucch_deltaF_Format2 = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF1;
} else if (strcmp(ccparams_lte.pucch_deltaF_Format2,"deltaF2")==0) {
RRCcfg->radioresourceconfig[j].pucch_deltaF_Format2 = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF2;
} else
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pucch_deltaF_Format2 choice: deltaF_2,dltaF0,deltaF1,deltaF2!\n",
RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format2);
if (strcmp(ccparams_lte.pucch_deltaF_Format2a,"deltaF_2")==0) {
RRCcfg->radioresourceconfig[j].pucch_deltaF_Format2a = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF_2;
} else if (strcmp(ccparams_lte.pucch_deltaF_Format2a,"deltaF0")==0) {
RRCcfg->radioresourceconfig[j].pucch_deltaF_Format2a = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF0;
} else if (strcmp(ccparams_lte.pucch_deltaF_Format2a,"deltaF2")==0) {
RRCcfg->radioresourceconfig[j].pucch_deltaF_Format2a = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF2;
} else
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pucch_deltaF_Format2a choice: deltaF_2,dltaF0,deltaF2!\n",
RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format2a);
if (strcmp(ccparams_lte.pucch_deltaF_Format2b,"deltaF_2")==0) {
RRCcfg->radioresourceconfig[j].pucch_deltaF_Format2b = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF_2;
} else if (strcmp(ccparams_lte.pucch_deltaF_Format2b,"deltaF0")==0) {
RRCcfg->radioresourceconfig[j].pucch_deltaF_Format2b = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF0;
} else if (strcmp(ccparams_lte.pucch_deltaF_Format2b,"deltaF2")==0) {
RRCcfg->radioresourceconfig[j].pucch_deltaF_Format2b = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF2;
} else
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pucch_deltaF_Format2b choice: deltaF_2,dltaF0,deltaF2!\n",
RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format2b);
RRCcfg->radioresourceconfig[j].rach_numberOfRA_Preambles = (ccparams_lte.rach_numberOfRA_Preambles / 4) - 1;
if ((ccparams_lte.rach_numberOfRA_Preambles <4) ||
(ccparams_lte.rach_numberOfRA_Preambles>64) ||
((ccparams_lte.rach_numberOfRA_Preambles&3)!=0))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for rach_numberOfRA_Preambles choice: 4,8,12,...,64!\n",
RC.config_file_name, i, ccparams_lte.rach_numberOfRA_Preambles);
if (strcmp(ccparams_lte.rach_preamblesGroupAConfig, "ENABLE") == 0) {
RRCcfg->radioresourceconfig[j].rach_preamblesGroupAConfig = true;
RRCcfg->radioresourceconfig[j].rach_sizeOfRA_PreamblesGroupA = (ccparams_lte.rach_sizeOfRA_PreamblesGroupA / 4) - 1;
if ((ccparams_lte.rach_numberOfRA_Preambles <4) ||
(ccparams_lte.rach_numberOfRA_Preambles>60) ||
((ccparams_lte.rach_numberOfRA_Preambles&3)!=0))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for rach_sizeOfRA_PreamblesGroupA choice: 4,8,12,...,60!\n",
RC.config_file_name, i, ccparams_lte.rach_sizeOfRA_PreamblesGroupA);
switch (ccparams_lte.rach_messageSizeGroupA) {
case 56:
RRCcfg->radioresourceconfig[j].rach_messageSizeGroupA = LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b56;
break;
case 144:
RRCcfg->radioresourceconfig[j].rach_messageSizeGroupA = LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b144;
break;
case 208:
RRCcfg->radioresourceconfig[j].rach_messageSizeGroupA = LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b208;
break;
case 256:
RRCcfg->radioresourceconfig[j].rach_messageSizeGroupA = LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b256;
break;
default:
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for rach_messageSizeGroupA choice: 56,144,208,256!\n",
RC.config_file_name, i, ccparams_lte.rach_messageSizeGroupA);
break;
}
if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"minusinfinity")==0) {
RRCcfg->radioresourceconfig[j].rach_messagePowerOffsetGroupB = LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_minusinfinity;
} else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB0")==0) {
RRCcfg->radioresourceconfig[j].rach_messagePowerOffsetGroupB = LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB0;
} else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB5")==0) {
RRCcfg->radioresourceconfig[j].rach_messagePowerOffsetGroupB = LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB5;
} else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB8")==0) {
RRCcfg->radioresourceconfig[j].rach_messagePowerOffsetGroupB = LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB8;
} else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB10")==0) {
RRCcfg->radioresourceconfig[j].rach_messagePowerOffsetGroupB = LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB10;
} else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB12")==0) {
RRCcfg->radioresourceconfig[j].rach_messagePowerOffsetGroupB = LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB12;
} else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB15")==0) {
RRCcfg->radioresourceconfig[j].rach_messagePowerOffsetGroupB = LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB15;
} else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB18")==0) {
RRCcfg->radioresourceconfig[j].rach_messagePowerOffsetGroupB = LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB18;
} else
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for rach_messagePowerOffsetGroupB choice: minusinfinity,dB0,dB5,dB8,dB10,dB12,dB15,dB18!\n",
RC.config_file_name, i, ccparams_lte.rach_messagePowerOffsetGroupB);
} else if (strcmp(ccparams_lte.rach_preamblesGroupAConfig, "DISABLE") == 0) {
RRCcfg->radioresourceconfig[j].rach_preamblesGroupAConfig = false;
} else
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for rach_preamblesGroupAConfig choice: ENABLE,DISABLE !\n",
RC.config_file_name, i, ccparams_lte.rach_preamblesGroupAConfig);
RRCcfg->radioresourceconfig[j].rach_preambleInitialReceivedTargetPower = (ccparams_lte.rach_preambleInitialReceivedTargetPower + 120) / 2;
if ((ccparams_lte.rach_preambleInitialReceivedTargetPower<-120) ||
(ccparams_lte.rach_preambleInitialReceivedTargetPower>-90) ||
((ccparams_lte.rach_preambleInitialReceivedTargetPower&1)!=0))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for rach_preambleInitialReceivedTargetPower choice: -120,-118,...,-90 !\n",
RC.config_file_name, i, ccparams_lte.rach_preambleInitialReceivedTargetPower);
RRCcfg->radioresourceconfig[j].rach_powerRampingStep = ccparams_lte.rach_powerRampingStep / 2;
if ((ccparams_lte.rach_powerRampingStep<0) ||
(ccparams_lte.rach_powerRampingStep>6) ||
((ccparams_lte.rach_powerRampingStep&1)!=0))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for rach_powerRampingStep choice: 0,2,4,6 !\n",
RC.config_file_name, i, ccparams_lte.rach_powerRampingStep);
switch (ccparams_lte.rach_preambleTransMax) {
case 3:
RRCcfg->radioresourceconfig[j].rach_preambleTransMax = LTE_PreambleTransMax_n3;
break;
case 4:
RRCcfg->radioresourceconfig[j].rach_preambleTransMax = LTE_PreambleTransMax_n4;
break;
case 5:
RRCcfg->radioresourceconfig[j].rach_preambleTransMax = LTE_PreambleTransMax_n5;
break;
case 6:
RRCcfg->radioresourceconfig[j].rach_preambleTransMax = LTE_PreambleTransMax_n6;
break;
case 7:
RRCcfg->radioresourceconfig[j].rach_preambleTransMax = LTE_PreambleTransMax_n7;
break;
case 8:
RRCcfg->radioresourceconfig[j].rach_preambleTransMax = LTE_PreambleTransMax_n8;
break;
case 10:
RRCcfg->radioresourceconfig[j].rach_preambleTransMax = LTE_PreambleTransMax_n10;
break;
case 20:
RRCcfg->radioresourceconfig[j].rach_preambleTransMax = LTE_PreambleTransMax_n20;
break;
case 50:
RRCcfg->radioresourceconfig[j].rach_preambleTransMax = LTE_PreambleTransMax_n50;
break;
case 100:
RRCcfg->radioresourceconfig[j].rach_preambleTransMax = LTE_PreambleTransMax_n100;
break;
case 200:
RRCcfg->radioresourceconfig[j].rach_preambleTransMax = LTE_PreambleTransMax_n200;
break;
default:
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for rach_preambleTransMax choice: 3,4,5,6,7,8,10,20,50,100,200!\n",
RC.config_file_name, i, ccparams_lte.rach_preambleTransMax);
break;
}
RRCcfg->radioresourceconfig[j].rach_raResponseWindowSize = (ccparams_lte.rach_raResponseWindowSize == 10) ? 7 : ccparams_lte.rach_raResponseWindowSize - 2;
if ((ccparams_lte.rach_raResponseWindowSize<0)||
(ccparams_lte.rach_raResponseWindowSize==9)||
(ccparams_lte.rach_raResponseWindowSize>10))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for rach_raResponseWindowSize choice: 2,3,4,5,6,7,8,10!\n",
RC.config_file_name, i, ccparams_lte.rach_preambleTransMax);
RRCcfg->radioresourceconfig[j].rach_macContentionResolutionTimer = (ccparams_lte.rach_macContentionResolutionTimer / 8) - 1;
if ((ccparams_lte.rach_macContentionResolutionTimer<8) ||
(ccparams_lte.rach_macContentionResolutionTimer>64) ||
((ccparams_lte.rach_macContentionResolutionTimer&7)!=0))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for rach_macContentionResolutionTimer choice: 8,16,...,56,64!\n",
RC.config_file_name, i, ccparams_lte.rach_preambleTransMax);
RRCcfg->radioresourceconfig[j].rach_maxHARQ_Msg3Tx = ccparams_lte.rach_maxHARQ_Msg3Tx;
if ((ccparams_lte.rach_maxHARQ_Msg3Tx<0) ||
(ccparams_lte.rach_maxHARQ_Msg3Tx>8))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for rach_maxHARQ_Msg3Tx choice: 1..8!\n",
RC.config_file_name, i, ccparams_lte.rach_preambleTransMax);
switch (ccparams_lte.pcch_defaultPagingCycle) {
case 32:
RRCcfg->radioresourceconfig[j].pcch_defaultPagingCycle = LTE_PCCH_Config__defaultPagingCycle_rf32;
break;
case 64:
RRCcfg->radioresourceconfig[j].pcch_defaultPagingCycle = LTE_PCCH_Config__defaultPagingCycle_rf64;
break;
case 128:
RRCcfg->radioresourceconfig[j].pcch_defaultPagingCycle = LTE_PCCH_Config__defaultPagingCycle_rf128;
break;
case 256:
RRCcfg->radioresourceconfig[j].pcch_defaultPagingCycle = LTE_PCCH_Config__defaultPagingCycle_rf256;
break;
default:
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for pcch_defaultPagingCycle choice: 32,64,128,256!\n",
RC.config_file_name, i, ccparams_lte.pcch_defaultPagingCycle);
break;
}
if (strcmp(ccparams_lte.pcch_nB, "fourT") == 0) {
RRCcfg->radioresourceconfig[j].pcch_nB = LTE_PCCH_Config__nB_fourT;
} else if (strcmp(ccparams_lte.pcch_nB, "twoT") == 0) {
RRCcfg->radioresourceconfig[j].pcch_nB = LTE_PCCH_Config__nB_twoT;
} else if (strcmp(ccparams_lte.pcch_nB, "oneT") == 0) {
RRCcfg->radioresourceconfig[j].pcch_nB = LTE_PCCH_Config__nB_oneT;
} else if (strcmp(ccparams_lte.pcch_nB, "halfT") == 0) {
RRCcfg->radioresourceconfig[j].pcch_nB = LTE_PCCH_Config__nB_halfT;
} else if (strcmp(ccparams_lte.pcch_nB, "quarterT") == 0) {
RRCcfg->radioresourceconfig[j].pcch_nB = LTE_PCCH_Config__nB_quarterT;
} else if (strcmp(ccparams_lte.pcch_nB, "oneEighthT") == 0) {
RRCcfg->radioresourceconfig[j].pcch_nB = LTE_PCCH_Config__nB_oneEighthT;
} else if (strcmp(ccparams_lte.pcch_nB, "oneSixteenthT") == 0) {
RRCcfg->radioresourceconfig[j].pcch_nB = LTE_PCCH_Config__nB_oneSixteenthT;
} else if (strcmp(ccparams_lte.pcch_nB, "oneThirtySecondT") == 0) {
RRCcfg->radioresourceconfig[j].pcch_nB = LTE_PCCH_Config__nB_oneThirtySecondT;
} else {
AssertFatal (0, "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pcch_nB choice: fourT,twoT,oneT,halfT,quarterT,oneighthT,oneSixteenthT,oneThirtySecondT !\n",
RC.config_file_name,
i,
ccparams_lte.pcch_nB);
}
if (strcmp(ccparams_lte.drx_Config_present, "prNothing") == 0) {
RRCcfg->radioresourceconfig[j].drx_Config_present = LTE_DRX_Config_PR_NOTHING;
} else if (strcmp(ccparams_lte.drx_Config_present, "prRelease") == 0) {
RRCcfg->radioresourceconfig[j].drx_Config_present = LTE_DRX_Config_PR_release;
} else if (strcmp(ccparams_lte.drx_Config_present, "prSetup") == 0) {
RRCcfg->radioresourceconfig[j].drx_Config_present = LTE_DRX_Config_PR_setup;
} else {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for drx_Config_present choice: prNothing, prRelease, prSetup!\n",
RC.config_file_name, i, ccparams_lte.drx_Config_present);
}
if (strcmp(ccparams_lte.drx_onDurationTimer, "psf1") == 0) {
RRCcfg->radioresourceconfig[j].drx_onDurationTimer = (long)LTE_DRX_Config__setup__onDurationTimer_psf1;
} else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf2") == 0) {
RRCcfg->radioresourceconfig[j].drx_onDurationTimer = (long)LTE_DRX_Config__setup__onDurationTimer_psf2;
} else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf3") == 0) {
RRCcfg->radioresourceconfig[j].drx_onDurationTimer = (long)LTE_DRX_Config__setup__onDurationTimer_psf3;
} else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf4") == 0) {
RRCcfg->radioresourceconfig[j].drx_onDurationTimer = (long)LTE_DRX_Config__setup__onDurationTimer_psf4;
} else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf5") == 0) {
RRCcfg->radioresourceconfig[j].drx_onDurationTimer = (long)LTE_DRX_Config__setup__onDurationTimer_psf5;
} else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf6") == 0) {
RRCcfg->radioresourceconfig[j].drx_onDurationTimer = (long)LTE_DRX_Config__setup__onDurationTimer_psf6;
} else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf8") == 0) {
RRCcfg->radioresourceconfig[j].drx_onDurationTimer = (long)LTE_DRX_Config__setup__onDurationTimer_psf8;
} else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf10") == 0) {
RRCcfg->radioresourceconfig[j].drx_onDurationTimer = (long)LTE_DRX_Config__setup__onDurationTimer_psf10;
} else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf20") == 0) {
RRCcfg->radioresourceconfig[j].drx_onDurationTimer = (long)LTE_DRX_Config__setup__onDurationTimer_psf20;
} else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf30") == 0) {
RRCcfg->radioresourceconfig[j].drx_onDurationTimer = (long)LTE_DRX_Config__setup__onDurationTimer_psf30;
} else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf40") == 0) {
RRCcfg->radioresourceconfig[j].drx_onDurationTimer = (long)LTE_DRX_Config__setup__onDurationTimer_psf40;
} else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf50") == 0) {
RRCcfg->radioresourceconfig[j].drx_onDurationTimer = (long)LTE_DRX_Config__setup__onDurationTimer_psf50;
} else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf60") == 0) {
RRCcfg->radioresourceconfig[j].drx_onDurationTimer = (long)LTE_DRX_Config__setup__onDurationTimer_psf60;
} else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf80") == 0) {
RRCcfg->radioresourceconfig[j].drx_onDurationTimer = (long)LTE_DRX_Config__setup__onDurationTimer_psf80;
} else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf100") == 0) {
RRCcfg->radioresourceconfig[j].drx_onDurationTimer = (long)LTE_DRX_Config__setup__onDurationTimer_psf100;
} else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf200") == 0) {
RRCcfg->radioresourceconfig[j].drx_onDurationTimer = (long)LTE_DRX_Config__setup__onDurationTimer_psf200;
} else {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for drx_onDurationTimer choice !\n",
RC.config_file_name, i, ccparams_lte.drx_onDurationTimer);
break;
}
if (strcmp(ccparams_lte.drx_InactivityTimer, "psf1") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_psf1;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf2") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_psf2;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf3") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_psf3;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf4") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_psf4;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf5") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_psf5;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf6") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_psf6;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf8") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_psf8;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf10") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_psf10;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf20") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_psf20;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf30") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_psf30;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf40") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_psf40;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf50") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_psf50;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf60") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_psf60;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf80") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_psf80;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf100") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_psf100;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf200") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_psf200;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf300") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_psf300;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf500") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_psf500;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf750") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_psf750;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf1280") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_psf1280;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf1920") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_psf1920;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf2560") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_psf2560;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf0-v1020") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_psf0_v1020;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare9") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_spare9;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare8") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_spare8;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare7") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_spare7;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare6") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_spare6;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare5") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_spare5;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare4") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_spare4;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare3") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_spare3;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare2") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_spare2;
} else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare1") == 0) {
RRCcfg->radioresourceconfig[j].drx_InactivityTimer = (long)LTE_DRX_Config__setup__drx_InactivityTimer_spare1;
} else {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for drx_InactivityTimer choice !\n",
RC.config_file_name, i, ccparams_lte.drx_InactivityTimer);
break;
}
RRCcfg->radioresourceconfig[j].ue_multiple_max = ccparams_lte.ue_multiple_max;
if (!ccparams_lte.mbms_dedicated_serving_cell)
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u define %s: TRUE,FALSE!\n",
RC.config_file_name, i, ENB_CONFIG_STRING_MBMS_DEDICATED_SERVING_CELL);
else if (strcmp(ccparams_lte.mbms_dedicated_serving_cell, "ENABLE") == 0) {
RRCcfg->radioresourceconfig[j].mbms_dedicated_serving_cell = true;
} else if (strcmp(ccparams_lte.mbms_dedicated_serving_cell, "DISABLE") == 0) {
RRCcfg->radioresourceconfig[j].mbms_dedicated_serving_cell = false;
} else {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for mbms_dedicated_serving_cell choice: TRUE or FALSE !\n",
RC.config_file_name, i, ccparams_lte.mbms_dedicated_serving_cell);
}
switch (ccparams_lte.N_RB_DL) {
case 25:
if ((ccparams_lte.ue_multiple_max < 1) ||
(ccparams_lte.ue_multiple_max > 4))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for ue_multiple_max choice: 1..4!\n",
RC.config_file_name, i, ccparams_lte.ue_multiple_max);
break;
case 50:
if ((ccparams_lte.ue_multiple_max < 1) ||
(ccparams_lte.ue_multiple_max > 8))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for ue_multiple_max choice: 1..8!\n",
RC.config_file_name, i, ccparams_lte.ue_multiple_max);
break;
case 100:
if ((ccparams_lte.ue_multiple_max < 1) ||
(ccparams_lte.ue_multiple_max > 16))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for ue_multiple_max choice: 1..16!\n",
RC.config_file_name, i, ccparams_lte.ue_multiple_max);
break;
default:
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for N_RB_DL choice: 25,50,100 !\n",
RC.config_file_name, i, ccparams_lte.N_RB_DL);
break;
}
if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf1") == 0) {
RRCcfg->radioresourceconfig[j].drx_RetransmissionTimer = (long)LTE_DRX_Config__setup__drx_RetransmissionTimer_psf1;
} else if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf2") == 0) {
RRCcfg->radioresourceconfig[j].drx_RetransmissionTimer = (long)LTE_DRX_Config__setup__drx_RetransmissionTimer_psf2;
} else if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf4") == 0) {
RRCcfg->radioresourceconfig[j].drx_RetransmissionTimer = (long)LTE_DRX_Config__setup__drx_RetransmissionTimer_psf4;
} else if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf6") == 0) {
RRCcfg->radioresourceconfig[j].drx_RetransmissionTimer = (long)LTE_DRX_Config__setup__drx_RetransmissionTimer_psf6;
} else if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf8") == 0) {
RRCcfg->radioresourceconfig[j].drx_RetransmissionTimer = (long)LTE_DRX_Config__setup__drx_RetransmissionTimer_psf8;
} else if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf16") == 0) {
RRCcfg->radioresourceconfig[j].drx_RetransmissionTimer = (long)LTE_DRX_Config__setup__drx_RetransmissionTimer_psf16;
} else if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf24") == 0) {
RRCcfg->radioresourceconfig[j].drx_RetransmissionTimer = (long)LTE_DRX_Config__setup__drx_RetransmissionTimer_psf24;
} else if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf33") == 0) {
RRCcfg->radioresourceconfig[j].drx_RetransmissionTimer = (long)LTE_DRX_Config__setup__drx_RetransmissionTimer_psf33;
} else {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for drx_RetransmissionTimer choice !\n",
RC.config_file_name, i, ccparams_lte.drx_RetransmissionTimer);
break;
}
if (ccparams_lte.drx_longDrx_CycleStartOffset_present == NULL || strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prNothing") == 0) {
RRCcfg->radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_NOTHING;
} else {
if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf10") == 0) {
RRCcfg->radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf10;
offsetMaxLimit = 10;
} else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf20") == 0) {
RRCcfg->radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf20;
offsetMaxLimit = 20;
} else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf32") == 0) {
RRCcfg->radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf32;
offsetMaxLimit = 32;
} else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf40") == 0) {
RRCcfg->radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf40;
offsetMaxLimit = 40;
} else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf64") == 0) {
RRCcfg->radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf64;
offsetMaxLimit = 64;
} else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf80") == 0) {
RRCcfg->radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf80;
offsetMaxLimit = 80;
} else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf128") == 0) {
RRCcfg->radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf128;
offsetMaxLimit = 128;
} else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf160") == 0) {
RRCcfg->radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf160;
offsetMaxLimit = 160;
} else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf256") == 0) {
RRCcfg->radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf256;
offsetMaxLimit = 256;
} else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf320") == 0) {
RRCcfg->radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf320;
offsetMaxLimit = 320;
} else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf512") == 0) {
RRCcfg->radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf512;
offsetMaxLimit = 512;
} else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf640") == 0) {
RRCcfg->radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf640;
offsetMaxLimit = 640;
} else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf1024") == 0) {
RRCcfg->radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1024;
offsetMaxLimit = 1024;
} else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf1280") == 0) {
RRCcfg->radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1280;
offsetMaxLimit = 1280;
} else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf2048") == 0) {
RRCcfg->radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2048;
offsetMaxLimit = 2048;
} else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf2560") == 0) {
RRCcfg->radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2560;
offsetMaxLimit = 2560;
} else {
AssertFatal (0,
"Failed to parse eNB configuration file \"%s\", enb %u unknown string value \"%s\" for drx_longDrx_CycleStartOffset_present choice !\n",
RC.config_file_name, i, ccparams_lte.drx_longDrx_CycleStartOffset_present);
}
if (ccparams_lte.drx_longDrx_CycleStartOffset >= 0 && ccparams_lte.drx_longDrx_CycleStartOffset < offsetMaxLimit) {
RRCcfg->radioresourceconfig[j].drx_longDrx_CycleStartOffset = ccparams_lte.drx_longDrx_CycleStartOffset;
} else {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u incoherent value \"%d\" for drx_longDrx_CycleStartOffset !\n",
RC.config_file_name, i, ccparams_lte.drx_longDrx_CycleStartOffset);
}
}
if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "") == 0 || ccparams_lte.drx_shortDrx_ShortCycleTimer == 0) {
if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "") != 0 || ccparams_lte.drx_shortDrx_ShortCycleTimer != 0) {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u incoherent values \"%s\" - \"%d\" for drx_shortDrx_Cycle or drx_shortDrx_ShortCycleTimer choice !\n",
RC.config_file_name, i, ccparams_lte.drx_shortDrx_Cycle, ccparams_lte.drx_shortDrx_ShortCycleTimer);
} else {
RRCcfg->radioresourceconfig[j].drx_shortDrx_Cycle = -1;
RRCcfg->radioresourceconfig[j].drx_shortDrx_ShortCycleTimer = 0;
}
} else {
if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf2") == 0) {
cycleNb = 2;
RRCcfg->radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf2;
} else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf5") == 0) {
cycleNb = 5;
RRCcfg->radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf5;
} else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf8") == 0) {
cycleNb = 8;
RRCcfg->radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf8;
} else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf10") == 0) {
cycleNb = 10;
RRCcfg->radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf10;
} else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf16") == 0) {
cycleNb = 16;
RRCcfg->radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf16;
} else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf20") == 0) {
cycleNb = 20;
RRCcfg->radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf20;
} else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf32") == 0) {
cycleNb = 32;
RRCcfg->radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf32;
} else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf40") == 0) {
cycleNb = 40;
RRCcfg->radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf40;
} else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf64") == 0) {
cycleNb = 64;
RRCcfg->radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf64;
} else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf80") == 0) {
cycleNb = 80;
RRCcfg->radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf80;
} else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf128") == 0) {
cycleNb = 128;
RRCcfg->radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf128;
} else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf160") == 0) {
cycleNb = 160;
RRCcfg->radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf160;
} else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf256") == 0) {
cycleNb = 256;
RRCcfg->radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf256;
} else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf320") == 0) {
cycleNb = 320;
RRCcfg->radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf320;
} else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf512") == 0) {
cycleNb = 512;
RRCcfg->radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf512;
} else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf640") == 0) {
cycleNb = 640;
RRCcfg->radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf640;
} else {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u incoherent value \"%s\" for drx_shortDrx_Cycle !\n",
RC.config_file_name, i, ccparams_lte.drx_shortDrx_Cycle);
}
if (cycleNb > 0 && (offsetMaxLimit % cycleNb != 0 || cycleNb == offsetMaxLimit)) {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u incompatible (not multiple) values \"%d\" - \"%d\" for drx_shortDrx_Cycle and drx_longDrx_CycleStartOffset choice !\n",
RC.config_file_name, i, cycleNb, offsetMaxLimit);
}
if (ccparams_lte.drx_shortDrx_ShortCycleTimer >= 1 && ccparams_lte.drx_shortDrx_ShortCycleTimer <= 16 ) {
RRCcfg->radioresourceconfig[j].drx_shortDrx_ShortCycleTimer = ccparams_lte.drx_shortDrx_ShortCycleTimer;
} else {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for drx_shortDrx_ShortCycleTimer choice !\n",
RC.config_file_name, i, ccparams_lte.drx_shortDrx_ShortCycleTimer );
}
}
switch (ccparams_lte.bcch_modificationPeriodCoeff) {
case 2:
RRCcfg->radioresourceconfig[j].bcch_modificationPeriodCoeff = LTE_BCCH_Config__modificationPeriodCoeff_n2;
break;
case 4:
RRCcfg->radioresourceconfig[j].bcch_modificationPeriodCoeff = LTE_BCCH_Config__modificationPeriodCoeff_n4;
break;
case 8:
RRCcfg->radioresourceconfig[j].bcch_modificationPeriodCoeff = LTE_BCCH_Config__modificationPeriodCoeff_n8;
break;
case 16:
RRCcfg->radioresourceconfig[j].bcch_modificationPeriodCoeff = LTE_BCCH_Config__modificationPeriodCoeff_n16;
break;
default:
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for bcch_modificationPeriodCoeff choice: 2,4,8,16",
RC.config_file_name, i, ccparams_lte.bcch_modificationPeriodCoeff);
break;
}
RRCcfg->radioresourceconfig[j].ue_TimersAndConstants_t300 = ccparams_lte.ue_TimersAndConstants_t300;
RRCcfg->radioresourceconfig[j].ue_TimersAndConstants_t301 = ccparams_lte.ue_TimersAndConstants_t301;
RRCcfg->radioresourceconfig[j].ue_TimersAndConstants_t310 = ccparams_lte.ue_TimersAndConstants_t310;
RRCcfg->radioresourceconfig[j].ue_TimersAndConstants_t311 = ccparams_lte.ue_TimersAndConstants_t311;
RRCcfg->radioresourceconfig[j].ue_TimersAndConstants_n310 = ccparams_lte.ue_TimersAndConstants_n310;
RRCcfg->radioresourceconfig[j].ue_TimersAndConstants_n311 = ccparams_lte.ue_TimersAndConstants_n311;
switch (ccparams_lte.ue_TransmissionMode) {
case 1:
RRCcfg->radioresourceconfig[j].ue_TransmissionMode = LTE_AntennaInfoDedicated__transmissionMode_tm1;
break;
case 2:
RRCcfg->radioresourceconfig[j].ue_TransmissionMode = LTE_AntennaInfoDedicated__transmissionMode_tm2;
break;
case 3:
RRCcfg->radioresourceconfig[j].ue_TransmissionMode = LTE_AntennaInfoDedicated__transmissionMode_tm3;
break;
case 4:
RRCcfg->radioresourceconfig[j].ue_TransmissionMode = LTE_AntennaInfoDedicated__transmissionMode_tm4;
break;
case 5:
RRCcfg->radioresourceconfig[j].ue_TransmissionMode = LTE_AntennaInfoDedicated__transmissionMode_tm5;
break;
case 6:
RRCcfg->radioresourceconfig[j].ue_TransmissionMode = LTE_AntennaInfoDedicated__transmissionMode_tm6;
break;
case 7:
RRCcfg->radioresourceconfig[j].ue_TransmissionMode = LTE_AntennaInfoDedicated__transmissionMode_tm7;
break;
default:
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for ue_TransmissionMode choice: 1,2,3,4,5,6,7",
RC.config_file_name, i, ccparams_lte.ue_TransmissionMode);
break;
}
RRCcfg->radioresourceconfig[j].ue_multiple_max = ccparams_lte.ue_multiple_max;
switch (ccparams_lte.N_RB_DL) {
case 25:
if ((ccparams_lte.ue_multiple_max < 1) ||
(ccparams_lte.ue_multiple_max > 4))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for ue_multiple_max choice: 1..4!\n",
RC.config_file_name, i, ccparams_lte.ue_multiple_max);
break;
case 50:
if ((ccparams_lte.ue_multiple_max < 1) ||
(ccparams_lte.ue_multiple_max > 8))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for ue_multiple_max choice: 1..8!\n",
RC.config_file_name, i, ccparams_lte.ue_multiple_max);
break;
case 100:
if ((ccparams_lte.ue_multiple_max < 1) ||
(ccparams_lte.ue_multiple_max > 16))
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for ue_multiple_max choice: 1..16!\n",
RC.config_file_name, i, ccparams_lte.ue_multiple_max);
break;
default:
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%d\" for N_RB_DL choice: 25,50,100 !\n",
RC.config_file_name, i, ccparams_lte.N_RB_DL);
break;
}
// eMBMS configuration
RRCcfg->eMBMS_configured = 0;
printf("No eMBMS configuration, skipping it\n");
// eMTC configuration
char brparamspath[MAX_OPTNAME_SIZE*2 + 160];
sprintf(brparamspath,"%s.%s", ccspath, ENB_CONFIG_STRING_EMTC_PARAMETERS);
config_get(config_get_if(), eMTCParams, sizeofArray(eMTCParams), brparamspath);
RRCcfg->eMTC_configured = eMTCconfig.eMTC_configured & 1;
if (eMTCconfig.eMTC_configured > 0)
fill_eMTC_configuration(RRCcfg, &eMTCconfig, i, j, RC.config_file_name, brparamspath);
else printf("No eMTC configuration, skipping it\n");
// Sidelink configuration
char SLparamspath[MAX_OPTNAME_SIZE*2 + 160];
sprintf(SLparamspath,"%s.%s", ccspath, ENB_CONFIG_STRING_SL_PARAMETERS);
config_get(config_get_if(), SLParams, sizeofArray(SLParams), SLparamspath);
// Sidelink Resource pool information
RRCcfg->SL_configured = SLconfig.sidelink_configured & 1;
if (SLconfig.sidelink_configured == 1)
fill_SL_configuration(RRCcfg, &SLconfig, i, j, RC.config_file_name);
else printf("No SL configuration skipping it\n");
}
RRCcfg->nr_scg_ssb_freq = ccparams_lte.nr_scg_ssb_freq;
char srb1path[MAX_OPTNAME_SIZE*2 + 8];
sprintf(srb1path,"%s.%s",enbpath,ENB_CONFIG_STRING_SRB1);
config_get(config_get_if(), SRB1Params, sizeofArray(SRB1Params), srb1path);
switch (srb1_params.srb1_max_retx_threshold) {
case 1:
rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t1;
break;
case 2:
rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t2;
break;
case 3:
rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t3;
break;
case 4:
rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t4;
break;
case 6:
rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t6;
break;
case 8:
rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t8;
break;
case 16:
rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t16;
break;
case 32:
rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t32;
break;
default:
AssertFatal (0,
"Bad config value when parsing eNB configuration file %s, enb %u srb1_max_retx_threshold %d!\n",
RC.config_file_name, i, srb1_params.srb1_max_retx_threshold);
}
switch (srb1_params.srb1_poll_pdu) {
case 4:
rrc->srb1_poll_pdu = LTE_PollPDU_p4;
break;
case 8:
rrc->srb1_poll_pdu = LTE_PollPDU_p8;
break;
case 16:
rrc->srb1_poll_pdu = LTE_PollPDU_p16;
break;
case 32:
rrc->srb1_poll_pdu = LTE_PollPDU_p32;
break;
case 64:
rrc->srb1_poll_pdu = LTE_PollPDU_p64;
break;
case 128:
rrc->srb1_poll_pdu = LTE_PollPDU_p128;
break;
case 256:
rrc->srb1_poll_pdu = LTE_PollPDU_p256;
break;
default:
if (srb1_params.srb1_poll_pdu >= 10000)
rrc->srb1_poll_pdu = LTE_PollPDU_pInfinity;
else
AssertFatal (0,
"Bad config value when parsing eNB configuration file %s, enb %u srb1_poll_pdu %d!\n",
RC.config_file_name, i, srb1_params.srb1_poll_pdu);
}
rrc->srb1_poll_byte = srb1_params.srb1_poll_byte;
switch (srb1_params.srb1_poll_byte) {
case 25:
rrc->srb1_poll_byte = LTE_PollByte_kB25;
break;
case 50:
rrc->srb1_poll_byte = LTE_PollByte_kB50;
break;
case 75:
rrc->srb1_poll_byte = LTE_PollByte_kB75;
break;
case 100:
rrc->srb1_poll_byte = LTE_PollByte_kB100;
break;
case 125:
rrc->srb1_poll_byte = LTE_PollByte_kB125;
break;
case 250:
rrc->srb1_poll_byte = LTE_PollByte_kB250;
break;
case 375:
rrc->srb1_poll_byte = LTE_PollByte_kB375;
break;
case 500:
rrc->srb1_poll_byte = LTE_PollByte_kB500;
break;
case 750:
rrc->srb1_poll_byte = LTE_PollByte_kB750;
break;
case 1000:
rrc->srb1_poll_byte = LTE_PollByte_kB1000;
break;
case 1250:
rrc->srb1_poll_byte = LTE_PollByte_kB1250;
break;
case 1500:
rrc->srb1_poll_byte = LTE_PollByte_kB1500;
break;
case 2000:
rrc->srb1_poll_byte = LTE_PollByte_kB2000;
break;
case 3000:
rrc->srb1_poll_byte = LTE_PollByte_kB3000;
break;
default:
if (srb1_params.srb1_poll_byte >= 10000)
rrc->srb1_poll_byte = LTE_PollByte_kBinfinity;
else
AssertFatal (0,
"Bad config value when parsing eNB configuration file %s, enb %u srb1_poll_byte %d!\n",
RC.config_file_name, i, srb1_params.srb1_poll_byte);
}
if (srb1_params.srb1_timer_poll_retransmit <= 250) {
rrc->srb1_timer_poll_retransmit = (srb1_params.srb1_timer_poll_retransmit - 5)/5;
} else if (srb1_params.srb1_timer_poll_retransmit <= 500) {
rrc->srb1_timer_poll_retransmit = (srb1_params.srb1_timer_poll_retransmit - 300)/50 + 50;
} else {
AssertFatal (0,
"Bad config value when parsing eNB configuration file %s, enb %u srb1_timer_poll_retransmit %d!\n",
RC.config_file_name, i, srb1_params.srb1_timer_poll_retransmit);
}
if (srb1_params.srb1_timer_status_prohibit <= 250) {
rrc->srb1_timer_status_prohibit = srb1_params.srb1_timer_status_prohibit/5;
} else if ((srb1_params.srb1_timer_poll_retransmit >= 300) && (srb1_params.srb1_timer_poll_retransmit <= 500)) {
rrc->srb1_timer_status_prohibit = (srb1_params.srb1_timer_status_prohibit - 300)/50 + 51;
} else {
AssertFatal (0,
"Bad config value when parsing eNB configuration file %s, enb %u srb1_timer_status_prohibit %d!\n",
RC.config_file_name, i, srb1_params.srb1_timer_status_prohibit);
}
switch (srb1_params.srb1_timer_reordering) {
case 0:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms0;
break;
case 5:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms5;
break;
case 10:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms10;
break;
case 15:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms15;
break;
case 20:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms20;
break;
case 25:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms25;
break;
case 30:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms30;
break;
case 35:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms35;
break;
case 40:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms40;
break;
case 45:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms45;
break;
case 50:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms50;
break;
case 55:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms55;
break;
case 60:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms60;
break;
case 65:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms65;
break;
case 70:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms70;
break;
case 75:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms75;
break;
case 80:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms80;
break;
case 85:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms85;
break;
case 90:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms90;
break;
case 95:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms95;
break;
case 100:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms100;
break;
case 110:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms110;
break;
case 120:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms120;
break;
case 130:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms130;
break;
case 140:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms140;
break;
case 150:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms150;
break;
case 160:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms160;
break;
case 170:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms170;
break;
case 180:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms180;
break;
case 190:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms190;
break;
case 200:
rrc->srb1_timer_reordering = LTE_T_Reordering_ms200;
break;
default:
AssertFatal (0,
"Bad config value when parsing eNB configuration file %s, enb %u srb1_timer_reordering %d!\n",
RC.config_file_name, i, srb1_params.srb1_timer_reordering);
}
}
}
}
}
return 0;
}
int RCconfig_gtpu(void ) {
int num_enbs = 0;
char *enb_interface_name_for_S1U = NULL;
char *enb_ipv4_address_for_S1U = NULL;
uint16_t enb_port_for_S1U = 0;
char *address = NULL;
char *cidr = NULL;
char gtpupath[MAX_OPTNAME_SIZE*2 + 8];
paramdef_t ENBSParams[] = ENBSPARAMS_DESC;
paramdef_t GTPUParams[] = GTPUPARAMS_DESC;
LOG_I(GTPU,"Configuring GTPu\n");
/* get number of active eNodeBs */
config_get(config_get_if(), ENBSParams, sizeofArray(ENBSParams), NULL);
num_enbs = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt;
AssertFatal (num_enbs >0,
"Failed to parse config file no active eNodeBs in %s \n", ENB_CONFIG_STRING_ACTIVE_ENBS);
sprintf(gtpupath,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,0,ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
config_get(config_get_if(), GTPUParams, sizeofArray(GTPUParams), gtpupath);
cidr = enb_ipv4_address_for_S1U;
address = strtok(cidr, "/");
if (address) {
MessageDef *message;
AssertFatal((message = itti_alloc_new_message(TASK_ENB_APP, 0, GTPV1U_REQ))!=NULL,"");
IPV4_STR_ADDR_TO_INT_NWBO ( address, GTPV1U_REQ(message).localAddr, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_REQ(message).localAddr);
GTPV1U_REQ(message).localPort = enb_port_for_S1U;
strcpy(GTPV1U_REQ(message).localAddrStr,address);
sprintf(GTPV1U_REQ(message).localPortStr,"%d", enb_port_for_S1U);
itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id)
} else
LOG_E(GTPU,"invalid address for S1U\n");
return 0;
}
int RCconfig_M2(MessageDef *msg_p, uint32_t i) {
int I, J, j, k, l;
int enb_id;
char *address = NULL;
char *cidr = NULL;
ccparams_lte_t ccparams_lte;
memset((void *)&ccparams_lte,0,sizeof(ccparams_lte_t));
paramdef_t ENBSParams[] = ENBSPARAMS_DESC;
paramdef_t ENBParams[] = ENBPARAMS_DESC;
paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST,NULL,0};
/* get global parameters, defined outside any section in the config file */
config_get(config_get_if(), ENBSParams, sizeofArray(ENBSParams), NULL);
checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK;
paramdef_t CCsParams[] = CCPARAMS_DESC(ccparams_lte);
paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS, NULL, 0};
// ccparams_MCE_t MCEconfig;
// memset((void *)&MCEconfig,0,sizeof(ccparams_MCE_t));
// paramdef_t MCEParams[] = MCEPARAMS_DESC((&MCEconfig));
// checkedparam_t config_check_MCEparams[] = MCEPARAMS_CHECK;
/* map parameter checking array instances to parameter definition array instances */
for (I = 0; I < sizeofArray(CCsParams); I++) {
CCsParams[I].chkPptr = &(config_check_CCparams[I]);
}
AssertFatal(i < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt,
"Failed to parse config file %s, %uth attribute %s \n",
RC.config_file_name, i, ENB_CONFIG_STRING_ACTIVE_ENBS);
if (ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt > 0) {
// Output a list of all eNBs.
config_getlist(config_get_if(), &ENBParamList, ENBParams, sizeofArray(ENBParams), NULL);
if (ENBParamList.numelt > 0) {
for (k = 0; k < ENBParamList.numelt; k++) {
if (ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr == NULL) {
// Calculate a default eNB ID
if (EPC_MODE_ENABLED) {
uint32_t hash;
hash = s1ap_generate_eNB_id ();
enb_id = k + (hash & 0xFFFF8);
} else {
enb_id = k;
}
} else {
enb_id = *(ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr);
}
// 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 < sizeofArray(PLMNParams); ++I)
PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]);
paramdef_t M2Params[] = M2PARAMS_DESC;
paramlist_def_t M2ParamList = {ENB_CONFIG_STRING_TARGET_MCE_M2_IP_ADDRESS,NULL,0};
paramdef_t SCTPParams[] = SCTPPARAMS_DESC;
paramdef_t NETParams[] = NETPARAMS_DESC;
paramdef_t MBMSConfigParams[] = MBMS_CONFIG_PARAMS_DESC;
paramdef_t MBMSParams[] = MBMSPARAMS_DESC;
paramlist_def_t MBMSConfigParamList = {ENB_CONFIG_STRING_MBMS_CONFIGURATION_DATA_LIST,NULL,0};
paramlist_def_t MBMSParamList = {ENB_CONFIG_STRING_MBMS_SERVICE_AREA_LIST,NULL,0};
/* 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 */
M2AP_REGISTER_ENB_REQ (msg_p).eNB_id = enb_id;
if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_ENB") == 0) {
M2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_ENB;
} else if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_HOME_ENB") == 0) {
M2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_HOME_ENB;
} else {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n",
RC.config_file_name, i, *(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr));
}
M2AP_REGISTER_ENB_REQ (msg_p).eNB_name = strdup(*(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr));
M2AP_REGISTER_ENB_REQ (msg_p).tac = *ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].uptr;
config_getlist(config_get_if(), &PLMNParamList, PLMNParams, sizeofArray(PLMNParams), aprefix);
// char aprefix2[MAX_OPTNAME_SIZE*80 + 8];
// sprintf(aprefix2,"%s.[%i].%s.[0]",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_MBMS_CONFIGURATION_DATA_LIST);
// config_getlist(config_get_if(),&MBMSParamList, MBMSParams, sizeofArray(MBMSParams),
// aprefix2);
// if (MBMSParamList.numelt < 1 || MBMSParamList.numelt > 8)
// AssertFatal(0, "The number of MBMS Areas must be in [1,8], but is %d\n",
// MBMSParamList.numelt);
// M2AP_REGISTER_ENB_REQ (msg_p).num_mbms_service_area_list = MBMSParamList.numelt;
// for(J=0; J<MBMSParamList.numelt;J++){
// M2AP_REGISTER_ENB_REQ (msg_p).mbms_service_area_list[J] =
// *MBMSParamList.paramarray[J][ENB_MBMS_SERVICE_AREA_IDX].uptr;
// }
//
char aprefix2[MAX_OPTNAME_SIZE*80 + 8];
sprintf(aprefix2,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k);
config_getlist(config_get_if(), &MBMSConfigParamList, MBMSConfigParams, sizeofArray(MBMSConfigParams), aprefix2);
if (MBMSConfigParamList.numelt < 1 || MBMSConfigParamList.numelt > 8)
AssertFatal(0, "The number of MBMS Config Data must be in [1,8], but is %d\n",
MBMSConfigParamList.numelt);
M2AP_REGISTER_ENB_REQ (msg_p).num_mbms_configuration_data_list = MBMSConfigParamList.numelt;
for(int I=0; I < MBMSConfigParamList.numelt; I++){
sprintf(aprefix2,"%s.[%i].%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_MBMS_CONFIGURATION_DATA_LIST,I);
config_getlist(config_get_if(), &MBMSParamList, MBMSParams, sizeofArray(MBMSParams), aprefix2);
if (MBMSParamList.numelt < 1 || MBMSParamList.numelt > 8)
AssertFatal(0, "The number of MBMS Areas must be in [1,8], but is %d\n",
MBMSParamList.numelt);
M2AP_REGISTER_ENB_REQ (msg_p).mbms_configuration_data_list[I].num_mbms_service_area_list = MBMSParamList.numelt;
for(J=0; J<MBMSParamList.numelt;J++){
M2AP_REGISTER_ENB_REQ (msg_p).mbms_configuration_data_list[I].mbms_service_area_list[J] = *MBMSParamList.paramarray[J][ENB_MBMS_SERVICE_AREA_IDX].uptr;
}
}
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(M2AP, "M2AP currently handles only one PLMN, ignoring the others!\n");
M2AP_REGISTER_ENB_REQ (msg_p).mcc = *PLMNParamList.paramarray[0][ENB_MOBILE_COUNTRY_CODE_IDX].uptr;
M2AP_REGISTER_ENB_REQ (msg_p).mnc = *PLMNParamList.paramarray[0][ENB_MOBILE_NETWORK_CODE_IDX].uptr;
M2AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length = *PLMNParamList.paramarray[0][ENB_MNC_DIGIT_LENGTH].u8ptr;
AssertFatal(M2AP_REGISTER_ENB_REQ(msg_p).mnc_digit_length == 3
|| M2AP_REGISTER_ENB_REQ(msg_p).mnc < 100,
"MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n",
M2AP_REGISTER_ENB_REQ(msg_p).mnc);
/* CC params */
config_getlist(config_get_if(), &CCsParamList, NULL, 0, aprefix);
M2AP_REGISTER_ENB_REQ (msg_p).num_cc = CCsParamList.numelt;
if (CCsParamList.numelt > 0) {
//char ccspath[MAX_OPTNAME_SIZE*2 + 16];
for (J = 0; J < CCsParamList.numelt ; J++) {
sprintf(aprefix, "%s.[%i].%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, k, ENB_CONFIG_STRING_COMPONENT_CARRIERS, J);
config_get(config_get_if(), CCsParams, sizeofArray(CCsParams), aprefix);
M2AP_REGISTER_ENB_REQ (msg_p).eutra_band[J] = ccparams_lte.eutra_band;
M2AP_REGISTER_ENB_REQ (msg_p).downlink_frequency[J] = (uint32_t) ccparams_lte.downlink_frequency;
M2AP_REGISTER_ENB_REQ (msg_p).uplink_frequency_offset[J] = (unsigned int) ccparams_lte.uplink_frequency_offset;
M2AP_REGISTER_ENB_REQ (msg_p).Nid_cell[J]= ccparams_lte.Nid_cell;
if (ccparams_lte.Nid_cell>503) {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for Nid_cell choice: 0...503 !\n",
RC.config_file_name, k, ccparams_lte.Nid_cell);
}
M2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J]= ccparams_lte.N_RB_DL;
if ((ccparams_lte.N_RB_DL!=6) && (ccparams_lte.N_RB_DL!=15) && (ccparams_lte.N_RB_DL!=25) && (ccparams_lte.N_RB_DL!=50) && (ccparams_lte.N_RB_DL!=75) && (ccparams_lte.N_RB_DL!=100)) {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 6,15,25,50,75,100 !\n",
RC.config_file_name, k, ccparams_lte.N_RB_DL);
}
if (strcmp(ccparams_lte.frame_type, "FDD") == 0) {
M2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = FDD;
} else if (strcmp(ccparams_lte.frame_type, "TDD") == 0) {
M2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD;
} else {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n",
RC.config_file_name, k, ccparams_lte.frame_type);
}
M2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_DL[J] = to_earfcn_DL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency, ccparams_lte.N_RB_DL);
M2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_UL[J] = to_earfcn_UL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency + ccparams_lte.uplink_frequency_offset, ccparams_lte.N_RB_DL);
}
}
sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k);
config_getlist(config_get_if(), &M2ParamList, M2Params, sizeofArray(M2Params), aprefix);
AssertFatal(M2ParamList.numelt <= M2AP_MAX_NB_ENB_IP_ADDRESS,
"value of M2ParamList.numelt %d must be lower than M2AP_MAX_NB_ENB_IP_ADDRESS %d value: reconsider to increase M2AP_MAX_NB_ENB_IP_ADDRESS\n",
M2ParamList.numelt,M2AP_MAX_NB_ENB_IP_ADDRESS);
M2AP_REGISTER_ENB_REQ (msg_p).nb_m2 = 0;
for (l = 0; l < M2ParamList.numelt; l++) {
M2AP_REGISTER_ENB_REQ (msg_p).nb_m2 += 1;
strcpy(M2AP_REGISTER_ENB_REQ (msg_p).target_mce_m2_ip_address[l].ipv4_address,*(M2ParamList.paramarray[l][ENB_M2_IPV4_ADDRESS_IDX].strptr));
strcpy(M2AP_REGISTER_ENB_REQ (msg_p).target_mce_m2_ip_address[l].ipv6_address,*(M2ParamList.paramarray[l][ENB_M2_IPV6_ADDRESS_IDX].strptr));
if (strcmp(*(M2ParamList.paramarray[l][ENB_M2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) {
M2AP_REGISTER_ENB_REQ (msg_p).target_mce_m2_ip_address[l].ipv4 = 1;
M2AP_REGISTER_ENB_REQ (msg_p).target_mce_m2_ip_address[l].ipv6 = 0;
} else if (strcmp(*(M2ParamList.paramarray[l][ENB_M2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) {
M2AP_REGISTER_ENB_REQ (msg_p).target_mce_m2_ip_address[l].ipv4 = 0;
M2AP_REGISTER_ENB_REQ (msg_p).target_mce_m2_ip_address[l].ipv6 = 1;
} else if (strcmp(*(M2ParamList.paramarray[l][ENB_M2_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) {
M2AP_REGISTER_ENB_REQ (msg_p).target_mce_m2_ip_address[l].ipv4 = 1;
M2AP_REGISTER_ENB_REQ (msg_p).target_mce_m2_ip_address[l].ipv6 = 1;
}
}
// timers
//{
// int t_reloc_prep = 0;
// int tx2_reloc_overall = 0;
// paramdef_t p[] = {
// { "t_reloc_prep", "t_reloc_prep", 0, iptr:&t_reloc_prep, defintval:0, TYPE_INT, 0 },
// { "tx2_reloc_overall", "tx2_reloc_overall", 0, iptr:&tx2_reloc_overall, defintval:0, TYPE_INT, 0 }
// };
// config_get(p, sizeofArray(p), aprefix);
// if (t_reloc_prep <= 0 || t_reloc_prep > 10000 ||
// tx2_reloc_overall <= 0 || tx2_reloc_overall > 20000) {
// LOG_E(M2AP, "timers in configuration file have wrong values. We must have [0 < t_reloc_prep <= 10000] and [0 < tx2_reloc_overall <= 20000]\n");
// exit(1);
// }
// M2AP_REGISTER_ENB_REQ (msg_p).t_reloc_prep = t_reloc_prep;
// M2AP_REGISTER_ENB_REQ (msg_p).tx2_reloc_overall = tx2_reloc_overall;
//}
// SCTP SETTING
M2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS;
M2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS;
if (EPC_MODE_ENABLED) {
sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_SCTP_CONFIG);
config_get(config_get_if(), SCTPParams, sizeofArray(SCTPParams), aprefix);
M2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[ENB_SCTP_INSTREAMS_IDX].uptr);
M2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[ENB_SCTP_OUTSTREAMS_IDX].uptr);
}
sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
// NETWORK_INTERFACES
config_get(config_get_if(), NETParams, sizeofArray(NETParams), aprefix);
M2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_M2C = (uint32_t)*(NETParams[ENB_PORT_FOR_M2C_IDX].uptr);
if ((NETParams[ENB_IPV4_ADDR_FOR_M2C_IDX].strptr == NULL) || (M2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_M2C == 0)) {
LOG_E(RRC,"Add eNB IPv4 address and/or port for M2C in the CONF file!\n");
exit(1);
}
cidr = *(NETParams[ENB_IPV4_ADDR_FOR_M2C_IDX].strptr);
address = strtok(cidr, "/");
M2AP_REGISTER_ENB_REQ (msg_p).enb_m2_ip_address.ipv6 = 0;
M2AP_REGISTER_ENB_REQ (msg_p).enb_m2_ip_address.ipv4 = 1;
strcpy(M2AP_REGISTER_ENB_REQ (msg_p).enb_m2_ip_address.ipv4_address, address);
}
}
}
}
}
return 0;
}
//-----------------------------------------------------------------------------
/*
* Configure the s1ap_register_enb_req in itti message for future
* communications between eNB(s) and MME.
*/
int RCconfig_S1(
MessageDef *msg_p,
uint32_t i)
//-----------------------------------------------------------------------------
{
int enb_id = 0;
int32_t my_int = 0;
const char *active_enb[MAX_ENB];
char *address = NULL;
char *cidr = NULL;
ccparams_lte_t ccparams_lte;
memset((void *)&ccparams_lte,0,sizeof(ccparams_lte_t));
// for no gcc warnings
(void)my_int;
memset((char *)active_enb, 0, MAX_ENB * sizeof(char *));
paramdef_t ENBSParams[] = ENBSPARAMS_DESC;
paramdef_t ENBParams[] = ENBPARAMS_DESC;
paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST, NULL, 0};
/* get global parameters, defined outside any section in the config file */
config_get(config_get_if(), ENBSParams, sizeofArray(ENBSParams), NULL);
AssertFatal (i < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt,
"Failed to parse config file %s, %uth attribute %s \n",
RC.config_file_name, i, ENB_CONFIG_STRING_ACTIVE_ENBS);
if (ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt > 0) {
// Output a list of all eNBs.
config_getlist(config_get_if(), &ENBParamList, ENBParams, sizeofArray(ENBParams), NULL);
if (ENBParamList.numelt > 0) {
for (int k = 0; k < ENBParamList.numelt; k++) {
if (ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr == NULL) {
// Calculate a default eNB ID
if (EPC_MODE_ENABLED) {
uint32_t hash = 0;
hash = s1ap_generate_eNB_id();
enb_id = k + (hash & 0xFFFF8);
} else {
enb_id = k;
}
} else {
enb_id = *(ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr);
}
// search if in active list
for (int 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};
paramdef_t CCsParams[] = CCPARAMS_DESC(ccparams_lte);
/* map parameter checking array instances to parameter definition array instances */
checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK;
for (int I = 0; I < sizeofArray(CCsParams); I++) {
CCsParams[I].chkPptr = &(config_check_CCparams[I]);
}
/* map parameter checking array instances to parameter definition array instances */
checkedparam_t config_check_PLMNParams [] = PLMNPARAMS_CHECK;
for (int I = 0; I < sizeofArray(PLMNParams); ++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) {
S1AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_ENB;
} else if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_HOME_ENB") == 0) {
S1AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_HOME_ENB;
// Temporary option to be able to parse an eNB configuration file which is treated as gNB from
// the X2AP layer and test the setup of an ENDC X2AP connection. To be removed when we are ready to
// parse an actual gNB configuration file wrt. the X2AP parameters instead.
} else if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_GNB") == 0) {
S1AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_GNB;
} else {
AssertFatal(0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n",
RC.config_file_name,
i,
*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr));
}
S1AP_REGISTER_ENB_REQ (msg_p).eNB_name = strdup(*(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr));
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");
if(*ENBParamList.paramarray[k][ENB_S1SETUP_RSP_TIMER_IDX].uptr <= 0xffff)
{
S1AP_REGISTER_ENB_REQ(msg_p).s1_setuprsp_wait_timer = *ENBParamList.paramarray[k][ENB_S1SETUP_RSP_TIMER_IDX].uptr;
}
else
{
LOG_E(S1AP,
"s1setup_rsp_timer value in conf file is invalid (%d). Default value is set.\n",
*ENBParamList.paramarray[k][ENB_S1SETUP_RSP_TIMER_IDX].uptr);
S1AP_REGISTER_ENB_REQ(msg_p).s1_setuprsp_wait_timer = 5;
}
if(*ENBParamList.paramarray[k][ENB_S1SETUP_REQ_TIMER_IDX].uptr <= 0xffff)
{
S1AP_REGISTER_ENB_REQ(msg_p).s1_setupreq_wait_timer = *ENBParamList.paramarray[k][ENB_S1SETUP_REQ_TIMER_IDX].uptr;
}
else
{
LOG_E(S1AP,
"s1setup_req_timer value in conf file is invalid (%d). Default value is set.\n",
*ENBParamList.paramarray[k][ENB_S1SETUP_REQ_TIMER_IDX].uptr);
S1AP_REGISTER_ENB_REQ(msg_p).s1_setupreq_wait_timer = 5;
}
if(*ENBParamList.paramarray[k][ENB_S1SETUP_REQ_COUNT_IDX].uptr <= 0xffff)
{
S1AP_REGISTER_ENB_REQ(msg_p).s1_setupreq_count = *ENBParamList.paramarray[k][ENB_S1SETUP_REQ_COUNT_IDX].uptr;
}
else
{
LOG_E(S1AP,
"s1setup_req_count value in conf file is invalid (%d). Default value is set.\n",
*ENBParamList.paramarray[k][ENB_S1SETUP_REQ_COUNT_IDX].uptr);
S1AP_REGISTER_ENB_REQ(msg_p).s1_setupreq_count = 0xffff;
}
if(*ENBParamList.paramarray[k][ENB_SCTP_REQ_TIMER_IDX].uptr <= 0xffff)
{
S1AP_REGISTER_ENB_REQ(msg_p).sctp_req_timer = *ENBParamList.paramarray[k][ENB_SCTP_REQ_TIMER_IDX].uptr;
}
else
{
LOG_E(S1AP,
"sctp_req_timer value in conf file is invalid (%d). Default value is set.\n",
*ENBParamList.paramarray[k][ENB_SCTP_REQ_TIMER_IDX].uptr);
S1AP_REGISTER_ENB_REQ(msg_p).sctp_req_timer = 180;
}
if(*ENBParamList.paramarray[k][ENB_SCTP_REQ_COUNT_IDX].uptr <= 0xffff)
{
S1AP_REGISTER_ENB_REQ(msg_p).sctp_req_count = *ENBParamList.paramarray[k][ENB_SCTP_REQ_COUNT_IDX].uptr;
}
else
{
LOG_E(S1AP,
"sctp_req_count value in conf file is invalid (%d). Default value is set.\n",
*ENBParamList.paramarray[k][ENB_SCTP_REQ_COUNT_IDX].uptr);
S1AP_REGISTER_ENB_REQ(msg_p).sctp_req_count = 0xffff;
}
config_getlist(config_get_if(), &PLMNParamList, PLMNParams, sizeofArray(PLMNParams), 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]);
}
/* Default DRX param */
/*
* Here we get the config of the first CC, since the s1ap_register_enb_req_t doesn't support multiple CC.
* There is a unique value of defaultPagingCycle per eNB (same for multiple cells).
* Hence, it should be stated somewhere that the value should be the same for every CC, or put the value outside the CC
* in the conf file.
*/
sprintf(aprefix, "%s.[%i].%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, k, ENB_CONFIG_STRING_COMPONENT_CARRIERS, 0);
config_get(config_get_if(), CCsParams, sizeofArray(CCsParams), aprefix);
switch (ccparams_lte.pcch_defaultPagingCycle) {
case 32: {
S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 0;
break;
}
case 64: {
S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 1;
break;
}
case 128: {
S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 2;
break;
}
case 256: {
S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 3;
break;
}
default: {
LOG_E(S1AP, "Default I-DRX value in conf file is invalid (%i). Should be 32, 64, 128 or 256. \
Default DRX set to 32 in MME configuration\n",
ccparams_lte.pcch_defaultPagingCycle);
S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 0;
}
}
/* MME connection params */
sprintf(aprefix, "%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, k);
config_getlist(config_get_if(), &S1ParamList, S1Params, sizeofArray(S1Params), aprefix);
S1AP_REGISTER_ENB_REQ (msg_p).nb_mme = 0;
for (int l = 0; l < S1ParamList.numelt; l++) {
S1AP_REGISTER_ENB_REQ (msg_p).nb_mme += 1;
strcpy(S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4_address,*(S1ParamList.paramarray[l][ENB_MME_IPV4_ADDRESS_IDX].strptr));
strcpy(S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6_address,*(S1ParamList.paramarray[l][ENB_MME_IPV6_ADDRESS_IDX].strptr));
if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) {
S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4 = 1;
S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6 = 0;
} else if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) {
S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4 = 0;
S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6 = 1;
} else if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) {
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;
}
/* set S1-mme port (sctp) */
S1AP_REGISTER_ENB_REQ(msg_p).mme_port[l] = *S1ParamList.paramarray[l][ENB_MME_PORT_IDX].u16ptr;
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
S1AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS;
S1AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS;
if (EPC_MODE_ENABLED) {
sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_SCTP_CONFIG);
config_get(config_get_if(), SCTPParams, sizeofArray(SCTPParams), aprefix);
S1AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[ENB_SCTP_INSTREAMS_IDX].uptr);
S1AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[ENB_SCTP_OUTSTREAMS_IDX].uptr);
}
sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
// NETWORK_INTERFACES
config_get(config_get_if(), NETParams, sizeofArray(NETParams), aprefix);
cidr = *(NETParams[ENB_IPV4_ADDRESS_FOR_S1_MME_IDX].strptr);
address = strtok(cidr, "/");
S1AP_REGISTER_ENB_REQ (msg_p).enb_ip_address.ipv6 = 0;
S1AP_REGISTER_ENB_REQ (msg_p).enb_ip_address.ipv4 = 1;
strcpy(S1AP_REGISTER_ENB_REQ (msg_p).enb_ip_address.ipv4_address, address);
break;
}
}
}
}
}
return 0;
}
int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
int I, J, j, k, l;
int enb_id;
char *address = NULL;
char *cidr = NULL;
ccparams_lte_t ccparams_lte;
memset((void *)&ccparams_lte,0,sizeof(ccparams_lte_t));
paramdef_t ENBSParams[] = ENBSPARAMS_DESC;
paramdef_t ENBParams[] = ENBPARAMS_DESC;
paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST,NULL,0};
/* get global parameters, defined outside any section in the config file */
config_get(config_get_if(), ENBSParams, sizeofArray(ENBSParams), NULL);
checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK;
paramdef_t CCsParams[] = CCPARAMS_DESC(ccparams_lte);
paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS, NULL, 0};
/* map parameter checking array instances to parameter definition array instances */
for (I = 0; I < sizeofArray(CCsParams); I++) {
CCsParams[I].chkPptr = &(config_check_CCparams[I]);
}
AssertFatal(i < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt,
"Failed to parse config file %s, %uth attribute %s \n",
RC.config_file_name, i, ENB_CONFIG_STRING_ACTIVE_ENBS);
if (ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt > 0) {
// Output a list of all eNBs.
config_getlist(config_get_if(), &ENBParamList, ENBParams, sizeofArray(ENBParams), NULL);
if (ENBParamList.numelt > 0) {
for (k = 0; k < ENBParamList.numelt; k++) {
if (ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr == NULL) {
// Calculate a default eNB ID
if (EPC_MODE_ENABLED) {
uint32_t hash;
hash = s1ap_generate_eNB_id ();
enb_id = k + (hash & 0xFFFF8);
} else {
enb_id = k;
}
} else {
enb_id = *(ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr);
}
// 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 < sizeofArray(PLMNParams); ++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;
paramdef_t NETParams[] = NETPARAMS_DESC;
/* 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;
if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_ENB") == 0) {
X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_ENB;
} else if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_HOME_ENB") == 0) {
X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_HOME_ENB;
}else {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n",
RC.config_file_name, i, *(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr));
}
X2AP_REGISTER_ENB_REQ (msg_p).eNB_name = strdup(*(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr));
X2AP_REGISTER_ENB_REQ (msg_p).tac = *ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].uptr;
config_getlist(config_get_if(), &PLMNParamList, PLMNParams, sizeofArray(PLMNParams), 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);
/* CC params */
config_getlist(config_get_if(), &CCsParamList, NULL, 0, aprefix);
X2AP_REGISTER_ENB_REQ (msg_p).num_cc = CCsParamList.numelt;
if (CCsParamList.numelt > 0) {
//char ccspath[MAX_OPTNAME_SIZE*2 + 16];
for (J = 0; J < CCsParamList.numelt ; J++) {
sprintf(aprefix, "%s.[%i].%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, k, ENB_CONFIG_STRING_COMPONENT_CARRIERS, J);
config_get(config_get_if(), CCsParams, sizeofArray(CCsParams), aprefix);
X2AP_REGISTER_ENB_REQ (msg_p).eutra_band[J] = ccparams_lte.eutra_band;
X2AP_REGISTER_ENB_REQ (msg_p).downlink_frequency[J] = (uint32_t) ccparams_lte.downlink_frequency;
X2AP_REGISTER_ENB_REQ (msg_p).uplink_frequency_offset[J] = (unsigned int) ccparams_lte.uplink_frequency_offset;
X2AP_REGISTER_ENB_REQ (msg_p).Nid_cell[J]= ccparams_lte.Nid_cell;
if (ccparams_lte.Nid_cell>503) {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for Nid_cell choice: 0...503 !\n",
RC.config_file_name, k, ccparams_lte.Nid_cell);
}
X2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J]= ccparams_lte.N_RB_DL;
if ((ccparams_lte.N_RB_DL!=6) && (ccparams_lte.N_RB_DL!=15) && (ccparams_lte.N_RB_DL!=25) && (ccparams_lte.N_RB_DL!=50) && (ccparams_lte.N_RB_DL!=75) && (ccparams_lte.N_RB_DL!=100)) {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 6,15,25,50,75,100 !\n",
RC.config_file_name, k, ccparams_lte.N_RB_DL);
}
if (strcmp(ccparams_lte.frame_type, "FDD") == 0) {
X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = FDD;
} else if (strcmp(ccparams_lte.frame_type, "TDD") == 0) {
X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD;
X2AP_REGISTER_ENB_REQ (msg_p).subframeAssignment[J] = ccparams_lte.tdd_config;
X2AP_REGISTER_ENB_REQ (msg_p).specialSubframe[J] = ccparams_lte.tdd_config_s;
} else {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n",
RC.config_file_name, k, ccparams_lte.frame_type);
}
X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_DL[J] = to_earfcn_DL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency, ccparams_lte.N_RB_DL);
X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_UL[J] = to_earfcn_UL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency + ccparams_lte.uplink_frequency_offset, ccparams_lte.N_RB_DL);
}
}
sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k);
config_getlist(config_get_if(), &X2ParamList, X2Params, sizeofArray(X2Params), 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);
X2AP_REGISTER_ENB_REQ (msg_p).nb_x2 = 0;
LOG_I(X2AP,"X2ParamList.numelt %d\n",X2ParamList.numelt);
for (l = 0; l < X2ParamList.numelt; l++) {
X2AP_REGISTER_ENB_REQ (msg_p).nb_x2 += 1;
strcpy(X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4_address,*(X2ParamList.paramarray[l][ENB_X2_IPV4_ADDRESS_IDX].strptr));
strcpy(X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6_address,*(X2ParamList.paramarray[l][ENB_X2_IPV6_ADDRESS_IDX].strptr));
LOG_I(X2AP,"registering with ip : %s\n",*(X2ParamList.paramarray[l][ENB_X2_IPV4_ADDRESS_IDX].strptr));
if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) {
X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 1;
X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 0;
} else if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) {
X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 0;
X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 1;
} else if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) {
X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 1;
X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 1;
}
}
// timers
{
int t_reloc_prep = 0;
int tx2_reloc_overall = 0;
int t_dc_prep = 0;
int t_dc_overall = 0;
paramdef_t p[] = {
{ "t_reloc_prep", "t_reloc_prep", 0, .iptr=&t_reloc_prep, .defintval=0, TYPE_INT, 0 },
{ "tx2_reloc_overall", "tx2_reloc_overall", 0, .iptr=&tx2_reloc_overall, .defintval=0, TYPE_INT, 0 },
{ "t_dc_prep", "t_dc_prep", 0, .iptr=&t_dc_prep, .defintval=0, TYPE_INT, 0 },
{ "t_dc_overall", "t_dc_overall", 0, .iptr=&t_dc_overall, .defintval=0, TYPE_INT, 0 }
};
config_get(config_get_if(), p, sizeofArray(p), aprefix);
if (t_reloc_prep <= 0 || t_reloc_prep > 10000 ||
tx2_reloc_overall <= 0 || tx2_reloc_overall > 20000 ||
t_dc_prep <= 0 || t_dc_prep > 10000 ||
t_dc_overall <= 0 || t_dc_overall > 20000) {
LOG_E(X2AP, "timers in configuration file have wrong values. We must have [0 < t_reloc_prep <= 10000] and [0 < tx2_reloc_overall <= 20000] and [0 < t_dc_prep <= 10000] and [0 < t_dc_overall <= 20000]\n");
exit(1);
}
X2AP_REGISTER_ENB_REQ (msg_p).t_reloc_prep = t_reloc_prep;
X2AP_REGISTER_ENB_REQ (msg_p).tx2_reloc_overall = tx2_reloc_overall;
X2AP_REGISTER_ENB_REQ (msg_p).t_dc_prep = t_dc_prep;
X2AP_REGISTER_ENB_REQ (msg_p).t_dc_overall = t_dc_overall;
}
// SCTP SETTING
X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS;
X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS;
if (EPC_MODE_ENABLED) {
sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_SCTP_CONFIG);
config_get(config_get_if(), SCTPParams, sizeofArray(SCTPParams), aprefix);
X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[ENB_SCTP_INSTREAMS_IDX].uptr);
X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[ENB_SCTP_OUTSTREAMS_IDX].uptr);
}
sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
// NETWORK_INTERFACES
config_get(config_get_if(), NETParams, sizeofArray(NETParams), aprefix);
X2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_X2C = (uint32_t)*(NETParams[ENB_PORT_FOR_X2C_IDX].uptr);
if ((NETParams[ENB_IPV4_ADDR_FOR_X2C_IDX].strptr == NULL) || (X2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_X2C == 0)) {
LOG_E(RRC,"Add eNB IPv4 address and/or port for X2C in the CONF file!\n");
exit(1);
}
cidr = *(NETParams[ENB_IPV4_ADDR_FOR_X2C_IDX].strptr);
address = strtok(cidr, "/");
X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv6 = 0;
X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv4 = 1;
strcpy(X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv4_address, address);
}
}
}
}
}
return 0;
}
int RCconfig_parallel(void) {
char *parallel_conf = NULL;
char *worker_conf = NULL;
paramdef_t ThreadParams[] = THREAD_CONF_DESC;
paramlist_def_t THREADParamList = {THREAD_CONFIG_STRING_THREAD_STRUCT,NULL,0};
config_getlist(config_get_if(), &THREADParamList, NULL, 0, NULL);
if(parallel_config == NULL) {
if(THREADParamList.numelt>0) {
config_getlist(config_get_if(), &THREADParamList, ThreadParams, sizeofArray(ThreadParams), NULL);
parallel_conf = strdup(*(THREADParamList.paramarray[0][THREAD_PARALLEL_IDX].strptr));
} else {
parallel_conf = strdup("PARALLEL_RU_L1_TRX_SPLIT");
}
set_parallel_conf(parallel_conf);
}
if(worker_config == NULL) {
if(THREADParamList.numelt>0) {
config_getlist(config_get_if(), &THREADParamList, ThreadParams, sizeofArray(ThreadParams), NULL);
worker_conf = strdup(*(THREADParamList.paramarray[0][THREAD_WORKER_IDX].strptr));
} else {
worker_conf = strdup("WORKER_ENABLE");
}
set_worker_conf(worker_conf);
}
free(worker_conf);
free(parallel_conf);
return 0;
}
void RCConfig(void) {
paramlist_def_t MACRLCParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0};
paramlist_def_t L1ParamList = {CONFIG_STRING_L1_LIST,NULL,0};
paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST,NULL,0};
paramdef_t ENBSParams[] = ENBSPARAMS_DESC;
paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS,NULL,0};
char aprefix[MAX_OPTNAME_SIZE*2 + 8];
/* get global parameters, defined outside any section in the config file */
printf("Getting ENBSParams\n");
config_get(config_get_if(), ENBSParams, sizeofArray(ENBSParams), NULL);
//EPC_MODE_ENABLED = ((*ENBSParams[ENB_NOS1_IDX].uptr) == 0);
RC.nb_inst = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt;
if (RC.nb_inst > 0) {
RC.nb_CC = (int *)malloc((1+RC.nb_inst)*sizeof(int));
for (int i=0; i<RC.nb_inst; i++) {
sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,i);
config_getlist(config_get_if(), &CCsParamList, NULL, 0, aprefix);
RC.nb_CC[i] = CCsParamList.numelt;
}
}
config_getlist(config_get_if(), &MACRLCParamList, NULL, 0, NULL);
RC.nb_macrlc_inst = MACRLCParamList.numelt;
AssertFatal(RC.nb_macrlc_inst <= MAX_MAC_INST,
"Too many macrlc instances %d\n",RC.nb_macrlc_inst);
// Get num L1 instances
config_getlist(config_get_if(), &L1ParamList, NULL, 0, NULL);
RC.nb_L1_inst = L1ParamList.numelt;
// Get num RU instances
config_getlist(config_get_if(), &RUParamList, NULL, 0, NULL);
RC.nb_RU = RUParamList.numelt;
RCconfig_parallel();
}
int check_plmn_identity(rrc_eNB_carrier_data_t *carrier,uint16_t mcc,uint16_t mnc,uint8_t mnc_digit_length) {
AssertFatal(carrier->sib1->cellAccessRelatedInfo.plmn_IdentityList.list.count > 0,
"plmn info isn't there\n");
AssertFatal(mnc_digit_length ==2 || mnc_digit_length == 3,
"impossible mnc_digit_length %d\n",mnc_digit_length);
LTE_PLMN_IdentityInfo_t *plmn_Identity_info = carrier->sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0];
// check if mcc is different and return failure if so
if (mcc !=
(*plmn_Identity_info->plmn_Identity.mcc->list.array[0]*100)+
(*plmn_Identity_info->plmn_Identity.mcc->list.array[1]*10) +
(*plmn_Identity_info->plmn_Identity.mcc->list.array[2])) return(0);
// check that mnc digit length is different and return failure if so
if (mnc_digit_length != plmn_Identity_info->plmn_Identity.mnc.list.count) return 0;
// check that 2 digit mnc is different and return failure if so
if (mnc_digit_length == 2 &&
(mnc !=
(*plmn_Identity_info->plmn_Identity.mnc.list.array[0]*10) +
(*plmn_Identity_info->plmn_Identity.mnc.list.array[1]))) return(0);
else if (mnc_digit_length == 3 &&
(mnc !=
(*plmn_Identity_info->plmn_Identity.mnc.list.array[0]*100) +
(*plmn_Identity_info->plmn_Identity.mnc.list.array[1]*10) +
(*plmn_Identity_info->plmn_Identity.mnc.list.array[2]))) return(0);
// if we're here, the mcc/mnc match so return success
return(1);
}
void extract_and_decode_SI(int inst,int si_ind,uint8_t *si_container,int si_container_length) {
eNB_RRC_INST *rrc = RC.rrc[inst];
rrc_eNB_carrier_data_t *carrier = &rrc->carrier[0];
LTE_BCCH_DL_SCH_Message_t *bcch_message ;
AssertFatal(si_ind==2,"Can only handle a single SI block for now\n");
LOG_I(ENB_APP, "rrc inst %d: Trying to decode SI block %d @ %p, length %d\n",inst,si_ind,si_container,si_container_length);
// point to first SI block
bcch_message = &carrier->systemInformation;
asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
&asn_DEF_LTE_BCCH_DL_SCH_Message,
(void **)&bcch_message,
(const void *)si_container,
si_container_length);
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
AssertFatal(1==0, "[ENB_APP][RRC inst %"PRIu8"] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n",
inst,
dec_rval.consumed );
}
if (bcch_message->message.present == LTE_BCCH_DL_SCH_MessageType_PR_c1) {
switch (bcch_message->message.choice.c1.present) {
case LTE_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1:
AssertFatal(1==0,"Should have received SIB1 from CU\n");
break;
case LTE_BCCH_DL_SCH_MessageType__c1_PR_systemInformation: {
LTE_SystemInformation_t *si = &bcch_message->message.choice.c1.choice.systemInformation;
for (int i=0; i<si->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count; i++) {
LOG_I(ENB_APP,"Extracting SI %d/%d\n",i,si->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count);
struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *typeandinfo;
typeandinfo = si->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.array[i];
switch(typeandinfo->present) {
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2:
carrier->sib2 = &typeandinfo->choice.sib2;
carrier->SIB23 = (uint8_t *)malloc(64);
memcpy((void *)carrier->SIB23,(void *)si_container,si_container_length);
carrier->sizeof_SIB23 = si_container_length;
LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB2\n", inst);
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib3:
carrier->sib3 = &typeandinfo->choice.sib3;
LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB3\n", inst);
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib4:
//carrier->sib4 = &typeandinfo->choice.sib4;
LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB4\n", inst);
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib5:
//carrier->sib5 = &typeandinfo->choice.sib5;
LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB5\n", inst);
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib6:
//carrier->sib6 = &typeandinfo->choice.sib6;
LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB6\n", inst);
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib7:
//carrier->sib7 = &typeandinfo->choice.sib7;
LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB7\n", inst);
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib8:
//carrier->sib8 = &typeandinfo->choice.sib8;
LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB8\n", inst);
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib9:
//carrier->sib9 = &typeandinfo->choice.sib9;
LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB9\n", inst);
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib10:
//carrier->sib10 = &typeandinfo->choice.sib10;
LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB10\n", inst);
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib11:
//carrier->sib11 = &typeandinfo->choice.sib11;
LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB11\n", inst);
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib12_v920:
//carrier->sib12 = &typeandinfo->choice.sib12;
LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB12\n", inst);
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920:
carrier->sib13 = &typeandinfo->choice.sib13_v920;
LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB13\n", inst);
break;
//SIB18
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib18_v1250:
carrier->sib18 = &typeandinfo->choice.sib18_v1250;
LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB18\n", inst);
break;
//SIB19
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib19_v1250:
carrier->sib19 = &typeandinfo->choice.sib19_v1250;
LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB19\n", inst);
break;
//SIB21
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib21_v1430:
carrier->sib21 = &typeandinfo->choice.sib21_v1430;
LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB21\n", inst);
break;
default:
AssertFatal(1==0,"Shouldn't have received this SI %d\n",typeandinfo->present);
break;
}
}
break;
}
case LTE_BCCH_DL_SCH_MessageType__c1_PR_NOTHING:
AssertFatal(0, "Should have received SIB1 from CU\n");
break;
}
} else AssertFatal(1==0,"No SI messages\n");
}
void configure_du_mac(int inst) {
eNB_RRC_INST *rrc = RC.rrc[inst];
rrc_eNB_carrier_data_t *carrier = &rrc->carrier[0];
LOG_I(ENB_APP,"Configuring MAC/L1 %d, carrier->sib2 %p\n",inst,&carrier->sib2->radioResourceConfigCommon);
rrc_mac_config_req_eNB_t tmp = {0};
tmp.physCellId = carrier->physCellId;
tmp.p_eNB = carrier->p_eNB;
tmp.Ncp = carrier->Ncp;
tmp.eutra_band = carrier->sib1->freqBandIndicator;
tmp.dl_CarrierFreq = carrier->dl_CarrierFreq;
tmp.pbch_repetition = carrier->pbch_repetition;
tmp.mib = &carrier->mib;
tmp.radioResourceConfigCommon = &carrier->sib2->radioResourceConfigCommon;
tmp.LTE_radioResourceConfigCommon_BR = &carrier->sib2_BR->radioResourceConfigCommon;
tmp.tdd_Config = carrier->sib1->tdd_Config;
tmp.schedulingInfoList = &carrier->sib1->schedulingInfoList;
tmp.ul_CarrierFreq = carrier->ul_CarrierFreq;
tmp.ul_Bandwidth = carrier->sib2->freqInfo.ul_Bandwidth;
tmp.additionalSpectrumEmission = &carrier->sib2->freqInfo.additionalSpectrumEmission;
tmp.mbsfn_SubframeConfigList = carrier->sib2->mbsfn_SubframeConfigList;
tmp.MBMS_Flag = carrier->MBMS_flag;
tmp.mbsfn_AreaInfoList = &carrier->sib13->mbsfn_AreaInfoList_r9;
rrc_mac_config_req_eNB(inst, &tmp);
}
void read_config_and_init(void) {
if (RC.nb_macrlc_inst > 0)
AssertFatal(RC.nb_macrlc_inst == RC.nb_inst,
"Number of MACRLC instances %d != number of RRC instances %d\n",
RC.nb_macrlc_inst, RC.nb_inst);
RCconfig_L1();
LOG_I(PHY, "%s() RC.nb_L1_inst: %d\n", __FUNCTION__, RC.nb_L1_inst);
RCconfig_macrlc();
LOG_I(MAC, "%s() RC.nb_macrlc_inst: %d\n", __FUNCTION__, RC.nb_macrlc_inst);
if (RC.nb_L1_inst > 0)
AssertFatal(l1_north_init_eNB() == 0, "could not initialize L1 north interface\n");
RC.rrc = malloc(RC.nb_inst * sizeof(eNB_RRC_INST *));
AssertFatal(RC.rrc, "could not allocate memory for RC.rrc\n");
for (uint32_t enb_id = 0; enb_id < RC.nb_inst; enb_id++) {
RC.rrc[enb_id] = malloc(sizeof(eNB_RRC_INST));
AssertFatal(RC.rrc[enb_id], "RRC context for eNB %u not allocated\n", enb_id);
memset((void *)RC.rrc[enb_id], 0, sizeof(eNB_RRC_INST));
RCconfig_RRC(enb_id, RC.rrc[enb_id]);
}
}
#ifdef E2_AGENT
e2_agent_args_t RCconfig_E2agent(void)
{
paramdef_t e2agent_params[] = E2AGENT_PARAMS_DESC;
int ret = config_get(config_get_if(), e2agent_params, sizeofArray(e2agent_params), CONFIG_STRING_E2AGENT);
if (ret < 0) {
LOG_W(GNB_APP, "configuration file does not contain a \"%s\" section, applying default parameters\n", CONFIG_STRING_E2AGENT);
return (e2_agent_args_t) {0};
}
bool enabled = config_isparamset(e2agent_params, E2AGENT_CONFIG_SMDIR_IDX)
&& config_isparamset(e2agent_params, E2AGENT_CONFIG_IP_IDX);
if (!enabled) {
LOG_W(GNB_APP, "E2 agent is DISABLED (for activation, define .%s.{%s,%s} parameters)\n", CONFIG_STRING_E2AGENT, E2AGENT_CONFIG_IP, E2AGENT_CONFIG_SMDIR);
return (e2_agent_args_t) {
.enabled = false,
};
}
return (e2_agent_args_t) {
.enabled = true,
.ip = *e2agent_params[E2AGENT_CONFIG_IP_IDX].strptr,
.sm_dir = *e2agent_params[E2AGENT_CONFIG_SMDIR_IDX].strptr,
};
}
#endif