/*******************************************************************************
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