Skip to content
Snippets Groups Projects
enb_config.c 134 KiB
Newer Older
/*
 * 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
 */
Lionel Gauthier's avatar
Lionel Gauthier committed
/*
  enb_config.c
  -------------------
  AUTHOR  : Lionel GAUTHIER, navid nikaein, Laurent Winckel
Lionel Gauthier's avatar
Lionel Gauthier committed
  COMPANY : EURECOM
  EMAIL   : Lionel.Gauthier@eurecom.fr, navid.nikaein@eurecom.fr
#include <inttypes.h>
#include "assertions.h"
#include "enb_config.h"
#include "UTIL/OTG/otg.h"
#include "UTIL/OTG/otg_externs.h"
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
# if defined(ENABLE_USE_MME)
#   include "s1ap_eNB.h"
#   include "sctp_eNB_task.h"
frtabu's avatar
frtabu committed
# else
#  define EPC_MODE_ENABLED 0
# endif
#include "sctp_default_values.h"
#include "SystemInformationBlockType2.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 "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h"
#include "L1_paramdef.h"
#include "MACRLC_paramdef.h"
#include "common/config/config_userapi.h"
#include "RRC_config_tools.h"
#include "enb_paramdef.h"
void RCconfig_flexran() {
  uint16_t i;
  uint16_t num_enbs;
  char aprefix[MAX_OPTNAME_SIZE*2 + 8];
  /* this will possibly truncate the cell id (RRC assumes int32_t).
   * Both Nid_cell and enb_id are signed in RRC case, but we use unsigned for
   * the bitshifting to work properly */
  int32_t Nid_cell = 0;
  uint16_t Nid_cell_tr = 0;
  uint32_t enb_id = 0;
  /*
   * the only reason for all these variables is, that they are "hard-encoded"
   * into the CCPARAMS_DESC macro and we need it for the Nid_cell variable ...
   */
  char *frame_type, *prefix_type, *pbch_repetition, *prach_high_speed,
       *pusch_hoppingMode, *pusch_enable64QAM, *pusch_groupHoppingEnabled,
       *pusch_sequenceHoppingEnabled, *phich_duration, *phich_resource,
       *srs_enable, *srs_ackNackST, *srs_MaxUpPts, *pusch_alpha,
       *pucch_deltaF_Format1, *pucch_deltaF_Format1b, *pucch_deltaF_Format2,
       *pucch_deltaF_Format2a, *pucch_deltaF_Format2b,
       *rach_preamblesGroupAConfig, *rach_messagePowerOffsetGroupB, *pcch_nB;
  long long int     downlink_frequency;
  int32_t tdd_config, tdd_config_s, eutra_band, uplink_frequency_offset,
          Nid_cell_mbsfn, N_RB_DL, nb_antenna_ports, prach_root, prach_config_index,
          prach_zero_correlation, prach_freq_offset, pucch_delta_shift,
          pucch_nRB_CQI, pucch_nCS_AN, pucch_n1_AN, pdsch_referenceSignalPower,
          pdsch_p_b, pusch_n_SB, pusch_hoppingOffset, pusch_groupAssignment,
          pusch_nDMRS1, srs_BandwidthConfig, srs_SubframeConfig, pusch_p0_Nominal,
          pucch_p0_Nominal, msg3_delta_Preamble, rach_numberOfRA_Preambles,
          rach_sizeOfRA_PreamblesGroupA, rach_messageSizeGroupA,
          rach_powerRampingStep, rach_preambleInitialReceivedTargetPower,
          rach_preambleTransMax, rach_raResponseWindowSize,
          rach_macContentionResolutionTimer, rach_maxHARQ_Msg3Tx,
          pcch_defaultPagingCycle, bcch_modificationPeriodCoeff,
          ue_TimersAndConstants_t300, ue_TimersAndConstants_t301,
          ue_TimersAndConstants_t310, ue_TimersAndConstants_t311,
          ue_TimersAndConstants_n310, ue_TimersAndConstants_n311,
          ue_TransmissionMode, ue_multiple_max;
  const char       *rxPool_sc_CP_Len;
  const char       *rxPool_sc_Period;
  const char       *rxPool_data_CP_Len;
  libconfig_int     rxPool_ResourceConfig_prb_Num;
  libconfig_int     rxPool_ResourceConfig_prb_Start;
  libconfig_int     rxPool_ResourceConfig_prb_End;
  const char       *rxPool_ResourceConfig_offsetIndicator_present;
  libconfig_int     rxPool_ResourceConfig_offsetIndicator_choice;
  const char       *rxPool_ResourceConfig_subframeBitmap_present;
  char             *rxPool_ResourceConfig_subframeBitmap_choice_bs_buf;
  libconfig_int     rxPool_ResourceConfig_subframeBitmap_choice_bs_size;
  libconfig_int     rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused;
  //SIB19
  //for discRxPool
  const char       *discRxPool_cp_Len;
  const char       *discRxPool_discPeriod;
  libconfig_int     discRxPool_numRetx;
  libconfig_int     discRxPool_numRepetition;
  libconfig_int     discRxPool_ResourceConfig_prb_Num;
  libconfig_int     discRxPool_ResourceConfig_prb_Start;
  libconfig_int     discRxPool_ResourceConfig_prb_End;
  const char       *discRxPool_ResourceConfig_offsetIndicator_present;
  libconfig_int     discRxPool_ResourceConfig_offsetIndicator_choice;
  const char       *discRxPool_ResourceConfig_subframeBitmap_present;
  char             *discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf;
  libconfig_int     discRxPool_ResourceConfig_subframeBitmap_choice_bs_size;
  libconfig_int     discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused;
  //for discRxPoolPS
  const char       *discRxPoolPS_cp_Len;
  const char       *discRxPoolPS_discPeriod;
  libconfig_int     discRxPoolPS_numRetx;
  libconfig_int     discRxPoolPS_numRepetition;
  libconfig_int     discRxPoolPS_ResourceConfig_prb_Num;
  libconfig_int     discRxPoolPS_ResourceConfig_prb_Start;
  libconfig_int     discRxPoolPS_ResourceConfig_prb_End;
  const char       *discRxPoolPS_ResourceConfig_offsetIndicator_present;
  libconfig_int     discRxPoolPS_ResourceConfig_offsetIndicator_choice;
  const char       *discRxPoolPS_ResourceConfig_subframeBitmap_present;
  char             *discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf;
  libconfig_int     discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size;
  libconfig_int     discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused;
  /* get number of eNBs */
  paramdef_t ENBSParams[] = ENBSPARAMS_DESC;
  config_get(ENBSParams, sizeof(ENBSParams)/sizeof(paramdef_t), NULL);
  num_enbs = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt;
  /* for eNB ID */
  paramdef_t ENBParams[]  = ENBPARAMS_DESC;
  paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST, NULL, 0};
  /* for Nid_cell */
  checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK;
  paramdef_t CCsParams[] = CCPARAMS_DESC;
  paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS, NULL, 0};
  /* map parameter checking array instances to parameter definition array instances */
  for (int I = 0; I < (sizeof(CCsParams) / sizeof(paramdef_t)); I++) {
    CCsParams[I].chkPptr = &(config_check_CCparams[I]);
  }
  paramdef_t flexranParams[] = FLEXRANPARAMS_DESC;
  config_get(flexranParams, sizeof(flexranParams)/sizeof(paramdef_t), CONFIG_STRING_NETWORK_CONTROLLER_CONFIG);
  if (!RC.flexran) {
    RC.flexran = calloc(num_enbs, sizeof(flexran_agent_info_t *));
                "can't ALLOCATE %zu Bytes for %d flexran agent info with size %zu\n",
                num_enbs * sizeof(flexran_agent_info_t *),
                num_enbs, sizeof(flexran_agent_info_t *));
    RC.flexran[i] = calloc(1, sizeof(flexran_agent_info_t));
                "can't ALLOCATE %zu Bytes for flexran agent info (iteration %d/%d)\n",
                sizeof(flexran_agent_info_t), i + 1, num_enbs);
    /* if config says "yes", enable Agent, in all other cases it's like "no" */
    RC.flexran[i]->enabled          = strcasecmp(*(flexranParams[FLEXRAN_ENABLED].strptr), "yes") == 0;
    /* if not enabled, simply skip the rest, it is not needed anyway */
    if (!RC.flexran[i]->enabled)
      continue;
    RC.flexran[i]->interface_name   = strdup(*(flexranParams[FLEXRAN_INTERFACE_NAME_IDX].strptr));
    //inet_ntop(AF_INET, &(enb_properties->properties[mod_id]->flexran_agent_ipv4_address), in_ip, INET_ADDRSTRLEN);
    RC.flexran[i]->remote_ipv4_addr = strdup(*(flexranParams[FLEXRAN_IPV4_ADDRESS_IDX].strptr));
    RC.flexran[i]->remote_port      = *(flexranParams[FLEXRAN_PORT_IDX].uptr);
    RC.flexran[i]->cache_name       = strdup(*(flexranParams[FLEXRAN_CACHE_IDX].strptr));
    RC.flexran[i]->node_ctrl_state  = strcasecmp(*(flexranParams[FLEXRAN_AWAIT_RECONF_IDX].strptr), "yes") == 0 ? ENB_WAIT : ENB_NORMAL_OPERATION;
    config_getlist(&ENBParamList, ENBParams, sizeof(ENBParams)/sizeof(paramdef_t),NULL);
    /* eNB ID from configuration, as read in by RCconfig_RRC() */
    if (!ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr) {
      // Calculate a default eNB ID
        enb_id = i + (s1ap_generate_eNB_id () & 0xFFFF8);
        enb_id = i;
      enb_id = *(ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr);
    /* cell ID */
    sprintf(aprefix, "%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, i);
    config_getlist(&CCsParamList, NULL, 0, aprefix);
    if (CCsParamList.numelt > 0) {
      sprintf(aprefix, "%s.[%i].%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, i, ENB_CONFIG_STRING_COMPONENT_CARRIERS, 0);
      config_get(CCsParams, sizeof(CCsParams)/sizeof(paramdef_t), aprefix);
      Nid_cell_tr = (uint16_t) Nid_cell;
    }
    RC.flexran[i]->mod_id   = i;
    RC.flexran[i]->agent_id = (((uint64_t)i) << 48) | (((uint64_t)enb_id) << 16) | ((uint64_t)Nid_cell_tr);
    /* assume for the moment the monolithic case, i.e. agent can provide
     * information for all layers */
    RC.flexran[i]->capability_mask = FLEXRAN_CAP_LOPHY | FLEXRAN_CAP_HIPHY
                                     | FLEXRAN_CAP_LOMAC | FLEXRAN_CAP_HIMAC
                                     | FLEXRAN_CAP_RLC   | FLEXRAN_CAP_PDCP
                                     | FLEXRAN_CAP_SDAP  | FLEXRAN_CAP_RRC;
  int               i,j;
  paramdef_t L1_Params[] = L1PARAMS_DESC;
  paramlist_def_t L1_ParamList = {CONFIG_STRING_L1_LIST,NULL,0};

    RC.eNB                       = (PHY_VARS_eNB ** *)malloc((1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_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));
  }
Cedric Roux's avatar
Cedric Roux committed
  config_getlist( &L1_ParamList,L1_Params,sizeof(L1_Params)/sizeof(paramdef_t), 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 *)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;
        }
      }

      if (strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_mac") == 0) {
        sf_ahead = 4; // Need 4 subframe gap between RX and TX
      } 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;
        sf_ahead = 2; // Cannot cope with 4 subframes betweem RX and TX - set it to 2
        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; // DJP - 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
    printf("Initializing northbound interface for L1\n");
    l1_north_init_eNB();
  } else {
    LOG_I(PHY,"No " CONFIG_STRING_L1_LIST " configuration found");
    // DJP need to create some structures for VNF
    j = 0;
    RC.nb_L1_CC = malloc((1+RC.nb_L1_inst)*sizeof(int)); // DJP - 1 lot then???
    RC.nb_L1_CC[j]=1; // DJP - hmmm

    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() {
  int               j;
  paramdef_t MacRLC_Params[] = MACRLCPARAMS_DESC;
  paramlist_def_t MacRLC_ParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0};
  config_getlist( &MacRLC_ParamList,MacRLC_Params,sizeof(MacRLC_Params)/sizeof(paramdef_t), NULL);
    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++) {
Cedric Roux's avatar
Cedric Roux committed
      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.nb_mac_CC[j] = *(MacRLC_ParamList.paramarray[j][MACRLC_CC_IDX].iptr);
Raymond Knopp's avatar
Raymond Knopp committed
      //RC.mac[j]->phy_test = *(MacRLC_ParamList.paramarray[j][MACRLC_PHY_TEST_IDX].iptr);
      //printf("PHY_TEST = %d,%d\n", RC.mac[j]->phy_test, j);

      if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_RRC") == 0) {
        // check number of instances is same as RRC/PDCP
      } else if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "cudu") == 0) {
        RC.mac[j]->eth_params_n.local_if_name            = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_IF_NAME_IDX].strptr));
        RC.mac[j]->eth_params_n.my_addr                  = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_ADDRESS_IDX].strptr));
        RC.mac[j]->eth_params_n.remote_addr              = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_ADDRESS_IDX].strptr));
        RC.mac[j]->eth_params_n.my_portc                 = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTC_IDX].iptr);
        RC.mac[j]->eth_params_n.remote_portc             = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTC_IDX].iptr);
        RC.mac[j]->eth_params_n.my_portd                 = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTD_IDX].iptr);
        RC.mac[j]->eth_params_n.remote_portd             = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTD_IDX].iptr);;
        RC.mac[j]->eth_params_n.transp_preference        = ETH_UDP_MODE;
        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;
        sf_ahead = 2; // Cannot cope with 4 subframes betweem RX and TX - set it to 2
        printf("**************** 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);
        printf("**************** RETURNED FROM configure_nfapi_vnf() vnf_port:%d\n", RC.mac[j]->eth_params_s.my_portc);
        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;
        printf("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));
    }// j=0..num_inst
  } else {// MacRLC_ParamList.numelt > 0
    AssertFatal (0,
                 "No " CONFIG_STRING_MACRLC_LIST " configuration found");
int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
  int               num_enbs                      = 0;
  int               j,k                           = 0;
  int32_t     enb_id                        = 0;
  int               nb_cc                         = 0;
  char       *frame_type                    = NULL;
  int32_t     tdd_config                    = 0;
  int32_t     tdd_config_s                  = 0;
  char       *prefix_type                   = NULL;
  char       *pbch_repetition               = NULL;
  int32_t     eutra_band                    = 0;
  long long int     downlink_frequency            = 0;
  int32_t     uplink_frequency_offset       = 0;
  int32_t     Nid_cell                      = 0;
  int32_t     Nid_cell_mbsfn                = 0;
  int32_t     N_RB_DL                       = 0;
  int32_t     nb_antenna_ports              = 0;
  int32_t     prach_root                    = 0;
  int32_t     prach_config_index            = 0;
  char            *prach_high_speed         = NULL;
  int32_t     prach_zero_correlation        = 0;
  int32_t     prach_freq_offset             = 0;
  int32_t     pucch_delta_shift             = 0;
  int32_t     pucch_nRB_CQI                 = 0;
  int32_t     pucch_nCS_AN                  = 0;
  //#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
  //#endif
  int32_t     pdsch_referenceSignalPower    = 0;
  int32_t     pdsch_p_b                     = 0;
  int32_t     pusch_n_SB                    = 0;
  char       *pusch_hoppingMode             = NULL;
  char          *pusch_enable64QAM          = NULL;
  char          *pusch_groupHoppingEnabled  = NULL;
  char          *pusch_sequenceHoppingEnabled = NULL;
  char       *phich_duration                = NULL;
  char       *phich_resource                = NULL;
  char       *srs_enable                    = NULL;
  int32_t     srs_BandwidthConfig           = 0;
  int32_t     srs_SubframeConfig            = 0;
  char       *srs_ackNackST                 = NULL;
  char       *srs_MaxUpPts                  = NULL;
  char       *pusch_alpha                   = NULL;
  int32_t     pucch_p0_Nominal              = 0;
  int32_t     msg3_delta_Preamble           = 0;
  //int32_t     ul_CyclicPrefixLength         = 0;
  char       *pucch_deltaF_Format1          = NULL;
  //const char*       pucch_deltaF_Format1a         = NULL;
  char       *pucch_deltaF_Format1b         = NULL;
  char       *pucch_deltaF_Format2          = NULL;
  char       *pucch_deltaF_Format2a         = NULL;
  char       *pucch_deltaF_Format2b         = NULL;
  int32_t     rach_numberOfRA_Preambles     = 0;
  char       *rach_preamblesGroupAConfig    = NULL;
  int32_t     rach_sizeOfRA_PreamblesGroupA = 0;
  int32_t     rach_messageSizeGroupA        = 0;
  char       *rach_messagePowerOffsetGroupB = NULL;
  int32_t     rach_powerRampingStep         = 0;
  int32_t     rach_preambleInitialReceivedTargetPower    = 0;
  int32_t     rach_preambleTransMax         = 0;
  int32_t     rach_macContentionResolutionTimer = 0;
  int32_t     rach_maxHARQ_Msg3Tx           = 0;
  int32_t     pcch_defaultPagingCycle       = 0;
  char       *pcch_nB                       = NULL;
  int32_t     bcch_modificationPeriodCoeff  = 0;
  int32_t     ue_TimersAndConstants_t300    = 0;
  int32_t     ue_TimersAndConstants_t301    = 0;
  int32_t     ue_TimersAndConstants_t310    = 0;
  int32_t     ue_TimersAndConstants_t311    = 0;
  int32_t     ue_TimersAndConstants_n310    = 0;
  int32_t     ue_TimersAndConstants_n311    = 0;
  int32_t     ue_TransmissionMode           = 0;
Xu Bo's avatar
Xu Bo committed
  int32_t     ue_multiple_max               = 0;
  const char       *rxPool_sc_CP_Len                                        = NULL;
  const char       *rxPool_sc_Period                                        = NULL;
  const char       *rxPool_data_CP_Len                                      = NULL;
  libconfig_int     rxPool_ResourceConfig_prb_Num                           = 0;
  libconfig_int     rxPool_ResourceConfig_prb_Start                         = 0;
  libconfig_int     rxPool_ResourceConfig_prb_End                           = 0;
  const char       *rxPool_ResourceConfig_offsetIndicator_present           = NULL;
  libconfig_int     rxPool_ResourceConfig_offsetIndicator_choice            = 0;
  const char       *rxPool_ResourceConfig_subframeBitmap_present            = NULL;
  char             *rxPool_ResourceConfig_subframeBitmap_choice_bs_buf      = NULL;
  libconfig_int     rxPool_ResourceConfig_subframeBitmap_choice_bs_size     = 0;
  libconfig_int     rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused     = 0;
  //SIB19
  //For discRxPool
  const char       *discRxPool_cp_Len                                              = NULL;
  const char       *discRxPool_discPeriod                                          = NULL;
  libconfig_int     discRxPool_numRetx                                             = 0;
  libconfig_int     discRxPool_numRepetition                                       = 0;
  libconfig_int     discRxPool_ResourceConfig_prb_Num                              = 0;
  libconfig_int     discRxPool_ResourceConfig_prb_Start                            = 0;
  libconfig_int     discRxPool_ResourceConfig_prb_End                              = 0;
  const char       *discRxPool_ResourceConfig_offsetIndicator_present              = NULL;
  libconfig_int     discRxPool_ResourceConfig_offsetIndicator_choice               = 0;
  const char       *discRxPool_ResourceConfig_subframeBitmap_present               = NULL;
  char             *discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf         = NULL;
  libconfig_int     discRxPool_ResourceConfig_subframeBitmap_choice_bs_size        = 0;
  libconfig_int     discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
  //For discRxPoolPS
  const char       *discRxPoolPS_cp_Len                                              = NULL;
  const char       *discRxPoolPS_discPeriod                                          = NULL;
  libconfig_int     discRxPoolPS_numRetx                                             = 0;
  libconfig_int     discRxPoolPS_numRepetition                                       = 0;
  libconfig_int     discRxPoolPS_ResourceConfig_prb_Num                              = 0;
  libconfig_int     discRxPoolPS_ResourceConfig_prb_Start                            = 0;
  libconfig_int     discRxPoolPS_ResourceConfig_prb_End                              = 0;
  const char       *discRxPoolPS_ResourceConfig_offsetIndicator_present              = NULL;
  libconfig_int     discRxPoolPS_ResourceConfig_offsetIndicator_choice               = 0;
  const char       *discRxPoolPS_ResourceConfig_subframeBitmap_present               = NULL;
  char             *discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf         = NULL;
  libconfig_int     discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size        = 0;
  libconfig_int     discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
  int32_t     srb1_timer_poll_retransmit    = 0;
  int32_t     srb1_timer_reordering         = 0;
  int32_t     srb1_timer_status_prohibit    = 0;
  int32_t     srb1_poll_pdu                 = 0;
  int32_t     srb1_poll_byte                = 0;
  int32_t     srb1_max_retx_threshold       = 0;
  int32_t     my_int;
  // for no gcc warnings
  (void)my_int;
  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;
  paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS,NULL,0};
  paramdef_t SRB1Params[] = SRB1PARAMS_DESC;
  /* map parameter checking array instances to parameter definition array instances */
  for (int I=0; I< ( sizeof(CCsParams)/ sizeof(paramdef_t)  ) ; I++) {
    CCsParams[I].chkPptr = &(config_check_CCparams[I]);
  /* get global parameters, defined outside any section in the config file */
  config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL);
  num_enbs = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt;
  AssertFatal (i<num_enbs,
               "Failed to parse config file no %ith element in %s \n",i, ENB_CONFIG_STRING_ACTIVE_ENBS);

  if (num_enbs>0) {
    // Output a list of all eNBs.
    config_getlist( &ENBParamList,ENBParams,sizeof(ENBParams)/sizeof(paramdef_t),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);
        enb_id = i;
    } else {
      enb_id = *(ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr);
    }
    printf("RRC %d: Southbound Transport %s\n",i,*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr));

    if (strcmp(*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr), "local_mac") == 0) {
    } else if (strcmp(*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr), "cudu") == 0) {
      rrc->eth_params_s.local_if_name            = strdup(*(ENBParamList.paramarray[i][ENB_LOCAL_S_IF_NAME_IDX].strptr));
      rrc->eth_params_s.my_addr                  = strdup(*(ENBParamList.paramarray[i][ENB_LOCAL_S_ADDRESS_IDX].strptr));
      rrc->eth_params_s.remote_addr              = strdup(*(ENBParamList.paramarray[i][ENB_REMOTE_S_ADDRESS_IDX].strptr));
      rrc->eth_params_s.my_portc                 = *(ENBParamList.paramarray[i][ENB_LOCAL_S_PORTC_IDX].uptr);
      rrc->eth_params_s.remote_portc             = *(ENBParamList.paramarray[i][ENB_REMOTE_S_PORTC_IDX].uptr);
      rrc->eth_params_s.my_portd                 = *(ENBParamList.paramarray[i][ENB_LOCAL_S_PORTD_IDX].uptr);
      rrc->eth_params_s.remote_portd             = *(ENBParamList.paramarray[i][ENB_REMOTE_S_PORTD_IDX].uptr);
      rrc->eth_params_s.transp_preference        = ETH_UDP_MODE;
    } else { // other midhaul
    }
    // 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 < sizeof(PLMNParams) / sizeof(paramdef_t); ++I)
          PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]);

        RRC_CONFIGURATION_REQ (msg_p).cell_identity = enb_id;
        /*
        if (strcmp(*(ENBParamList.paramarray[i][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_ENB") == 0) {
        enb_properties_loc.properties[enb_properties_loc_index]->cell_type = CELL_MACRO_ENB;
        } else  if (strcmp(cell_type, "CELL_HOME_ENB") == 0) {
        enb_properties_loc.properties[enb_properties_loc_index]->cell_type = CELL_HOME_ENB;
        } else {
        AssertFatal (0,
        "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n",
        lib_config_file_name_pP, i, cell_type);
        }

        enb_properties_loc.properties[enb_properties_loc_index]->eNB_name         = strdup(enb_name);
        */
        RRC_CONFIGURATION_REQ(msg_p).tac = *ENBParamList.paramarray[i][ENB_TRACKING_AREA_CODE_IDX].uptr;
        AssertFatal(!ENBParamList.paramarray[i][ENB_MOBILE_COUNTRY_CODE_IDX_OLD].strptr
                    && !ENBParamList.paramarray[i][ENB_MOBILE_NETWORK_CODE_IDX_OLD].strptr,
                    "It seems that you use an old configuration file. Please change the existing\n"
                    "    tracking_area_code  =  \"1\";\n"
                    "    mobile_country_code =  \"208\";\n"
                    "    mobile_network_code =  \"93\";\n"
                    "to\n"
                    "    tracking_area_code  =  1; // no string!!\n"
                    "    plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } )\n");
        config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), enbpath);

        if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6)
          AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n",
                      PLMNParamList.numelt);

        RRC_CONFIGURATION_REQ(msg_p).num_plmn = PLMNParamList.numelt;

        for (int l = 0; l < PLMNParamList.numelt; ++l) {
          RRC_CONFIGURATION_REQ(msg_p).mcc[l] = *PLMNParamList.paramarray[l][ENB_MOBILE_COUNTRY_CODE_IDX].uptr;
          RRC_CONFIGURATION_REQ(msg_p).mnc[l] = *PLMNParamList.paramarray[l][ENB_MOBILE_NETWORK_CODE_IDX].uptr;
          RRC_CONFIGURATION_REQ(msg_p).mnc_digit_length[l] = *PLMNParamList.paramarray[l][ENB_MNC_DIGIT_LENGTH].u8ptr;
          AssertFatal(RRC_CONFIGURATION_REQ(msg_p).mnc_digit_length[l] == 3
                      || RRC_CONFIGURATION_REQ(msg_p).mnc[l] < 100,
                      "MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n",
                      RRC_CONFIGURATION_REQ(msg_p).mnc[l]);
        }

        // Parse optional physical parameters
        config_getlist( &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, sizeof(CCsParams)/sizeof(paramdef_t), ccspath);
            config_get( CCsParams,sizeof(CCsParams)/sizeof(paramdef_t),ccspath);
            //printf("Component carrier %d\n",component_carrier);
            nb_cc++;
            RRC_CONFIGURATION_REQ (msg_p).tdd_config[j] = tdd_config;
            AssertFatal (tdd_config <= TDD_Config__subframeAssignment_sa6,
                         "Failed to parse eNB configuration file %s, enb %d illegal tdd_config %d (should be 0-%d)!",
                         RC.config_file_name, i, tdd_config, TDD_Config__subframeAssignment_sa6);
            RRC_CONFIGURATION_REQ (msg_p).tdd_config_s[j] = tdd_config_s;
            AssertFatal (tdd_config_s <= TDD_Config__specialSubframePatterns_ssp8,
                         "Failed to parse eNB configuration file %s, enb %d illegal tdd_config_s %d (should be 0-%d)!",
                         RC.config_file_name, i, tdd_config_s, TDD_Config__specialSubframePatterns_ssp8);

            if (!prefix_type)
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d define %s: NORMAL,EXTENDED!\n",
                           RC.config_file_name, i, ENB_CONFIG_STRING_PREFIX_TYPE);
            else if (strcmp(prefix_type, "NORMAL") == 0) {
              RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = NORMAL;
            } else  if (strcmp(prefix_type, "EXTENDED") == 0) {
              RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = EXTENDED;
            } else {
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prefix_type choice: NORMAL or EXTENDED !\n",
                           RC.config_file_name, i, prefix_type);
            }
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))

            if (!pbch_repetition)
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d define %s: TRUE,FALSE!\n",
                           RC.config_file_name, i, ENB_CONFIG_STRING_PBCH_REPETITION);
            else if (strcmp(pbch_repetition, "TRUE") == 0) {
              RRC_CONFIGURATION_REQ (msg_p).pbch_repetition[j] = 1;
            } else  if (strcmp(pbch_repetition, "FALSE") == 0) {
              RRC_CONFIGURATION_REQ (msg_p).pbch_repetition[j] = 0;
            } else {
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pbch_repetition choice: TRUE or FALSE !\n",
                           RC.config_file_name, i, pbch_repetition);
            }

            RRC_CONFIGURATION_REQ (msg_p).eutra_band[j] = eutra_band;
            RRC_CONFIGURATION_REQ (msg_p).downlink_frequency[j] = (uint32_t) downlink_frequency;
            RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j] = (unsigned int) uplink_frequency_offset;
            RRC_CONFIGURATION_REQ (msg_p).Nid_cell[j]= Nid_cell;

            if (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, i, Nid_cell);
            }

            RRC_CONFIGURATION_REQ (msg_p).N_RB_DL[j]= N_RB_DL;

            if ((N_RB_DL!=6) && (N_RB_DL!=15) && (N_RB_DL!=25) && (N_RB_DL!=50) && (N_RB_DL!=75) && (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, i, N_RB_DL);
            }

            if (strcmp(frame_type, "FDD") == 0) {
              RRC_CONFIGURATION_REQ (msg_p).frame_type[j] = FDD;
            } else  if (strcmp(frame_type, "TDD") == 0) {
              RRC_CONFIGURATION_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, i, frame_type);
            }

            RRC_CONFIGURATION_REQ (msg_p).tdd_config[j] = tdd_config;
            AssertFatal (tdd_config <= TDD_Config__subframeAssignment_sa6,
                         "Failed to parse eNB configuration file %s, enb %d illegal tdd_config %d (should be 0-%d)!",
                         RC.config_file_name, i, tdd_config, TDD_Config__subframeAssignment_sa6);
            RRC_CONFIGURATION_REQ (msg_p).tdd_config_s[j] = tdd_config_s;
            AssertFatal (tdd_config_s <= TDD_Config__specialSubframePatterns_ssp8,
                         "Failed to parse eNB configuration file %s, enb %d illegal tdd_config_s %d (should be 0-%d)!",
                         RC.config_file_name, i, tdd_config_s, TDD_Config__specialSubframePatterns_ssp8);

            if (!prefix_type)
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d define %s: NORMAL,EXTENDED!\n",
                           RC.config_file_name, i, ENB_CONFIG_STRING_PREFIX_TYPE);
            else if (strcmp(prefix_type, "NORMAL") == 0) {
              RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = NORMAL;
            } else  if (strcmp(prefix_type, "EXTENDED") == 0) {
              RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = EXTENDED;
            } else {
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prefix_type choice: NORMAL or EXTENDED !\n",
                           RC.config_file_name, i, prefix_type);
            }

            RRC_CONFIGURATION_REQ (msg_p).eutra_band[j] = eutra_band;
            // printf( "\teutra band:\t%d\n",RRC_CONFIGURATION_REQ (msg_p).eutra_band);
            RRC_CONFIGURATION_REQ (msg_p).downlink_frequency[j] = (uint32_t) downlink_frequency;
            //printf( "\tdownlink freq:\t%u\n",RRC_CONFIGURATION_REQ (msg_p).downlink_frequency);
            RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j] = (unsigned int) uplink_frequency_offset;

            if (config_check_band_frequencies(j,
                                              RRC_CONFIGURATION_REQ (msg_p).eutra_band[j],
                                              RRC_CONFIGURATION_REQ (msg_p).downlink_frequency[j],
                                              RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j],
                                              RRC_CONFIGURATION_REQ (msg_p).frame_type[j])) {
              AssertFatal(0, "error calling enb_check_band_frequencies\n");
            }

            if ((nb_antenna_ports <1) || (nb_antenna_ports > 2))
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for nb_antenna_ports choice: 1..2 !\n",
                           RC.config_file_name, i, nb_antenna_ports);

            RRC_CONFIGURATION_REQ (msg_p).nb_antenna_ports[j] = nb_antenna_ports;
            RRC_CONFIGURATION_REQ (msg_p).prach_root[j] =  prach_root;

            if ((prach_root <0) || (prach_root > 1023))
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_root choice: 0..1023 !\n",
                           RC.config_file_name, i, prach_root);

            RRC_CONFIGURATION_REQ (msg_p).prach_config_index[j] = prach_config_index;

            if ((prach_config_index <0) || (prach_config_index > 63))
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_config_index choice: 0..1023 !\n",
                           RC.config_file_name, i, prach_config_index);

            if (!prach_high_speed)
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n",
                           RC.config_file_name, i, ENB_CONFIG_STRING_PRACH_HIGH_SPEED);
            else if (strcmp(prach_high_speed, "ENABLE") == 0) {
              RRC_CONFIGURATION_REQ (msg_p).prach_high_speed[j] = TRUE;
            } else if (strcmp(prach_high_speed, "DISABLE") == 0) {
              RRC_CONFIGURATION_REQ (msg_p).prach_high_speed[j] = FALSE;
            } else
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prach_config choice: ENABLE,DISABLE !\n",
                           RC.config_file_name, i, prach_high_speed);

            RRC_CONFIGURATION_REQ (msg_p).prach_zero_correlation[j] =prach_zero_correlation;

            if ((prach_zero_correlation <0) || (prach_zero_correlation > 15))
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_zero_correlation choice: 0..15!\n",
                           RC.config_file_name, i, prach_zero_correlation);

            RRC_CONFIGURATION_REQ (msg_p).prach_freq_offset[j] = prach_freq_offset;

            if ((prach_freq_offset <0) || (prach_freq_offset > 94))
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_freq_offset choice: 0..94!\n",
                           RC.config_file_name, i, prach_freq_offset);

            RRC_CONFIGURATION_REQ (msg_p).pucch_delta_shift[j] = pucch_delta_shift-1;

            if ((pucch_delta_shift <1) || (pucch_delta_shift > 3))
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_delta_shift choice: 1..3!\n",
                           RC.config_file_name, i, pucch_delta_shift);

            RRC_CONFIGURATION_REQ (msg_p).pucch_nRB_CQI[j] = pucch_nRB_CQI;

            if ((pucch_nRB_CQI <0) || (pucch_nRB_CQI > 98))
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_nRB_CQI choice: 0..98!\n",
                           RC.config_file_name, i, pucch_nRB_CQI);

            RRC_CONFIGURATION_REQ (msg_p).pucch_nCS_AN[j] = pucch_nCS_AN;

            if ((pucch_nCS_AN <0) || (pucch_nCS_AN > 7))
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_nCS_AN choice: 0..7!\n",
                           RC.config_file_name, i, pucch_nCS_AN);

            //#if (RRC_VERSION < MAKE_VERSION(10, 0, 0))
            RRC_CONFIGURATION_REQ (msg_p).pucch_n1_AN[j] = pucch_n1_AN;

            if ((pucch_n1_AN <0) || (pucch_n1_AN > 2047))
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_n1_AN choice: 0..2047!\n",
                           RC.config_file_name, i, pucch_n1_AN);

            //#endif
            RRC_CONFIGURATION_REQ (msg_p).pdsch_referenceSignalPower[j] = pdsch_referenceSignalPower;

            if ((pdsch_referenceSignalPower <-60) || (pdsch_referenceSignalPower > 50))
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pdsch_referenceSignalPower choice:-60..50!\n",
                           RC.config_file_name, i, pdsch_referenceSignalPower);

            RRC_CONFIGURATION_REQ (msg_p).pdsch_p_b[j] = pdsch_p_b;

            if ((pdsch_p_b <0) || (pdsch_p_b > 3))
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pdsch_p_b choice: 0..3!\n",
                           RC.config_file_name, i, pdsch_p_b);

            RRC_CONFIGURATION_REQ (msg_p).pusch_n_SB[j] = pusch_n_SB;

            if ((pusch_n_SB <1) || (pusch_n_SB > 4))
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_n_SB choice: 1..4!\n",
                           RC.config_file_name, i, pusch_n_SB);

            if (!pusch_hoppingMode)
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d define %s: interSubframe,intraAndInterSubframe!\n",
                           RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_HOPPINGMODE);
            else if (strcmp(pusch_hoppingMode,"interSubFrame")==0) {
              RRC_CONFIGURATION_REQ (msg_p).pusch_hoppingMode[j] = PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_interSubFrame;
            }  else if (strcmp(pusch_hoppingMode,"intraAndInterSubFrame")==0) {
              RRC_CONFIGURATION_REQ (msg_p).pusch_hoppingMode[j] = PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_intraAndInterSubFrame;
            } else
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_hoppingMode choice: interSubframe,intraAndInterSubframe!\n",
                           RC.config_file_name, i, pusch_hoppingMode);

            RRC_CONFIGURATION_REQ (msg_p).pusch_hoppingOffset[j] = pusch_hoppingOffset;

            if ((pusch_hoppingOffset<0) || (pusch_hoppingOffset>98))
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_hoppingOffset choice: 0..98!\n",
                           RC.config_file_name, i, pusch_hoppingMode);

            if (!pusch_enable64QAM)
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n",
                           RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_ENABLE64QAM);
            else if (strcmp(pusch_enable64QAM, "ENABLE") == 0) {
              RRC_CONFIGURATION_REQ (msg_p).pusch_enable64QAM[j] = TRUE;
            }  else if (strcmp(pusch_enable64QAM, "DISABLE") == 0) {
              RRC_CONFIGURATION_REQ (msg_p).pusch_enable64QAM[j] = FALSE;
            } else
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_enable64QAM choice: ENABLE,DISABLE!\n",
                           RC.config_file_name, i, pusch_enable64QAM);

            if (!pusch_groupHoppingEnabled)
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n",
                           RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_GROUP_HOPPING_EN);
            else if (strcmp(pusch_groupHoppingEnabled, "ENABLE") == 0) {
              RRC_CONFIGURATION_REQ (msg_p).pusch_groupHoppingEnabled[j] = TRUE;
            }  else if (strcmp(pusch_groupHoppingEnabled, "DISABLE") == 0) {
              RRC_CONFIGURATION_REQ (msg_p).pusch_groupHoppingEnabled[j] = FALSE;
            } else
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_groupHoppingEnabled choice: ENABLE,DISABLE!\n",
                           RC.config_file_name, i, pusch_groupHoppingEnabled);

            RRC_CONFIGURATION_REQ (msg_p).pusch_groupAssignment[j] = pusch_groupAssignment;

            if ((pusch_groupAssignment<0)||(pusch_groupAssignment>29))
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_groupAssignment choice: 0..29!\n",
                           RC.config_file_name, i, pusch_groupAssignment);

            if (!pusch_sequenceHoppingEnabled)
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n",
                           RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_SEQUENCE_HOPPING_EN);
            else if (strcmp(pusch_sequenceHoppingEnabled, "ENABLE") == 0) {
              RRC_CONFIGURATION_REQ (msg_p).pusch_sequenceHoppingEnabled[j] = TRUE;
            }  else if (strcmp(pusch_sequenceHoppingEnabled, "DISABLE") == 0) {
              RRC_CONFIGURATION_REQ (msg_p).pusch_sequenceHoppingEnabled[j] = FALSE;
            } else
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_sequenceHoppingEnabled choice: ENABLE,DISABLE!\n",
                           RC.config_file_name, i, pusch_sequenceHoppingEnabled);

            RRC_CONFIGURATION_REQ (msg_p).pusch_nDMRS1[j] = pusch_nDMRS1;  //cyclic_shift in RRC!

            if ((pusch_nDMRS1 <0) || (pusch_nDMRS1>7))
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_nDMRS1 choice: 0..7!\n",
                           RC.config_file_name, i, pusch_nDMRS1);

            if (strcmp(phich_duration,"NORMAL")==0) {
              RRC_CONFIGURATION_REQ (msg_p).phich_duration[j] = PHICH_Config__phich_Duration_normal;
            } else if (strcmp(phich_duration,"EXTENDED")==0) {
              RRC_CONFIGURATION_REQ (msg_p).phich_duration[j] = PHICH_Config__phich_Duration_extended;
            } else
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for phich_duration choice: NORMAL,EXTENDED!\n",
                           RC.config_file_name, i, phich_duration);

            if (strcmp(phich_resource,"ONESIXTH")==0) {
              RRC_CONFIGURATION_REQ (msg_p).phich_resource[j] = PHICH_Config__phich_Resource_oneSixth ;
            } else if (strcmp(phich_resource,"HALF")==0) {
              RRC_CONFIGURATION_REQ (msg_p).phich_resource[j] = PHICH_Config__phich_Resource_half;
            } else if (strcmp(phich_resource,"ONE")==0) {
              RRC_CONFIGURATION_REQ (msg_p).phich_resource[j] = PHICH_Config__phich_Resource_one;
            } else if (strcmp(phich_resource,"TWO")==0) {
              RRC_CONFIGURATION_REQ (msg_p).phich_resource[j] = PHICH_Config__phich_Resource_two;
            } else
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for phich_resource choice: ONESIXTH,HALF,ONE,TWO!\n",
                           RC.config_file_name, i, phich_resource);

            printf("phich.resource %ld (%s), phich.duration %ld (%s)\n",
                   RRC_CONFIGURATION_REQ (msg_p).phich_resource[j],phich_resource,
                   RRC_CONFIGURATION_REQ (msg_p).phich_duration[j],phich_duration);

            if (strcmp(srs_enable, "ENABLE") == 0) {
              RRC_CONFIGURATION_REQ (msg_p).srs_enable[j] = TRUE;
            } else if (strcmp(srs_enable, "DISABLE") == 0) {
              RRC_CONFIGURATION_REQ (msg_p).srs_enable[j] = FALSE;
            } else
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n",
                           RC.config_file_name, i, srs_enable);

            if (RRC_CONFIGURATION_REQ (msg_p).srs_enable[j] == TRUE) {
              RRC_CONFIGURATION_REQ (msg_p).srs_BandwidthConfig[j] = srs_BandwidthConfig;

              if ((srs_BandwidthConfig < 0) || (srs_BandwidthConfig >7))
                AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value %d for srs_BandwidthConfig choice: 0...7\n",
                             RC.config_file_name, i, srs_BandwidthConfig);

              RRC_CONFIGURATION_REQ (msg_p).srs_SubframeConfig[j] = srs_SubframeConfig;

              if ((srs_SubframeConfig<0) || (srs_SubframeConfig>15))
                AssertFatal (0,
                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for srs_SubframeConfig choice: 0..15 !\n",
                             RC.config_file_name, i, srs_SubframeConfig);

              if (strcmp(srs_ackNackST, "ENABLE") == 0) {
                RRC_CONFIGURATION_REQ (msg_p).srs_ackNackST[j] = TRUE;
              } else if (strcmp(srs_ackNackST, "DISABLE") == 0) {
                RRC_CONFIGURATION_REQ (msg_p).srs_ackNackST[j] = FALSE;
              } else
                AssertFatal (0,
                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n",
                             RC.config_file_name, i, srs_ackNackST);

              if (strcmp(srs_MaxUpPts, "ENABLE") == 0) {
                RRC_CONFIGURATION_REQ (msg_p).srs_MaxUpPts[j] = TRUE;
              } else if (strcmp(srs_MaxUpPts, "DISABLE") == 0) {
                RRC_CONFIGURATION_REQ (msg_p).srs_MaxUpPts[j] = FALSE;
              } else
                AssertFatal (0,
                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_MaxUpPts choice: ENABLE,DISABLE !\n",
                             RC.config_file_name, i, srs_MaxUpPts);
            }

            RRC_CONFIGURATION_REQ (msg_p).pusch_p0_Nominal[j] = pusch_p0_Nominal;

            if ((pusch_p0_Nominal<-126) || (pusch_p0_Nominal>24))
              AssertFatal (0,
                           "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_p0_Nominal choice: -126..24 !\n",
                           RC.config_file_name, i, pusch_p0_Nominal);
            if (strcmp(pusch_alpha,"AL0")==0) {
              RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al0;
            } else if (strcmp(pusch_alpha,"AL04")==0) {
              RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al04;
            } else if (strcmp(pusch_alpha,"AL05")==0) {
              RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al05;
            } else if (strcmp(pusch_alpha,"AL06")==0) {
              RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al06;
            } else if (strcmp(pusch_alpha,"AL07")==0) {
              RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al07;
            } else if (strcmp(pusch_alpha,"AL08")==0) {
              RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al08;
            } else if (strcmp(pusch_alpha,"AL09")==0) {
              RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al09;
            } else if (strcmp(pusch_alpha,"AL1")==0) {
              RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al1;