/******************************************************************************* OpenAirInterface Copyright(c) 1999 - 2014 Eurecom OpenAirInterface is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenAirInterface is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenAirInterface.The full GNU General Public License is included in this distribution in the file called "COPYING". If not, see . Contact Information OpenAirInterface Admin: openair_admin@eurecom.fr OpenAirInterface Tech : openair_tech@eurecom.fr OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE *******************************************************************************/ /*! \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 "SystemInformationBlockType2.h" //#include "RadioResourceConfigCommonSIB.h" #include "RadioResourceConfigDedicated.h" #include "MeasGapConfig.h" #include "MeasObjectToAddModList.h" #include "TDD-Config.h" #include "defs.h" #include "proto.h" #include "extern.h" #include "UTIL/LOG/log.h" #include "UTIL/LOG/vcd_signal_dumper.h" #ifdef Rel10 #include "MBSFN-AreaInfoList-r9.h" #include "MBSFN-AreaInfo-r9.h" #include "MBSFN-SubframeConfigList.h" #include "PMCH-InfoList-r9.h" #endif #if FAPI #include "ff-mac-csched-sap.h" #endif /* sec 5.9, 36.321: MAC Reset Procedure */ void ue_mac_reset(module_id_t module_idP,uint8_t eNB_index) { //Resetting Bj UE_mac_inst[module_idP].scheduling_info.Bj[0] = 0; UE_mac_inst[module_idP].scheduling_info.Bj[1] = 0; UE_mac_inst[module_idP].scheduling_info.Bj[2] = 0; //Stopping all timers //timeAlignmentTimer expires // PHY changes for UE MAC reset mac_xface->phy_reset_ue(module_idP,0,eNB_index); // notify RRC to relase PUCCH/SRS // cancel all pending SRs UE_mac_inst[module_idP].scheduling_info.SR_pending=0; UE_mac_inst[module_idP].scheduling_info.SR_COUNTER=0; // stop ongoing RACH procedure // discard explicitly signaled ra_PreambleIndex and ra_RACH_MaskIndex, if any UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = 0; // check! UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0; ue_init_mac(module_idP); //This will hopefully do the rest of the MAC reset procedure } int rrc_mac_config_req( module_id_t Mod_id, int CC_id, eNB_flag_t eNB_flagP, rnti_t rntiP, uint8_t eNB_index, RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, struct PhysicalConfigDedicated *physicalConfigDedicated, #ifdef Rel10 SCellToAddMod_r10_t *sCellToAddMod_r10, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif MeasObjectToAddMod_t **measObj, MAC_MainConfig_t *mac_MainConfig, long logicalChannelIdentity, LogicalChannelConfig_t *logicalChannelConfig, MeasGapConfig_t *measGapConfig, TDD_Config_t *tdd_Config, MobilityControlInfo_t *mobilityControlInfo, uint8_t *SIwindowsize, uint16_t *SIperiod, ARFCN_ValueEUTRA_t *ul_CarrierFreq, long *ul_Bandwidth, AdditionalSpectrumEmission_t *additionalSpectrumEmission, struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList #ifdef Rel10 ,uint8_t MBMS_Flag, MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList, PMCH_InfoList_r9_t *pmch_InfoList #endif #ifdef CBA ,uint8_t num_active_cba_groups, uint16_t cba_rnti #endif ) { int i; int UE_id = -1; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN); if (eNB_flagP==0) { LOG_I(MAC,"[CONFIG][UE %d] Configuring MAC/PHY from eNB %d\n",Mod_id,eNB_index); if (tdd_Config != NULL) { UE_mac_inst[Mod_id].tdd_Config = tdd_Config; } } else { UE_id = find_UE_id(Mod_id, rntiP); if (physicalConfigDedicated == NULL) { LOG_I(MAC,"[CONFIG][eNB %d/%d] Configuring MAC/PHY\n", Mod_id, CC_id); } else { LOG_I(MAC,"[CONFIG][eNB %d/%d] Configuring MAC/PHY for UE %d (%x)\n", Mod_id, CC_id, UE_id, UE_RNTI(Mod_id, UE_id)); } } if (tdd_Config && SIwindowsize && SIperiod) { if (eNB_flagP == ENB_FLAG_YES) { mac_xface->phy_config_sib1_eNB(Mod_id, CC_id, tdd_Config, *SIwindowsize, *SIperiod); } else { mac_xface->phy_config_sib1_ue(Mod_id,0,eNB_index,tdd_Config,*SIwindowsize,*SIperiod); } } if (radioResourceConfigCommon!=NULL) { if (eNB_flagP==1) { LOG_I(MAC,"[CONFIG]SIB2/3 Contents (partial)\n"); LOG_I(MAC,"[CONFIG]pusch_config_common.n_SB = %ld\n",radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.n_SB); LOG_I(MAC,"[CONFIG]pusch_config_common.hoppingMode = %ld\n",radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode); LOG_I(MAC,"[CONFIG]pusch_config_common.pusch_HoppingOffset = %ld\n", radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset); LOG_I(MAC,"[CONFIG]pusch_config_common.enable64QAM = %d\n",radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM); LOG_I(MAC,"[CONFIG]pusch_config_common.groupHoppingEnabled = %d\n",radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled); LOG_I(MAC,"[CONFIG]pusch_config_common.groupAssignmentPUSCH = %ld\n",radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH); LOG_I(MAC,"[CONFIG]pusch_config_common.sequenceHoppingEnabled = %d\n",radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled); LOG_I(MAC,"[CONFIG]pusch_config_common.cyclicShift = %ld\n",radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift); mac_xface->phy_config_sib2_eNB(Mod_id, CC_id, radioResourceConfigCommon, ul_CarrierFreq, ul_Bandwidth, additionalSpectrumEmission, mbsfn_SubframeConfigList); } else { UE_mac_inst[Mod_id].radioResourceConfigCommon = radioResourceConfigCommon; mac_xface->phy_config_sib2_ue(Mod_id,0,eNB_index,radioResourceConfigCommon,ul_CarrierFreq,ul_Bandwidth,additionalSpectrumEmission,mbsfn_SubframeConfigList); } } // SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters->logicalChannelGroup if (logicalChannelConfig!= NULL) { #if FAPI if (eNB_flagP == 1) { printf("MAC CONFIG lcid %d group %d\n", (int)logicalChannelIdentity, (int)*logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup); /* only configure DRBs, SRBs are already configured */ if (logicalChannelIdentity > 2) { struct CschedLcConfigReqParameters lc; struct LogicalChannelConfigListElement_s lcs; struct CschedLcConfigCnfParameters lcr; fapi_interface_t *fapi; LOG_I(MAC, "eNB %d/%d: FAPI: configure DRB %d for UE %x\n", Mod_id, CC_id, logicalChannelIdentity, rntiP); fapi = eNB_mac_inst[Mod_id].fapi; lc.rnti = rntiP; lc.reconfigureFlag = false; lc.nr_logicalChannelConfigList = 1; lc.logicalChannelConfigList = &lcs; lc.nr_vendorSpecificList = 0; lc.vendorSpecificList = NULL; lcs.logicalChannelIdentity = logicalChannelIdentity; lcs.logicalChannelGroup = *logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup; lcs.direction = DIR_BOTH; /* TODO: not necessarily */ lcs.qosBearerType = QBT_NON_GBR; /* TODO: not necessarily */ lcs.qci = 5; /* what to put? see 23.203 table 6.1.7 */ /* TODO: bitrates not used - let's suppose we are in non GBR */ CschedLcConfigReq(fapi->sched, &lc); CschedLcConfigCnf(fapi, &lcr); if (lcr.rnti != rntiP) { LOG_E(MAC, "%s:%d:%s: possible?\n", __FILE__, __LINE__, __FUNCTION__); abort(); } if (lcr.result != ff_SUCCESS) { LOG_E(MAC, "%s:%d:%s: possible?\n", __FILE__, __LINE__, __FUNCTION__); abort(); } if (lcr.nr_logicalChannelIdendity != 1) { LOG_E(MAC, "%s:%d:%s: possible?\n", __FILE__, __LINE__, __FUNCTION__); abort(); } /* TODO: check other return values (see rrc_mac_fapi_configure_srb12 for why it's not done) */ } } #endif /* FAPI */ if (eNB_flagP==0) { LOG_I(MAC,"[CONFIG][UE %d] Applying RRC logicalChannelConfig from eNB%d\n",Mod_id,eNB_index); UE_mac_inst[Mod_id].logicalChannelConfig[logicalChannelIdentity]=logicalChannelConfig; UE_mac_inst[Mod_id].scheduling_info.Bj[logicalChannelIdentity]=0; // initilize the bucket for this lcid if (logicalChannelConfig->ul_SpecificParameters) { UE_mac_inst[Mod_id].scheduling_info.bucket_size[logicalChannelIdentity]=logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate * logicalChannelConfig->ul_SpecificParameters->bucketSizeDuration; // set the max bucket size UE_mac_inst[Mod_id].scheduling_info.LCGID[logicalChannelIdentity]=*logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup; LOG_D(MAC,"[CONFIG][UE %d] LCID %d is attached to the LCGID %d\n",Mod_id,logicalChannelIdentity,*logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup); } else { LOG_E(MAC,"[CONFIG][UE %d] LCID %d NULL ul_SpecificParameters\n",Mod_id,logicalChannelIdentity); mac_xface->macphy_exit("NULL ul_SpecificParameters"); } } } if (mac_MainConfig != NULL) { if (eNB_flagP==0) { LOG_I(MAC,"[CONFIG][UE%d] Applying RRC macMainConfig from eNB%d\n",Mod_id,eNB_index); UE_mac_inst[Mod_id].macConfig=mac_MainConfig; UE_mac_inst[Mod_id].measGapConfig=measGapConfig; if (mac_MainConfig->ul_SCH_Config) { if (mac_MainConfig->ul_SCH_Config->periodicBSR_Timer) { UE_mac_inst[Mod_id].scheduling_info.periodicBSR_Timer = (uint16_t) *mac_MainConfig->ul_SCH_Config->periodicBSR_Timer; } else { UE_mac_inst[Mod_id].scheduling_info.periodicBSR_Timer = (uint16_t) MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity; } if (mac_MainConfig->ul_SCH_Config->maxHARQ_Tx) { UE_mac_inst[Mod_id].scheduling_info.maxHARQ_Tx = (uint16_t) *mac_MainConfig->ul_SCH_Config->maxHARQ_Tx; } else { UE_mac_inst[Mod_id].scheduling_info.maxHARQ_Tx = (uint16_t) MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; } if (mac_MainConfig->ul_SCH_Config->retxBSR_Timer) { UE_mac_inst[Mod_id].scheduling_info.retxBSR_Timer = (uint16_t) mac_MainConfig->ul_SCH_Config->retxBSR_Timer; } else { UE_mac_inst[Mod_id].scheduling_info.retxBSR_Timer = (uint16_t)MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf2560; } } #ifdef Rel10 if (mac_MainConfig->ext1 && mac_MainConfig->ext1->sr_ProhibitTimer_r9) { UE_mac_inst[Mod_id].scheduling_info.sr_ProhibitTimer = (uint16_t) *mac_MainConfig->ext1->sr_ProhibitTimer_r9; } else { UE_mac_inst[Mod_id].scheduling_info.sr_ProhibitTimer = (uint16_t) 0; } #endif UE_mac_inst[Mod_id].scheduling_info.periodicBSR_SF = get_sf_periodicBSRTimer(UE_mac_inst[Mod_id].scheduling_info.periodicBSR_Timer); UE_mac_inst[Mod_id].scheduling_info.retxBSR_SF = get_sf_retxBSRTimer(UE_mac_inst[Mod_id].scheduling_info.retxBSR_Timer); UE_mac_inst[Mod_id].scheduling_info.drx_config = mac_MainConfig->drx_Config; UE_mac_inst[Mod_id].scheduling_info.phr_config = mac_MainConfig->phr_Config; if (mac_MainConfig->phr_Config) { UE_mac_inst[Mod_id].PHR_state = mac_MainConfig->phr_Config->present; UE_mac_inst[Mod_id].PHR_reconfigured = 1; UE_mac_inst[Mod_id].scheduling_info.periodicPHR_Timer = mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer; UE_mac_inst[Mod_id].scheduling_info.prohibitPHR_Timer = mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer; UE_mac_inst[Mod_id].scheduling_info.PathlossChange = mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange; } else { UE_mac_inst[Mod_id].PHR_reconfigured = 0; UE_mac_inst[Mod_id].PHR_state = MAC_MainConfig__phr_Config_PR_setup; UE_mac_inst[Mod_id].scheduling_info.periodicPHR_Timer = MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; UE_mac_inst[Mod_id].scheduling_info.prohibitPHR_Timer = MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; UE_mac_inst[Mod_id].scheduling_info.PathlossChange = MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; } UE_mac_inst[Mod_id].scheduling_info.periodicPHR_SF = get_sf_perioidicPHR_Timer(UE_mac_inst[Mod_id].scheduling_info.periodicPHR_Timer); UE_mac_inst[Mod_id].scheduling_info.prohibitPHR_SF = get_sf_prohibitPHR_Timer(UE_mac_inst[Mod_id].scheduling_info.prohibitPHR_Timer); UE_mac_inst[Mod_id].scheduling_info.PathlossChange_db = get_db_dl_PathlossChange(UE_mac_inst[Mod_id].scheduling_info.PathlossChange); LOG_D(MAC,"[UE %d] config PHR (%d): periodic %d (SF) prohibit %d (SF) pathlosschange %d (db) \n", Mod_id, (mac_MainConfig->phr_Config)?mac_MainConfig->phr_Config->present:-1, UE_mac_inst[Mod_id].scheduling_info.periodicPHR_SF, UE_mac_inst[Mod_id].scheduling_info.prohibitPHR_SF, UE_mac_inst[Mod_id].scheduling_info.PathlossChange_db); } } if (physicalConfigDedicated != NULL) { if (eNB_flagP==1) { mac_xface->phy_config_dedicated_eNB(Mod_id, CC_id, UE_RNTI(Mod_id, UE_id), physicalConfigDedicated); } else { mac_xface->phy_config_dedicated_ue(Mod_id,0,eNB_index,physicalConfigDedicated); UE_mac_inst[Mod_id].physicalConfigDedicated=physicalConfigDedicated; // for SR proc } } #ifdef Rel10 if (sCellToAddMod_r10 != NULL) { if (eNB_flagP==1) { mac_xface->phy_config_dedicated_scell_eNB(Mod_id,UE_RNTI(Mod_id,UE_id),sCellToAddMod_r10,1); } else { #warning "phy_config_dedicated_scell_ue is empty" mac_xface->phy_config_dedicated_scell_ue(Mod_id,eNB_index,sCellToAddMod_r10,1); UE_mac_inst[Mod_id].physicalConfigDedicatedSCell_r10 = sCellToAddMod_r10->radioResourceConfigDedicatedSCell_r10->physicalConfigDedicatedSCell_r10; // using SCell index 0 } } #endif if (eNB_flagP == 0) { if (measObj!= NULL) { if (measObj[0]!= NULL) { UE_mac_inst[Mod_id].n_adj_cells = measObj[0]->measObject.choice.measObjectEUTRA.cellsToAddModList->list.count; LOG_I(MAC,"Number of adjacent cells %d\n",UE_mac_inst[Mod_id].n_adj_cells); for (i=0; imeasObject.choice.measObjectEUTRA.cellsToAddModList->list.array[i]->physCellId; LOG_I(MAC,"Cell %d : Nid_cell %d\n",i,UE_mac_inst[Mod_id].adj_cell_id[i]); } mac_xface->phy_config_meas_ue(Mod_id,0,eNB_index,UE_mac_inst[Mod_id].n_adj_cells,UE_mac_inst[Mod_id].adj_cell_id); } /* if (quantityConfig != NULL) { if (quantityConfig[0] != NULL) { UE_mac_inst[Mod_id].quantityConfig = quantityConfig[0]; LOG_I(MAC,"UE %d configured filterCoeff.",UE_mac_inst[Mod_id].crnti); mac_xface->phy_config_meas_ue } } */ } } if (eNB_flagP==0) { if(mobilityControlInfo != NULL) { LOG_D(MAC,"[UE%d] MAC Reset procedure triggered by RRC eNB %d \n",Mod_id,eNB_index); ue_mac_reset(Mod_id,eNB_index); if(mobilityControlInfo->radioResourceConfigCommon.rach_ConfigCommon) { memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->rach_ConfigCommon, (void *)mobilityControlInfo->radioResourceConfigCommon.rach_ConfigCommon, sizeof(RACH_ConfigCommon_t)); } memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->prach_Config.prach_ConfigInfo, (void *)mobilityControlInfo->radioResourceConfigCommon.prach_Config.prach_ConfigInfo, sizeof(PRACH_ConfigInfo_t)); UE_mac_inst[Mod_id].radioResourceConfigCommon->prach_Config.rootSequenceIndex = mobilityControlInfo->radioResourceConfigCommon.prach_Config.rootSequenceIndex; if(mobilityControlInfo->radioResourceConfigCommon.pdsch_ConfigCommon) { memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->pdsch_ConfigCommon, (void *)mobilityControlInfo->radioResourceConfigCommon.pdsch_ConfigCommon, sizeof(PDSCH_ConfigCommon_t)); } // not a pointer: mobilityControlInfo->radioResourceConfigCommon.pusch_ConfigCommon memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->pusch_ConfigCommon, (void *)&mobilityControlInfo->radioResourceConfigCommon.pusch_ConfigCommon, sizeof(PUSCH_ConfigCommon_t)); if(mobilityControlInfo->radioResourceConfigCommon.phich_Config) { /* memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->phich_Config, (void *)mobilityControlInfo->radioResourceConfigCommon.phich_Config, sizeof(PHICH_Config_t)); */ } if(mobilityControlInfo->radioResourceConfigCommon.pucch_ConfigCommon) { memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->pucch_ConfigCommon, (void *)mobilityControlInfo->radioResourceConfigCommon.pucch_ConfigCommon, sizeof(PUCCH_ConfigCommon_t)); } if(mobilityControlInfo->radioResourceConfigCommon.soundingRS_UL_ConfigCommon) { memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->soundingRS_UL_ConfigCommon, (void *)mobilityControlInfo->radioResourceConfigCommon.soundingRS_UL_ConfigCommon, sizeof(SoundingRS_UL_ConfigCommon_t)); } if(mobilityControlInfo->radioResourceConfigCommon.uplinkPowerControlCommon) { memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->uplinkPowerControlCommon, (void *)mobilityControlInfo->radioResourceConfigCommon.uplinkPowerControlCommon, sizeof(UplinkPowerControlCommon_t)); } //configure antennaInfoCommon somewhere here.. if(mobilityControlInfo->radioResourceConfigCommon.p_Max) { //to be configured } if(mobilityControlInfo->radioResourceConfigCommon.tdd_Config) { UE_mac_inst[Mod_id].tdd_Config = mobilityControlInfo->radioResourceConfigCommon.tdd_Config; } if(mobilityControlInfo->radioResourceConfigCommon.ul_CyclicPrefixLength) { memcpy((void *)&UE_mac_inst[Mod_id].radioResourceConfigCommon->ul_CyclicPrefixLength, (void *)mobilityControlInfo->radioResourceConfigCommon.ul_CyclicPrefixLength, sizeof(UL_CyclicPrefixLength_t)); } // store the previous rnti in case of failure, and set thenew rnti UE_mac_inst[Mod_id].crnti_before_ho = UE_mac_inst[Mod_id].crnti; UE_mac_inst[Mod_id].crnti = ((mobilityControlInfo->newUE_Identity.buf[0])|(mobilityControlInfo->newUE_Identity.buf[1]<<8)); LOG_I(MAC,"[UE %d] Received new identity %x from %d\n", Mod_id, UE_mac_inst[Mod_id].crnti, eNB_index); UE_mac_inst[Mod_id].rach_ConfigDedicated = malloc(sizeof(*mobilityControlInfo->rach_ConfigDedicated)); if (mobilityControlInfo->rach_ConfigDedicated) { memcpy((void*)UE_mac_inst[Mod_id].rach_ConfigDedicated, (void*)mobilityControlInfo->rach_ConfigDedicated, sizeof(*mobilityControlInfo->rach_ConfigDedicated)); } mac_xface->phy_config_afterHO_ue(Mod_id,0,eNB_index,mobilityControlInfo,0); } } if (mbsfn_SubframeConfigList != NULL) { if (eNB_flagP == 1) { LOG_I(MAC,"[eNB %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n", Mod_id, mbsfn_SubframeConfigList->list.count); eNB_mac_inst[Mod_id].common_channels[0].num_sf_allocation_pattern= mbsfn_SubframeConfigList->list.count; for (i=0; ilist.count; i++) { eNB_mac_inst[Mod_id].common_channels[0].mbsfn_SubframeConfig[i] = mbsfn_SubframeConfigList->list.array[i]; LOG_I(MAC, "[eNB %d][CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", Mod_id, i, eNB_mac_inst[Mod_id].common_channels[0].mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]); } #ifdef Rel10 eNB_mac_inst[Mod_id].common_channels[0].MBMS_flag = MBMS_Flag; #endif } else { // UE LOG_I(MAC,"[UE %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n", Mod_id, mbsfn_SubframeConfigList->list.count); UE_mac_inst[Mod_id].num_sf_allocation_pattern= mbsfn_SubframeConfigList->list.count; for (i=0; ilist.count; i++) { LOG_I(MAC, "[UE %d] Configuring MBSFN_SubframeConfig %d from received SIB2 \n", Mod_id, i); UE_mac_inst[Mod_id].mbsfn_SubframeConfig[i] = mbsfn_SubframeConfigList->list.array[i]; // LOG_I("[UE %d] MBSFN_SubframeConfig[%d] pattern is %ld\n", Mod_id, // UE_mac_inst[Mod_id].mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]); } } } #ifdef Rel10 if (mbsfn_AreaInfoList != NULL) { if (eNB_flagP == 1) { // 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_id, mbsfn_AreaInfoList->list.count); eNB_mac_inst[Mod_id].common_channels[0].num_active_mbsfn_area = mbsfn_AreaInfoList->list.count; for (i =0; i< mbsfn_AreaInfoList->list.count; i++) { eNB_mac_inst[Mod_id].common_channels[0].mbsfn_AreaInfo[i] = mbsfn_AreaInfoList->list.array[i]; LOG_I(MAC,"[eNB %d][CONFIG] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n", Mod_id,i, eNB_mac_inst[Mod_id].common_channels[0].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9); mac_xface->phy_config_sib13_eNB(Mod_id,0,i,eNB_mac_inst[Mod_id].common_channels[0].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9); } } else { // UE LOG_I(MAC,"[UE %d][CONFIG] Received %d MBSFN Area Info\n", Mod_id, mbsfn_AreaInfoList->list.count); UE_mac_inst[Mod_id].num_active_mbsfn_area = mbsfn_AreaInfoList->list.count; for (i =0; i< mbsfn_AreaInfoList->list.count; i++) { UE_mac_inst[Mod_id].mbsfn_AreaInfo[i] = mbsfn_AreaInfoList->list.array[i]; LOG_I(MAC,"[UE %d] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n",Mod_id, i, UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9); mac_xface->phy_config_sib13_ue(Mod_id,0,eNB_index,i,UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9); } } } if (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)); if (eNB_flagP == 1) { LOG_I(MAC, "[CONFIG] Number of PMCH in this MBSFN Area %d\n", pmch_InfoList->list.count); for (i =0; i< pmch_InfoList->list.count; i++) { eNB_mac_inst[Mod_id].common_channels[0].pmch_Config[i] = &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_mac_inst[Mod_id].common_channels[0].pmch_Config[i]->sf_AllocEnd_r9); LOG_I(MAC, "[CONFIG] PMCH[%d]: mch_Scheduling_Period = %ld\n", i, eNB_mac_inst[Mod_id].common_channels[0].pmch_Config[i]->mch_SchedulingPeriod_r9); LOG_I(MAC, "[CONFIG] PMCH[%d]: dataMCS = %ld\n", i, eNB_mac_inst[Mod_id].common_channels[0].pmch_Config[i]->dataMCS_r9); // MBMS session info list in each MCH eNB_mac_inst[Mod_id].common_channels[0].mbms_SessionList[i] = &pmch_InfoList->list.array[i]->mbms_SessionInfoList_r9; LOG_I(MAC, "PMCH[%d] Number of session (MTCH) is: %d\n",i, eNB_mac_inst[Mod_id].common_channels[0].mbms_SessionList[i]->list.count); } } else { // UE LOG_I(MAC, "[UE %d] Configuring PMCH_config from MCCH MESSAGE \n",Mod_id); for (i =0; i< pmch_InfoList->list.count; i++) { UE_mac_inst[Mod_id].pmch_Config[i] = &pmch_InfoList->list.array[i]->pmch_Config_r9; LOG_I(MAC, "[UE %d] PMCH[%d]: MCH_Scheduling_Period = %ld\n", Mod_id, i, UE_mac_inst[Mod_id].pmch_Config[i]->mch_SchedulingPeriod_r9); } UE_mac_inst[Mod_id].mcch_status = 1; } } #endif #ifdef CBA if (eNB_flagP == 0) { if (cba_rnti) { UE_mac_inst[Mod_id].cba_rnti[num_active_cba_groups-1] = cba_rnti; LOG_D(MAC,"[UE %d] configure CBA group %d RNTI %x for eNB %d (total active cba group %d)\n", Mod_id,Mod_id%num_active_cba_groups, cba_rnti,eNB_index,num_active_cba_groups); mac_xface->phy_config_cba_rnti(Mod_id,CC_id,eNB_flagP,eNB_index,cba_rnti,num_active_cba_groups-1, num_active_cba_groups); } } else { if (cba_rnti) { LOG_D(MAC,"[eNB %d] configure CBA RNTI for UE %d (total active cba groups %d)\n", Mod_id, UE_id, num_active_cba_groups); eNB_mac_inst[Mod_id].common_channels[CC_id].num_active_cba_groups=num_active_cba_groups; for (i=0; i < num_active_cba_groups; i ++) { if (eNB_mac_inst[Mod_id].common_channels[CC_id].cba_rnti[i] != cba_rnti + i) { eNB_mac_inst[Mod_id].common_channels[CC_id].cba_rnti[i] = cba_rnti + i; } //only configure UE ids up to num_active_cba_groups //we use them as candidates for the transmission of dci format0) if (UE_id%num_active_cba_groups == i) { mac_xface->phy_config_cba_rnti(Mod_id,CC_id,eNB_flagP,UE_id,cba_rnti + i,i,num_active_cba_groups ); LOG_D(MAC,"[eNB %d] configure CBA groups %d with RNTI %x for UE %d (total active cba groups %d)\n", Mod_id, i, eNB_mac_inst[Mod_id].common_channels[CC_id].cba_rnti[i],UE_id, num_active_cba_groups); } } } } #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT); return(0); } #ifdef LOCALIZATION //------------------------------------------------------------------------------ double rrc_get_estimated_ue_distance( const protocol_ctxt_t* const ctxt_pP, const int CC_idP, const uint8_t loc_typeP ) //------------------------------------------------------------------------------ { // localization types: // 0: power based // 1: time based LTE_eNB_UE_stats *eNB_UE_stats = NULL; UE_list_t* UE_list = &eNB_mac_inst[ctxt_pP->module_id].UE_list; int pCCid; int UE_id; if(ctxt_pP->rnti == NOT_A_RNTI) { return -1; } UE_id = find_UE_id(ctxt_pP->module_id,ctxt_pP->rnti); pCCid = UE_PCCID(ctxt_pP->module_id,UE_id); eNB_UE_stats = mac_xface->get_eNB_UE_stats(ctxt_pP->module_id,pCCid,ctxt_pP->rnti); switch (loc_typeP) { case 0: return eNB_UE_stats->distance.power_based; break; case 1: return eNB_UE_stats->distance.time_based; break; default: return eNB_UE_stats->distance.power_based; } // LOG_D(LOCALIZE, "DEBUG ME, dist = %d\n", &eNB_mac_inst[ctxt_pP->module_id].UE_list.UE_template[CC_id][UE_id].distance.power_based); } #endif #if FAPI void rrc_mac_fapi_configure_srb12(int module_id, int CC_id, int rnti) { struct CschedLcConfigReqParameters lc; struct LogicalChannelConfigListElement_s lcs[2]; struct CschedLcConfigCnfParameters lcr; fapi_interface_t *fapi; LOG_I(MAC, "eNB %d/%d: FAPI: configure SRB 1 and 2 for UE %x\n", module_id, CC_id, rnti); fapi = eNB_mac_inst[module_id].fapi; lc.rnti = rnti; lc.reconfigureFlag = false; lc.nr_logicalChannelConfigList = 2; lc.logicalChannelConfigList = lcs; lc.nr_vendorSpecificList = 0; lc.vendorSpecificList = NULL; /* SRB 1 */ lcs[0].logicalChannelIdentity = 1; lcs[0].logicalChannelGroup = 0; /* TBC */ lcs[0].direction = DIR_BOTH; lcs[0].qosBearerType = QBT_NON_GBR; lcs[0].qci = 5; /* what to put? see 23.203 table 6.1.7 */ /* bitrates not used - we are in non GBR */ /* SRB 2 */ lcs[1].logicalChannelIdentity = 2; lcs[1].logicalChannelGroup = 0; /* TBC */ lcs[1].direction = DIR_BOTH; lcs[1].qosBearerType = QBT_NON_GBR; lcs[1].qci = 5; /* what to put? see 23.203 table 6.1.7 */ /* bitrates not used - we are in non GBR */ CschedLcConfigReq(fapi->sched, &lc); CschedLcConfigCnf(fapi, &lcr); if (lcr.rnti != rnti) { LOG_E(MAC, "%s:%d:%s: possible?\n", __FILE__, __LINE__, __FUNCTION__); abort(); } if (lcr.result != ff_SUCCESS) { LOG_E(MAC, "%s:%d:%s: possible?\n", __FILE__, __LINE__, __FUNCTION__); abort(); } if (lcr.nr_logicalChannelIdendity != 2) { LOG_E(MAC, "%s:%d:%s: possible?\n", __FILE__, __LINE__, __FUNCTION__); abort(); } /* libscheduler.a does not set those values as of v7 */ #if 0 if (lcr.logicalChannelIdentity[0] != 1 && lcr.logicalChannelIdentity[0] != 2) { LOG_E(MAC, "%s:%d:%s: possible?\n", __FILE__, __LINE__, __FUNCTION__); abort(); } if (lcr.logicalChannelIdentity[1] != 2 && lcr.logicalChannelIdentity[1] != 1) { LOG_E(MAC, "%s:%d:%s: possible?\n", __FILE__, __LINE__, __FUNCTION__); abort(); } if (lcr.logicalChannelIdentity[0] == lcr.logicalChannelIdentity[1]) { LOG_E(MAC, "%s:%d:%s: possible?\n", __FILE__, __LINE__, __FUNCTION__); abort(); } #endif } #endif