/* * 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 */ /*! \file config.c * \brief UE and eNB configuration performed by RRC or as a consequence of RRC procedures * \author Navid Nikaein and Raymond Knopp * \date 2010 - 2014 * \version 0.1 * \email navid.nikaein@eurecom.fr * @ingroup _mac */ #include "common/platform_types.h" #include "common/platform_constants.h" #include "LTE_SystemInformationBlockType2.h" //#include "RadioResourceConfigCommonSIB.h" #include "LTE_RadioResourceConfigDedicated.h" #include "LTE_PRACH-ConfigSIB-v1310.h" #include "LTE_MeasGapConfig.h" #include "LTE_MeasObjectToAddModList.h" #include "LTE_TDD-Config.h" #include "LTE_MAC-MainConfig.h" #include "mac.h" #include "mac_proto.h" #include "mac_extern.h" #include "common/utils/LOG/log.h" #include "nfapi/oai_integration/vendor_ext.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "common/ran_context.h" #include "LTE_MBSFN-AreaInfoList-r9.h" #include "LTE_MBSFN-AreaInfo-r9.h" #include "LTE_MBSFN-SubframeConfigList.h" #include "LTE_MBSFN-SubframeConfig.h" #include "LTE_PMCH-InfoList-r9.h" #include extern RAN_CONTEXT_t RC; extern int l2_init_eNB(void); extern void mac_top_init_eNB(void); extern void mac_init_cell_params(int Mod_idP,int CC_idP); SCHEDULER_MODES global_scheduler_mode; typedef struct eutra_bandentry_s { int16_t band; uint32_t ul_min; uint32_t ul_max; uint32_t dl_min; uint32_t dl_max; uint32_t N_OFFs_DL; } eutra_bandentry_t; typedef struct band_info_s { int nbands; eutra_bandentry_t band_info[100]; } band_info_t; static const eutra_bandentry_t eutra_bandtable[] = { {1, 19200, 19800, 21100, 21700, 0 }, {2, 18500, 19100, 19300, 19900, 6000 }, {3, 17100, 17850, 18050, 18800, 12000 }, {4, 17100, 17550, 21100, 21550, 19500 }, {5, 8240, 8490, 8690, 8940, 24000 }, {6, 8300, 8400, 8750, 8850, 26500 }, {7, 25000, 25700, 26200, 26900, 27500 }, {8, 8800, 9150, 9250, 9600, 34500 }, {9, 17499, 17849, 18449, 18799, 38000 }, {10, 17100, 17700, 21100, 21700, 41500 }, {11, 14279, 14529, 14759, 15009, 47500 }, {12, 6980, 7160, 7280, 7460, 50100 }, {13, 7770, 7870, 7460, 7560, 51800 }, {14, 7880, 7980, 7580, 7680, 52800 }, {17, 7040, 7160, 7340, 7460, 57300 }, {18, 8150, 9650, 8600, 10100, 58500 }, {19, 8300, 8450, 8750, 8900, 60000 }, {20, 8320, 8620, 7910, 8210, 61500 }, {21, 14479, 14629, 14959, 15109, 64500 }, {22, 34100, 34900, 35100, 35900, 66000 }, {23, 20000, 20200, 21800, 22000, 75000 }, {24, 16126, 16605, 15250, 15590, 77000 }, {25, 18500, 19150, 19300, 19950, 80400 }, {26, 8140, 8490, 8590, 8940, 86900 }, {27, 8070, 8240, 8520, 8690, 90400 }, {28, 7030, 7580, 7580, 8130, 92100 }, {29, 0, 0, 7170, 7280, 96600 }, {30, 23050, 23250, 23500, 23600, 97700 }, {31, 45250, 34900, 46250, 35900, 98700 }, {32, 0, 0, 14520, 14960, 99200 }, {33, 19000, 19200, 19000, 19200, 360000}, {34, 20100, 20250, 20100, 20250, 362000}, {35, 18500, 19100, 18500, 19100, 363500}, {36, 19300, 19900, 19300, 19900, 369500}, {37, 19100, 19300, 19100, 19300, 375500}, {38, 25700, 26200, 25700, 26300, 377500}, {39, 18800, 19200, 18800, 19200, 382500}, {40, 23000, 24000, 23000, 24000, 386500}, {41, 24960, 26900, 24960, 26900, 396500}, {42, 34000, 36000, 34000, 36000, 415900}, {43, 36000, 38000, 36000, 38000, 435900}, {44, 7030, 8030, 7030, 8030, 455900}, {45, 14470, 14670, 14470, 14670, 465900}, {46, 51500, 59250, 51500, 59250, 467900}, {64, 0, 0, 0, 0, 60140},//reserved {65, 19200, 20100, 21100, 22000, 655360}, {66, 17100, 18000, 21100, 22000, 664360}, {67, 0, 0, 7380, 7580, 67336 }, {68, 6980, 7280, 7530, 7830, 67536 }, {71, 6630, 6980, 6170, 6520, 68586 }, {72, 4510, 4560, 4610, 4660, 68936 }, {73, 4500, 4550, 4600, 4650, 68986 } }; #define BANDTABLE_SIZE (sizeof(eutra_bandtable)/sizeof(eutra_bandentry_t)) uint32_t to_earfcn(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw) { uint32_t dl_CarrierFreq_by_100k = dl_CarrierFreq / 100000; int bw_by_100 = bw / 100; int i; AssertFatal(eutra_bandP < 74, "eutra_band %d > 74\n", eutra_bandP); for (i = 0; i < BANDTABLE_SIZE && eutra_bandtable[i].band != eutra_bandP; i++); AssertFatal(i < BANDTABLE_SIZE, "i %d >= BANDTABLE_SIZE %ld\n", i, BANDTABLE_SIZE); AssertFatal(eutra_bandP != 64, "LTE b64 is a reserved band"); AssertFatal(dl_CarrierFreq_by_100k >= eutra_bandtable[i].dl_min, "Band %d, bw %u : DL carrier frequency %u Hz < %u\n", eutra_bandP, bw, dl_CarrierFreq, eutra_bandtable[i].dl_min); AssertFatal(dl_CarrierFreq_by_100k <= (eutra_bandtable[i].dl_max - bw_by_100), "Band %d, bw %u: DL carrier frequency %u Hz > %d\n", eutra_bandP, bw, dl_CarrierFreq, eutra_bandtable[i].dl_max - bw_by_100); return (dl_CarrierFreq_by_100k - eutra_bandtable[i].dl_min + (eutra_bandtable[i].N_OFFs_DL / 10)); } uint32_t to_earfcn_DL(int eutra_bandP, long long int dl_CarrierFreq, uint32_t bw) { uint32_t dl_CarrierFreq_by_100k = dl_CarrierFreq / 100000; int bw_by_100 = bw / 100; int i; AssertFatal(eutra_bandP < 74, "eutra_band %d > 74\n", eutra_bandP); for (i = 0; i < BANDTABLE_SIZE && eutra_bandtable[i].band != eutra_bandP; i++); AssertFatal(i < BANDTABLE_SIZE, "i = %d , it will trigger out-of-bounds read.\n",i); AssertFatal(eutra_bandP != 64, "LTE b64 is a reserved band"); AssertFatal(dl_CarrierFreq_by_100k >= eutra_bandtable[i].dl_min, "Band %d, bw %u : DL carrier frequency %lld Hz < %u\n", eutra_bandP, bw, dl_CarrierFreq, eutra_bandtable[i].dl_min); AssertFatal(dl_CarrierFreq_by_100k <= (eutra_bandtable[i].dl_max - bw_by_100), "Band %d, bw %u : DL carrier frequency %lld Hz > %d\n", eutra_bandP, bw, dl_CarrierFreq, eutra_bandtable[i].dl_max - bw_by_100); return (dl_CarrierFreq_by_100k - eutra_bandtable[i].dl_min + (eutra_bandtable[i].N_OFFs_DL / 10)); } uint32_t to_earfcn_UL(int eutra_bandP, long long int ul_CarrierFreq, uint32_t bw) { uint32_t ul_CarrierFreq_by_100k = ul_CarrierFreq / 100000; int bw_by_100 = bw / 100; int i; AssertFatal(eutra_bandP < 74, "eutra_band %d > 74\n", eutra_bandP); for (i = 0; i < BANDTABLE_SIZE && eutra_bandtable[i].band != eutra_bandP; i++); AssertFatal(i < BANDTABLE_SIZE, "i = %d , it will trigger out-of-bounds read.\n",i); AssertFatal(eutra_bandP != 64, "LTE b64 is a reserved band"); AssertFatal(ul_CarrierFreq_by_100k >= eutra_bandtable[i].ul_min, "Band %d, bw %u : UL carrier frequency %lld Hz < %u\n", eutra_bandP, bw, ul_CarrierFreq, eutra_bandtable[i].ul_min); AssertFatal(ul_CarrierFreq_by_100k <= (eutra_bandtable[i].ul_max - bw_by_100), "Band %d, bw %u : UL carrier frequency %lld Hz > %d\n", eutra_bandP, bw, ul_CarrierFreq, eutra_bandtable[i].ul_max - bw_by_100); return (ul_CarrierFreq_by_100k - eutra_bandtable[i].ul_min + ((eutra_bandtable[i].N_OFFs_DL + 180000) / 10)); } uint32_t from_earfcn(int eutra_bandP, uint32_t dl_earfcn) { int i; AssertFatal(eutra_bandP < 74, "eutra_band %d > 74\n", eutra_bandP); for (i = 0; i < BANDTABLE_SIZE && eutra_bandtable[i].band != eutra_bandP; i++); AssertFatal(i < BANDTABLE_SIZE, "i %d >= BANDTABLE_SIZE %ld\n", i, BANDTABLE_SIZE); AssertFatal(eutra_bandP != 64, "LTE b64 is a reserved band"); return (eutra_bandtable[i].dl_min + (dl_earfcn - (eutra_bandtable[i].N_OFFs_DL / 10))) * 100000; } int32_t get_uldl_offset(int eutra_bandP) { int i; for (i = 0; i < BANDTABLE_SIZE && eutra_bandtable[i].band != eutra_bandP; i++); AssertFatal(i < BANDTABLE_SIZE, "i %d >= BANDTABLE_SIZE %ld\n", i, BANDTABLE_SIZE); return (eutra_bandtable[i].dl_min - eutra_bandtable[i].ul_min); } const int32_t bw_table[6] = {6 * 180, 15 * 180, 25 * 180, 50 * 180, 75 * 180, 100 * 180}; void config_mib(int Mod_idP, int CC_idP, int eutra_bandP, int dl_BandwidthP, LTE_PHICH_Config_t *phich_configP, int Nid_cellP, int NcpP, int p_eNBP, uint32_t dl_CarrierFreqP, uint32_t ul_CarrierFreqP, uint32_t pbch_repetitionP ) { nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; cfg->num_tlv=0; cfg->subframe_config.pcfich_power_offset.value = 6000; // 0dB cfg->subframe_config.pcfich_power_offset.tl.tag = NFAPI_SUBFRAME_CONFIG_PCFICH_POWER_OFFSET_TAG; cfg->num_tlv++; cfg->subframe_config.dl_cyclic_prefix_type.value = NcpP; cfg->subframe_config.dl_cyclic_prefix_type.tl.tag = NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG; cfg->num_tlv++; cfg->subframe_config.ul_cyclic_prefix_type.value = NcpP; cfg->subframe_config.ul_cyclic_prefix_type.tl.tag = NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG; cfg->num_tlv++; cfg->rf_config.dl_channel_bandwidth.value = to_prb(dl_BandwidthP); cfg->rf_config.dl_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG; cfg->num_tlv++; LOG_D(PHY,"%s() dl_BandwidthP:%d\n", __FUNCTION__, dl_BandwidthP); cfg->rf_config.ul_channel_bandwidth.value = to_prb(dl_BandwidthP); cfg->rf_config.ul_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG; cfg->num_tlv++; cfg->rf_config.tx_antenna_ports.value = p_eNBP; cfg->rf_config.tx_antenna_ports.tl.tag = NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG; cfg->num_tlv++; cfg->rf_config.rx_antenna_ports.value = 2; cfg->rf_config.rx_antenna_ports.tl.tag = NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG; cfg->num_tlv++; cfg->nfapi_config.earfcn.value = to_earfcn(eutra_bandP,dl_CarrierFreqP,bw_table[dl_BandwidthP]/100); cfg->nfapi_config.earfcn.tl.tag = NFAPI_NFAPI_EARFCN_TAG; cfg->num_tlv++; cfg->nfapi_config.rf_bands.number_rf_bands = 1; cfg->nfapi_config.rf_bands.rf_band[0] = eutra_bandP; cfg->nfapi_config.rf_bands.tl.tag = NFAPI_PHY_RF_BANDS_TAG; cfg->num_tlv++; cfg->phich_config.phich_resource.value = phich_configP->phich_Resource; cfg->phich_config.phich_resource.tl.tag = NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG; cfg->num_tlv++; cfg->phich_config.phich_duration.value = phich_configP->phich_Duration; cfg->phich_config.phich_duration.tl.tag = NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG; cfg->num_tlv++; cfg->phich_config.phich_power_offset.value = 6000; // 0dB cfg->phich_config.phich_power_offset.tl.tag = NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG; cfg->num_tlv++; cfg->sch_config.primary_synchronization_signal_epre_eprers.value = 6000; // 0dB cfg->sch_config.primary_synchronization_signal_epre_eprers.tl.tag = NFAPI_SCH_CONFIG_PRIMARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG; cfg->num_tlv++; cfg->sch_config.secondary_synchronization_signal_epre_eprers.value = 6000; // 0dB cfg->sch_config.secondary_synchronization_signal_epre_eprers.tl.tag = NFAPI_SCH_CONFIG_SECONDARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG; cfg->num_tlv++; cfg->sch_config.physical_cell_id.value = Nid_cellP; cfg->sch_config.physical_cell_id.tl.tag = NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG; cfg->num_tlv++; cfg->emtc_config.pbch_repetitions_enable_r13.value = pbch_repetitionP; cfg->emtc_config.pbch_repetitions_enable_r13.tl.tag = NFAPI_EMTC_CONFIG_PBCH_REPETITIONS_ENABLE_R13_TAG; cfg->num_tlv++; LOG_I(MAC, "%s() NFAPI_CONFIG_REQUEST(num_tlv:%u) DL_BW:%u UL_BW:%u Ncp %d,p_eNB %d,earfcn %d,band %d,phich_resource %u phich_duration %u phich_power_offset %u PSS %d SSS %d PCI %d" " PBCH repetition %d" "\n" ,__FUNCTION__ ,cfg->num_tlv ,cfg->rf_config.dl_channel_bandwidth.value ,cfg->rf_config.ul_channel_bandwidth.value ,NcpP,p_eNBP ,cfg->nfapi_config.earfcn.value ,cfg->nfapi_config.rf_bands.rf_band[0] ,cfg->phich_config.phich_resource.value ,cfg->phich_config.phich_duration.value ,cfg->phich_config.phich_power_offset.value ,cfg->sch_config.primary_synchronization_signal_epre_eprers.value ,cfg->sch_config.secondary_synchronization_signal_epre_eprers.value ,cfg->sch_config.physical_cell_id.value ,cfg->emtc_config.pbch_repetitions_enable_r13.value ); } void config_sib1(int Mod_idP, int CC_idP, LTE_TDD_Config_t *tdd_ConfigP) { nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; if (tdd_ConfigP) { //TDD cfg->subframe_config.duplex_mode.value = 0; cfg->subframe_config.duplex_mode.tl.tag = NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG; cfg->num_tlv++; cfg->tdd_frame_structure_config.subframe_assignment.value = tdd_ConfigP->subframeAssignment; cfg->tdd_frame_structure_config.subframe_assignment.tl.tag = NFAPI_TDD_FRAME_STRUCTURE_SUBFRAME_ASSIGNMENT_TAG; cfg->num_tlv++; cfg->tdd_frame_structure_config.special_subframe_patterns.value = tdd_ConfigP->specialSubframePatterns; cfg->tdd_frame_structure_config.special_subframe_patterns.tl.tag = NFAPI_TDD_FRAME_STRUCTURE_SPECIAL_SUBFRAME_PATTERNS_TAG; cfg->num_tlv++; } else { // FDD cfg->subframe_config.duplex_mode.value = 1; cfg->subframe_config.duplex_mode.tl.tag = NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG; cfg->num_tlv++; // Note no half-duplex here } } const int power_off_dB[6] = {78, 118, 140, 170, 188, 200}; void config_sib2(int Mod_idP, int CC_idP, LTE_RadioResourceConfigCommonSIB_t *radioResourceConfigCommonP, LTE_RadioResourceConfigCommonSIB_t *radioResourceConfigCommon_BRP, LTE_ARFCN_ValueEUTRA_t *ul_CArrierFreqP, long *ul_BandwidthP, LTE_AdditionalSpectrumEmission_t *additionalSpectrumEmissionP, struct LTE_MBSFN_SubframeConfigList *mbsfn_SubframeConfigListP, int dl_Bandwidth) { nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; cfg->subframe_config.pb.value = radioResourceConfigCommonP->pdsch_ConfigCommon.p_b; cfg->subframe_config.pb.tl.tag = NFAPI_SUBFRAME_CONFIG_PB_TAG; cfg->num_tlv++; cfg->rf_config.reference_signal_power.value = radioResourceConfigCommonP->pdsch_ConfigCommon.referenceSignalPower; cfg->rf_config.reference_signal_power.tl.tag = NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG; cfg->num_tlv++; cfg->nfapi_config.max_transmit_power.value = cfg->rf_config.reference_signal_power.value + power_off_dB[dl_Bandwidth]; cfg->nfapi_config.max_transmit_power.tl.tag = NFAPI_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG; cfg->num_tlv++; cfg->prach_config.configuration_index.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.prach_ConfigIndex; cfg->prach_config.configuration_index.tl.tag = NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG; cfg->num_tlv++; cfg->prach_config.root_sequence_index.value = radioResourceConfigCommonP->prach_Config.rootSequenceIndex; cfg->prach_config.root_sequence_index.tl.tag = NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG; cfg->num_tlv++; cfg->prach_config.zero_correlation_zone_configuration.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig; cfg->prach_config.zero_correlation_zone_configuration.tl.tag = NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG; cfg->num_tlv++; cfg->prach_config.high_speed_flag.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.highSpeedFlag; cfg->prach_config.high_speed_flag.tl.tag = NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG; cfg->num_tlv++; cfg->prach_config.frequency_offset.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.prach_FreqOffset; cfg->prach_config.frequency_offset.tl.tag = NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG; cfg->num_tlv++; cfg->pusch_config.hopping_mode.value = radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode; cfg->pusch_config.hopping_mode.tl.tag = NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG; cfg->num_tlv++; cfg->pusch_config.number_of_subbands.value = radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic.n_SB; cfg->pusch_config.number_of_subbands.tl.tag = NFAPI_PUSCH_CONFIG_NUMBER_OF_SUBBANDS_TAG; cfg->num_tlv++; cfg->pusch_config.hopping_offset.value = radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset; cfg->pusch_config.hopping_offset.tl.tag = NFAPI_PUSCH_CONFIG_HOPPING_OFFSET_TAG; cfg->num_tlv++; cfg->pucch_config.delta_pucch_shift.value = radioResourceConfigCommonP->pucch_ConfigCommon.deltaPUCCH_Shift; cfg->pucch_config.delta_pucch_shift.tl.tag = NFAPI_PUCCH_CONFIG_DELTA_PUCCH_SHIFT_TAG; cfg->num_tlv++; cfg->pucch_config.n_cqi_rb.value = radioResourceConfigCommonP->pucch_ConfigCommon.nRB_CQI; cfg->pucch_config.n_cqi_rb.tl.tag = NFAPI_PUCCH_CONFIG_N_CQI_RB_TAG; cfg->num_tlv++; cfg->pucch_config.n_an_cs.value = radioResourceConfigCommonP->pucch_ConfigCommon.nCS_AN; cfg->pucch_config.n_an_cs.tl.tag = NFAPI_PUCCH_CONFIG_N_AN_CS_TAG; cfg->num_tlv++; cfg->pucch_config.n1_pucch_an.value = radioResourceConfigCommonP->pucch_ConfigCommon.n1PUCCH_AN; cfg->pucch_config.n1_pucch_an.tl.tag = NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG; cfg->num_tlv++; if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled == true) { cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 1; } else if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled == true) { cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 2; } else { cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 0; } cfg->uplink_reference_signal_config.uplink_rs_hopping.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG; cfg->num_tlv++; cfg->uplink_reference_signal_config.group_assignment.value = radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH; cfg->uplink_reference_signal_config.group_assignment.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG; cfg->num_tlv++; cfg->uplink_reference_signal_config.cyclic_shift_1_for_drms.value = radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift; cfg->uplink_reference_signal_config.cyclic_shift_1_for_drms.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG; cfg->num_tlv++; // how to enable/disable SRS? if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.present== LTE_SoundingRS_UL_ConfigCommon_PR_setup) { cfg->srs_config.bandwidth_configuration.value = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig; cfg->srs_config.bandwidth_configuration.tl.tag = NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG; cfg->num_tlv++; cfg->srs_config.srs_subframe_configuration.value = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig; cfg->srs_config.srs_subframe_configuration.tl.tag = NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG; cfg->num_tlv++; cfg->srs_config.srs_acknack_srs_simultaneous_transmission.value = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; cfg->srs_config.srs_acknack_srs_simultaneous_transmission.tl.tag = NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG; cfg->num_tlv++; if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts) { cfg->srs_config.max_up_pts.value = 1; } else { cfg->srs_config.max_up_pts.value = 0; } cfg->srs_config.max_up_pts.tl.tag = NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG; cfg->num_tlv++; } if (RC.mac[Mod_idP]->common_channels[CC_idP].mib->message.schedulingInfoSIB1_BR_r13 > 0) { AssertFatal(radioResourceConfigCommon_BRP != NULL, "radioResource rou is missing\n"); AssertFatal(radioResourceConfigCommon_BRP->ext4 != NULL, "ext4 is missing\n"); cfg->emtc_config.prach_catm_root_sequence_index.value = radioResourceConfigCommon_BRP->prach_Config.rootSequenceIndex; cfg->emtc_config.prach_catm_root_sequence_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_ROOT_SEQUENCE_INDEX_TAG; cfg->num_tlv++; cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.value = radioResourceConfigCommon_BRP->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig; cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG; cfg->num_tlv++; cfg->emtc_config.prach_catm_high_speed_flag.value = radioResourceConfigCommon_BRP->prach_Config.prach_ConfigInfo.highSpeedFlag; cfg->emtc_config.prach_catm_high_speed_flag.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_HIGH_SPEED_FLAG; cfg->num_tlv++; struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach = radioResourceConfigCommon_BRP->ext4->prach_ConfigCommon_v1310; LTE_PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; LTE_PRACH_ParametersCE_r13_t *p; cfg->emtc_config.prach_ce_level_0_enable.value = 0; cfg->emtc_config.prach_ce_level_0_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG; cfg->num_tlv++; cfg->emtc_config.prach_ce_level_1_enable.value = 0; cfg->emtc_config.prach_ce_level_1_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG; cfg->num_tlv++; cfg->emtc_config.prach_ce_level_2_enable.value = 0; cfg->emtc_config.prach_ce_level_2_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG; cfg->num_tlv++; cfg->emtc_config.prach_ce_level_3_enable.value = 0; cfg->emtc_config.prach_ce_level_3_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG; cfg->num_tlv++; switch (prach_ParametersListCE_r13->list.count) { case 4: p = prach_ParametersListCE_r13->list.array[3]; cfg->emtc_config.prach_ce_level_3_enable.value = 1; cfg->emtc_config.prach_ce_level_3_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG; cfg->num_tlv++; cfg->emtc_config.prach_ce_level_3_configuration_index.value = p->prach_ConfigIndex_r13; cfg->emtc_config.prach_ce_level_3_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_CONFIGURATION_INDEX_TAG; cfg->num_tlv++; cfg->emtc_config.prach_ce_level_3_frequency_offset.value = p->prach_FreqOffset_r13; cfg->emtc_config.prach_ce_level_3_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_FREQUENCY_OFFSET_TAG; cfg->num_tlv++; cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.value = 1<numRepetitionPerPreambleAttempt_r13; cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; cfg->num_tlv++; if (p->prach_StartingSubframe_r13) { cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.value = 2<<*p->prach_StartingSubframe_r13; cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_STARTING_SUBFRAME_PERIODICITY_TAG; cfg->num_tlv++; } cfg->emtc_config.prach_ce_level_3_hopping_enable.value = p->prach_HoppingConfig_r13; cfg->emtc_config.prach_ce_level_3_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_ENABLE_TAG; cfg->num_tlv++; cfg->emtc_config.prach_ce_level_3_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value - 6; cfg->emtc_config.prach_ce_level_3_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_OFFSET_TAG; cfg->num_tlv++; case 3: p = prach_ParametersListCE_r13->list.array[2]; cfg->emtc_config.prach_ce_level_2_enable.value = 1; cfg->emtc_config.prach_ce_level_2_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG; cfg->num_tlv++; cfg->emtc_config.prach_ce_level_2_configuration_index.value = p->prach_ConfigIndex_r13; cfg->emtc_config.prach_ce_level_2_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_CONFIGURATION_INDEX_TAG; cfg->num_tlv++; cfg->emtc_config.prach_ce_level_2_frequency_offset.value = p->prach_FreqOffset_r13; cfg->emtc_config.prach_ce_level_2_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_FREQUENCY_OFFSET_TAG; cfg->num_tlv++; cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.value = 1<numRepetitionPerPreambleAttempt_r13; cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; cfg->num_tlv++; if (p->prach_StartingSubframe_r13) { cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.value = 2<<*p->prach_StartingSubframe_r13; cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_STARTING_SUBFRAME_PERIODICITY_TAG; cfg->num_tlv++; } cfg->emtc_config.prach_ce_level_2_hopping_enable.value = p->prach_HoppingConfig_r13; cfg->emtc_config.prach_ce_level_2_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_ENABLE_TAG; cfg->num_tlv++; cfg->emtc_config.prach_ce_level_2_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value - 6; cfg->emtc_config.prach_ce_level_2_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_OFFSET_TAG; cfg->num_tlv++; case 2: p = prach_ParametersListCE_r13->list.array[1]; cfg->emtc_config.prach_ce_level_1_enable.value = 1; cfg->emtc_config.prach_ce_level_1_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG; cfg->num_tlv++; cfg->emtc_config.prach_ce_level_1_configuration_index.value = p->prach_ConfigIndex_r13; cfg->emtc_config.prach_ce_level_1_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_CONFIGURATION_INDEX_TAG; cfg->num_tlv++; cfg->emtc_config.prach_ce_level_1_frequency_offset.value = p->prach_FreqOffset_r13; cfg->emtc_config.prach_ce_level_1_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_FREQUENCY_OFFSET_TAG; cfg->num_tlv++; cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.value = 1<numRepetitionPerPreambleAttempt_r13; cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; cfg->num_tlv++; if (p->prach_StartingSubframe_r13) { cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.value = 2<<*p->prach_StartingSubframe_r13; cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_STARTING_SUBFRAME_PERIODICITY_TAG; cfg->num_tlv++; } cfg->emtc_config.prach_ce_level_1_hopping_enable.value = p->prach_HoppingConfig_r13; cfg->emtc_config.prach_ce_level_1_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_ENABLE_TAG; cfg->num_tlv++; cfg->emtc_config.prach_ce_level_1_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value - 6; cfg->emtc_config.prach_ce_level_1_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_OFFSET_TAG; cfg->num_tlv++; case 1: p = prach_ParametersListCE_r13->list.array[0]; cfg->emtc_config.prach_ce_level_0_enable.value = 1; cfg->emtc_config.prach_ce_level_0_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG; cfg->num_tlv++; cfg->emtc_config.prach_ce_level_0_configuration_index.value = p->prach_ConfigIndex_r13; cfg->emtc_config.prach_ce_level_0_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_CONFIGURATION_INDEX_TAG; cfg->num_tlv++; cfg->emtc_config.prach_ce_level_0_frequency_offset.value = p->prach_FreqOffset_r13; cfg->emtc_config.prach_ce_level_0_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_FREQUENCY_OFFSET_TAG; cfg->num_tlv++; cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.value = 1<numRepetitionPerPreambleAttempt_r13; cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; cfg->num_tlv++; if (p->prach_StartingSubframe_r13) { cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.value = 2<<*p->prach_StartingSubframe_r13; cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_STARTING_SUBFRAME_PERIODICITY_TAG; cfg->num_tlv++; } cfg->emtc_config.prach_ce_level_0_hopping_enable.value = p->prach_HoppingConfig_r13; cfg->emtc_config.prach_ce_level_0_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_ENABLE_TAG; cfg->num_tlv++; cfg->emtc_config.prach_ce_level_0_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value - 6; cfg->emtc_config.prach_ce_level_0_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_OFFSET_TAG; cfg->num_tlv++; } AssertFatal(cfg->emtc_config.prach_ce_level_0_enable.value>0,"CE_level0 is not enabled\n"); struct LTE_FreqHoppingParameters_r13 *ext4_freqHoppingParameters = radioResourceConfigCommonP->ext4->freqHoppingParameters_r13; if ((ext4_freqHoppingParameters) && (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13)) { switch(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->present) { case LTE_FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_NOTHING: /* No components present */ break; case LTE_FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_FDD_r13: cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_FDD_r13; cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG; cfg->num_tlv++; break; case LTE_FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_TDD_r13: cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_TDD_r13; cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG; cfg->num_tlv++; break; } } if ((ext4_freqHoppingParameters) && (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13)) { switch(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->present) { case LTE_FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_NOTHING: /* No components present */ break; case LTE_FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_FDD_r13: cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_FDD_r13; cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG; cfg->num_tlv++; break; case LTE_FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_TDD_r13: cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_TDD_r13; cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG; cfg->num_tlv++; break; } } } } void config_sib2_mbsfn_part( int Mod_idP, int CC_idP, struct LTE_MBSFN_SubframeConfigList *mbsfn_SubframeConfigListP) { //LTE_DL_FRAME_PARMS *fp = &RC.eNB[Mod_idP][CC_idP]->frame_parms; //int i; //if(mbsfn_SubframeConfigListP != NULL) { // fp->num_MBSFN_config = mbsfn_SubframeConfigListP->list.count; // for(i = 0; i < mbsfn_SubframeConfigListP->list.count; i++) { // fp->MBSFN_config[i].radioframeAllocationPeriod = mbsfn_SubframeConfigListP->list.array[i]->radioframeAllocationPeriod; // fp->MBSFN_config[i].radioframeAllocationOffset = mbsfn_SubframeConfigListP->list.array[i]->radioframeAllocationOffset; // if (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { // fp->MBSFN_config[i].fourFrames_flag = 0; // fp->MBSFN_config[i].mbsfn_SubframeConfig = mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration // LOG_I (PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, fp->MBSFN_config[i].mbsfn_SubframeConfig); // } else if (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration // fp->MBSFN_config[i].fourFrames_flag = 1; // fp->MBSFN_config[i].mbsfn_SubframeConfig = // mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]| // (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)| // (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]<<16); // LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", i, // fp->MBSFN_config[i].mbsfn_SubframeConfig); // } // } //} else // fp->num_MBSFN_config = 0; PHY_Config_t phycfg; phycfg.Mod_id = Mod_idP; phycfg.CC_id = CC_idP; phycfg.cfg = &RC.mac[Mod_idP]->config[CC_idP]; int i; if(mbsfn_SubframeConfigListP != NULL) { phycfg.cfg->embms_mbsfn_config.num_mbsfn_config = mbsfn_SubframeConfigListP->list.count; for(i = 0; i < mbsfn_SubframeConfigListP->list.count; i++) { phycfg.cfg->embms_mbsfn_config.radioframe_allocation_period[i] = mbsfn_SubframeConfigListP->list.array[i]->radioframeAllocationPeriod; phycfg.cfg->embms_mbsfn_config.radioframe_allocation_offset[i] = mbsfn_SubframeConfigListP->list.array[i]->radioframeAllocationOffset; if (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { phycfg.cfg->embms_mbsfn_config.fourframes_flag[i] = 0; phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i] = mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration LOG_I (MAC, "[CONFIG] MBSFN_SubframeConfig[%d] oneFrame pattern is %d\n", i, phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i]); } else if (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration phycfg.cfg->embms_mbsfn_config.fourframes_flag[i] = 1; phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i] = mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]| (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)| (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]<<16); LOG_I(MAC, "[CONFIG] MBSFN_SubframeConfig[%d] fourFrame pattern is %x\n", i, phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i]); } } phycfg.cfg->num_tlv++; } else{ phycfg.cfg->embms_mbsfn_config.num_mbsfn_config = 0; phycfg.cfg->num_tlv++; } phycfg.cfg->embms_mbsfn_config.tl.tag = NFAPI_EMBMS_MBSFN_CONFIG_TAG; if (RC.mac[Mod_idP]->if_inst->PHY_config_update_sib2_req) RC.mac[Mod_idP]->if_inst->PHY_config_update_sib2_req(&phycfg); } void config_sib13( int Mod_id, int CC_id, int mbsfn_Area_idx, long mbsfn_AreaId_r9){ //nfapi_config_request_t *cfg = &RC.mac[Mod_id]->config[CC_id]; //work around until PHY_config_re "update" mechanisms get defined // LTE_DL_FRAME_PARMS *fp = &RC.eNB[Mod_id][CC_id]->frame_parms; // LOG_I (MAC, "[eNB%d] Applying MBSFN_Area_id %ld for index %d\n", Mod_id, mbsfn_AreaId_r9, mbsfn_Area_idx); // // AssertFatal(mbsfn_Area_idx == 0, "Fix me: only called when mbsfn_Area_idx == 0\n"); // if (mbsfn_Area_idx == 0) { // fp->Nid_cell_mbsfn = (uint16_t)mbsfn_AreaId_r9; // LOG_I(MAC,"Fix me: only called when mbsfn_Area_idx == 0)\n"); // } // lte_gold_mbsfn (fp, RC.eNB[Mod_id][CC_id]->lte_gold_mbsfn_table, fp->Nid_cell_mbsfn); // // lte_gold_mbsfn_khz_1dot25 (fp, RC.eNB[Mod_id][CC_id]->lte_gold_mbsfn_khz_1dot25_table, fp->Nid_cell_mbsfn); // PHY_Config_t phycfg; phycfg.Mod_id = Mod_id; phycfg.CC_id = CC_id; phycfg.cfg = &RC.mac[Mod_id]->config[CC_id]; phycfg.cfg->embms_sib13_config.mbsfn_area_idx.value = (uint8_t)mbsfn_Area_idx; phycfg.cfg->embms_sib13_config.mbsfn_area_idx.tl.tag = NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDX_TAG; phycfg.cfg->num_tlv++; phycfg.cfg->embms_sib13_config.mbsfn_area_id_r9.value = (uint32_t)mbsfn_AreaId_r9; phycfg.cfg->embms_sib13_config.mbsfn_area_id_r9.tl.tag = NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDR9_TAG; phycfg.cfg->num_tlv++; if (RC.mac[Mod_id]->if_inst->PHY_config_update_sib13_req) RC.mac[Mod_id]->if_inst->PHY_config_update_sib13_req(&phycfg); // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT); } void config_dedicated(int Mod_idP, int CC_idP, uint16_t rnti, struct LTE_PhysicalConfigDedicated *physicalConfigDedicated) { } void config_dedicated_scell(int Mod_idP, uint16_t rnti, LTE_SCellToAddMod_r10_t *sCellToAddMod_r10) { } int rrc_mac_config_req_eNB(const module_id_t Mod_idP, const rrc_mac_config_req_eNB_t *param) { int i; int UE_id = -1; eNB_MAC_INST *eNB = RC.mac[Mod_idP]; UE_info_t *UE_info= &eNB->UE_info; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN); if (param->mib != NULL) { if (RC.mac == NULL) l2_init_eNB(); //mac_top_init_eNB(); eNB->common_channels[param->CC_id].mib = param->mib; eNB->common_channels[param->CC_id].physCellId = param->physCellId; eNB->common_channels[param->CC_id].p_eNB = param->p_eNB; eNB->common_channels[param->CC_id].Ncp = param->Ncp; eNB->common_channels[param->CC_id].eutra_band = param->eutra_band; eNB->common_channels[param->CC_id].dl_CarrierFreq = param->dl_CarrierFreq; LOG_A(MAC, "Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d,Nid_cell %d,p %d,DL freq %u,phich_config.resource %ld, phich_config.duration %ld)\n", Mod_idP, param->CC_id, param->eutra_band, to_prb(param->mib->message.dl_Bandwidth), param->physCellId, param->p_eNB, param->dl_CarrierFreq, param->mib->message.phich_Config.phich_Resource, param->mib->message.phich_Config.phich_Duration); config_mib(Mod_idP, param->CC_id, param->eutra_band, param->mib->message.dl_Bandwidth, ¶m->mib->message.phich_Config, param->physCellId, param->Ncp, param->p_eNB, param->dl_CarrierFreq, param->ul_CarrierFreq, param->pbch_repetition); mac_init_cell_params(Mod_idP, param->CC_id); if (param->schedulingInfoList != NULL) { eNB->common_channels[param->CC_id].tdd_Config = param->tdd_Config; eNB->common_channels[param->CC_id].schedulingInfoList = param->schedulingInfoList; config_sib1(Mod_idP, param->CC_id, param->tdd_Config); } //TODO MBMS this must be passed through function /*if (schedulingInfoList_MBMS!=NULL) { eNB->common_channels[param->CC_id].schedulingInfoList_MBMS = schedulingInfoList_MBMS; config_sib1_mbms(Mod_idP,param->CC_id,tdd_Config); }*/ if (param->sib1_ext_r13 != NULL) { eNB->common_channels[param->CC_id].sib1_v13ext = param->sib1_ext_r13; } AssertFatal(param->radioResourceConfigCommon != NULL, "radioResourceConfigCommon is null\n"); LOG_I(MAC, "[CONFIG]SIB2/3 Contents (partial)\n"); LOG_I(MAC, "[CONFIG]pusch_config_common.n_SB = %ld\n", param->radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.n_SB); LOG_I(MAC, "[CONFIG]pusch_config_common.hoppingMode = %ld\n", param->radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode); LOG_I(MAC, "[CONFIG]pusch_config_common.pusch_HoppingOffset = %ld\n", param->radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset); LOG_I(MAC, "[CONFIG]pusch_config_common.enable64QAM = %d\n", param->radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM); LOG_I(MAC, "[CONFIG]pusch_config_common.groupHoppingEnabled = %d\n", param->radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled); LOG_I(MAC, "[CONFIG]pusch_config_common.groupAssignmentPUSCH = %ld\n", param->radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH); LOG_I(MAC, "[CONFIG]pusch_config_common.sequenceHoppingEnabled = %d\n", param->radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled); LOG_I(MAC, "[CONFIG]pusch_config_common.cyclicShift = %ld\n", param->radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift); AssertFatal(param->radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx > 0, "radioResourceconfigCommon %ld == 0\n", param->radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx); eNB->common_channels[param->CC_id].radioResourceConfigCommon = param->radioResourceConfigCommon; eNB->common_channels[param->CC_id].radioResourceConfigCommon_BR = param->LTE_radioResourceConfigCommon_BR; if (param->ul_CarrierFreq > 0) eNB->common_channels[param->CC_id].ul_CarrierFreq = param->ul_CarrierFreq; if (param->ul_Bandwidth) eNB->common_channels[param->CC_id].ul_Bandwidth = *param->ul_Bandwidth; else eNB->common_channels[param->CC_id].ul_Bandwidth = eNB->common_channels[param->CC_id].mib->message.dl_Bandwidth; config_sib2(Mod_idP, param->CC_id, param->radioResourceConfigCommon, param->LTE_radioResourceConfigCommon_BR, NULL, param->ul_Bandwidth, param->additionalSpectrumEmission, param->mbsfn_SubframeConfigList, param->mib->message.dl_Bandwidth); } // mib != NULL if (param->mobilityControlInfo != NULL) { if ((UE_id = add_new_ue(Mod_idP, param->CC_id, param->rnti, -1, 0)) == -1) { LOG_E(MAC, "%s:%d: fatal\n", __FILE__, __LINE__); abort(); } } if (param->logicalChannelIdentity > 0) { // is SRB1,2 or DRB if ((UE_id = find_UE_id(Mod_idP, param->rnti)) < 0) { LOG_E(MAC, "Configuration received for unknown UE (%x), shouldn't happen\n", param->rnti); return(-1); } int idx = -1; UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; for (int i = 0; i < sched_ctrl->dl_lc_num; ++i) { if (sched_ctrl->dl_lc_ids[i] == param->logicalChannelIdentity) { /* TODO this might also mean we have to remove it, not clear */ idx = i; break; } } if (idx < 0) { sched_ctrl->dl_lc_num++; sched_ctrl->dl_lc_ids[sched_ctrl->dl_lc_num - 1] = param->logicalChannelIdentity; sched_ctrl->dl_lc_bytes[sched_ctrl->dl_lc_num-1] = 0; LOG_I(MAC, "UE %d RNTI %x adding LC %ld idx %d to scheduling control (total %d)\n", UE_id, param->rnti, param->logicalChannelIdentity, sched_ctrl->dl_lc_num - 1, sched_ctrl->dl_lc_num); if (param->logicalChannelIdentity == 1) { // if it is SRB1, add SRB2 directly because RRC does not indicate this separately sched_ctrl->dl_lc_num++; sched_ctrl->dl_lc_ids[sched_ctrl->dl_lc_num-1] = 2; sched_ctrl->dl_lc_bytes[sched_ctrl->dl_lc_num-1] = 0; LOG_I(MAC, "UE %d RNTI %x adding LC 2 idx %d to scheduling control (total %d)\n", UE_id, param->rnti, sched_ctrl->dl_lc_num - 1, sched_ctrl->dl_lc_num); } } } // SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters->logicalChannelGroup if (param->logicalChannelConfig != NULL) { // check for eMTC specific things UE_id = find_UE_id(Mod_idP, param->rnti); if (UE_id<0) { LOG_E(MAC, "Configuration received for unknown UE (%x), shouldn't happen\n", param->rnti); return(-1); } if (param->logicalChannelConfig) { UE_info->UE_template[param->CC_id][UE_id].lcgidmap[param->logicalChannelIdentity] = *param->logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup; UE_info->UE_template[param->CC_id][UE_id].lcgidpriority[param->logicalChannelIdentity] = param->logicalChannelConfig->ul_SpecificParameters->priority; } else UE_info->UE_template[param->CC_id][UE_id].lcgidmap[param->logicalChannelIdentity] = 0; } if (param->physicalConfigDedicated != NULL) { UE_id = find_UE_id(Mod_idP, param->rnti); if (UE_id<0) { LOG_E(MAC, "Configuration received for unknown UE (%x), shouldn't happen\n", param->rnti); return(-1); } UE_info->UE_template[param->CC_id][UE_id].physicalConfigDedicated = param->physicalConfigDedicated; LOG_I(MAC, "Added physicalConfigDedicated %p for %d.%d\n", param->physicalConfigDedicated, param->CC_id, UE_id); } if (param->sCellToAddMod_r10 != NULL) { if (UE_id<0) { LOG_E(MAC, "Configuration received for unknown UE (%x), shouldn't happen\n", param->rnti); return(-1); } AssertFatal(UE_id >= 0, "Configuration received for unknown UE (%x), shouldn't happen\n", param->rnti); config_dedicated_scell(Mod_idP, param->rnti, param->sCellToAddMod_r10); } if (param->mbsfn_SubframeConfigList != NULL) { LOG_I(MAC, "[eNB %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n", Mod_idP, param->mbsfn_SubframeConfigList->list.count); eNB->common_channels[0].num_sf_allocation_pattern = param->mbsfn_SubframeConfigList->list.count; for (i = 0; i < param->mbsfn_SubframeConfigList->list.count; i++) { eNB->common_channels[0].mbsfn_SubframeConfig[i] = param->mbsfn_SubframeConfigList->list.array[i]; LOG_I(MAC, "[eNB %d][CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", Mod_idP, i, eNB->common_channels[0].mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]); } eNB->common_channels[0].MBMS_flag = param->MBMS_Flag; config_sib2_mbsfn_part(Mod_idP, 0, param->mbsfn_SubframeConfigList); } if (param->nonMBSFN_SubframeConfig != NULL) { LOG_D(MAC, "[eNB %d][CONFIG] Received a non MBSFN subframe allocation pattern (%x,%x):%x for FeMBMS-CAS\n", Mod_idP, param->nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[0], param->nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[1], param->nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[0] << 1 | param->nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[1] >> 7); // eNB->common_channels[0].non_mbsfn_SubframeConfig = (int)(nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[0]<<1) | (int)(nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[1]>>7); eNB->common_channels[0].non_mbsfn_SubframeConfig = param->nonMBSFN_SubframeConfig; nfapi_config_request_t *cfg = &eNB->config[param->CC_id]; cfg->fembms_config.non_mbsfn_config_flag.value = 1; cfg->fembms_config.non_mbsfn_config_flag.tl.tag = NFAPI_FEMBMS_CONFIG_NON_MBSFN_FLAG_TAG; cfg->num_tlv++; cfg->fembms_config.non_mbsfn_subframeconfig.value = (param->nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[0] << 1 | param->nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[1] >> 7); cfg->fembms_config.non_mbsfn_subframeconfig.tl.tag = NFAPI_FEMBMS_CONFIG_NON_MBSFN_SUBFRAMECONFIG_TAG; cfg->num_tlv++; cfg->fembms_config.radioframe_allocation_period.value = param->nonMBSFN_SubframeConfig->radioFrameAllocationPeriod_r14; cfg->fembms_config.radioframe_allocation_period.tl.tag = NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_PERIOD_TAG; cfg->num_tlv++; cfg->fembms_config.radioframe_allocation_offset.value = param->nonMBSFN_SubframeConfig->radioFrameAllocationOffset_r14; cfg->fembms_config.radioframe_allocation_offset.tl.tag = NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_OFFSET_TAG; cfg->num_tlv++; //We need to reuse current MCH scheduler //TOCHECK whether we can simply reuse current mbsfn_SubframeConfig stuff eNB->common_channels[0].FeMBMS_flag = param->FeMBMS_Flag; } if (param->mbsfn_AreaInfoList != NULL) { // One eNB could be part of multiple mbsfn syc area, this could change over time so reset each time LOG_I(MAC, "[eNB %d][CONFIG] Received %d MBSFN Area Info\n", Mod_idP, param->mbsfn_AreaInfoList->list.count); eNB->common_channels[0].num_active_mbsfn_area = param->mbsfn_AreaInfoList->list.count; for (i = 0; i < param->mbsfn_AreaInfoList->list.count; i++) { eNB->common_channels[0].mbsfn_AreaInfo[i] = param->mbsfn_AreaInfoList->list.array[i]; LOG_I(MAC, "[eNB %d][CONFIG] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n", Mod_idP, i, eNB->common_channels[0].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9); // config_sib13(Mod_idP,0,i,eNB->common_channels[0].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9); config_sib13(Mod_idP, 0, i, eNB->common_channels[0].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9); } } if (param->mbms_AreaConfiguration != NULL) { eNB->common_channels[0].commonSF_AllocPeriod_r9 = param->mbms_AreaConfiguration->commonSF_AllocPeriod_r9; LOG_I(MAC, "[eNB %d][CONFIG] commonSF_AllocPeriod_r9(%d)\n", Mod_idP, eNB->common_channels[0].commonSF_AllocPeriod_r9); for (i = 0; i < param->mbms_AreaConfiguration->commonSF_Alloc_r9.list.count; i++) { eNB->common_channels[0].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] = param->mbms_AreaConfiguration->commonSF_Alloc_r9.list.array[i]; LOG_I(RRC, "[eNB %d][CONFIG] MBSFNArea[%d] commonSF_Alloc_r9: radioframeAllocationPeriod(%ldn),radioframeAllocationOffset(%ld), subframeAllocation(%x)\n", Mod_idP, i, eNB->common_channels[0].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->radioframeAllocationPeriod, eNB->common_channels[0].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->radioframeAllocationOffset, eNB->common_channels[0].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]); } } if (param->pmch_InfoList != NULL) { // LOG_I(MAC,"DUY: lcid when entering rrc_mac config_req is %02d\n",(pmch_InfoList->list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9)); LOG_I(MAC, "[CONFIG] Number of PMCH in this MBSFN Area %d\n", param->pmch_InfoList->list.count); for (i = 0; i < param->pmch_InfoList->list.count; i++) { eNB->common_channels[0].pmch_Config[i] = ¶m->pmch_InfoList->list.array[i]->pmch_Config_r9; LOG_I(MAC, "[CONFIG] PMCH[%d]: This PMCH stop (sf_AllocEnd_r9) at subframe %ldth\n", i, eNB->common_channels[0].pmch_Config[i]->sf_AllocEnd_r9); LOG_I(MAC, "[CONFIG] PMCH[%d]: mch_Scheduling_Period = %ld\n", i, eNB->common_channels[0].pmch_Config[i]->mch_SchedulingPeriod_r9); LOG_I(MAC, "[CONFIG] PMCH[%d]: dataMCS = %ld\n", i, eNB->common_channels[0].pmch_Config[i]->dataMCS_r9); // MBMS session info list in each MCH eNB->common_channels[0].mbms_SessionList[i] = ¶m->pmch_InfoList->list.array[i]->mbms_SessionInfoList_r9; LOG_I(MAC, "PMCH[%d] Number of session (MTCH) is: %d\n", i, eNB->common_channels[0].mbms_SessionList[i]->list.count); for (int ii = 0; ii < eNB->common_channels[0].mbms_SessionList[i]->list.count; ii++) { LOG_I(MAC, "PMCH[%d] MBMS Session[%d] is: %lu\n", i, ii, eNB->common_channels[0].mbms_SessionList[i]->list.array[ii]->logicalChannelIdentity_r9); } } } LOG_D(MAC, "%s() %s:%d eNB->if_inst->PHY_config_req:%p\n", __FUNCTION__, __FILE__, __LINE__, eNB->if_inst->PHY_config_req); // if in nFAPI mode if ((NFAPI_MODE == NFAPI_MODE_PNF || NFAPI_MODE == NFAPI_MODE_VNF) && (eNB->if_inst->PHY_config_req == NULL)) { while (eNB->if_inst->PHY_config_req == NULL) { // DJP AssertFatal(eNB->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n"); usleep(100 * 1000); LOG_I(MAC, "Waiting for PHY_config_req\n"); } } if (param->radioResourceConfigCommon != NULL) { PHY_Config_t phycfg; phycfg.Mod_id = Mod_idP; phycfg.CC_id = param->CC_id; phycfg.cfg = &eNB->config[param->CC_id]; if (eNB->if_inst->PHY_config_req) eNB->if_inst->PHY_config_req(&phycfg); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT); } eNB->scheduler_mode = global_scheduler_mode; return(0); } //----------------------------------------------------------------------------- /* * Configure local CDRX timers and thresholds following the drx_configuration input */ void eNB_Config_Local_DRX(instance_t Mod_id, rrc_mac_drx_config_req_t *rrc_mac_drx_config_req) //----------------------------------------------------------------------------- { UE_info_t *UE_info_mac = &RC.mac[Mod_id]->UE_info; UE_sched_ctrl_t *UE_scheduling_control = NULL; LTE_DRX_Config_t *const drx_Configuration = rrc_mac_drx_config_req->drx_Configuration; rnti_t rnti = rrc_mac_drx_config_req->rnti; int UE_id = find_UE_id(Mod_id, rnti); /* Check UE_id */ if (UE_id == -1) { LOG_E(MAC, "[eNB_Config_Local_DRX] UE_id == -1\n"); return; } /* Get struct to modify */ UE_scheduling_control = &(UE_info_mac->UE_sched_ctrl[UE_id]); UE_scheduling_control->cdrx_configured = false; // will be set to true when no error /* Check drx_Configuration */ if (drx_Configuration == NULL) { LOG_W(MAC, "[eNB_Config_Local_DRX] drx_Configuration parameter is NULL, cannot configure local UE parameters for CDRX\n"); return; } /* Check if drx config present */ if (drx_Configuration->present != LTE_DRX_Config_PR_setup) { LOG_I(MAC, "[eNB_Config_Local_DRX] No drx_Configuration present, don't configure local UE parameters for CDRX\n"); return; } /* Modify scheduling control structure according to DRX configuration: doesn't support every configurations! */ UE_scheduling_control->cdrx_configured = false; // will be set to true when receiving RRC Reconfiguration Complete UE_scheduling_control->cdrx_waiting_ack = true; // waiting for RRC Reconfiguration Complete message UE_scheduling_control->in_active_time = false; UE_scheduling_control->dci0_ongoing_timer = 0; UE_scheduling_control->on_duration_timer = 0; struct LTE_DRX_Config__setup *choiceSetup = &drx_Configuration->choice.setup; switch (choiceSetup->onDurationTimer) { case 0: UE_scheduling_control->on_duration_timer_thres = 1; break; case 1: UE_scheduling_control->on_duration_timer_thres = 2; break; case 2: UE_scheduling_control->on_duration_timer_thres = 3; break; case 3: UE_scheduling_control->on_duration_timer_thres = 4; break; case 4: UE_scheduling_control->on_duration_timer_thres = 5; break; case 5: UE_scheduling_control->on_duration_timer_thres = 6; break; case 6: UE_scheduling_control->on_duration_timer_thres = 8; break; case 7: UE_scheduling_control->on_duration_timer_thres = 10; break; case 8: UE_scheduling_control->on_duration_timer_thres = 20; break; case 9: UE_scheduling_control->on_duration_timer_thres = 30; break; case 10: UE_scheduling_control->on_duration_timer_thres = 40; break; case 11: UE_scheduling_control->on_duration_timer_thres = 50; break; case 12: UE_scheduling_control->on_duration_timer_thres = 60; break; case 13: UE_scheduling_control->on_duration_timer_thres = 80; break; case 14: UE_scheduling_control->on_duration_timer_thres = 100; break; case 15: UE_scheduling_control->on_duration_timer_thres = 200; break; default: LOG_E(MAC, "[eNB_Config_Local_DRX] Error in local DRX configuration, the on duration timer value specified is unknown\n"); break; } UE_scheduling_control->drx_inactivity_timer = 0; switch (choiceSetup->drx_InactivityTimer) { case 0: UE_scheduling_control->drx_inactivity_timer_thres = 1; break; case 1: UE_scheduling_control->drx_inactivity_timer_thres = 2; break; case 2: UE_scheduling_control->drx_inactivity_timer_thres = 3; break; case 3: UE_scheduling_control->drx_inactivity_timer_thres = 4; break; case 4: UE_scheduling_control->drx_inactivity_timer_thres = 5; break; case 5: UE_scheduling_control->drx_inactivity_timer_thres = 6; break; case 6: UE_scheduling_control->drx_inactivity_timer_thres = 8; break; case 7: UE_scheduling_control->drx_inactivity_timer_thres = 10; break; case 8: UE_scheduling_control->drx_inactivity_timer_thres = 20; break; case 9: UE_scheduling_control->drx_inactivity_timer_thres = 30; break; case 10: UE_scheduling_control->drx_inactivity_timer_thres = 40; break; case 11: UE_scheduling_control->drx_inactivity_timer_thres = 50; break; case 12: UE_scheduling_control->drx_inactivity_timer_thres = 60; break; case 13: UE_scheduling_control->drx_inactivity_timer_thres = 80; break; case 14: UE_scheduling_control->drx_inactivity_timer_thres = 100; break; case 15: UE_scheduling_control->drx_inactivity_timer_thres = 200; break; case 16: UE_scheduling_control->drx_inactivity_timer_thres = 300; break; case 17: UE_scheduling_control->drx_inactivity_timer_thres = 500; break; case 18: UE_scheduling_control->drx_inactivity_timer_thres = 750; break; case 19: UE_scheduling_control->drx_inactivity_timer_thres = 1280; break; case 20: UE_scheduling_control->drx_inactivity_timer_thres = 1920; break; case 21: UE_scheduling_control->drx_inactivity_timer_thres = 2560; break; case 22: UE_scheduling_control->drx_inactivity_timer_thres = 0; break; default: LOG_E(MAC, "[eNB_Config_Local_DRX] Error in local DRX configuration, the drx inactivity timer value specified is unknown\n"); break; } if (choiceSetup->shortDRX == NULL) { UE_scheduling_control->in_short_drx_cycle = false; UE_scheduling_control->drx_shortCycle_timer_value = 0; UE_scheduling_control->short_drx_cycle_duration = 0; UE_scheduling_control->drx_shortCycle_timer = 0; UE_scheduling_control->drx_shortCycle_timer_thres = -1; } else { UE_scheduling_control->in_short_drx_cycle = false; UE_scheduling_control->drx_shortCycle_timer_value = (uint8_t) choiceSetup->shortDRX->drxShortCycleTimer; switch (choiceSetup->shortDRX->shortDRX_Cycle) { case 0: UE_scheduling_control->short_drx_cycle_duration = 2; break; case 1: UE_scheduling_control->short_drx_cycle_duration = 5; break; case 2: UE_scheduling_control->short_drx_cycle_duration = 8; break; case 3: UE_scheduling_control->short_drx_cycle_duration = 10; break; case 4: UE_scheduling_control->short_drx_cycle_duration = 16; break; case 5: UE_scheduling_control->short_drx_cycle_duration = 20; break; case 6: UE_scheduling_control->short_drx_cycle_duration = 32; break; case 7: UE_scheduling_control->short_drx_cycle_duration = 40; break; case 8: UE_scheduling_control->short_drx_cycle_duration = 64; break; case 9: UE_scheduling_control->short_drx_cycle_duration = 80; break; case 10: UE_scheduling_control->short_drx_cycle_duration = 128; break; case 11: UE_scheduling_control->short_drx_cycle_duration = 160; break; case 12: UE_scheduling_control->short_drx_cycle_duration = 256; break; case 13: UE_scheduling_control->short_drx_cycle_duration = 320; break; case 14: UE_scheduling_control->short_drx_cycle_duration = 512; break; case 15: UE_scheduling_control->short_drx_cycle_duration = 640; break; default: LOG_E(MAC, "[eNB_Config_Local_DRX] Error in local DRX configuration, the short drx timer value specified is unknown\n"); break; } UE_scheduling_control->drx_shortCycle_timer = 0; UE_scheduling_control->drx_shortCycle_timer_thres = UE_scheduling_control->drx_shortCycle_timer_value * UE_scheduling_control->short_drx_cycle_duration; } UE_scheduling_control->in_long_drx_cycle = false; UE_scheduling_control->drx_longCycle_timer = 0; switch (choiceSetup->longDRX_CycleStartOffset.present) { case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf10: UE_scheduling_control->drx_longCycle_timer_thres = 10; UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf10; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf20: UE_scheduling_control->drx_longCycle_timer_thres = 20; UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf20; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf32: UE_scheduling_control->drx_longCycle_timer_thres = 32; UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf32; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf40: UE_scheduling_control->drx_longCycle_timer_thres = 40; UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf40; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf64: UE_scheduling_control->drx_longCycle_timer_thres = 64; UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf64; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf80: UE_scheduling_control->drx_longCycle_timer_thres = 80; UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf80; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf128: UE_scheduling_control->drx_longCycle_timer_thres = 128; UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf128; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf160: UE_scheduling_control->drx_longCycle_timer_thres = 160; UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf160; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf256: UE_scheduling_control->drx_longCycle_timer_thres = 256; UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf256; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf320: UE_scheduling_control->drx_longCycle_timer_thres = 320; UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf320; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf512: UE_scheduling_control->drx_longCycle_timer_thres = 512; UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf512; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf640: UE_scheduling_control->drx_longCycle_timer_thres = 640; UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf640; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1024: UE_scheduling_control->drx_longCycle_timer_thres = 1024; UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf1024; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1280: UE_scheduling_control->drx_longCycle_timer_thres = 1280; UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf1280; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2048: UE_scheduling_control->drx_longCycle_timer_thres = 2048; UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf2048; break; case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2560: UE_scheduling_control->drx_longCycle_timer_thres = 2560; UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf2560; break; default: LOG_E(MAC, "[eNB_Config_Local_DRX] Invalid long_DRX value in DRX local configuration\n"); break; } memset(UE_scheduling_control->drx_retransmission_timer, 0, sizeof(UE_scheduling_control->drx_retransmission_timer)); switch (choiceSetup->drx_RetransmissionTimer) { case 0: memset(UE_scheduling_control->drx_retransmission_timer_thres, 1, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); break; case 1: memset(UE_scheduling_control->drx_retransmission_timer_thres, 2, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); break; case 2: memset(UE_scheduling_control->drx_retransmission_timer_thres, 4, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); break; case 3: memset(UE_scheduling_control->drx_retransmission_timer_thres, 6, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); break; case 4: memset(UE_scheduling_control->drx_retransmission_timer_thres, 8, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); break; case 5: memset(UE_scheduling_control->drx_retransmission_timer_thres, 16, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); break; case 6: memset(UE_scheduling_control->drx_retransmission_timer_thres, 24, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); break; case 7: memset(UE_scheduling_control->drx_retransmission_timer_thres, 33, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); break; default: LOG_E(MAC, "[eNB_Config_Local_DRX] Error in local DRX configuration, the drx retransmission timer value specified is unknown\n"); break; } }