From 83c3acd0aec03e6cb419275d2c9e7095907282ab Mon Sep 17 00:00:00 2001 From: Raymond Knopp <raymond.knopp@eurecom.fr> Date: Mon, 11 Aug 2014 14:13:04 +0000 Subject: [PATCH] git-svn-id: http://svn.eurecom.fr/openair4G/trunk@5699 818b1a75-f10b-46b9-bf7c-635c3b92a50f --- openair2/LAYER2/MAC/config.c | 108 +- openair2/LAYER2/MAC/defs.h | 57 +- openair2/LAYER2/MAC/eNB_scheduler.c | 167 +- openair2/LAYER2/MAC/eNB_scheduler_RA.c | 538 +++ openair2/LAYER2/MAC/eNB_scheduler_bch.c | 133 +- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 3307 +++++++++-------- .../LAYER2/MAC/eNB_scheduler_primitives.c | 263 +- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 1482 ++++---- openair2/LAYER2/MAC/l1_helpers.c | 20 +- openair2/LAYER2/MAC/main.c | 51 +- openair2/LAYER2/MAC/pre_processor.c | 1262 ++++--- openair2/LAYER2/MAC/proto.h | 112 +- openair2/LAYER2/MAC/ra_procedures.c | 707 +--- openair2/LAYER2/MAC/rar_tools.c | 40 +- openair2/LAYER2/MAC/ue_procedures.c | 111 +- openair2/LAYER2/MAC/vars.h | 5 + openair2/LAYER2/Makefile.inc | 1 + openair2/LAYER2/openair2_proc.c | 91 +- openair2/PHY_INTERFACE/defs.h | 72 +- openair2/RRC/LITE/rrc_eNB.c | 4 +- 20 files changed, 4508 insertions(+), 4023 deletions(-) create mode 100644 openair2/LAYER2/MAC/eNB_scheduler_RA.c diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index 462a972a08..a67fa091d0 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -63,6 +63,7 @@ void ue_mac_reset(module_id_t module_idP,uint8_t eNB_index) { 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 @@ -74,45 +75,50 @@ void ue_mac_reset(module_id_t module_idP,uint8_t eNB_index) { // 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, eNB_flag_t eNB_flagP,uint8_t UE_id,uint8_t eNB_index, - RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, - struct PhysicalConfigDedicated *physicalConfigDedicated, - 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 + RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, + struct PhysicalConfigDedicated *physicalConfigDedicated, #ifdef Rel10 - ,uint8_t MBMS_Flag, - MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList, - PMCH_InfoList_r9_t *pmch_InfoList + 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 + ,uint8_t num_active_cba_groups, + uint16_t cba_rnti #endif ) { - int i; + int i,CC_id; vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN); @@ -124,15 +130,15 @@ int rrc_mac_config_req(module_id_t Mod_id, eNB_flag_t eNB_flagP,uint8_t UE_id,ui if (physicalConfigDedicated == NULL){ LOG_I(MAC,"[CONFIG][eNB %d] Configuring MAC/PHY\n",Mod_id); } else{ - LOG_I(MAC,"[CONFIG][eNB %d] Configuring MAC/PHY for UE %d (%x)\n",Mod_id,UE_id,find_UE_RNTI(Mod_id,UE_id)); + LOG_I(MAC,"[CONFIG][eNB %d] Configuring MAC/PHY for UE %d (%x)\n",Mod_id,UE_id,UE_RNTI(Mod_id,UE_id)); } } if ((tdd_Config!=NULL)||(SIwindowsize!=NULL)||(SIperiod!=NULL)){ if (eNB_flagP==1) - mac_xface->phy_config_sib1_eNB(Mod_id,tdd_Config,*SIwindowsize,*SIperiod); + mac_xface->phy_config_sib1_eNB(Mod_id,0,tdd_Config,*SIwindowsize,*SIperiod); else - mac_xface->phy_config_sib1_ue(Mod_id,eNB_index,tdd_Config,*SIwindowsize,*SIperiod); + mac_xface->phy_config_sib1_ue(Mod_id,0,eNB_index,tdd_Config,*SIwindowsize,*SIperiod); } if (radioResourceConfigCommon!=NULL) { @@ -146,11 +152,11 @@ int rrc_mac_config_req(module_id_t Mod_id, eNB_flag_t eNB_flagP,uint8_t UE_id,ui 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,radioResourceConfigCommon,ul_CarrierFreq,ul_Bandwidth,additionalSpectrumEmission,mbsfn_SubframeConfigList); + mac_xface->phy_config_sib2_eNB(Mod_id,0,radioResourceConfigCommon,ul_CarrierFreq,ul_Bandwidth,additionalSpectrumEmission,mbsfn_SubframeConfigList); } else { UE_mac_inst[Mod_id].radioResourceConfigCommon = radioResourceConfigCommon; - mac_xface->phy_config_sib2_ue(Mod_id,eNB_index,radioResourceConfigCommon,ul_CarrierFreq,ul_Bandwidth,additionalSpectrumEmission,mbsfn_SubframeConfigList); + 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 @@ -229,12 +235,24 @@ int rrc_mac_config_req(module_id_t Mod_id, eNB_flag_t eNB_flagP,uint8_t UE_id,ui if (physicalConfigDedicated != NULL) { if (eNB_flagP==1){ - mac_xface->phy_config_dedicated_eNB(Mod_id,find_UE_RNTI(Mod_id,UE_id),physicalConfigDedicated); + mac_xface->phy_config_dedicated_eNB(Mod_id,0,UE_RNTI(Mod_id,UE_id),physicalConfigDedicated); }else{ - mac_xface->phy_config_dedicated_ue(Mod_id,eNB_index,physicalConfigDedicated); - UE_mac_inst[Mod_id].physicalConfigDedicated=physicalConfigDedicated; // for SR proc + 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_flag==1){ + mac_xface->phy_config_dedicated_scell_eNB(Mod_id,UE_RNTI(Mod_id,UE_id),sCellToAddMod_r10,1); + } + else { + 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) { @@ -245,7 +263,7 @@ int rrc_mac_config_req(module_id_t Mod_id, eNB_flag_t eNB_flagP,uint8_t UE_id,ui UE_mac_inst[Mod_id].adj_cell_id[i] = measObj[0]->measObject.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,eNB_index,UE_mac_inst[Mod_id].n_adj_cells,UE_mac_inst[Mod_id].adj_cell_id); + 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) { @@ -334,14 +352,14 @@ int rrc_mac_config_req(module_id_t Mod_id, eNB_flag_t eNB_flagP,uint8_t UE_id,ui 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].num_sf_allocation_pattern= mbsfn_SubframeConfigList->list.count; + eNB_mac_inst[Mod_id].common_channels[0].num_sf_allocation_pattern= mbsfn_SubframeConfigList->list.count; for (i=0; i<mbsfn_SubframeConfigList->list.count; i++) { - eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[i] = mbsfn_SubframeConfigList->list.array[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].mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]); + eNB_mac_inst[Mod_id].common_channels[0].mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]); } #ifdef Rel10 - eNB_mac_inst[Mod_id].MBMS_flag = MBMS_Flag; + eNB_mac_inst[Mod_id].common_channels[0].MBMS_flag = MBMS_Flag; #endif } else { // UE @@ -361,12 +379,12 @@ int rrc_mac_config_req(module_id_t Mod_id, eNB_flag_t eNB_flagP,uint8_t UE_id,ui 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].num_active_mbsfn_area = 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].mbsfn_AreaInfo[i] = mbsfn_AreaInfoList->list.array[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].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9); - mac_xface->phy_config_sib13_eNB(Mod_id,i,eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9); + 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 @@ -376,7 +394,7 @@ int rrc_mac_config_req(module_id_t Mod_id, eNB_flag_t eNB_flagP,uint8_t UE_id,ui 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,eNB_index,i,UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9); + mac_xface->phy_config_sib13_ue(Mod_id,0,eNB_index,i,UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9); } } } @@ -391,17 +409,17 @@ int rrc_mac_config_req(module_id_t Mod_id, eNB_flag_t eNB_flagP,uint8_t UE_id,ui 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].pmch_Config[i] = &pmch_InfoList->list.array[i]->pmch_Config_r9; + 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 at subframe %ldth\n", i, - eNB_mac_inst[Mod_id].pmch_Config[i]->sf_AllocEnd_r9); + 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].pmch_Config[i]->mch_SchedulingPeriod_r9); + 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].pmch_Config[i]->dataMCS_r9); + 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].mbms_SessionList[i] = &pmch_InfoList->list.array[i]->mbms_SessionInfoList_r9; + 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].mbms_SessionList[i]->list.count); } } diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index dd9852c69c..6850dcf143 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -64,6 +64,7 @@ #include "MBSFN-AreaInfoList-r9.h" #include "MBSFN-SubframeConfigList.h" #include "PMCH-InfoList-r9.h" +#include "SCellToAddMod-r10.h" #endif //#ifdef PHY_EMUL @@ -620,14 +621,28 @@ typedef struct{ }SBMAP_CONF; //end ALU's algo +typedef struct{ + DLSCH_PDU DLSCH_pdu[MAX_NUM_CCs][2][NUMBER_OF_UE_MAX]; + /// DCI template and MAC connection parameters for UEs + UE_TEMPLATE UE_template[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; + /// DCI template and MAC connection for RA processes + int pCC_id[NUMBER_OF_UE_MAX]; + int ordered_CCids[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; + int numactiveCCs[NUMBER_OF_UE_MAX]; + int ordered_ULCCids[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; + int numactiveULCCs[NUMBER_OF_UE_MAX]; + /// eNB to UE statistics + eNB_UE_STATS eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; + UE_sched_ctrl UE_sched_ctrl[NUMBER_OF_UE_MAX]; + + int next[NUMBER_OF_UE_MAX]; + int head; + int avail; + int num_UEs; + boolean_t active[NUMBER_OF_UE_MAX]; +} UE_list_t; typedef struct{ - /// - uint16_t Node_id; - /// frame counter - frame_t frame; - /// subframe counter - sub_frame_t subframe; /// Outgoing DCI for PHY generated by eNB scheduler DCI_PDU DCI_pdu; /// Outgoing BCCH pdu for PHY @@ -636,11 +651,6 @@ typedef struct{ uint32_t BCCH_alloc_pdu; /// Outgoing CCCH pdu for PHY CCCH_PDU CCCH_pdu; - /// Outgoing DLSCH pdu for PHY - DLSCH_PDU DLSCH_pdu[NUMBER_OF_UE_MAX+1][2]; - /// DCI template and MAC connection parameters for UEs - UE_TEMPLATE UE_template[NUMBER_OF_UE_MAX]; - /// DCI template and MAC connection for RA processes RA_TEMPLATE RA_template[NB_RA_PROC_MAX]; /// BCCH active flag uint8_t bcch_active; @@ -674,16 +684,25 @@ typedef struct{ uint8_t num_active_cba_groups; uint16_t cba_rnti[NUM_MAX_CBA_GROUP]; #endif +}COMMON_channels_t; + +typedef struct{ + /// + uint16_t Node_id; + /// frame counter + frame_t frame; + /// subframe counter + sub_frame_t subframe; + /// Common cell resources + COMMON_channels_t common_channels[MAX_NUM_CCs]; + UE_list_t UE_list; ///subband bitmap configuration SBMAP_CONF sbmap_conf; /// active flag for Other lcid - uint8_t lcid_active[NB_RB_MAX]; + // uint8_t lcid_active[NB_RB_MAX]; // eNB stats eNB_STATS eNB_stats; - /// eNB to UE statistics - eNB_UE_STATS eNB_UE_stats[NUMBER_OF_UE_MAX]; - UE_sched_ctrl UE_sched_ctrl[NUMBER_OF_UE_MAX]; // MAC function execution peformance profiler time_stats_t eNB_scheduler; time_stats_t schedule_si; @@ -766,6 +785,10 @@ typedef struct{ struct RACH_ConfigDedicated *rach_ConfigDedicated; /// pointer to RRC PHY configuration struct PhysicalConfigDedicated *physicalConfigDedicated; +#ifdef Rel10 + /// pointer to RRC PHY configuration SCEll + struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10; +#endif /// pointer to TDD Configuration (NULL for FDD) TDD_Config_t *tdd_Config; /// Number of adjacent cells to measure @@ -912,6 +935,10 @@ int rrc_mac_config_req(module_id_t module_idP, 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, diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 82a2382445..846800fb3a 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -83,10 +83,10 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, frame_t frameP, sub_frame_t subframeP) {//, int calibration_flag) { start_meas(&eNB_mac_inst[module_idP].eNB_scheduler); - unsigned char nprb=0; - unsigned int nCCE=0; - int mbsfn_status=0; - uint32_t RBalloc=0; + unsigned int nprb[MAX_NUM_CCs]; + unsigned int nCCE[MAX_NUM_CCs]; + int mbsfn_status[MAX_NUM_CCs]; + uint32_t RBalloc[MAX_NUM_CCs]; #ifdef EXMIMO int ret; #endif @@ -96,12 +96,22 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, instance_t instance; int result; #endif + DCI_PDU *DCI_pdu[MAX_NUM_CCs]; + int CC_id; - DCI_PDU *DCI_pdu= &eNB_mac_inst[module_idP].DCI_pdu; LOG_D(MAC,"[eNB %d] Frame %d, Subframe %d, entering MAC scheduler\n",module_idP, frameP, subframeP); + + vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,1); + for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { + DCI_pdu[CC_id] = &eNB_mac_inst[module_idP].common_channels[CC_id].DCI_pdu; + nCCE[CC_id]=0; + nprb[CC_id]=0; + RBalloc[CC_id]=0; + mbsfn_status[CC_id]=0; + } #if defined(ENABLE_ITTI) do { // Checks if a message has been sent to MAC sub-task @@ -154,16 +164,18 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, #endif // clear DCI and BCCH contents before scheduling - DCI_pdu->Num_common_dci = 0; - DCI_pdu->Num_ue_spec_dci = 0; - eNB_mac_inst[module_idP].bcch_active = 0; - + for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { + DCI_pdu[CC_id]->Num_common_dci = 0; + DCI_pdu[CC_id]->Num_ue_spec_dci = 0; + eNB_mac_inst[module_idP].common_channels[CC_id].bcch_active = 0; + #ifdef Rel10 - eNB_mac_inst[module_idP].mcch_active =0; + eNB_mac_inst[module_idP].common_channels.mcch_active =0; #endif - - eNB_mac_inst[module_idP].frame = frameP; - eNB_mac_inst[module_idP].subframe = subframeP; + + eNB_mac_inst[module_idP].frame = frameP; + eNB_mac_inst[module_idP].subframe = subframeP; + } //if (subframeP%5 == 0) #ifdef EXMIMO @@ -180,10 +192,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, #endif #ifdef Rel10 - if (eNB_mac_inst[module_idP].MBMS_flag >0) { - start_meas(&eNB_mac_inst[module_idP].schedule_mch); - mbsfn_status = schedule_MBMS(module_idP,frameP,subframeP); - stop_meas(&eNB_mac_inst[module_idP].schedule_mch); + for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { + if (eNB_mac_inst[module_idP].common_channels.MBMS_flag >0) { + start_meas(&eNB_mac_inst[module_idP].common_channels.schedule_mch); + mbsfn_status = schedule_MBMS(module_idP,CC_id,frameP,subframeP); + stop_meas(&eNB_mac_inst[module_idP][CC-id].schedule_mch); + } } #endif @@ -193,18 +207,18 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, // Schedule ULSCH for FDD or subframeP 4 (TDD config 0,3,6) // Schedule Normal DLSCH - schedule_RA(module_idP,frameP,subframeP,2,&nprb,&nCCE); + schedule_RA(module_idP,frameP,subframeP,2,nprb,nCCE); if (mac_xface->lte_frame_parms->frame_type == FDD) { //FDD - schedule_ulsch(module_idP,frameP,cooperation_flag,0,4,&nCCE);//,calibration_flag); + schedule_ulsch(module_idP,frameP,cooperation_flag,0,4,nCCE);//,calibration_flag); } else if ((mac_xface->lte_frame_parms->tdd_config == TDD) || //TDD (mac_xface->lte_frame_parms->tdd_config == 3) || (mac_xface->lte_frame_parms->tdd_config == 6)) - //schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4,&nCCE);//,calibration_flag); + //schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4,nCCE);//,calibration_flag); - // schedule_ue_spec(module_idP,subframeP,nprb,&nCCE,mbsfn_status); + // schedule_ue_spec(module_idP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status); break; @@ -216,11 +230,11 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, switch (mac_xface->lte_frame_parms->tdd_config) { case 0: case 1: - schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7,&nCCE); + schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7,nCCE); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); break; case 6: - schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8,&nCCE); + schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8,nCCE); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); break; default: @@ -228,8 +242,8 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, } } else { //FDD - schedule_ulsch(module_idP,frameP,cooperation_flag,1,5,&nCCE); - // schedule_ue_spec(module_idP,subframeP,nprb,&nCCE,mbsfn_status); + schedule_ulsch(module_idP,frameP,cooperation_flag,1,5,nCCE); + // schedule_ue_spec(module_idP,subframeP,nprb,nCCE,mbsfn_status); // fill_DLSCH_dci(module_idP,subframeP,RBalloc,0,mbsfn_status); } break; @@ -238,8 +252,8 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, // TDD, nothing // FDD, normal UL/DLSCH if (mac_xface->lte_frame_parms->frame_type == FDD) { //FDD - schedule_ulsch(module_idP,frameP,cooperation_flag,2,6,&nCCE); - // schedule_ue_spec(module_idP,subframeP,nprb,&nCCE,mbsfn_status); + schedule_ulsch(module_idP,frameP,cooperation_flag,2,6,nCCE); + // schedule_ue_spec(module_idP,subframeP,nprb,nCCE,mbsfn_status); // fill_DLSCH_dci(module_idP,subframeP,RBalloc,0,mbsfn_status); } break; @@ -251,9 +265,9 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, if (mac_xface->lte_frame_parms->frame_type == TDD) { switch (mac_xface->lte_frame_parms->tdd_config) { case 2: - schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7,&nCCE); + schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7,nCCE); case 5: - schedule_ue_spec(module_idP,frameP,subframeP,nprb,&nCCE,mbsfn_status); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); break; default: @@ -261,7 +275,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, } } else { //FDD - // schedule_ulsch(module_idP,frameP,cooperation_flag,3,7,&nCCE); + // schedule_ulsch(module_idP,frameP,cooperation_flag,3,7,nCCE); // schedule_ue_spec(module_idP,subframeP,0,0,mbsfn_status); // fill_DLSCH_dci(module_idP,subframeP,RBalloc,0,mbsfn_status); } @@ -274,12 +288,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, if (mac_xface->lte_frame_parms->frame_type == 1) { // TDD switch (mac_xface->lte_frame_parms->tdd_config) { case 1: - // schedule_RA(module_idP,frameP,subframeP,&nprb,&nCCE); - schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8,&nCCE); + // schedule_RA(module_idP,frameP,subframeP,nprb,nCCE); + schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8,nCCE); case 2: case 4: case 5: - schedule_ue_spec(module_idP,frameP,subframeP,nprb,&nCCE,mbsfn_status); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status); break; default: @@ -288,10 +302,10 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, } else { if (mac_xface->lte_frame_parms->frame_type == FDD) { //FDD - schedule_RA(module_idP, frameP, subframeP, 0, &nprb, &nCCE); - // schedule_ulsch(module_idP, frameP, cooperation_flag, 4, 8, &nCCE); - //schedule_ue_spec(module_idP, frameP, subframeP, nprb, &nCCE, mbsfn_status); - fill_DLSCH_dci(module_idP, frameP, subframeP, RBalloc, 1, mbsfn_status); + schedule_RA(module_idP,frameP, subframeP, 0, nprb, nCCE); + // schedule_ulsch(module_idP, frameP, cooperation_flag, 4, 8, nCCE); + //schedule_ue_spec(module_idP, frameP, subframeP, nprb, nCCE, mbsfn_status); + fill_DLSCH_dci(module_idP, frameP, subframeP, RBalloc, 1, mbsfn_status); } } @@ -302,21 +316,21 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, // TDD Config 0,6 ULSCH for subframes 9,3 resp. // TDD normal DLSCH // FDD normal UL/DLSCH - schedule_SI(module_idP,frameP,&nprb,&nCCE); - //schedule_RA(module_idP,frameP,subframeP,5,&nprb,&nCCE); + schedule_SI(module_idP,frameP,nprb,nCCE); + //schedule_RA(module_idP,frameP,subframeP,5,nprb,nCCE); if ((mac_xface->lte_frame_parms->frame_type == FDD) ) { - // schedule_RA(module_idP,frameP,subframeP,1,&nprb,&nCCE); - // schedule_ulsch(module_idP,frameP,cooperation_flag,5,9,&nCCE); + // schedule_RA(module_idP,frameP,subframeP,1,nprb,nCCE); + // schedule_ulsch(module_idP,frameP,cooperation_flag,5,9,nCCE); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); } else if ((mac_xface->lte_frame_parms->tdd_config == 0) || // TDD Config 0 (mac_xface->lte_frame_parms->tdd_config == 6)) { // TDD Config 6 - //schedule_ulsch(module_idP,cooperation_flag,subframeP,&nCCE); + //schedule_ulsch(module_idP,cooperation_flag,subframeP,nCCE); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); } else { - //schedule_ue_spec(module_idP,subframeP,nprb,&nCCE,mbsfn_status); + //schedule_ue_spec(module_idP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); } break; @@ -330,23 +344,23 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, case 0: break; case 1: - schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2,&nCCE); - // schedule_ue_spec(module_idP,frameP,subframeP,nprb,&nCCE,mbsfn_status); + schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2,nCCE); + // schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); break; case 6: - schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,&nCCE); - // schedule_ue_spec(module_idP,frameP,subframeP,nprb,&nCCE,mbsfn_status); + schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,nCCE); + // schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); break; case 5: - schedule_RA(module_idP,frameP,subframeP,2,&nprb,&nCCE); - schedule_ue_spec(module_idP,frameP,subframeP,nprb,&nCCE,mbsfn_status); + schedule_RA(module_idP,frameP,subframeP,2,nprb,nCCE); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status); break; case 3: case 4: - schedule_ue_spec(module_idP,frameP,subframeP,nprb,&nCCE,mbsfn_status); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); break; @@ -355,8 +369,8 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, } } else { //FDD - // schedule_ulsch(module_idP,frameP,cooperation_flag,6,0,&nCCE); - schedule_ue_spec(module_idP,frameP,subframeP,nprb,&nCCE,mbsfn_status); + // schedule_ulsch(module_idP,frameP,cooperation_flag,6,0,nCCE); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); } break; @@ -368,12 +382,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, switch (mac_xface->lte_frame_parms->tdd_config) { case 3: case 4: - // schedule_RA(module_idP,frameP,subframeP,3,&nprb,&nCCE); // 3 = Msg3 subframeP, not - schedule_ue_spec(module_idP,frameP,subframeP,nprb,&nCCE,mbsfn_status); + // schedule_RA(module_idP,frameP,subframeP,3,nprb,nCCE); // 3 = Msg3 subframeP, not + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); //1,mbsfn_status); break; case 5: - schedule_ue_spec(module_idP,frameP,subframeP,nprb,&nCCE,mbsfn_status); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); break; default: @@ -381,8 +395,8 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, } } else { //FDD - // schedule_ulsch(module_idP,frameP,cooperation_flag,7,1,&nCCE); - schedule_ue_spec(module_idP,frameP,subframeP,nprb,&nCCE,mbsfn_status); + // schedule_ulsch(module_idP,frameP,cooperation_flag,7,1,nCCE); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); } break; @@ -398,9 +412,9 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, case 4: case 5: - // schedule_RA(module_idP,subframeP,&nprb,&nCCE); - schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2,&nCCE); - schedule_ue_spec(module_idP,frameP,subframeP,0,&nCCE,mbsfn_status); + // schedule_RA(module_idP,subframeP,nprb,nCCE); + schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2,nCCE); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); break; default: @@ -408,8 +422,8 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, } } else { //FDD - // schedule_ulsch(module_idP,frameP,cooperation_flag,8,2,&nCCE); - schedule_ue_spec(module_idP,frameP,subframeP,0,&nCCE,mbsfn_status); + // schedule_ulsch(module_idP,frameP,cooperation_flag,8,2,nCCE); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); } break; @@ -419,27 +433,27 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, if (mac_xface->lte_frame_parms->frame_type == TDD) { switch (mac_xface->lte_frame_parms->tdd_config) { case 1: - schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,&nCCE); - schedule_RA(module_idP,frameP,subframeP,7,&nprb,&nCCE); // 7 = Msg3 subframeP, not - schedule_ue_spec(module_idP,frameP,subframeP,0,&nCCE,mbsfn_status); + schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,nCCE); + schedule_RA(module_idP,frameP,subframeP,7,nprb,nCCE); // 7 = Msg3 subframeP, not + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status); break; case 3: case 4: - schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,&nCCE); - schedule_ue_spec(module_idP,frameP,subframeP,0,&nCCE,mbsfn_status); + schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,nCCE); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); break; case 6: - schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4,&nCCE); - //schedule_RA(module_idP,frameP,subframeP,&nprb,&nCCE); - schedule_ue_spec(module_idP,frameP,subframeP,0,&nCCE,mbsfn_status); + schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4,nCCE); + //schedule_RA(module_idP,frameP,subframeP,nprb,nCCE); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); break; case 2: case 5: - //schedule_RA(module_idP,frameP,subframeP,&nprb,&nCCE); - schedule_ue_spec(module_idP,frameP,subframeP,0,&nCCE,mbsfn_status); + //schedule_RA(module_idP,frameP,subframeP,nprb,nCCE); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); break; default: @@ -447,16 +461,17 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, } } else { //FDD - // schedule_ulsch(module_idP,frameP,cooperation_flag,9,3,&nCCE); - schedule_ue_spec(module_idP,frameP,subframeP,0,&nCCE,mbsfn_status); + // schedule_ulsch(module_idP,frameP,cooperation_flag,9,3,nCCE); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); } break; } - DCI_pdu->nCCE = nCCE; - LOG_D(MAC,"frameP %d, subframeP %d nCCE %d\n",frameP,subframeP,nCCE); + for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) + DCI_pdu[CC_id]->nCCE = nCCE[CC_id]; + LOG_D(MAC,"frameP %d, subframeP %d nCCE %d\n",frameP,subframeP,nCCE[0]); vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,0); stop_meas(&eNB_mac_inst[module_idP].eNB_scheduler); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c new file mode 100644 index 0000000000..6494702ddc --- /dev/null +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -0,0 +1,538 @@ +/******************************************************************************* + 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 <http://www.gnu.org/licenses/>. + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@eurecom.fr + + Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France. + +*******************************************************************************/ + +/*! \file eNB_scheduler_primitives.c + * \brief primitives used by eNB for BCH, RACH, ULSCH, DLSCH scheduling + * \author Navid Nikaein and Raymond Knopp + * \date 2010 - 2014 + * \email: navid.nikaein@eurecom.fr + * \version 1.0 + * @ingroup _mac + + */ + +#include "assertions.h" +#include "PHY/defs.h" +#include "PHY/extern.h" + +#include "SCHED/defs.h" +#include "SCHED/extern.h" + +#include "LAYER2/MAC/defs.h" +#include "LAYER2/MAC/extern.h" + +#include "LAYER2/MAC/proto.h" +#include "UTIL/LOG/log.h" +#include "UTIL/LOG/vcd_signal_dumper.h" +#include "UTIL/OPT/opt.h" +#include "OCG.h" +#include "OCG_extern.h" +#include "ARCH/CBMIMO1/DEVICE_DRIVER/extern.h" +#include "ARCH/CBMIMO1/DEVICE_DRIVER/defs.h" +#include "ARCH/CBMIMO1/DEVICE_DRIVER/from_grlib_softregs.h" + +#include "RRC/LITE/extern.h" +#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" + +//#include "LAYER2/MAC/pre_processor.c" +#include "pdcp.h" + +#if defined(ENABLE_ITTI) +# include "intertask_interface.h" +#endif + + +void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP,unsigned char Msg3_subframe,unsigned int *nprb,unsigned int *nCCE) { + + int CC_id; + eNB_MAC_INST *eNB = &eNB_mac_inst[module_idP]; + + + RA_TEMPLATE *RA_template; + unsigned char i;//,harq_pid,round; + uint16_t rrc_sdu_length; + unsigned char lcid,offset; + module_id_t UE_id= UE_INDEX_INVALID; + unsigned short TBsize = -1; + unsigned short msg4_padding,msg4_post_padding,msg4_header; + + start_meas(&eNB->schedule_ra); + + for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { + + RA_template = (RA_TEMPLATE *)&eNB->common_channels[CC_id].RA_template[0]; + for (i=0;i<NB_RA_PROC_MAX;i++) { + + if (RA_template[i].RA_active == TRUE) { + + LOG_I(MAC,"[eNB %d][RAPROC] RA %d is active (generate RAR %d, generate_Msg4 %d, wait_ack_Msg4 %d, rnti %x)\n", + module_idP,i,RA_template[i].generate_rar,RA_template[i].generate_Msg4,RA_template[i].wait_ack_Msg4, RA_template[i].rnti); + + if (RA_template[i].generate_rar == 1) { + nprb[CC_id]= nprb[CC_id] + 3; + nCCE[CC_id] = nCCE[CC_id] + 4; + RA_template[i].Msg3_subframe=Msg3_subframe; + } + else if (RA_template[i].generate_Msg4 == 1) { + + // check for Msg4 Message + UE_id = find_UE_id(module_idP,RA_template[i].rnti); + if (Is_rrc_registered == 1) { + + // Get RRCConnectionSetup for Piggyback + rrc_sdu_length = mac_rrc_data_req(module_idP, + frameP, + CCCH,1, + &eNB->common_channels[CC_id].CCCH_pdu.payload[0], + 1, + module_idP, + 0); // not used in this case + if (rrc_sdu_length == -1) + mac_xface->macphy_exit("[MAC][eNB Scheduler] CCCH not allocated\n"); + else { + //msg("[MAC][eNB %d] Frame %d, subframeP %d: got %d bytes from RRC\n",module_idP,frameP, subframeP,rrc_sdu_length); + } + } + + LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d: UE_id %d, Is_rrc_registered %d, rrc_sdu_length %d\n", + module_idP,frameP, subframeP,UE_id, Is_rrc_registered,rrc_sdu_length); + + if (rrc_sdu_length>0) { + LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RA proc %d, RNTI %x)\n", + module_idP,frameP, subframeP,i,RA_template[i].rnti); + + //msg("[MAC][eNB %d][RAPROC] Frame %d, subframeP %d: Received %d bytes for Msg4: \n",module_idP,frameP,subframeP,rrc_sdu_length); + // for (j=0;j<rrc_sdu_length;j++) + // msg("%x ",(unsigned char)eNB_mac_inst[module_idP][CC_id].CCCH_pdu.payload[j]); + // msg("\n"); + // msg("[MAC][eNB] Frame %d, subframeP %d: Generated DLSCH (Msg4) DCI, format 1A, for UE %d\n",frameP, subframeP,UE_id); + // Schedule Reflection of Connection request + + + + // Compute MCS for 3 PRB + msg4_header = 1+6+1; // CR header, CR CE, SDU header + + if (mac_xface->lte_frame_parms->frame_type == TDD) { + + switch (mac_xface->lte_frame_parms->N_RB_DL) { + case 6: + ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1; + + if ((rrc_sdu_length+msg4_header) <= 22) { + ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4; + TBsize = 22; + } + else if ((rrc_sdu_length+msg4_header) <= 28) { + ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5; + TBsize = 28; + } + else if ((rrc_sdu_length+msg4_header) <= 32) { + ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6; + TBsize = 32; + } + else if ((rrc_sdu_length+msg4_header) <= 41) { + ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7; + TBsize = 41; + } + else if ((rrc_sdu_length+msg4_header) <= 49) { + ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8; + TBsize = 49; + } + else if ((rrc_sdu_length+msg4_header) <= 57) { + ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9; + TBsize = 57; + } + break; + case 25: + + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1; + + if ((rrc_sdu_length+msg4_header) <= 22) { + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4; + TBsize = 22; + } + else if ((rrc_sdu_length+msg4_header) <= 28) { + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5; + TBsize = 28; + } + else if ((rrc_sdu_length+msg4_header) <= 32) { + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6; + TBsize = 32; + } + else if ((rrc_sdu_length+msg4_header) <= 41) { + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7; + TBsize = 41; + } + else if ((rrc_sdu_length+msg4_header) <= 49) { + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8; + TBsize = 49; + } + else if ((rrc_sdu_length+msg4_header) <= 57) { + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9; + TBsize = 57; + } + break; + case 50: + + ((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1; + + if ((rrc_sdu_length+msg4_header) <= 22) { + ((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4; + TBsize = 22; + } + else if ((rrc_sdu_length+msg4_header) <= 28) { + ((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5; + TBsize = 28; + } + else if ((rrc_sdu_length+msg4_header) <= 32) { + ((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6; + TBsize = 32; + } + else if ((rrc_sdu_length+msg4_header) <= 41) { + ((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7; + TBsize = 41; + } + else if ((rrc_sdu_length+msg4_header) <= 49) { + ((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8; + TBsize = 49; + } + else if ((rrc_sdu_length+msg4_header) <= 57) { + ((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9; + TBsize = 57; + } + break; + case 100: + + ((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1; + + if ((rrc_sdu_length+msg4_header) <= 22) { + ((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4; + TBsize = 22; + } + else if ((rrc_sdu_length+msg4_header) <= 28) { + ((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5; + TBsize = 28; + } + else if ((rrc_sdu_length+msg4_header) <= 32) { + ((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6; + TBsize = 32; + } + else if ((rrc_sdu_length+msg4_header) <= 41) { + ((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7; + TBsize = 41; + } + else if ((rrc_sdu_length+msg4_header) <= 49) { + ((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8; + TBsize = 49; + } + else if ((rrc_sdu_length+msg4_header) <= 57) { + ((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9; + TBsize = 57; + } + break; + } + } + else { // FDD DCI + switch (mac_xface->lte_frame_parms->N_RB_DL) { + case 6: + ((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1; + + if ((rrc_sdu_length+msg4_header) <= 22) { + ((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4; + TBsize = 22; + } + else if ((rrc_sdu_length+msg4_header) <= 28) { + ((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5; + TBsize = 28; + } + else if ((rrc_sdu_length+msg4_header) <= 32) { + ((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6; + TBsize = 32; + } + else if ((rrc_sdu_length+msg4_header) <= 41) { + ((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7; + TBsize = 41; + } + else if ((rrc_sdu_length+msg4_header) <= 49) { + ((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8; + TBsize = 49; + } + else if ((rrc_sdu_length+msg4_header) <= 57) { + ((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9; + TBsize = 57; + } + break; + case 25: + ((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1; + + if ((rrc_sdu_length+msg4_header) <= 22) { + ((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4; + TBsize = 22; + } + else if ((rrc_sdu_length+msg4_header) <= 28) { + ((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5; + TBsize = 28; + } + else if ((rrc_sdu_length+msg4_header) <= 32) { + ((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6; + TBsize = 32; + } + else if ((rrc_sdu_length+msg4_header) <= 41) { + ((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7; + TBsize = 41; + } + else if ((rrc_sdu_length+msg4_header) <= 49) { + ((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8; + TBsize = 49; + } + else if ((rrc_sdu_length+msg4_header) <= 57) { + ((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9; + TBsize = 57; + } + break; + case 50: + ((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1; + + if ((rrc_sdu_length+msg4_header) <= 22) { + ((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4; + TBsize = 22; + } + else if ((rrc_sdu_length+msg4_header) <= 28) { + ((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5; + TBsize = 28; + } + else if ((rrc_sdu_length+msg4_header) <= 32) { + ((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6; + TBsize = 32; + } + else if ((rrc_sdu_length+msg4_header) <= 41) { + ((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7; + TBsize = 41; + } + else if ((rrc_sdu_length+msg4_header) <= 49) { + ((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8; + TBsize = 49; + } + else if ((rrc_sdu_length+msg4_header) <= 57) { + ((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9; + TBsize = 57; + } + break; + case 100: + ((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1; + + if ((rrc_sdu_length+msg4_header) <= 22) { + ((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4; + TBsize = 22; + } + else if ((rrc_sdu_length+msg4_header) <= 28) { + ((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5; + TBsize = 28; + } + else if ((rrc_sdu_length+msg4_header) <= 32) { + ((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6; + TBsize = 32; + } + else if ((rrc_sdu_length+msg4_header) <= 41) { + ((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7; + TBsize = 41; + } + else if ((rrc_sdu_length+msg4_header) <= 49) { + ((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8; + TBsize = 49; + } + else if ((rrc_sdu_length+msg4_header) <= 57) { + ((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9; + TBsize = 57; + } + break; + } + } + RA_template[i].generate_Msg4=0; + RA_template[i].generate_Msg4_dci=1; + RA_template[i].wait_ack_Msg4=1; + RA_template[i].RA_active = FALSE; + lcid=0; + + if ((TBsize - rrc_sdu_length - msg4_header) <= 2) { + msg4_padding = TBsize - rrc_sdu_length - msg4_header; + msg4_post_padding = 0; + } + else { + msg4_padding = 0; + msg4_post_padding = TBsize - rrc_sdu_length - msg4_header -1; + } + LOG_I(MAC,"[eNB %d][RAPROC] Frame %d subframeP %d Msg4 : TBS %d, sdu_len %d, msg4_header %d, msg4_padding %d, msg4_post_padding %d\n", + module_idP,frameP,subframeP,TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding); + offset = generate_dlsch_header((unsigned char*)eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0], + 1, //num_sdus + &rrc_sdu_length, // + &lcid, // sdu_lcid + 255, // no drx + 0, // no timing advance + RA_template[i].cont_res_id, // contention res id + msg4_padding, // no padding + msg4_post_padding); + + memcpy((void*)&eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0][(unsigned char)offset], + &eNB->common_channels[CC_id].CCCH_pdu.payload[0], + rrc_sdu_length); + +#if defined(USER_MODE) && defined(OAI_EMU) + if (oai_emulation.info.opt_enabled){ + trace_pdu(1, (uint8_t *)eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0], + rrc_sdu_length, UE_id, 3, UE_RNTI(module_idP, UE_id), + eNB->subframe,0,0); + LOG_D(OPT,"[eNB %d][DLSCH] Frame %d trace pdu for rnti %x with size %d\n", + module_idP, frameP, UE_RNTI(module_idP,UE_id), rrc_sdu_length); + } +#endif + nprb[CC_id]= nprb[CC_id] + 3; + nCCE[CC_id] = nCCE[CC_id] + 4; + } + //try here + } + /* + else if (eNB_mac_inst[module_idP][CC_id].RA_template[i].wait_ack_Msg4==1) { + // check HARQ status and retransmit if necessary + LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d: Checking if Msg4 was acknowledged :\n",module_idP,frameP,subframeP); + // Get candidate harq_pid from PHY + mac_xface->get_ue_active_harq_pid(module_idP,eNB_mac_inst[module_idP][CC_id].RA_template[i].rnti,subframeP,&harq_pid,&round,0); + if (round>0) { + *nprb= (*nprb) + 3; + *nCCE = (*nCCE) + 4; + } + } + */ + } + } + } + stop_meas(&eNB->schedule_ra); +} + +void initiate_ra_proc(module_id_t module_idP, int CC_id,frame_t frameP, uint16_t preamble_index,int16_t timing_offset,uint8_t sect_id,sub_frame_t subframeP,uint8_t f_id) { + + uint8_t i; + RA_TEMPLATE *RA_template = (RA_TEMPLATE *)&eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[0]; + + LOG_I(MAC,"[eNB %d][RAPROC] Frame %d Initiating RA procedure for preamble index %d\n",module_idP,frameP,preamble_index); + + for (i=0;i<NB_RA_PROC_MAX;i++) { + if (RA_template[i].RA_active==FALSE) { + RA_template[i].RA_active=TRUE; + RA_template[i].generate_rar=1; + RA_template[i].generate_Msg4=0; + RA_template[i].wait_ack_Msg4=0; + RA_template[i].timing_offset=timing_offset; + // Put in random rnti (to be replaced with proper procedure!!) + RA_template[i].rnti = taus(); + RA_template[i].RA_rnti = 1+subframeP+(10*f_id); + RA_template[i].preamble_index = preamble_index; + LOG_D(MAC,"[eNB %d][RAPROC] Frame %d Activating RAR generation for process %d, rnti %x, RA_active %d\n", + module_idP,frameP,i,RA_template[i].rnti, + RA_template[i].RA_active); + + return; + } + } +} + +void cancel_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, rnti_t rnti) { + unsigned char i; + RA_TEMPLATE *RA_template = (RA_TEMPLATE *)&eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[0]; + + LOG_I(MAC,"[eNB %d][RAPROC] Frame %d Cancelling RA procedure for UE rnti %x\n",module_idP,frameP,rnti); + + for (i=0;i<NB_RA_PROC_MAX;i++) { + if (rnti == RA_template[i].rnti) { + RA_template[i].RA_active=FALSE; + RA_template[i].generate_rar=0; + RA_template[i].generate_Msg4=0; + RA_template[i].wait_ack_Msg4=0; + RA_template[i].timing_offset=0; + RA_template[i].RRC_timer=20; + RA_template[i].rnti = 0; + } + } +} + +void terminate_ra_proc(module_id_t module_idP,int CC_id,frame_t frameP,rnti_t rnti,unsigned char *msg3, uint16_t msg3_len) { + + unsigned char rx_ces[MAX_NUM_CE],num_ce,num_sdu,i,*payload_ptr; + unsigned char rx_lcids[NB_RB_MAX]; + uint16_t rx_lengths[NB_RB_MAX]; + int8_t UE_id; + RA_TEMPLATE *RA_template = (RA_TEMPLATE *)&eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[0]; + + LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, Received msg3 %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n", + module_idP,frameP, + msg3[3],msg3[4],msg3[5],msg3[6],msg3[7], msg3[8], rnti); + + for (i=0;i<NB_RA_PROC_MAX;i++) { + LOG_D(MAC,"[RAPROC] Checking proc %d : rnti (%x, %x), active %d\n",i, + RA_template[i].rnti, rnti, + RA_template[i].RA_active); + if ((RA_template[i].rnti==rnti) && + (RA_template[i].RA_active==TRUE)) { + + payload_ptr = parse_ulsch_header(msg3,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,msg3_len); + LOG_D(MAC,"[eNB %d][RAPROC] Frame %d Received CCCH: length %d, offset %d\n", + module_idP,frameP,rx_lengths[0],payload_ptr-msg3); + if (/*(num_ce == 0) &&*/ (num_sdu==1) && (rx_lcids[0] == CCCH)) { // This is an RRCConnectionRequest/Restablishment + memcpy(&RA_template[i].cont_res_id[0],payload_ptr,6); + LOG_D(MAC,"[eNB %d][RAPROC] Frame %d Received CCCH: length %d, offset %d\n", + module_idP,frameP,rx_lengths[0],payload_ptr-msg3); + UE_id=add_new_ue(module_idP,CC_id,RA_template[i].rnti); + if (UE_id==-1) { + mac_xface->macphy_exit("[MAC][eNB] Max user count reached\n"); + } + else { + LOG_I(MAC,"[eNB %d][RAPROC] Frame %d Added user with rnti %x => UE %d\n", + module_idP,frameP,RA_template[i].rnti,UE_id); + } + + if (Is_rrc_registered == 1) + mac_rrc_data_ind(module_idP,frameP,CCCH,(uint8_t *)payload_ptr,rx_lengths[0],1,module_idP,0); + // add_user. This is needed to have the rnti for configuring UE (PHY). The UE is removed if RRC + // doesn't provide a CCCH SDU + + } + else if (num_ce >0) { // handle msg3 which is not RRCConnectionRequest + // process_ra_message(msg3,num_ce,rx_lcids,rx_ces); + } + + RA_template[i].generate_Msg4 = 1; + RA_template[i].wait_ack_Msg4 = 0; + + return; + } // if process is active + + } // loop on RA processes +} diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c index d6b77b9d52..c4a84c1583 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c @@ -70,25 +70,33 @@ #define DEBUG_eNB_SCHEDULER 1 -void schedule_SI(module_id_t module_idP,frame_t frameP, unsigned char *nprb,unsigned int *nCCE) { +void schedule_SI(module_id_t module_idP,frame_t frameP, unsigned int *nprbP,unsigned int *nCCEP) { + - start_meas(&eNB_mac_inst[module_idP].schedule_si); unsigned char bcch_sdu_length; int mcs = -1; - void *BCCH_alloc_pdu=(void*)&eNB_mac_inst[module_idP].BCCH_alloc_pdu; - - bcch_sdu_length = mac_rrc_data_req(module_idP, - frameP, - BCCH,1, - &eNB_mac_inst[module_idP].BCCH_pdu.payload[0], - 1, - module_idP, - 0); // not used in this case - if (bcch_sdu_length > 0) { - LOG_D(MAC,"[eNB %d] Frame %d : BCCH->DLSCH, Received %d bytes \n",module_idP,frameP,bcch_sdu_length); - - + void *BCCH_alloc_pdu; + int CC_id; + eNB_MAC_INST *eNB = &eNB_mac_inst[module_idP]; + + start_meas(&eNB->schedule_si); + + for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { + + BCCH_alloc_pdu=(void*)&eNB->common_channels[CC_id].BCCH_alloc_pdu; + + bcch_sdu_length = mac_rrc_data_req(module_idP, + frameP, + BCCH,1, + &eNB->common_channels[CC_id].BCCH_pdu.payload[0], + 1, + module_idP, + 0); // not used in this case + if (bcch_sdu_length > 0) { + LOG_D(MAC,"[eNB %d] Frame %d : BCCH->DLSCH CC_id %d, Received %d bytes \n",module_idP,CC_id,frameP,bcch_sdu_length); + + if (bcch_sdu_length <= (mac_xface->get_TBS_DL(0,3))) mcs=0; else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(1,3))) @@ -108,82 +116,83 @@ void schedule_SI(module_id_t module_idP,frame_t frameP, unsigned char *nprb,unsi else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(8,3))) mcs=8; - if (mac_xface->lte_frame_parms->frame_type == TDD) { - switch (mac_xface->lte_frame_parms->N_RB_DL) { - case 6: - ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs; - break; - case 25: - ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs; - break; - case 50: - ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs; - break; - case 100: - ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs; - break; - - } + if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) { + switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs; + break; + case 25: + ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs; + break; + case 50: + ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs; + break; + case 100: + ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs; + break; + + } } else { - switch (mac_xface->lte_frame_parms->N_RB_DL) { - case 6: - ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs; - break; - case 25: - ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs; - break; - case 50: - ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs; - break; - case 100: - ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs; - break; - - } + switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs; + break; + case 25: + ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs; + break; + case 50: + ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs; + break; + case 100: + ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs; + break; + + } } #if defined(USER_MODE) && defined(OAI_EMU) if (oai_emulation.info.opt_enabled) { trace_pdu(1, - &eNB_mac_inst[module_idP].BCCH_pdu.payload[0], + &eNB->common_channels[CC_id].BCCH_pdu.payload[0], bcch_sdu_length, 0xffff, 4, 0xffff, - eNB_mac_inst[module_idP].subframe, + eNB->subframe, 0, 0); } LOG_D(OPT,"[eNB %d][BCH] Frame %d trace pdu for rnti %x with size %d\n", - module_idP, frameP, 0xffff, bcch_sdu_length); + module_idP, frameP, 0xffff, bcch_sdu_length); #endif - if (mac_xface->lte_frame_parms->frame_type == TDD) { - LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH->DLSCH (TDD) for SI %d bytes (mcs %d, rb 3, TBS %d)\n", + if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) { + LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH->DLSCH (TDD) for SI %d bytes (mcs %d, rb 3, TBS %d)\n", frameP, bcch_sdu_length, mcs, mac_xface->get_TBS_DL(mcs,3)); } else { - LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH->DLSCH (FDD) for SI %d bytes (mcs %d, rb 3, TBS %d)\n", + LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH->DLSCH (FDD) for SI %d bytes (mcs %d, rb 3, TBS %d)\n", frameP, bcch_sdu_length, mcs, mac_xface->get_TBS_DL(mcs,3)); } - eNB_mac_inst[module_idP].bcch_active=1; - *nprb=3; - *nCCE=4; - } - else { - eNB_mac_inst[module_idP].bcch_active=0; - *nprb=0; - *nCCE=0; - //LOG_D(MAC,"[eNB %d] Frame %d : BCCH not active \n",Mod_id,frame); + eNB->common_channels[CC_id].bcch_active=1; + nprbP[CC_id]=3; + nCCEP[CC_id]=4; + } + else { + eNB->common_channels[CC_id].bcch_active=0; + nprbP[CC_id]=0; + nCCEP[CC_id]=0; + //LOG_D(MAC,"[eNB %d] Frame %d : BCCH not active \n",Mod_id,frame); + } } // this might be misleading when bcch is inactive - stop_meas(&eNB_mac_inst[module_idP].schedule_si); + stop_meas(&eNB->schedule_si); return; } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index aa835d52d4..36ca01a81e 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -72,50 +72,45 @@ extern inline unsigned int taus(void); -// function for determining which active ue should be granted resources in downlink based on CQI, SI, and BSR -uint8_t find_dlgranted_UEs(module_id_t module_idP){ +void add_ue_dlsch_info(module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframeP, UE_DLSCH_STATUS status){ - // all active users should be granted - return(find_active_UEs(module_idP)); -} - -void add_ue_dlsch_info(module_id_t module_idP, module_id_t ue_mod_idP, sub_frame_t subframeP, UE_DLSCH_STATUS status){ - - eNB_dlsch_info[module_idP][ue_mod_idP].rnti = find_UE_RNTI(module_idP,ue_mod_idP); + eNB_dlsch_info[module_idP][UE_id].rnti = UE_RNTI(module_idP,UE_id); // eNB_dlsch_info[module_idP][ue_mod_idP].weight = weight; - eNB_dlsch_info[module_idP][ue_mod_idP].subframe = subframeP; - eNB_dlsch_info[module_idP][ue_mod_idP].status = status; + eNB_dlsch_info[module_idP][UE_id].subframe = subframeP; + eNB_dlsch_info[module_idP][UE_id].status = status; - eNB_dlsch_info[module_idP][ue_mod_idP].serving_num++; + eNB_dlsch_info[module_idP][UE_id].serving_num++; } -module_id_t schedule_next_dlue(module_id_t module_idP, sub_frame_t subframeP){ +int schedule_next_dlue(module_id_t module_idP, sub_frame_t subframeP){ - module_id_t next_ue; + int next_ue; + UE_list_t *UE_list=&eNB_mac_inst[module_idP].UE_list; - for (next_ue=0; next_ue < NUMBER_OF_UE_MAX; next_ue++ ){ - if (eNB_dlsch_info[module_idP][next_ue].status == S_DL_WAITING) - return next_ue; + for (next_ue=UE_list->head; next_ue>=0; next_ue=UE_list->next[next_ue] ){ + if (eNB_dlsch_info[module_idP][next_ue].status == S_DL_WAITING) + return next_ue; } - for (next_ue=0; next_ue <NUMBER_OF_UE_MAX; next_ue++ ) + for (next_ue=UE_list->head; next_ue>=0; next_ue=UE_list->next[next_ue] ){ if (eNB_dlsch_info[module_idP][next_ue].status == S_DL_BUFFERED) { - eNB_dlsch_info[module_idP][next_ue].status = S_DL_WAITING; + eNB_dlsch_info[module_idP][next_ue].status = S_DL_WAITING; } - // next_ue = -1; - return (module_id_t)(-1);//next_ue; + } + + return(-1);//next_ue; } unsigned char generate_dlsch_header(unsigned char *mac_header, - unsigned char num_sdus, - unsigned short *sdu_lengths, - unsigned char *sdu_lcids, - unsigned char drx_cmd, - short timing_advance_cmd, - unsigned char *ue_cont_res_id, - unsigned char short_padding, - unsigned short post_padding) { + unsigned char num_sdus, + unsigned short *sdu_lengths, + unsigned char *sdu_lcids, + unsigned char drx_cmd, + short timing_advance_cmd, + unsigned char *ue_cont_res_id, + unsigned char short_padding, + unsigned short post_padding) { SCH_SUBHEADER_FIXED *mac_header_ptr = (SCH_SUBHEADER_FIXED *)mac_header; uint8_t first_element=0,last_size=0,i; @@ -126,76 +121,76 @@ unsigned char generate_dlsch_header(unsigned char *mac_header, // compute header components if ((short_padding == 1) || (short_padding == 2)) { - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_PADDING; - first_element=1; - last_size=1; + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = SHORT_PADDING; + first_element=1; + last_size=1; } if (short_padding == 2) { - mac_header_ptr->E = 1; - mac_header_ptr++; - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_PADDING; - last_size=1; + mac_header_ptr->E = 1; + mac_header_ptr++; + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = SHORT_PADDING; + last_size=1; } if (drx_cmd != 255) { - if (first_element>0) { - mac_header_ptr->E = 1; - mac_header_ptr++; - } - else { - first_element=1; - } - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = DRX_CMD; - last_size=1; + if (first_element>0) { + mac_header_ptr->E = 1; + mac_header_ptr++; + } + else { + first_element=1; + } + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = DRX_CMD; + last_size=1; } if (timing_advance_cmd != 0) { - if (first_element>0) { - mac_header_ptr->E = 1; - mac_header_ptr++; - } - else { - first_element=1; - } - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = TIMING_ADV_CMD; - last_size=1; - // msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); - ((TIMING_ADVANCE_CMD *)ce_ptr)->R=0; - ((TIMING_ADVANCE_CMD *)ce_ptr)->TA=timing_advance_cmd&0x3f; - LOG_I(MAC,"timing advance =%d (%d)\n",timing_advance_cmd,((TIMING_ADVANCE_CMD *)ce_ptr)->TA); - ce_ptr+=sizeof(TIMING_ADVANCE_CMD); - //msg("offset %d\n",ce_ptr-mac_header_control_elements); + if (first_element>0) { + mac_header_ptr->E = 1; + mac_header_ptr++; + } + else { + first_element=1; + } + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = TIMING_ADV_CMD; + last_size=1; + // msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); + ((TIMING_ADVANCE_CMD *)ce_ptr)->R=0; + ((TIMING_ADVANCE_CMD *)ce_ptr)->TA=timing_advance_cmd&0x3f; + LOG_I(MAC,"timing advance =%d (%d)\n",timing_advance_cmd,((TIMING_ADVANCE_CMD *)ce_ptr)->TA); + ce_ptr+=sizeof(TIMING_ADVANCE_CMD); + //msg("offset %d\n",ce_ptr-mac_header_control_elements); } if (ue_cont_res_id) { - if (first_element>0) { - mac_header_ptr->E = 1; - /* - printf("[eNB][MAC] last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); - */ - mac_header_ptr++; - } - else { - first_element=1; - } + if (first_element>0) { + mac_header_ptr->E = 1; + /* + printf("[eNB][MAC] last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); + */ + mac_header_ptr++; + } + else { + first_element=1; + } - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = UE_CONT_RES; - last_size=1; + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = UE_CONT_RES; + last_size=1; - LOG_T(MAC,"[eNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n", + LOG_T(MAC,"[eNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n", ue_cont_res_id[0], ue_cont_res_id[1], ue_cont_res_id[2], @@ -203,53 +198,53 @@ unsigned char generate_dlsch_header(unsigned char *mac_header, ue_cont_res_id[4], ue_cont_res_id[5]); - memcpy(ce_ptr,ue_cont_res_id,6); - ce_ptr+=6; - // msg("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements); + memcpy(ce_ptr,ue_cont_res_id,6); + ce_ptr+=6; + // msg("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements); } //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); for (i=0;i<num_sdus;i++) { - LOG_T(MAC,"[eNB] Generate DLSCH header num sdu %d len sdu %d\n",num_sdus, sdu_lengths[i]); + LOG_T(MAC,"[eNB] Generate DLSCH header num sdu %d len sdu %d\n",num_sdus, sdu_lengths[i]); - if (first_element>0) { - mac_header_ptr->E = 1; - /*msg("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, + if (first_element>0) { + mac_header_ptr->E = 1; + /*msg("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); - */ - mac_header_ptr+=last_size; - //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); - } - else { - first_element=1; - } - if (sdu_lengths[i] < 128) { - ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->R = 0; - ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->E = 0; - ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F = 0; - ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID = sdu_lcids[i]; - ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L = (unsigned char)sdu_lengths[i]; - last_size=2; - } - else { - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->R = 0; - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->E = 0; - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->F = 1; - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->LCID = sdu_lcids[i]; - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB = ((unsigned short) sdu_lengths[i]>>8)&0x7f; - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB = (unsigned short) sdu_lengths[i]&0xff; - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->padding = 0x00; - last_size=3; + */ + mac_header_ptr+=last_size; + //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); + } + else { + first_element=1; + } + if (sdu_lengths[i] < 128) { + ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->R = 0; + ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->E = 0; + ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F = 0; + ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID = sdu_lcids[i]; + ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L = (unsigned char)sdu_lengths[i]; + last_size=2; + } + else { + ((SCH_SUBHEADER_LONG *)mac_header_ptr)->R = 0; + ((SCH_SUBHEADER_LONG *)mac_header_ptr)->E = 0; + ((SCH_SUBHEADER_LONG *)mac_header_ptr)->F = 1; + ((SCH_SUBHEADER_LONG *)mac_header_ptr)->LCID = sdu_lcids[i]; + ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB = ((unsigned short) sdu_lengths[i]>>8)&0x7f; + ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB = (unsigned short) sdu_lengths[i]&0xff; + ((SCH_SUBHEADER_LONG *)mac_header_ptr)->padding = 0x00; + last_size=3; #ifdef DEBUG_HEADER_PARSING - LOG_D(MAC,"[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n", - sdu_lengths[i], - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB, - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB); + LOG_D(MAC,"[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n", + sdu_lengths[i], + ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB, + ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB); #endif - } + } } /* @@ -267,27 +262,27 @@ unsigned char generate_dlsch_header(unsigned char *mac_header, else printf("F = 1, sdu len (L field) %d\n",(((SCH_SUBHEADER_LONG*)mac_header_ptr)->L)); } - */ + */ if (post_padding>0) {// we have lots of padding at the end of the packet - mac_header_ptr->E = 1; - mac_header_ptr+=last_size; - // add a padding element - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_PADDING; - mac_header_ptr++; + mac_header_ptr->E = 1; + mac_header_ptr+=last_size; + // add a padding element + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = SHORT_PADDING; + mac_header_ptr++; } else { // no end of packet padding - // last SDU subhead is of fixed type (sdu length implicitly to be computed at UE) - mac_header_ptr++; + // last SDU subhead is of fixed type (sdu length implicitly to be computed at UE) + mac_header_ptr++; } //msg("After subheaders %d\n",(uint8_t*)mac_header_ptr - mac_header); if ((ce_ptr-mac_header_control_elements) > 0) { - // printf("Copying %d bytes for control elements\n",ce_ptr-mac_header_control_elements); - memcpy((void*)mac_header_ptr,mac_header_control_elements,ce_ptr-mac_header_control_elements); - mac_header_ptr+=(unsigned char)(ce_ptr-mac_header_control_elements); + // printf("Copying %d bytes for control elements\n",ce_ptr-mac_header_control_elements); + memcpy((void*)mac_header_ptr,mac_header_control_elements,ce_ptr-mac_header_control_elements); + mac_header_ptr+=(unsigned char)(ce_ptr-mac_header_control_elements); } //msg("After CEs %d\n",(uint8_t*)mac_header_ptr - mac_header); @@ -299,14 +294,14 @@ unsigned char generate_dlsch_header(unsigned char *mac_header, void schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, - uint16_t nb_rb_used0, - unsigned int *nCCE_used, - int mbsfn_flag) { - - module_id_t ue_mod_id = -1; - module_id_t next_ue = -1; - unsigned char granted_UEs = 0; - uint16_t nCCE; + unsigned int *nb_rb_used0, + unsigned int *nCCE_used, + int *mbsfn_flag) { + + int CC_id; + int UE_id; + uint16_t nCCE[MAX_NUM_CCs]; + int N_RBGS[MAX_NUM_CCs]; unsigned char aggregation; mac_rlc_status_resp_t rlc_status; unsigned char header_len_dcch=0, header_len_dcch_tmp=0,header_len_dtch=0,header_len_dtch_tmp=0, ta_len=0; @@ -319,1599 +314,1653 @@ void schedule_ue_spec(module_id_t module_idP, LTE_eNB_UE_stats *eNB_UE_stats = NULL; uint16_t sdu_length_total = 0; unsigned char DAI; - uint16_t i = 0; - uint8_t dl_pow_off[NUMBER_OF_UE_MAX]; - unsigned char rballoc_sub_UE[NUMBER_OF_UE_MAX][N_RBGS_MAX]; - uint16_t pre_nb_available_rbs[NUMBER_OF_UE_MAX]; + int i; + uint8_t dl_pow_off[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; + unsigned char rballoc_sub_UE[MAX_NUM_CCs][NUMBER_OF_UE_MAX][N_RBGS_MAX]; + uint16_t pre_nb_available_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; int mcs; - uint16_t min_rb_unit; + uint16_t min_rb_unit[MAX_NUM_CCs]; short ta_update = 0; + eNB_MAC_INST *eNB = &eNB_mac_inst[module_idP]; + UE_list_t *UE_list = &eNB->UE_list; - if (mbsfn_flag>0) + reset_meas(&eNB->schedule_dlsch); + if (UE_list->head==-1) return; - reset_meas(&eNB_mac_inst[module_idP].schedule_dlsch); - - switch (mac_xface->lte_frame_parms->N_RB_DL) { - case 6: - min_rb_unit=1; - break; - case 25: - min_rb_unit=2; - break; - case 50: - min_rb_unit=3; - break; - case 100: - min_rb_unit=4; - break; - default: - min_rb_unit=2; - break; + for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { + switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) { + case 6: + min_rb_unit[CC_id]=1; + break; + case 25: + min_rb_unit[CC_id]=2; + break; + case 50: + min_rb_unit[CC_id]=3; + break; + case 100: + min_rb_unit[CC_id]=4; + break; + default: + min_rb_unit[CC_id]=2; + break; + } } - //int **rballoc_sub = (int **)malloc(1792*sizeof(int *)); - granted_UEs = find_dlgranted_UEs(module_idP); - - //weight = get_ue_weight(module_idP,UE_id); aggregation = 1; // set to the maximum aggregation level - /// Initialization for pre-processor - for(i=0;i<NUMBER_OF_UE_MAX;i++){ - pre_nb_available_rbs[i] = 0; - dl_pow_off[i] = 2; - for(j=0;j<mac_xface->lte_frame_parms->N_RBGS;j++){ - // rballoc_sub[j] = 0; - rballoc_sub_UE[i][j] = 0; - } - } - - - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { - PHY_vars_eNB_g[module_idP]->mu_mimo_mode[i].pre_nb_available_rbs = 0; - for (j = 0; j < mac_xface->lte_frame_parms->N_RBGS; j++) { - PHY_vars_eNB_g[module_idP]->mu_mimo_mode[i].rballoc_sub[j] = 0; - } - } - // set current available nb_rb and nCCE to maximum - nb_available_rb = mac_xface->lte_frame_parms->N_RB_DL - nb_rb_used0; - nCCE = mac_xface->get_nCCE_max(module_idP) - *nCCE_used; - // store the goloabl enb stats - eNB_mac_inst[module_idP].eNB_stats.num_dlactive_UEs = granted_UEs; - eNB_mac_inst[module_idP].eNB_stats.available_prbs = nb_available_rb; - eNB_mac_inst[module_idP].eNB_stats.total_available_prbs += nb_available_rb; - eNB_mac_inst[module_idP].eNB_stats.available_ncces = nCCE; - eNB_mac_inst[module_idP].eNB_stats.dlsch_bytes_tx=0; - eNB_mac_inst[module_idP].eNB_stats.dlsch_pdus_tx=0; + for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { + // set current available nb_rb and nCCE to maximum + nb_available_rb = PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL - nb_rb_used0[CC_id]; + + /// Initialization for pre-processor + for(i=UE_list->head;i>=0;i=UE_list->next[i]){ + pre_nb_available_rbs[CC_id][i] = 0; + dl_pow_off[CC_id][i] = 2; + for(j=0;j<PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RBGS;j++){ + // rballoc_sub[j] = 0; + rballoc_sub_UE[CC_id][i][j] = 0; + } + } + + + for (i = UE_list->head; i>=0; i=UE_list->next[i]) { + PHY_vars_eNB_g[module_idP][CC_id]->mu_mimo_mode[i].pre_nb_available_rbs = 0; + for (j = 0; j < PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RBGS; j++) { + PHY_vars_eNB_g[module_idP][CC_id]->mu_mimo_mode[i].rballoc_sub[j] = 0; + } + } + + nCCE[CC_id] = mac_xface->get_nCCE_max(module_idP,CC_id) - nCCE_used[CC_id]; + N_RBGS[CC_id] = PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RBGS; + // store the goloabl enb stats + eNB->eNB_stats.num_dlactive_UEs = UE_list->num_UEs; + eNB->eNB_stats.available_prbs = nb_available_rb; + eNB->eNB_stats.total_available_prbs += nb_available_rb; + eNB->eNB_stats.available_ncces = nCCE[CC_id]; + eNB->eNB_stats.dlsch_bytes_tx=0; + eNB->eNB_stats.dlsch_pdus_tx=0; + } + /// CALLING Pre_Processor for downlink scheduling (Returns estimation of RBs required by each UE and the allocation on sub-band) - start_meas(&eNB_mac_inst[module_idP].schedule_dlsch_preprocessor); + start_meas(&eNB->schedule_dlsch_preprocessor); + printf("preprocessor in\n"); dlsch_scheduler_pre_processor(module_idP, frameP, subframeP, dl_pow_off, pre_nb_available_rbs, - mac_xface->lte_frame_parms->N_RBGS, - rballoc_sub_UE); - stop_meas(&eNB_mac_inst[module_idP].schedule_dlsch_preprocessor); + N_RBGS, + rballoc_sub_UE, + mbsfn_flag); + stop_meas(&eNB->schedule_dlsch_preprocessor); + printf("preprocessor out\n"); + + for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { + if (mbsfn_flag[CC_id]>0) + continue; + for (UE_id=UE_list->head;UE_id>=0;UE_id=UE_list->next[UE_id]) { - for (ue_mod_id=0;ue_mod_id<granted_UEs;ue_mod_id++) { - rnti = find_UE_RNTI(module_idP,ue_mod_id); + + rnti = UE_RNTI(module_idP,UE_id); - eNB_mac_inst[module_idP].eNB_UE_stats[ue_mod_id].crnti= rnti; - eNB_mac_inst[module_idP].eNB_UE_stats[ue_mod_id].rrc_status=mac_get_rrc_status(module_idP,1,ue_mod_id); + printf("Scheduling UE %d for CC_id %d (rnti %x)\n",UE_id,CC_id,rnti); + + UE_list->eNB_UE_stats[CC_id][UE_id].crnti= rnti; + UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status=mac_get_rrc_status(module_idP,1,UE_id); if (rnti==0) { - LOG_E(MAC,"Cannot find rnti for UE_id %d (granted UEs %d)\n",ue_mod_id,granted_UEs); - mac_xface->macphy_exit("Cannot find rnti for UE_id");//continue; + LOG_E(MAC,"Cannot find rnti for UE_id %d (num_UEs %d)\n",UE_id,UE_list->num_UEs); + mac_xface->macphy_exit("Cannot find rnti for UE_id");//continue; } - - eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,rnti); + + eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti); if (eNB_UE_stats==NULL) - mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n"); - + mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n"); + // Get candidate harq_pid from PHY - mac_xface->get_ue_active_harq_pid(module_idP,rnti,subframeP,&harq_pid,&round,0); - // printf("Got harq_pid %d, round %d\n",harq_pid,round); - - - nb_available_rb = pre_nb_available_rbs[ue_mod_id]; - - if ((nb_available_rb == 0) || (nCCE < (1<<aggregation))) { - LOG_D(MAC,"UE %d: nb_availiable_rb exhausted (nb_rb_used %d, nb_available_rb %d, nCCE %d, aggregation %d)\n", - ue_mod_id, nb_rb_used0, nb_available_rb, nCCE, aggregation); - //if(mac_xface->get_transmission_mode(module_idP,rnti)==5) - continue; //to next user (there might be rbs availiable for other UEs in TM5 - // else - // break; + mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,subframeP,&harq_pid,&round,0); + printf("Got harq_pid %d, round %d\n",harq_pid,round); + + + nb_available_rb = pre_nb_available_rbs[CC_id][UE_id]; + + if ((nb_available_rb == 0) || (nCCE[CC_id] < (1<<aggregation))) { + LOG_D(MAC,"UE %d, CC_id %d: nb_availiable_rb exhausted (nb_rb_used %d, nb_available_rb %d, nCCE %d, aggregation %d)\n", + UE_id, CC_id, nb_rb_used0[CC_id], nb_available_rb, nCCE[CC_id], aggregation); + //if(mac_xface->get_transmission_mode(module_idP,rnti)==5) + continue; //to next user (there might be rbs availiable for other UEs in TM5 + // else + // break; } sdu_length_total=0; num_sdus=0; - + // get Round-Robin allocation - next_ue = ue_mod_id;//schedule_next_dlue(module_idP,subframeP); // next scheduled user - // If nobody is left, exit while loop and go to next step - if (next_ue == 255) - break; - - if (mac_xface->lte_frame_parms->frame_type == TDD) { - switch (mac_xface->lte_frame_parms->tdd_config) { - case 0: - if ((subframeP==0)||(subframeP==1)||(subframeP==3)||(subframeP==5)||(subframeP==6)||(subframeP==8)) - eNB_mac_inst[module_idP].UE_template[next_ue].DAI = 0; - case 1: - if ((subframeP==0)||(subframeP==4)||(subframeP==5)||(subframeP==9)) - eNB_mac_inst[module_idP].UE_template[next_ue].DAI = 0; - break; - case 2: - if ((subframeP==4)||(subframeP==5)) - eNB_mac_inst[module_idP].UE_template[next_ue].DAI = 0; - break; - case 3: - if ((subframeP==5)||(subframeP==7)||(subframeP==9)) - eNB_mac_inst[module_idP].UE_template[next_ue].DAI = 0; - break; - case 4: - if ((subframeP==0)||(subframeP==6)) - eNB_mac_inst[module_idP].UE_template[next_ue].DAI = 0; - break; - case 5: - if (subframeP==9) - eNB_mac_inst[module_idP].UE_template[next_ue].DAI = 0; - break; - case 6: - if ((subframeP==0)||(subframeP==1)||(subframeP==5)||(subframeP==6)||(subframeP==9)) - eNB_mac_inst[module_idP].UE_template[next_ue].DAI = 0; - default: - break; - } - } - + + if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) { + switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.tdd_config) { + case 0: + if ((subframeP==0)||(subframeP==1)||(subframeP==3)||(subframeP==5)||(subframeP==6)||(subframeP==8)) + UE_list->UE_template[CC_id][UE_id].DAI = 0; + case 1: + if ((subframeP==0)||(subframeP==4)||(subframeP==5)||(subframeP==9)) + UE_list->UE_template[CC_id][UE_id].DAI = 0; + break; + case 2: + if ((subframeP==4)||(subframeP==5)) + UE_list->UE_template[CC_id][UE_id].DAI = 0; + break; + case 3: + if ((subframeP==5)||(subframeP==7)||(subframeP==9)) + UE_list->UE_template[CC_id][UE_id].DAI = 0; + break; + case 4: + if ((subframeP==0)||(subframeP==6)) + UE_list->UE_template[CC_id][UE_id].DAI = 0; + break; + case 5: + if (subframeP==9) + UE_list->UE_template[CC_id][UE_id].DAI = 0; + break; + case 6: + if ((subframeP==0)||(subframeP==1)||(subframeP==5)||(subframeP==6)||(subframeP==9)) + UE_list->UE_template[CC_id][UE_id].DAI = 0; + default: + break; + } + } + // This is an allocated UE_id - rnti = find_UE_RNTI(module_idP,next_ue); + rnti = UE_RNTI(module_idP,UE_id); if (rnti==0) - continue; - - eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,rnti); - + continue; + + eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti); + if (eNB_UE_stats==NULL) - mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n"); - + mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n"); + if (openair_daq_vars.target_ue_dl_mcs <= 0) { eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[eNB_UE_stats->DL_cqi[0]]; LOG_T(MAC,"CQI %d\n",eNB_UE_stats->DL_cqi[0]); } else eNB_UE_stats->dlsch_mcs1 = openair_daq_vars.target_ue_dl_mcs; - - + + if(eNB_UE_stats->dlsch_mcs1>22) - eNB_UE_stats->dlsch_mcs1=22; - - + eNB_UE_stats->dlsch_mcs1=22; + + // for TM5, limit the MCS to 16QAM - - + + // for EXMIMO, limit the MCS to 16QAM as well #ifdef EXMIMO eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1,16); #endif - + // Get candidate harq_pid from PHY - mac_xface->get_ue_active_harq_pid(module_idP,rnti,subframeP,&harq_pid,&round,0); - - eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].harq_pid = harq_pid; - eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].harq_round = round; + mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,subframeP,&harq_pid,&round,0); + + UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; + UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round; // Note this code is for a specific DCI format - DLSCH_dci = (void *)eNB_mac_inst[module_idP].UE_template[next_ue].DLSCH_DCI[harq_pid]; - - for(j=0;j<mac_xface->lte_frame_parms->N_RBGS;j++){ // initializing the rb allocation indicator for each UE - eNB_mac_inst[module_idP].UE_template[next_ue].rballoc_subband[harq_pid][j] = 0; + DLSCH_dci = (void *)UE_list->UE_template[CC_id][UE_id].DLSCH_DCI[harq_pid]; + + for(j=0;j<PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RBGS;j++){ // initializing the rb allocation indicator for each UE + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = 0; } // store stats - eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].dl_cqi= eNB_UE_stats->DL_cqi[0]; - + UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->DL_cqi[0]; + if (round > 0) { - if (mac_xface->lte_frame_parms->frame_type == TDD) { - eNB_mac_inst[module_idP].UE_template[next_ue].DAI++; - LOG_D(MAC,"DAI update: subframeP %d: UE %d, DAI %d\n",subframeP,next_ue,eNB_mac_inst[module_idP].UE_template[next_ue].DAI); - - update_ul_dci(module_idP,rnti,eNB_mac_inst[module_idP].UE_template[next_ue].DAI); - } - - // get freq_allocation - nb_rb = eNB_mac_inst[module_idP].UE_template[next_ue].nb_rb[harq_pid]; - if (nb_rb <= nb_available_rb) { - - if(nb_rb == pre_nb_available_rbs[next_ue]){ - for(j=0;j<mac_xface->lte_frame_parms->N_RBGS;j++) // for indicating the rballoc for each sub-band - eNB_mac_inst[module_idP].UE_template[next_ue].rballoc_subband[harq_pid][j] = rballoc_sub_UE[next_ue][j];} - else - { - nb_rb_temp = nb_rb; - j = 0; - while((nb_rb_temp > 0) && (j<mac_xface->lte_frame_parms->N_RBGS)){ - if(rballoc_sub_UE[next_ue][j] == 1){ - eNB_mac_inst[module_idP].UE_template[next_ue].rballoc_subband[harq_pid][j] = rballoc_sub_UE[next_ue][j]; - if((j == mac_xface->lte_frame_parms->N_RBGS-1) && - ((mac_xface->lte_frame_parms->N_RB_DL == 25)|| - (mac_xface->lte_frame_parms->N_RB_DL == 50))) - nb_rb_temp = nb_rb_temp - min_rb_unit+1; - else - nb_rb_temp = nb_rb_temp - min_rb_unit; - } - j = j+1; - } - } - - nb_available_rb -= nb_rb; - aggregation = process_ue_cqi(module_idP,next_ue); - nCCE-=(1<<aggregation); // adjust the remaining nCCE - *nCCE_used += (1<<aggregation); - - - PHY_vars_eNB_g[module_idP]->mu_mimo_mode[next_ue].pre_nb_available_rbs = nb_rb; - PHY_vars_eNB_g[module_idP]->mu_mimo_mode[next_ue].dl_pow_off = dl_pow_off[next_ue]; - - for(j=0;j<mac_xface->lte_frame_parms->N_RBGS;j++) - PHY_vars_eNB_g[module_idP]->mu_mimo_mode[next_ue].rballoc_sub[j] = eNB_mac_inst[module_idP].UE_template[next_ue].rballoc_subband[harq_pid][j]; - - switch (mac_xface->get_transmission_mode(module_idP,rnti)) { - case 1: - case 2: - default: - switch (mac_xface->lte_frame_parms->N_RB_DL) { - case 6: - if (mac_xface->lte_frame_parms->frame_type == TDD) { - // ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->ndi = 0; - ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->rv = round&3; - ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->dai = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3; - LOG_D(MAC,"[eNB %d] Retransmission : harq_pid %d, round %d, dai %d, mcs %d\n",module_idP,harq_pid,round,(eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1),((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->mcs); - } - else { - // ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->ndi = 0; - ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->rv = round&3; - LOG_D(MAC,"[eNB %d] Retransmission : harq_pid %d, round %d, mcs %d\n",module_idP,harq_pid,round,((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->mcs); - - } - break; - case 25: - if (mac_xface->lte_frame_parms->frame_type == TDD) { - // ((DCI1_5MHz_TDD_t*)DLSCH_dci)->ndi = 0; - ((DCI1_5MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI1_5MHz_TDD_t*)DLSCH_dci)->rv = round&3; - ((DCI1_5MHz_TDD_t*)DLSCH_dci)->dai = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3; - LOG_D(MAC,"[eNB %d] Retransmission : harq_pid %d, round %d, dai %d, mcs %d\n",module_idP,harq_pid,round,(eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1),((DCI1_5MHz_TDD_t*)DLSCH_dci)->mcs); - } - else { - // ((DCI1_5MHz_FDD_t*)DLSCH_dci)->ndi = 0; - ((DCI1_5MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI1_5MHz_FDD_t*)DLSCH_dci)->rv = round&3; - LOG_D(MAC,"[eNB %d] Retransmission : harq_pid %d, round %d, mcs %d\n",module_idP,harq_pid,round,((DCI1_5MHz_FDD_t*)DLSCH_dci)->mcs); - - } - break; - case 50: - if (mac_xface->lte_frame_parms->frame_type == TDD) { - // ((DCI1_10MHz_TDD_t*)DLSCH_dci)->ndi = 0; - ((DCI1_10MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI1_10MHz_TDD_t*)DLSCH_dci)->rv = round&3; - ((DCI1_10MHz_TDD_t*)DLSCH_dci)->dai = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3; - LOG_D(MAC,"[eNB %d] Retransmission : harq_pid %d, round %d, dai %d, mcs %d\n",module_idP,harq_pid,round,(eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1),((DCI1_10MHz_TDD_t*)DLSCH_dci)->mcs); - } - else { - // ((DCI1_10MHz_FDD_t*)DLSCH_dci)->ndi = 0; - ((DCI1_10MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI1_10MHz_FDD_t*)DLSCH_dci)->rv = round&3; - LOG_D(MAC,"[eNB %d] Retransmission : harq_pid %d, round %d, mcs %d\n",module_idP,harq_pid,round,((DCI1_10MHz_FDD_t*)DLSCH_dci)->mcs); - - } - break; - case 100: - if (mac_xface->lte_frame_parms->frame_type == TDD) { - // ((DCI1_20MHz_TDD_t*)DLSCH_dci)->ndi = 0; - ((DCI1_20MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI1_20MHz_TDD_t*)DLSCH_dci)->rv = round&3; - ((DCI1_20MHz_TDD_t*)DLSCH_dci)->dai = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3; - LOG_D(MAC,"[eNB %d] Retransmission : harq_pid %d, round %d, dai %d, mcs %d\n",module_idP,harq_pid,round,(eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1),((DCI1_20MHz_TDD_t*)DLSCH_dci)->mcs); - } - else { - // ((DCI1_20MHz_FDD_t*)DLSCH_dci)->ndi = 0; - ((DCI1_20MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI1_20MHz_FDD_t*)DLSCH_dci)->rv = round&3; - LOG_D(MAC,"[eNB %d] Retransmission : harq_pid %d, round %d, mcs %d\n",module_idP,harq_pid,round,((DCI1_20MHz_FDD_t*)DLSCH_dci)->mcs); - - } - break; - } - break; - case 4: - // if (nb_rb>10) { - ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->ndi1 = 0; - ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->dai = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3; - // } - //else { - // ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->ndi1 = 0; - // ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; - // ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->rv1 = round&3; - // ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->dai = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3; - // } - break; - case 5: - // if(nb_rb>10){ - //((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->mcs = eNB_UE_stats->DL_cqi[0]<<1; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->ndi = 0; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rv = round&3; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dai = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3; - if(dl_pow_off[next_ue] == 2) - dl_pow_off[next_ue] = 1; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dl_power_off = dl_pow_off[next_ue]; - // } - break; - case 6: - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->ndi = 0; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rv = round&3; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dai = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dl_power_off = 1;//dl_pow_off[next_ue]; - break; - } - - add_ue_dlsch_info(module_idP, - next_ue, - subframeP, - S_DL_SCHEDULED); - - //eNB_UE_stats->dlsch_trials[round]++; - eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].num_retransmission+=1; - eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].rbs_used_retx=nb_rb; - eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].total_rbs_used_retx+=nb_rb; - eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].ncce_used_retx=nCCE; - eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].dlsch_mcs1=eNB_UE_stats->dlsch_mcs1; - eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].dlsch_mcs2=eNB_UE_stats->dlsch_mcs1; - } - else { // don't schedule this UE, its retransmission takes more resources than we have - - } + if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) { + UE_list->UE_template[CC_id][UE_id].DAI++; + LOG_D(MAC,"DAI update: subframeP %d: UE %d, DAI %d\n",subframeP,UE_id,UE_list->UE_template[CC_id][UE_id].DAI); + + update_ul_dci(module_idP,CC_id,rnti,UE_list->UE_template[CC_id][UE_id].DAI); + } + + // get freq_allocation + nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + if (nb_rb <= nb_available_rb) { + + if(nb_rb == pre_nb_available_rbs[CC_id][UE_id]){ + for(j=0;j<PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RBGS;j++) // for indicating the rballoc for each sub-band + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = rballoc_sub_UE[CC_id][UE_id][j];} + else + { + nb_rb_temp = nb_rb; + j = 0; + while((nb_rb_temp > 0) && (j<PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RBGS)){ + if(rballoc_sub_UE[CC_id][UE_id][j] == 1){ + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = rballoc_sub_UE[CC_id][UE_id][j]; + if((j == PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RBGS-1) && + ((PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL == 25)|| + (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL == 50))) + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]+1; + else + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; + } + j = j+1; + } + } + + nb_available_rb -= nb_rb; + aggregation = process_ue_cqi(module_idP,UE_id); + nCCE[CC_id]-=(1<<aggregation); // adjust the remaining nCCE + nCCE_used[CC_id] += (1<<aggregation); + + + PHY_vars_eNB_g[module_idP][CC_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; + PHY_vars_eNB_g[module_idP][CC_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[CC_id][UE_id]; + + for(j=0;j<PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RBGS;j++) + PHY_vars_eNB_g[module_idP][CC_id]->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; + + switch (mac_xface->get_transmission_mode(module_idP,CC_id,rnti)) { + case 1: + case 2: + default: + switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) { + case 6: + if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) { + // ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->ndi = 0; + ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->rv = round&3; + ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + LOG_D(MAC,"[eNB %d] Retransmission : harq_pid %d, round %d, dai %d, mcs %d\n",module_idP,harq_pid,round,(UE_list->UE_template[CC_id][UE_id].DAI-1),((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->mcs); + } + else { + // ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->ndi = 0; + ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->rv = round&3; + LOG_D(MAC,"[eNB %d] Retransmission : harq_pid %d, round %d, mcs %d\n",module_idP,harq_pid,round,((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->mcs); + + } + break; + case 25: + if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) { + // ((DCI1_5MHz_TDD_t*)DLSCH_dci)->ndi = 0; + ((DCI1_5MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_5MHz_TDD_t*)DLSCH_dci)->rv = round&3; + ((DCI1_5MHz_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + LOG_D(MAC,"[eNB %d] Retransmission : harq_pid %d, round %d, dai %d, mcs %d\n",module_idP,harq_pid,round,(UE_list->UE_template[CC_id][UE_id].DAI-1),((DCI1_5MHz_TDD_t*)DLSCH_dci)->mcs); + } + else { + // ((DCI1_5MHz_FDD_t*)DLSCH_dci)->ndi = 0; + ((DCI1_5MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_5MHz_FDD_t*)DLSCH_dci)->rv = round&3; + LOG_D(MAC,"[eNB %d] Retransmission : harq_pid %d, round %d, mcs %d\n",module_idP,harq_pid,round,((DCI1_5MHz_FDD_t*)DLSCH_dci)->mcs); + + } + break; + case 50: + if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) { + // ((DCI1_10MHz_TDD_t*)DLSCH_dci)->ndi = 0; + ((DCI1_10MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_10MHz_TDD_t*)DLSCH_dci)->rv = round&3; + ((DCI1_10MHz_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + LOG_D(MAC,"[eNB %d] Retransmission : harq_pid %d, round %d, dai %d, mcs %d\n",module_idP,harq_pid,round,(UE_list->UE_template[CC_id][UE_id].DAI-1),((DCI1_10MHz_TDD_t*)DLSCH_dci)->mcs); + } + else { + // ((DCI1_10MHz_FDD_t*)DLSCH_dci)->ndi = 0; + ((DCI1_10MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_10MHz_FDD_t*)DLSCH_dci)->rv = round&3; + LOG_D(MAC,"[eNB %d] Retransmission : harq_pid %d, round %d, mcs %d\n",module_idP,harq_pid,round,((DCI1_10MHz_FDD_t*)DLSCH_dci)->mcs); + + } + break; + case 100: + if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) { + // ((DCI1_20MHz_TDD_t*)DLSCH_dci)->ndi = 0; + ((DCI1_20MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_20MHz_TDD_t*)DLSCH_dci)->rv = round&3; + ((DCI1_20MHz_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + LOG_D(MAC,"[eNB %d] Retransmission : harq_pid %d, round %d, dai %d, mcs %d\n",module_idP,harq_pid,round,(UE_list->UE_template[CC_id][UE_id].DAI-1),((DCI1_20MHz_TDD_t*)DLSCH_dci)->mcs); + } + else { + // ((DCI1_20MHz_FDD_t*)DLSCH_dci)->ndi = 0; + ((DCI1_20MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_20MHz_FDD_t*)DLSCH_dci)->rv = round&3; + LOG_D(MAC,"[eNB %d] Retransmission : harq_pid %d, round %d, mcs %d\n",module_idP,harq_pid,round,((DCI1_20MHz_FDD_t*)DLSCH_dci)->mcs); + + } + break; + } + break; + case 4: + // if (nb_rb>10) { + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->ndi1 = 0; + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + // } + //else { + // ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->ndi1 = 0; + // ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + // ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->rv1 = round&3; + // ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + // } + break; + case 5: + // if(nb_rb>10){ + //((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->mcs = eNB_UE_stats->DL_cqi[0]<<1; + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->ndi = 0; + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rv = round&3; + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + if(dl_pow_off[CC_id][UE_id] == 2) + dl_pow_off[CC_id][UE_id] = 1; + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dl_power_off = dl_pow_off[CC_id][UE_id]; + // } + break; + case 6: + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->ndi = 0; + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rv = round&3; + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dl_power_off = 1;//dl_pow_off[UE_id]; + break; + } + + add_ue_dlsch_info(module_idP, + CC_id, + UE_id, + subframeP, + S_DL_SCHEDULED); + + //eNB_UE_stats->dlsch_trials[round]++; + UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission+=1; + UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx=nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_retx+=nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].ncce_used_retx=nCCE[CC_id]; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1=eNB_UE_stats->dlsch_mcs1; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2=eNB_UE_stats->dlsch_mcs1; + } + else { // don't schedule this UE, its retransmission takes more resources than we have + + } } else { // This is a potentially new SDU opportunity - - // calculate mcs - - rlc_status.bytes_in_buffer = 0; - // Now check RLC information to compute number of required RBs - // get maximum TBS size for RLC request - //TBS = mac_xface->get_TBS(eNB_UE_stats->DL_cqi[0]<<1,nb_available_rb); - TBS = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_available_rb); - // check first for RLC data on DCCH - // add the length for all the control elements (timing adv, drx, etc) : header + payload + + // calculate mcs + + rlc_status.bytes_in_buffer = 0; + // Now check RLC information to compute number of required RBs + // get maximum TBS size for RLC request + //TBS = mac_xface->get_TBS(eNB_UE_stats->DL_cqi[0]<<1,nb_available_rb); + TBS = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_available_rb); + // check first for RLC data on DCCH + // add the length for all the control elements (timing adv, drx, etc) : header + payload #ifndef EXMIMO_IOT - ta_len = ((eNB_UE_stats->timing_advance_update/4)!=0) ? 2 : 0; + ta_len = ((eNB_UE_stats->timing_advance_update/4)!=0) ? 2 : 0; #else - ta_len = 0; + ta_len = 0; #endif - - header_len_dcch = 2; // 2 bytes DCCH SDU subheader - - - rlc_status = mac_rlc_status_ind( - module_idP, - ue_mod_id, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - DCCH, - (TBS-ta_len-header_len_dcch)); // transport block set size - - sdu_lengths[0]=0; - if (rlc_status.bytes_in_buffer > 0) { // There is DCCH to transmit - LOG_D(MAC,"[eNB %d] Frame %d, DL-DCCH->DLSCH, Requesting %d bytes from RLC (RRC message)\n",module_idP,frameP,TBS-header_len_dcch); - sdu_lengths[0] += mac_rlc_data_req( - module_idP, - ue_mod_id, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - DCCH, - (char *)&dlsch_buffer[sdu_lengths[0]]); - - LOG_D(MAC,"[eNB %d][DCCH] Got %d bytes from RLC\n",module_idP,sdu_lengths[0]); - sdu_length_total = sdu_lengths[0]; - sdu_lcids[0] = DCCH; - eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].num_pdu_tx[DCCH]+=1; - eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].num_bytes_tx[DCCH]+=sdu_lengths[0]; - num_sdus = 1; + + header_len_dcch = 2; // 2 bytes DCCH SDU subheader + + + rlc_status = mac_rlc_status_ind( + module_idP, + UE_id, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + DCCH, + (TBS-ta_len-header_len_dcch)); // transport block set size + + sdu_lengths[0]=0; + if (rlc_status.bytes_in_buffer > 0) { // There is DCCH to transmit + LOG_D(MAC,"[eNB %d] Frame %d, DL-DCCH->DLSCH, Requesting %d bytes from RLC (RRC message)\n",module_idP,frameP,TBS-header_len_dcch); + sdu_lengths[0] += mac_rlc_data_req( + module_idP, + UE_id, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + DCCH, + (char *)&dlsch_buffer[sdu_lengths[0]]); + + LOG_D(MAC,"[eNB %d][DCCH] Got %d bytes from RLC\n",module_idP,sdu_lengths[0]); + sdu_length_total = sdu_lengths[0]; + sdu_lcids[0] = DCCH; + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH]+=1; + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH]+=sdu_lengths[0]; + num_sdus = 1; #ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC,"[eNB %d][DCCH] Got %d bytes :",module_idP,sdu_lengths[0]); - for (j=0;j<sdu_lengths[0];j++) - LOG_T(MAC,"%x ",dlsch_buffer[j]); - LOG_T(MAC,"\n"); + LOG_T(MAC,"[eNB %d][DCCH] Got %d bytes :",module_idP,sdu_lengths[0]); + for (j=0;j<sdu_lengths[0];j++) + LOG_T(MAC,"%x ",dlsch_buffer[j]); + LOG_T(MAC,"\n"); #endif - } - else { - header_len_dcch = 0; - sdu_length_total = 0; - } - - // check for DCCH1 and update header information (assume 2 byte sub-header) - rlc_status = mac_rlc_status_ind( - module_idP, - ue_mod_id, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - DCCH+1, - (TBS-ta_len-header_len_dcch-sdu_length_total)); // transport block set size less allocations for timing advance and - // DCCH SDU - - if (rlc_status.bytes_in_buffer > 0) { - LOG_D(MAC,"[eNB %d], Frame %d, DCCH1->DLSCH, Requesting %d bytes from RLC (RRC message)\n", - module_idP,frameP,TBS-header_len_dcch-sdu_length_total); - sdu_lengths[num_sdus] += mac_rlc_data_req( - module_idP, - ue_mod_id, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - DCCH+1, - (char *)&dlsch_buffer[sdu_lengths[0]]); - - sdu_lcids[num_sdus] = DCCH1; - sdu_length_total += sdu_lengths[num_sdus]; - header_len_dcch += 2; - eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].num_pdu_tx[DCCH1]+=1; - eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].num_bytes_tx[DCCH1]+=sdu_lengths[num_sdus]; - num_sdus++; - LOG_D(MAC,"[eNB %d] Got %d bytes for DCCH from RLC\n",module_idP,sdu_lengths[0]); - } - // check for DTCH and update header information - // here we should loop over all possible DTCH - - header_len_dtch = 3; // 3 bytes DTCH SDU subheader - - LOG_D(MAC,"[eNB %d], Frame %d, DTCH->DLSCH, Checking RLC status (rab %d, tbs %d, len %d)\n", - module_idP,frameP,DTCH,TBS, - TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch); - - rlc_status = mac_rlc_status_ind( - module_idP, - ue_mod_id, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - DTCH, - TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch); - - if (rlc_status.bytes_in_buffer > 0) { - - LOG_I(MAC,"[eNB %d][USER-PLANE DEFAULT DRB], Frame %d, DTCH->DLSCH, Requesting %d bytes from RLC (hdr len dtch %d)\n", - module_idP,frameP,TBS-header_len_dcch-sdu_length_total-header_len_dtch,header_len_dtch); - sdu_lengths[num_sdus] = mac_rlc_data_req( - module_idP, - ue_mod_id, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - DTCH, - (char*)&dlsch_buffer[sdu_length_total]); - - LOG_I(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n",module_idP,sdu_lengths[num_sdus],DTCH); - sdu_lcids[num_sdus] = DTCH; - sdu_length_total += sdu_lengths[num_sdus]; - eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].num_pdu_tx[DTCH]+=1; - eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].num_bytes_tx[DTCH]+=sdu_lengths[num_sdus]; - if (sdu_lengths[num_sdus] < 128) { - header_len_dtch=2; - } - num_sdus++; - } - else { - header_len_dtch = 0; - } - - // there is a payload - if (((sdu_length_total + header_len_dcch + header_len_dtch )> 0)) { - - // Now compute number of required RBs for total sdu length - // Assume RAH format 2 - // adjust header lengths - header_len_dcch_tmp = header_len_dcch; - header_len_dtch_tmp = header_len_dtch; - if (header_len_dtch==0) { - header_len_dcch = (header_len_dcch >0) ? 1 : header_len_dcch; // remove length field - } else { - header_len_dtch = (header_len_dtch > 0) ? 1 :header_len_dtch; // remove length field for the last SDU - } - - - mcs = eNB_UE_stats->dlsch_mcs1; - if (mcs==0) nb_rb = 4; // don't let the TBS get too small - else nb_rb=min_rb_unit; - - TBS = mac_xface->get_TBS_DL(mcs,nb_rb); - - while (TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) { - nb_rb += min_rb_unit; // - if (nb_rb>nb_available_rb) { // if we've gone beyond the maximum number of RBs - // (can happen if N_RB_DL is odd) - TBS = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_available_rb); - nb_rb = nb_available_rb; - break; - } - TBS = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_rb); - } - - if(nb_rb == pre_nb_available_rbs[next_ue]) { - for(j=0;j<mac_xface->lte_frame_parms->N_RBGS;j++) {// for indicating the rballoc for each sub-band - eNB_mac_inst[module_idP].UE_template[next_ue].rballoc_subband[harq_pid][j] = rballoc_sub_UE[next_ue][j]; - } - } else - { - nb_rb_temp = nb_rb; - j = 0; - while((nb_rb_temp > 0) && (j<mac_xface->lte_frame_parms->N_RBGS)){ - if(rballoc_sub_UE[next_ue][j] == 1){ - eNB_mac_inst[module_idP].UE_template[next_ue].rballoc_subband[harq_pid][j] = rballoc_sub_UE[next_ue][j]; - if ((j == mac_xface->lte_frame_parms->N_RBGS-1) && - ((mac_xface->lte_frame_parms->N_RB_DL == 25)|| - (mac_xface->lte_frame_parms->N_RB_DL == 50))) - nb_rb_temp = nb_rb_temp - min_rb_unit+1; - else - nb_rb_temp = nb_rb_temp - min_rb_unit; - } - j = j+1; - } - } - - PHY_vars_eNB_g[module_idP]->mu_mimo_mode[next_ue].pre_nb_available_rbs = nb_rb; - PHY_vars_eNB_g[module_idP]->mu_mimo_mode[next_ue].dl_pow_off = dl_pow_off[next_ue]; - - for(j=0;j<mac_xface->lte_frame_parms->N_RBGS;j++) - PHY_vars_eNB_g[module_idP]->mu_mimo_mode[next_ue].rballoc_sub[j] = eNB_mac_inst[module_idP].UE_template[next_ue].rballoc_subband[harq_pid][j]; - - - // decrease mcs until TBS falls below required length - while ((TBS > (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && (mcs>0)) { - mcs--; - TBS = mac_xface->get_TBS_DL(mcs,nb_rb); - } - - // if we have decreased too much or we don't have enough RBs, increase MCS - while ((TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && ((( dl_pow_off[next_ue]>0) && (mcs<28)) || ( (dl_pow_off[next_ue]==0) && (mcs<=15)))) { - mcs++; - TBS = mac_xface->get_TBS_DL(mcs,nb_rb); - } - - LOG_D(MAC,"dlsch_mcs before and after the rate matching = (%d, %d)\n",eNB_UE_stats->dlsch_mcs1, mcs); - + } + else { + header_len_dcch = 0; + sdu_length_total = 0; + } + + // check for DCCH1 and update header information (assume 2 byte sub-header) + rlc_status = mac_rlc_status_ind( + module_idP, + UE_id, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + DCCH+1, + (TBS-ta_len-header_len_dcch-sdu_length_total)); // transport block set size less allocations for timing advance and + // DCCH SDU + + if (rlc_status.bytes_in_buffer > 0) { + LOG_D(MAC,"[eNB %d], Frame %d, DCCH1->DLSCH, Requesting %d bytes from RLC (RRC message)\n", + module_idP,frameP,TBS-header_len_dcch-sdu_length_total); + sdu_lengths[num_sdus] += mac_rlc_data_req( + module_idP, + UE_id, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + DCCH+1, + (char *)&dlsch_buffer[sdu_lengths[0]]); + + sdu_lcids[num_sdus] = DCCH1; + sdu_length_total += sdu_lengths[num_sdus]; + header_len_dcch += 2; + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH1]+=1; + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1]+=sdu_lengths[num_sdus]; + num_sdus++; + LOG_D(MAC,"[eNB %d] Got %d bytes for DCCH from RLC\n",module_idP,sdu_lengths[0]); + } + // check for DTCH and update header information + // here we should loop over all possible DTCH + + header_len_dtch = 3; // 3 bytes DTCH SDU subheader + + LOG_D(MAC,"[eNB %d], Frame %d, DTCH->DLSCH, Checking RLC status (rab %d, tbs %d, len %d)\n", + module_idP,frameP,DTCH,TBS, + TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch); + + rlc_status = mac_rlc_status_ind( + module_idP, + UE_id, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + DTCH, + TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch); + + if (rlc_status.bytes_in_buffer > 0) { + + LOG_I(MAC,"[eNB %d][USER-PLANE DEFAULT DRB], Frame %d, DTCH->DLSCH, Requesting %d bytes from RLC (hdr len dtch %d)\n", + module_idP,frameP,TBS-header_len_dcch-sdu_length_total-header_len_dtch,header_len_dtch); + sdu_lengths[num_sdus] = mac_rlc_data_req( + module_idP, + UE_id, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + DTCH, + (char*)&dlsch_buffer[sdu_length_total]); + + LOG_I(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n",module_idP,sdu_lengths[num_sdus],DTCH); + sdu_lcids[num_sdus] = DTCH; + sdu_length_total += sdu_lengths[num_sdus]; + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DTCH]+=1; + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DTCH]+=sdu_lengths[num_sdus]; + if (sdu_lengths[num_sdus] < 128) { + header_len_dtch=2; + } + num_sdus++; + } + else { + header_len_dtch = 0; + } + + // there is a payload + if (((sdu_length_total + header_len_dcch + header_len_dtch )> 0)) { + + // Now compute number of required RBs for total sdu length + // Assume RAH format 2 + // adjust header lengths + header_len_dcch_tmp = header_len_dcch; + header_len_dtch_tmp = header_len_dtch; + if (header_len_dtch==0) { + header_len_dcch = (header_len_dcch >0) ? 1 : header_len_dcch; // remove length field + } else { + header_len_dtch = (header_len_dtch > 0) ? 1 :header_len_dtch; // remove length field for the last SDU + } + + + mcs = eNB_UE_stats->dlsch_mcs1; + if (mcs==0) nb_rb = 4; // don't let the TBS get too small + else nb_rb=min_rb_unit[CC_id]; + + TBS = mac_xface->get_TBS_DL(mcs,nb_rb); + + while (TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) { + nb_rb += min_rb_unit[CC_id]; // + if (nb_rb>nb_available_rb) { // if we've gone beyond the maximum number of RBs + // (can happen if N_RB_DL is odd) + TBS = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_available_rb); + nb_rb = nb_available_rb; + break; + } + TBS = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_rb); + } + + if(nb_rb == pre_nb_available_rbs[CC_id][UE_id]) { + for(j=0;j<PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RBGS;j++) {// for indicating the rballoc for each sub-band + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = rballoc_sub_UE[CC_id][UE_id][j]; + } + } else + { + nb_rb_temp = nb_rb; + j = 0; + while((nb_rb_temp > 0) && (j<PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RBGS)){ + if(rballoc_sub_UE[CC_id][UE_id][j] == 1){ + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = rballoc_sub_UE[CC_id][UE_id][j]; + if ((j == PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RBGS-1) && + ((PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL == 25)|| + (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL == 50))) + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]+1; + else + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; + } + j = j+1; + } + } + + PHY_vars_eNB_g[module_idP][CC_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; + PHY_vars_eNB_g[module_idP][CC_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[CC_id][UE_id]; + + for(j=0;j<PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RBGS;j++) + PHY_vars_eNB_g[module_idP][CC_id]->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; + + + // decrease mcs until TBS falls below required length + while ((TBS > (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && (mcs>0)) { + mcs--; + TBS = mac_xface->get_TBS_DL(mcs,nb_rb); + } + + // if we have decreased too much or we don't have enough RBs, increase MCS + while ((TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && ((( dl_pow_off[CC_id][UE_id]>0) && (mcs<28)) || ( (dl_pow_off[CC_id][UE_id]==0) && (mcs<=15)))) { + mcs++; + TBS = mac_xface->get_TBS_DL(mcs,nb_rb); + } + + LOG_D(MAC,"dlsch_mcs before and after the rate matching = (%d, %d)\n",eNB_UE_stats->dlsch_mcs1, mcs); + #ifdef DEBUG_eNB_SCHEDULER - LOG_D(MAC,"[eNB %d] Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n", - module_idP,mcs,TBS,nb_rb); - // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n", - // TBS, sdu_length_total, offset, TBS-sdu_length_total-offset); + LOG_D(MAC,"[eNB %d] Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n", + module_idP,mcs,TBS,nb_rb); + // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n", + // TBS, sdu_length_total, offset, TBS-sdu_length_total-offset); #endif - - if ((TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len) <= 2) { - padding = (TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len); - post_padding = 0; - } - else { - padding = 0; - // adjust the header len - if (header_len_dtch==0) - header_len_dcch = header_len_dcch_tmp; - else //if (( header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2))) - header_len_dtch = header_len_dtch_tmp; - - post_padding = TBS - sdu_length_total - header_len_dcch - header_len_dtch - ta_len ; // 1 is for the postpadding header - } + + if ((TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len) <= 2) { + padding = (TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len); + post_padding = 0; + } + else { + padding = 0; + // adjust the header len + if (header_len_dtch==0) + header_len_dcch = header_len_dcch_tmp; + else //if (( header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2))) + header_len_dtch = header_len_dtch_tmp; + + post_padding = TBS - sdu_length_total - header_len_dcch - header_len_dtch - ta_len ; // 1 is for the postpadding header + } #ifndef EXMIMO_IOT - ta_update = eNB_UE_stats->timing_advance_update/4; + ta_update = eNB_UE_stats->timing_advance_update/4; #else - ta_update = 0; + ta_update = 0; #endif - - offset = generate_dlsch_header((unsigned char*)eNB_mac_inst[module_idP].DLSCH_pdu[(module_id_t)next_ue][0].payload[0], - // offset = generate_dlsch_header((unsigned char*)eNB_mac_inst[0].DLSCH_pdu[0][0].payload[0], - num_sdus, //num_sdus - sdu_lengths, // - sdu_lcids, - 255, // no drx - ta_update, // timing advance - NULL, // contention res id - padding, - post_padding); - //#ifdef DEBUG_eNB_SCHEDULER - LOG_I(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] Generate header : sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, next_ue %d,padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_dcch %d, header_dtch %d\n", - module_idP,sdu_length_total,num_sdus,sdu_lengths[0],sdu_lcids[0],offset, - ta_len,next_ue,padding,post_padding,mcs,TBS,nb_rb,header_len_dcch,header_len_dtch); - //#endif - - LOG_T(MAC,"[eNB %d] First 16 bytes of DLSCH : \n"); - for (i=0;i<16;i++) - LOG_T(MAC,"%x.",dlsch_buffer[i]); - LOG_T(MAC,"\n"); - - // cycle through SDUs and place in dlsch_buffer - memcpy(&eNB_mac_inst[module_idP].DLSCH_pdu[(module_id_t)next_ue][0].payload[0][offset],dlsch_buffer,sdu_length_total); - // memcpy(&eNB_mac_inst[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); - - // fill remainder of DLSCH with random data - for (j=0;j<(TBS-sdu_length_total-offset);j++) - eNB_mac_inst[module_idP].DLSCH_pdu[(module_id_t)next_ue][0].payload[0][offset+sdu_length_total+j] = (char)(taus()&0xff); - //eNB_mac_inst[0].DLSCH_pdu[0][0].payload[0][offset+sdu_lengths[0]+j] = (char)(taus()&0xff); - + + offset = generate_dlsch_header((unsigned char*)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], + // offset = generate_dlsch_header((unsigned char*)eNB_mac_inst[0].DLSCH_pdu[0][0].payload[0], + num_sdus, //num_sdus + sdu_lengths, // + sdu_lcids, + 255, // no drx + ta_update, // timing advance + NULL, // contention res id + padding, + post_padding); + //#ifdef DEBUG_eNB_SCHEDULER + LOG_I(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] Generate header : sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, UE_id %d,padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_dcch %d, header_dtch %d\n", + module_idP,sdu_length_total,num_sdus,sdu_lengths[0],sdu_lcids[0],offset, + ta_len,UE_id,padding,post_padding,mcs,TBS,nb_rb,header_len_dcch,header_len_dtch); + //#endif + + LOG_T(MAC,"[eNB %d] First 16 bytes of DLSCH : \n"); + for (i=0;i<16;i++) + LOG_T(MAC,"%x.",dlsch_buffer[i]); + LOG_T(MAC,"\n"); + + // cycle through SDUs and place in dlsch_buffer + memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset],dlsch_buffer,sdu_length_total); + // memcpy(&eNB_mac_inst[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); + + // fill remainder of DLSCH with random data + for (j=0;j<(TBS-sdu_length_total-offset);j++) + UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset+sdu_length_total+j] = (char)(taus()&0xff); + //eNB_mac_inst[0].DLSCH_pdu[0][0].payload[0][offset+sdu_lengths[0]+j] = (char)(taus()&0xff); + #if defined(USER_MODE) && defined(OAI_EMU) - /* Tracing of PDU is done on UE side */ - if (oai_emulation.info.opt_enabled) - trace_pdu(1, (uint8_t *)eNB_mac_inst[module_idP].DLSCH_pdu[(module_id_t)next_ue][0].payload[0], - TBS, module_idP, 3, find_UE_RNTI(module_idP,next_ue), - eNB_mac_inst[module_idP].subframe,0,0); - LOG_D(OPT,"[eNB %d][DLSCH] Frame %d rnti %x with size %d\n", - module_idP, frameP, find_UE_RNTI(module_idP,next_ue), TBS); + /* Tracing of PDU is done on UE side */ + if (oai_emulation.info.opt_enabled) + trace_pdu(1, (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], + TBS, module_idP, 3, UE_RNTI(module_idP,UE_id), + eNB->subframe,0,0); + LOG_D(OPT,"[eNB %d][DLSCH] Frame %d rnti %x with size %d\n", + module_idP, frameP, UE_RNTI(module_idP,UE_id), TBS); #endif - - aggregation = process_ue_cqi(module_idP,next_ue); - nCCE-=(1<<aggregation); // adjust the remaining nCCE - *nCCE_used+=(1<<aggregation); // adjust the remaining nCCE - eNB_mac_inst[module_idP].UE_template[next_ue].nb_rb[harq_pid] = nb_rb; - - add_ue_dlsch_info(module_idP, - next_ue, - subframeP, - S_DL_SCHEDULED); - // store stats - eNB_mac_inst[module_idP].eNB_stats.dlsch_bytes_tx+=sdu_length_total; - eNB_mac_inst[module_idP].eNB_stats.dlsch_pdus_tx+=1; - - eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].rbs_used = nb_rb; - eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].total_rbs_used += nb_rb; - eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].ncce_used = nCCE; - eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].dlsch_mcs1=eNB_UE_stats->dlsch_mcs1; - eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].dlsch_mcs2=mcs; - eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].TBS = TBS; - - eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].overhead_bytes= TBS- sdu_length_total; - eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].total_sdu_bytes+= sdu_length_total; - eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].total_pdu_bytes+= TBS; - eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].total_num_pdus+=1; - - if (mac_xface->lte_frame_parms->frame_type == TDD) { - eNB_mac_inst[module_idP].UE_template[next_ue].DAI++; - // printf("DAI update: subframeP %d: UE %d, DAI %d\n",subframeP,next_ue,eNB_mac_inst[module_idP].UE_template[next_ue].DAI); + + aggregation = process_ue_cqi(module_idP,UE_id); + nCCE[CC_id]-=(1<<aggregation); // adjust the remaining nCCE + nCCE_used[CC_id]+=(1<<aggregation); // adjust the remaining nCCE + UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb; + + add_ue_dlsch_info(module_idP, + CC_id, + UE_id, + subframeP, + S_DL_SCHEDULED); + // store stats + eNB->eNB_stats.dlsch_bytes_tx+=sdu_length_total; + eNB->eNB_stats.dlsch_pdus_tx+=1; + + UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used += nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].ncce_used = nCCE[CC_id]; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1=eNB_UE_stats->dlsch_mcs1; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2=mcs; + UE_list->eNB_UE_stats[CC_id][UE_id].TBS = TBS; + + UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes= TBS- sdu_length_total; + UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes+= sdu_length_total; + UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes+= TBS; + UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus+=1; + + if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) { + UE_list->UE_template[CC_id][UE_id].DAI++; + // printf("DAI update: subframeP %d: UE %d, DAI %d\n",subframeP,UE_id,UE_list->UE_template[CC_id][UE_id].DAI); #warning only for 5MHz channel - update_ul_dci(module_idP,rnti,eNB_mac_inst[module_idP].UE_template[next_ue].DAI); - } - - switch (mac_xface->get_transmission_mode(module_idP,rnti)) { - case 1: - case 2: - default: - if (mac_xface->lte_frame_parms->frame_type == TDD) { - switch (mac_xface->lte_frame_parms->N_RB_DL) { - case 6: - ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->mcs = mcs; - ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->ndi = 1-eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid]; - ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->rv = 0; - ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->dai = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3; - break; - case 25: - ((DCI1_5MHz_TDD_t*)DLSCH_dci)->mcs = mcs; - ((DCI1_5MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI1_5MHz_TDD_t*)DLSCH_dci)->ndi = 1-eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid]; - ((DCI1_5MHz_TDD_t*)DLSCH_dci)->rv = 0; - ((DCI1_5MHz_TDD_t*)DLSCH_dci)->dai = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3; - LOG_D(MAC,"Format1 DCI: harq_pid %d, ndi %d\n",harq_pid,((DCI1_5MHz_TDD_t*)DLSCH_dci)->ndi); - break; - case 50: - ((DCI1_10MHz_TDD_t*)DLSCH_dci)->mcs = mcs; - ((DCI1_10MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI1_10MHz_TDD_t*)DLSCH_dci)->ndi = 1-eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid]; - ((DCI1_10MHz_TDD_t*)DLSCH_dci)->rv = 0; - ((DCI1_10MHz_TDD_t*)DLSCH_dci)->dai = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3; - break; - case 100: - ((DCI1_20MHz_TDD_t*)DLSCH_dci)->mcs = mcs; - ((DCI1_20MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI1_20MHz_TDD_t*)DLSCH_dci)->ndi = 1-eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid]; - ((DCI1_20MHz_TDD_t*)DLSCH_dci)->rv = 0; - ((DCI1_20MHz_TDD_t*)DLSCH_dci)->dai = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3; - break; - default: - ((DCI1_5MHz_TDD_t*)DLSCH_dci)->mcs = mcs; - ((DCI1_5MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI1_5MHz_TDD_t*)DLSCH_dci)->ndi = 1-eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid]; - ((DCI1_5MHz_TDD_t*)DLSCH_dci)->rv = 0; - ((DCI1_5MHz_TDD_t*)DLSCH_dci)->dai = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3; - break; - } - } - else { - switch (mac_xface->lte_frame_parms->N_RB_DL) { - case 6: - ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->mcs = mcs; - ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->ndi = 1-eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid]; - ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->rv = 0; - break; - case 25: - ((DCI1_5MHz_FDD_t*)DLSCH_dci)->mcs = mcs; - ((DCI1_5MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI1_5MHz_FDD_t*)DLSCH_dci)->ndi = 1-eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid]; - ((DCI1_5MHz_FDD_t*)DLSCH_dci)->rv = 0; - break; - case 50: - ((DCI1_10MHz_FDD_t*)DLSCH_dci)->mcs = mcs; - ((DCI1_10MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI1_10MHz_FDD_t*)DLSCH_dci)->ndi = 1-eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid]; - ((DCI1_10MHz_FDD_t*)DLSCH_dci)->rv = 0; - break; - case 100: - ((DCI1_20MHz_FDD_t*)DLSCH_dci)->mcs = mcs; - ((DCI1_20MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI1_20MHz_FDD_t*)DLSCH_dci)->ndi = 1-eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid]; - ((DCI1_20MHz_FDD_t*)DLSCH_dci)->rv = 0; - break; - default: - ((DCI1_5MHz_FDD_t*)DLSCH_dci)->mcs = mcs; - ((DCI1_5MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI1_5MHz_FDD_t*)DLSCH_dci)->ndi = 1-eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid]; - ((DCI1_5MHz_FDD_t*)DLSCH_dci)->rv = 0; - break; - } - } - break; - case 4: - // if (nb_rb>10) { - ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->mcs1 = mcs; - ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->ndi1 = 1; - ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->rv1 = round&3; - ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->dai = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3; - - //} - /* else { - ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->mcs1 = eNB_UE_stats->DL_cqi[0]; - ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->ndi1 = 1; - ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->rv1 = round&3; - ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->tpmi = 5; - ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->dai = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3; - }*/ - break; - case 5: - - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->mcs = mcs; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->ndi = 1; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rv = round&3; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dai = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3; - if(dl_pow_off[next_ue] == 2) - dl_pow_off[next_ue] = 1; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dl_power_off = dl_pow_off[next_ue]; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->tpmi = 5; - break; - case 6: - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->mcs = mcs; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->ndi = 1; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rv = round&3; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dai = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dl_power_off = 1; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->tpmi = 5; - break; - } - // Toggle NDI for next time - LOG_D(MAC,"Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n",frameP,subframeP,next_ue, - eNB_mac_inst[module_idP].UE_template[next_ue].rnti,harq_pid,eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid]); - eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid]=1-eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid]; - } - - else { // There is no data from RLC or MAC header, so don't schedule - - } + update_ul_dci(module_idP,CC_id,rnti,UE_list->UE_template[CC_id][UE_id].DAI); + } + + switch (mac_xface->get_transmission_mode(module_idP,CC_id,rnti)) { + case 1: + case 2: + default: + if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) { + switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->mcs = mcs; + ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->ndi = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->rv = 0; + ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + break; + case 25: + ((DCI1_5MHz_TDD_t*)DLSCH_dci)->mcs = mcs; + ((DCI1_5MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_5MHz_TDD_t*)DLSCH_dci)->ndi = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + ((DCI1_5MHz_TDD_t*)DLSCH_dci)->rv = 0; + ((DCI1_5MHz_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + LOG_D(MAC,"Format1 DCI: harq_pid %d, ndi %d\n",harq_pid,((DCI1_5MHz_TDD_t*)DLSCH_dci)->ndi); + break; + case 50: + ((DCI1_10MHz_TDD_t*)DLSCH_dci)->mcs = mcs; + ((DCI1_10MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_10MHz_TDD_t*)DLSCH_dci)->ndi = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + ((DCI1_10MHz_TDD_t*)DLSCH_dci)->rv = 0; + ((DCI1_10MHz_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + break; + case 100: + ((DCI1_20MHz_TDD_t*)DLSCH_dci)->mcs = mcs; + ((DCI1_20MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_20MHz_TDD_t*)DLSCH_dci)->ndi = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + ((DCI1_20MHz_TDD_t*)DLSCH_dci)->rv = 0; + ((DCI1_20MHz_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + break; + default: + ((DCI1_5MHz_TDD_t*)DLSCH_dci)->mcs = mcs; + ((DCI1_5MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_5MHz_TDD_t*)DLSCH_dci)->ndi = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + ((DCI1_5MHz_TDD_t*)DLSCH_dci)->rv = 0; + ((DCI1_5MHz_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + break; + } + } + else { + switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->mcs = mcs; + ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->ndi = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->rv = 0; + break; + case 25: + ((DCI1_5MHz_FDD_t*)DLSCH_dci)->mcs = mcs; + ((DCI1_5MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_5MHz_FDD_t*)DLSCH_dci)->ndi = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + ((DCI1_5MHz_FDD_t*)DLSCH_dci)->rv = 0; + break; + case 50: + ((DCI1_10MHz_FDD_t*)DLSCH_dci)->mcs = mcs; + ((DCI1_10MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_10MHz_FDD_t*)DLSCH_dci)->ndi = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + ((DCI1_10MHz_FDD_t*)DLSCH_dci)->rv = 0; + break; + case 100: + ((DCI1_20MHz_FDD_t*)DLSCH_dci)->mcs = mcs; + ((DCI1_20MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_20MHz_FDD_t*)DLSCH_dci)->ndi = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + ((DCI1_20MHz_FDD_t*)DLSCH_dci)->rv = 0; + break; + default: + ((DCI1_5MHz_FDD_t*)DLSCH_dci)->mcs = mcs; + ((DCI1_5MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_5MHz_FDD_t*)DLSCH_dci)->ndi = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + ((DCI1_5MHz_FDD_t*)DLSCH_dci)->rv = 0; + break; + } + } + break; + case 4: + // if (nb_rb>10) { + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->mcs1 = mcs; + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->ndi1 = 1; + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->rv1 = round&3; + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + + //} + /* else { + ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->mcs1 = eNB_UE_stats->DL_cqi[0]; + ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->ndi1 = 1; + ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->rv1 = round&3; + ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->tpmi = 5; + ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + }*/ + break; + case 5: + + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->mcs = mcs; + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->ndi = 1; + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rv = round&3; + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + if(dl_pow_off[CC_id][UE_id] == 2) + dl_pow_off[CC_id][UE_id] = 1; + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dl_power_off = dl_pow_off[CC_id][UE_id]; + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->tpmi = 5; + break; + case 6: + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->mcs = mcs; + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->ndi = 1; + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rv = round&3; + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dl_power_off = 1; + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->tpmi = 5; + break; + } + // Toggle NDI for next time + LOG_D(MAC,"Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n",frameP,subframeP,UE_id, + UE_list->UE_template[CC_id][UE_id].rnti,harq_pid,UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]); + UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]=1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + } + + else { // There is no data from RLC or MAC header, so don't schedule + + } } - if (mac_xface->lte_frame_parms->frame_type == TDD) { - DAI = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3; - LOG_D(MAC,"[eNB %d] Frame %d: DAI %d for UE %d\n",module_idP,frameP,DAI,next_ue); - // Save DAI for Format 0 DCI - - switch (mac_xface->lte_frame_parms->tdd_config) { - case 0: - // if ((subframeP==0)||(subframeP==1)||(subframeP==5)||(subframeP==6)) - break; - case 1: - switch (subframeP) { - case 1: - eNB_mac_inst[module_idP].UE_template[next_ue].DAI_ul[7] = DAI; - break; - case 4: - eNB_mac_inst[module_idP].UE_template[next_ue].DAI_ul[8] = DAI; - break; - case 6: - eNB_mac_inst[module_idP].UE_template[next_ue].DAI_ul[2] = DAI; - break; - case 9: - eNB_mac_inst[module_idP].UE_template[next_ue].DAI_ul[3] = DAI; - break; - } - case 2: - // if ((subframeP==3)||(subframeP==8)) - // eNB_mac_inst[module_idP].UE_template[next_ue].DAI_ul = DAI; - break; - case 3: - if ((subframeP==6)||(subframeP==8)||(subframeP==0)) { - LOG_D(MAC,"schedule_ue_spec: setting UL DAI to %d for subframeP %d => %d\n",DAI,subframeP, ((subframeP+8)%10)>>1); - eNB_mac_inst[module_idP].UE_template[next_ue].DAI_ul[((subframeP+8)%10)>>1] = DAI; - } - break; - case 4: - // if ((subframeP==8)||(subframeP==9)) - // eNB_mac_inst[module_idP].UE_template[next_ue].DAI_ul = DAI; - break; - case 5: - // if (subframeP==8) - // eNB_mac_inst[module_idP].UE_template[next_ue].DAI_ul = DAI; - break; - case 6: - // if ((subframeP==1)||(subframeP==4)||(subframeP==6)||(subframeP==9)) - // eNB_mac_inst[module_idP].UE_template[next_ue].DAI_ul = DAI; - break; - default: - break; - } + if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) { + DAI = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + LOG_D(MAC,"[eNB %d] Frame %d: DAI %d for UE %d\n",module_idP,frameP,DAI,UE_id); + // Save DAI for Format 0 DCI + + switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.tdd_config) { + case 0: + // if ((subframeP==0)||(subframeP==1)||(subframeP==5)||(subframeP==6)) + break; + case 1: + switch (subframeP) { + case 1: + UE_list->UE_template[CC_id][UE_id].DAI_ul[7] = DAI; + break; + case 4: + UE_list->UE_template[CC_id][UE_id].DAI_ul[8] = DAI; + break; + case 6: + UE_list->UE_template[CC_id][UE_id].DAI_ul[2] = DAI; + break; + case 9: + UE_list->UE_template[CC_id][UE_id].DAI_ul[3] = DAI; + break; + } + case 2: + // if ((subframeP==3)||(subframeP==8)) + // UE_list->UE_template[CC_id][UE_id].DAI_ul = DAI; + break; + case 3: + if ((subframeP==6)||(subframeP==8)||(subframeP==0)) { + LOG_D(MAC,"schedule_ue_spec: setting UL DAI to %d for subframeP %d => %d\n",DAI,subframeP, ((subframeP+8)%10)>>1); + UE_list->UE_template[CC_id][UE_id].DAI_ul[((subframeP+8)%10)>>1] = DAI; + } + break; + case 4: + // if ((subframeP==8)||(subframeP==9)) + // UE_list->UE_template[CC_id][UE_id].DAI_ul = DAI; + break; + case 5: + // if (subframeP==8) + // UE_list->UE_template[CC_id][UE_id].DAI_ul = DAI; + break; + case 6: + // if ((subframeP==1)||(subframeP==4)||(subframeP==6)||(subframeP==9)) + // UE_list->UE_template[CC_id][UE_id].DAI_ul = DAI; + break; + default: + break; + } } - //printf("MAC nCCE : %d\n",*nCCE_used); + } } - stop_meas(&eNB_mac_inst[module_idP].schedule_dlsch); + //printf("MAC nCCE : %d\n",*nCCE_used); + + + stop_meas(&eNB->schedule_dlsch); + } -void fill_DLSCH_dci(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP,uint32_t RBalloc,uint8_t RA_scheduled,int mbsfn_flag) { +void fill_DLSCH_dci(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP,uint32_t *RBallocP,uint8_t RA_scheduledP,int *mbsfn_flagP) { // loop over all allocated UEs and compute frequency allocations for PDSCH - module_id_t ue_mod_id = -1; + int UE_id = -1; uint8_t first_rb,nb_rb=3; rnti_t rnti; unsigned char vrb_map[100]; - uint8_t rballoc_sub[mac_xface->lte_frame_parms->N_RBGS]; + uint8_t rballoc_sub[25]; //uint8_t number_of_subbands=13; - uint32_t rballoc = RBalloc; + uint32_t *rballoc=RBallocP; unsigned char round; unsigned char harq_pid; void *DLSCH_dci=NULL; - DCI_PDU *DCI_pdu= &eNB_mac_inst[module_idP].DCI_pdu; + DCI_PDU *DCI_pdu; int i; - void *BCCH_alloc_pdu=(void*)&eNB_mac_inst[module_idP].BCCH_alloc_pdu; + void *BCCH_alloc_pdu; int size_bits,size_bytes; + int CC_id; + eNB_MAC_INST *eNB =&eNB_mac_inst[module_idP]; + UE_list_t *UE_list = &eNB->UE_list; + RA_TEMPLATE *RA_template; - if (mbsfn_flag>0) - return; - start_meas(&eNB_mac_inst[module_idP].fill_DLSCH_dci); + start_meas(&eNB->fill_DLSCH_dci); + + for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { + + if (mbsfn_flagP[CC_id]>0) + continue; - // clear vrb_map - memset(vrb_map,0,100); + DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu; + BCCH_alloc_pdu=(void*)&eNB->common_channels[CC_id].BCCH_alloc_pdu; + // clear vrb_map + memset(vrb_map,0,100); - // SI DLSCH - // printf("BCCH check\n"); - if (eNB_mac_inst[module_idP].bcch_active == 1) { - eNB_mac_inst[module_idP].bcch_active = 0; + + // SI DLSCH + // printf("BCCH check\n"); + if (eNB->common_channels[CC_id].bcch_active == 1) { + eNB->common_channels[CC_id].bcch_active = 0; LOG_D(MAC,"[eNB %d] Frame %d subframeP %d: BCCH active\n", module_idP, frameP, subframeP); // randomize frequency allocation for SI - first_rb = (unsigned char)(taus()%(mac_xface->lte_frame_parms->N_RB_DL-4)); - if (mac_xface->lte_frame_parms->frame_type == TDD) { + first_rb = (unsigned char)(taus()%(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL-4)); + + /* Where is this from, should be removed!!!! + + if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) { + + } + else { + BCCH_alloc_pdu_fdd.rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + rballoc[CC_id] |= mac_xface->get_rballoc(BCCH_alloc_pdu_fdd.vrb_type,BCCH_alloc_pdu_fdd.rballoc); + } + */ - } - else { - BCCH_alloc_pdu_fdd.rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - rballoc |= mac_xface->get_rballoc(BCCH_alloc_pdu_fdd.vrb_type,BCCH_alloc_pdu_fdd.rballoc); - } vrb_map[first_rb] = 1; vrb_map[first_rb+1] = 1; vrb_map[first_rb+2] = 1; vrb_map[first_rb+3] = 1; - - if (mac_xface->lte_frame_parms->frame_type == TDD) { - switch (mac_xface->lte_frame_parms->N_RB_DL) { - case 6: - ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->type = 1; - ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->vrb_type = 0; - ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->ndi = 1; - ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rv = 1; - ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->harq_pid = 0; - ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->TPC = 1; - ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->padding = 0; - rballoc |= mac_xface->get_rballoc(0,((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc); - add_common_dci(DCI_pdu, - BCCH_alloc_pdu, - SI_RNTI, - sizeof(DCI1A_1_5MHz_TDD_1_6_t), - 2, - sizeof_DCI1A_1_5MHz_TDD_1_6_t, - format1A,0); - break; - case 25: - ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->type = 1; - ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->vrb_type = 0; - ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->ndi = 1; - ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rv = 1; - ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->harq_pid = 0; - ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->TPC = 1; - ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->padding = 0; - rballoc |= mac_xface->get_rballoc(0,((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc); - add_common_dci(DCI_pdu, - BCCH_alloc_pdu, - SI_RNTI, - sizeof(DCI1A_5MHz_TDD_1_6_t), - 2, - sizeof_DCI1A_5MHz_TDD_1_6_t, - format1A,0); - break; - case 50: - ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->type = 1; - ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->vrb_type = 0; - ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->ndi = 1; - ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rv = 1; - ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->harq_pid = 0; - ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->TPC = 1; - ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->padding = 0; - rballoc |= mac_xface->get_rballoc(0,((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc); - add_common_dci(DCI_pdu, - BCCH_alloc_pdu, - SI_RNTI, - sizeof(DCI1A_10MHz_TDD_1_6_t), - 2, - sizeof_DCI1A_10MHz_TDD_1_6_t, - format1A,0); - break; - case 100: - ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->type = 1; - ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->vrb_type = 0; - ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->ndi = 1; - ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rv = 1; - ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->harq_pid = 0; - ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->TPC = 1; - ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->padding = 0; - rballoc |= mac_xface->get_rballoc(0,((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc); - add_common_dci(DCI_pdu, - BCCH_alloc_pdu, - SI_RNTI, - sizeof(DCI1A_20MHz_TDD_1_6_t), - 2, - sizeof_DCI1A_20MHz_TDD_1_6_t, - format1A,0); - break; - } + + if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) { + switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->type = 1; + ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->vrb_type = 0; + ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->ndi = 1; + ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rv = 1; + ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->harq_pid = 0; + ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->TPC = 1; + ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->padding = 0; + rballoc[CC_id] |= mac_xface->get_rballoc(0,((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc); + add_common_dci(DCI_pdu, + BCCH_alloc_pdu, + SI_RNTI, + sizeof(DCI1A_1_5MHz_TDD_1_6_t), + 2, + sizeof_DCI1A_1_5MHz_TDD_1_6_t, + format1A,0); + break; + case 25: + ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->type = 1; + ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->vrb_type = 0; + ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->ndi = 1; + ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rv = 1; + ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->harq_pid = 0; + ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->TPC = 1; + ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->padding = 0; + rballoc[CC_id] |= mac_xface->get_rballoc(0,((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc); + add_common_dci(DCI_pdu, + BCCH_alloc_pdu, + SI_RNTI, + sizeof(DCI1A_5MHz_TDD_1_6_t), + 2, + sizeof_DCI1A_5MHz_TDD_1_6_t, + format1A,0); + break; + case 50: + ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->type = 1; + ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->vrb_type = 0; + ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->ndi = 1; + ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rv = 1; + ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->harq_pid = 0; + ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->TPC = 1; + ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->padding = 0; + rballoc[CC_id] |= mac_xface->get_rballoc(0,((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc); + add_common_dci(DCI_pdu, + BCCH_alloc_pdu, + SI_RNTI, + sizeof(DCI1A_10MHz_TDD_1_6_t), + 2, + sizeof_DCI1A_10MHz_TDD_1_6_t, + format1A,0); + break; + case 100: + ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->type = 1; + ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->vrb_type = 0; + ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->ndi = 1; + ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rv = 1; + ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->harq_pid = 0; + ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->TPC = 1; + ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->padding = 0; + rballoc[CC_id] |= mac_xface->get_rballoc(0,((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc); + add_common_dci(DCI_pdu, + BCCH_alloc_pdu, + SI_RNTI, + sizeof(DCI1A_20MHz_TDD_1_6_t), + 2, + sizeof_DCI1A_20MHz_TDD_1_6_t, + format1A,0); + break; + } } else { - switch (mac_xface->lte_frame_parms->N_RB_DL) { - case 6: - ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->type = 1; - ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->vrb_type = 0; - ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->ndi = 1; - ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->rv = 1; - ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->harq_pid = 0; - ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->TPC = 1; - ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->padding = 0; - - rballoc |= mac_xface->get_rballoc(0,((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->rballoc); - add_common_dci(DCI_pdu, - BCCH_alloc_pdu, - SI_RNTI, - sizeof(DCI1A_1_5MHz_FDD_t), - 2, - sizeof_DCI1A_1_5MHz_FDD_t, - format1A,0); - break; - case 25: - ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->type = 1; - ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->vrb_type = 0; - ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->ndi = 1; - ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->rv = 1; - ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->harq_pid = 0; - ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->TPC = 1; - ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->padding = 0; - - rballoc |= mac_xface->get_rballoc(0,((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->rballoc); - add_common_dci(DCI_pdu, - BCCH_alloc_pdu, - SI_RNTI, - sizeof(DCI1A_5MHz_FDD_t), - 2, - sizeof_DCI1A_5MHz_FDD_t, - format1A,0); - break; - case 50: - ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->type = 1; - ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->vrb_type = 0; - ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->ndi = 1; - ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->rv = 1; - ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->harq_pid = 0; - ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->TPC = 1; - ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->padding = 0; - - rballoc |= mac_xface->get_rballoc(0,((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->rballoc); - add_common_dci(DCI_pdu, - BCCH_alloc_pdu, - SI_RNTI, - sizeof(DCI1A_10MHz_FDD_t), - 2, - sizeof_DCI1A_10MHz_FDD_t, - format1A,0); - break; - case 100: - ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->type = 1; - ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->vrb_type = 0; - ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->ndi = 1; - ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->rv = 1; - ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->harq_pid = 0; - ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->TPC = 1; - ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->padding = 0; - - rballoc |= mac_xface->get_rballoc(0,((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->rballoc); - add_common_dci(DCI_pdu, - BCCH_alloc_pdu, - SI_RNTI, - sizeof(DCI1A_20MHz_FDD_t), - 2, - sizeof_DCI1A_20MHz_FDD_t, - format1A,0); - break; - } + switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->type = 1; + ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->vrb_type = 0; + ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->ndi = 1; + ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->rv = 1; + ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->harq_pid = 0; + ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->TPC = 1; + ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->padding = 0; + + rballoc[CC_id] |= mac_xface->get_rballoc(0,((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->rballoc); + add_common_dci(DCI_pdu, + BCCH_alloc_pdu, + SI_RNTI, + sizeof(DCI1A_1_5MHz_FDD_t), + 2, + sizeof_DCI1A_1_5MHz_FDD_t, + format1A,0); + break; + case 25: + ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->type = 1; + ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->vrb_type = 0; + ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->ndi = 1; + ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->rv = 1; + ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->harq_pid = 0; + ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->TPC = 1; + ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->padding = 0; + + rballoc[CC_id] |= mac_xface->get_rballoc(0,((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->rballoc); + add_common_dci(DCI_pdu, + BCCH_alloc_pdu, + SI_RNTI, + sizeof(DCI1A_5MHz_FDD_t), + 2, + sizeof_DCI1A_5MHz_FDD_t, + format1A,0); + break; + case 50: + ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->type = 1; + ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->vrb_type = 0; + ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->ndi = 1; + ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->rv = 1; + ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->harq_pid = 0; + ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->TPC = 1; + ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->padding = 0; + + rballoc[CC_id] |= mac_xface->get_rballoc(0,((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->rballoc); + add_common_dci(DCI_pdu, + BCCH_alloc_pdu, + SI_RNTI, + sizeof(DCI1A_10MHz_FDD_t), + 2, + sizeof_DCI1A_10MHz_FDD_t, + format1A,0); + break; + case 100: + ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->type = 1; + ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->vrb_type = 0; + ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->ndi = 1; + ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->rv = 1; + ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->harq_pid = 0; + ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->TPC = 1; + ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->padding = 0; + + rballoc[CC_id] |= mac_xface->get_rballoc(0,((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->rballoc); + add_common_dci(DCI_pdu, + BCCH_alloc_pdu, + SI_RNTI, + sizeof(DCI1A_20MHz_FDD_t), + 2, + sizeof_DCI1A_20MHz_FDD_t, + format1A,0); + break; + } } - } - if (RA_scheduled == 1) { + } + if (RA_scheduledP == 1) { for (i=0;i<NB_RA_PROC_MAX;i++) { - if (eNB_mac_inst[module_idP].RA_template[i].generate_rar == 1) { - - //FK: postponed to fill_rar - //eNB_mac_inst[module_idP].RA_template[i].generate_rar = 0; - - LOG_D(MAC,"[eNB %d] Frame %d, subframeP %d: Generating RAR DCI (proc %d), RA_active %d format 1A (%d,%d))\n", - module_idP,frameP, subframeP,i, - eNB_mac_inst[module_idP].RA_template[i].RA_active, - eNB_mac_inst[module_idP].RA_template[i].RA_dci_fmt1, - eNB_mac_inst[module_idP].RA_template[i].RA_dci_size_bits1); - // randomize frequency allocation for RA - while (1) { - first_rb = (unsigned char)(taus()%(mac_xface->lte_frame_parms->N_RB_DL-4)); - if ((vrb_map[first_rb] != 1) && (vrb_map[first_rb+3] != 1)) - break; - } - vrb_map[first_rb] = 1; - vrb_map[first_rb+1] = 1; - vrb_map[first_rb+2] = 1; - vrb_map[first_rb+3] = 1; - - if (mac_xface->lte_frame_parms->frame_type == TDD) { - switch(mac_xface->lte_frame_parms->N_RB_DL) { - case 6: - ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->type=1; - ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type=0; - ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->ndi=1; - ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rv=0; - ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->mcs=0; - ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->harq_pid=0; - ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->TPC=1; - ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->padding=0; - ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - rballoc |= mac_xface->get_rballoc(((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type, - ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc); - break; - case 25: - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->type=1; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type=0; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->ndi=1; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rv=0; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->mcs=0; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->harq_pid=0; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->TPC=1; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->padding=0; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - rballoc |= mac_xface->get_rballoc(((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type, - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc); - break; - case 50: - ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->type=1; - ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type=0; - ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->ndi=1; - ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rv=0; - ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->mcs=0; - ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->harq_pid=0; - ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->TPC=1; - ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->padding=0; - ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - rballoc |= mac_xface->get_rballoc(((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type, - ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc); - break; - case 100: - ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->type=1; - ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type=0; - ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->ndi=1; - ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rv=0; - ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->mcs=0; - ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->harq_pid=0; - ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->TPC=1; - ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->padding=0; - ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - rballoc |= mac_xface->get_rballoc(((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type, - ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc); - break; - default: - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->type=1; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type=0; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->ndi=1; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rv=0; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->mcs=0; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->harq_pid=0; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->TPC=1; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->padding=0; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - rballoc |= mac_xface->get_rballoc(((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type, - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc); - break; - } - } - else { - switch(mac_xface->lte_frame_parms->N_RB_DL) { - case 6: - ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->type=1; - ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type=0; - ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->ndi=1; - ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rv=0; - ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->mcs=0; - ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->harq_pid=0; - ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->TPC=1; - ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->padding=0; - ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - rballoc |= mac_xface->get_rballoc(((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type, - ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc); - break; - case 25: - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->type=1; - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type=0; - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->ndi=1; - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rv=0; - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->mcs=0; - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->harq_pid=0; - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->TPC=1; - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->padding=0; - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_UL,first_rb,4); - rballoc |= mac_xface->get_rballoc(((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type, - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc); - break; - case 50: - ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->type=1; - ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type=0; - ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->ndi=1; - ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rv=0; - ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->mcs=0; - ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->harq_pid=0; - ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->TPC=1; - ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->padding=0; - ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - rballoc |= mac_xface->get_rballoc(((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type, - ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc); - break; - case 100: - ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->type=1; - ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type=0; - ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->ndi=1; - ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rv=0; - ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->mcs=0; - ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->harq_pid=0; - ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->TPC=1; - ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->padding=0; - ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - rballoc |= mac_xface->get_rballoc(((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type, - ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc); - break; - default: - break; - } - } - add_common_dci(DCI_pdu, - (void*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0], - eNB_mac_inst[module_idP].RA_template[i].RA_rnti, - eNB_mac_inst[module_idP].RA_template[i].RA_dci_size_bytes1, - 2, - eNB_mac_inst[module_idP].RA_template[i].RA_dci_size_bits1, - eNB_mac_inst[module_idP].RA_template[i].RA_dci_fmt1, - 1); - - - - LOG_D(MAC,"[eNB %d] Frame %d: Adding common dci for RA%d (RAR) RA_active %d\n",module_idP,frameP,i, - eNB_mac_inst[module_idP].RA_template[i].RA_active); - } - if (eNB_mac_inst[module_idP].RA_template[i].generate_Msg4_dci == 1) { - - // randomize frequency allocation for RA - while (1) { - first_rb = (unsigned char)(taus()%(mac_xface->lte_frame_parms->N_RB_DL-4)); - if ((vrb_map[first_rb] != 1) && (vrb_map[first_rb+3] != 1)) - break; - } - vrb_map[first_rb] = 1; - vrb_map[first_rb+1] = 1; - vrb_map[first_rb+2] = 1; - vrb_map[first_rb+3] = 1; - - if (mac_xface->lte_frame_parms->frame_type == TDD) { - switch (mac_xface->lte_frame_parms->N_RB_DL) { - case 6: - ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->type=1; - ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type=0; - ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rv=0; - ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->harq_pid=0; - ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->TPC=1; - ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->padding=0; - ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - rballoc |= mac_xface->get_rballoc(((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type, - ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc); - break; - case 25: - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->type=1; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type=0; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rv=0; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->harq_pid=0; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->TPC=1; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->padding=0; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - rballoc |= mac_xface->get_rballoc(((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type, - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc); - break; - case 50: - ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->type=1; - ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type=0; - ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rv=0; - ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->harq_pid=0; - ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->TPC=1; - ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->padding=0; - ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - rballoc |= mac_xface->get_rballoc(((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type, - ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc); - break; - case 100: - ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->type=1; - ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type=0; - ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rv=0; - ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->harq_pid=0; - ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->TPC=1; - ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - rballoc |= mac_xface->get_rballoc(((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type, - ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc); - break; - default: - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->type=1; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type=0; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rv=0; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->harq_pid=0; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->TPC=1; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->padding=0; - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - rballoc |= mac_xface->get_rballoc(((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type, - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc); - break; - } - } - else { - switch (mac_xface->lte_frame_parms->N_RB_DL) { - - case 6: - ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->type=1; - ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type=0; - ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rv=0; - ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->harq_pid=0; - ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->TPC=1; - ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->padding=0; - ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - rballoc |= mac_xface->get_rballoc(((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type, - ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc); - break; - case 25: - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->type=1; - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type=0; - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rv=0; - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->harq_pid=0; - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->TPC=1; - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->padding=0; - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - rballoc |= mac_xface->get_rballoc(((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type, - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc); - break; - case 50: - ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->type=1; - ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type=0; - ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rv=0; - ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->harq_pid=0; - ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->TPC=1; - ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->padding=0; - ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - rballoc |= mac_xface->get_rballoc(((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type, - ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc); - break; - case 100: - ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->type=1; - ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type=0; - ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rv=0; - ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->harq_pid=0; - ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->TPC=1; - ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->padding=0; - ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - rballoc |= mac_xface->get_rballoc(((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type, - ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc); - break; - default: - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->type=1; - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type=0; - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rv=0; - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->harq_pid=0; - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->TPC=1; - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4); - rballoc |= mac_xface->get_rballoc(((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type, - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc); - break; - } - } - - add_ue_spec_dci(DCI_pdu, - (void*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0], - eNB_mac_inst[module_idP].RA_template[i].rnti, - eNB_mac_inst[module_idP].RA_template[i].RA_dci_size_bytes2, - 1, - eNB_mac_inst[module_idP].RA_template[i].RA_dci_size_bits2, - eNB_mac_inst[module_idP].RA_template[i].RA_dci_fmt2, - 0); - LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d: Adding ue specific dci (rnti %x) for Msg4\n", - module_idP,frameP,subframeP,eNB_mac_inst[module_idP].RA_template[i].rnti); - eNB_mac_inst[module_idP].RA_template[i].generate_Msg4_dci=0; - - } - else if (eNB_mac_inst[module_idP].RA_template[i].wait_ack_Msg4==1) { - // check HARQ status and retransmit if necessary - LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d: Checking if Msg4 was acknowledged: \n", - module_idP,frameP,subframeP); - // Get candidate harq_pid from PHY - mac_xface->get_ue_active_harq_pid(module_idP,eNB_mac_inst[module_idP].RA_template[i].rnti,subframeP,&harq_pid,&round,0); - if (round>0) { - // we have to schedule a retransmission - if (mac_xface->lte_frame_parms->frame_type == TDD) - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->ndi=1; - else - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->ndi=1; - // randomize frequency allocation for RA - while (1) { - first_rb = (unsigned char)(taus()%(mac_xface->lte_frame_parms->N_RB_DL-4)); - if ((vrb_map[first_rb] != 1) && (vrb_map[first_rb+3] != 1)) - break; - } - vrb_map[first_rb] = 1; - vrb_map[first_rb+1] = 1; - vrb_map[first_rb+2] = 1; - vrb_map[first_rb+3] = 1; - if (mac_xface->lte_frame_parms->frame_type == TDD) { - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_UL,first_rb,4); - rballoc |= mac_xface->get_rballoc(((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type, - ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc); - } - else { - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_UL,first_rb,4); - rballoc |= mac_xface->get_rballoc(((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type, - ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc); - } - - add_ue_spec_dci(DCI_pdu, - (void*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0], - eNB_mac_inst[module_idP].RA_template[i].rnti, - eNB_mac_inst[module_idP].RA_template[i].RA_dci_size_bytes2, - 2, - eNB_mac_inst[module_idP].RA_template[i].RA_dci_size_bits2, - eNB_mac_inst[module_idP].RA_template[i].RA_dci_fmt2, - 0); - LOG_W(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d: Msg4 not acknowledged, adding ue specific dci (rnti %x) for RA (Msg4 Retransmission)\n", - module_idP,frameP,subframeP,eNB_mac_inst[module_idP].RA_template[i].rnti); - } - else { - LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d : Msg4 acknowledged\n",module_idP,frameP,subframeP); - eNB_mac_inst[module_idP].RA_template[i].wait_ack_Msg4=0; - eNB_mac_inst[module_idP].RA_template[i].RA_active=FALSE; - } - } - } - } // RA is scheduled in this subframeP - - // UE specific DCIs - for (ue_mod_id=0;ue_mod_id<NUMBER_OF_UE_MAX;ue_mod_id++) { - //printf("UE_id: %d => status %d\n",UE_id,eNB_dlsch_info[module_idP][UE_id].status); - if (eNB_dlsch_info[module_idP][ue_mod_id].status == S_DL_SCHEDULED) { - - // clear scheduling flag - eNB_dlsch_info[module_idP][ue_mod_id].status = S_DL_WAITING; - rnti = find_UE_RNTI(module_idP,ue_mod_id); - mac_xface->get_ue_active_harq_pid(module_idP,rnti,subframeP,&harq_pid,&round,0); - nb_rb = eNB_mac_inst[module_idP].UE_template[ue_mod_id].nb_rb[harq_pid]; - - DLSCH_dci = (void *)eNB_mac_inst[module_idP].UE_template[ue_mod_id].DLSCH_DCI[harq_pid]; - - - /// Synchronizing rballoc with rballoc_sub - for(i=0;i<mac_xface->lte_frame_parms->N_RBGS;i++){ - rballoc_sub[i] = eNB_mac_inst[module_idP].UE_template[ue_mod_id].rballoc_subband[harq_pid][i]; - if(rballoc_sub[i] == 1) - rballoc |= (0x0001<<i); // TO be FIXED!!!!!! - } - - - switch(mac_xface->get_transmission_mode(module_idP,rnti)) { - default: - - case 1: - - case 2: - LOG_D(MAC,"[USER-PLANE DEFAULT DRB] Adding UE spec DCI for %d PRBS (%x) => ",nb_rb,rballoc); - if (mac_xface->lte_frame_parms->frame_type == TDD) { - switch (mac_xface->lte_frame_parms->N_RB_DL) { - case 6: - ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); - ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->rah = 0; - size_bytes = sizeof(DCI1_1_5MHz_TDD_t); - size_bits = sizeof_DCI1_1_5MHz_TDD_t; - break; - case 25: - ((DCI1_5MHz_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); - ((DCI1_5MHz_TDD_t*)DLSCH_dci)->rah = 0; - size_bytes = sizeof(DCI1_5MHz_TDD_t); - size_bits = sizeof_DCI1_5MHz_TDD_t; - break; - case 50: - ((DCI1_10MHz_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); - ((DCI1_10MHz_TDD_t*)DLSCH_dci)->rah = 0; - size_bytes = sizeof(DCI1_10MHz_TDD_t); - size_bits = sizeof_DCI1_10MHz_TDD_t; - break; - case 100: - ((DCI1_20MHz_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); - ((DCI1_20MHz_TDD_t*)DLSCH_dci)->rah = 0; - size_bytes = sizeof(DCI1_20MHz_TDD_t); - size_bits = sizeof_DCI1_20MHz_TDD_t; - break; - default: - ((DCI1_5MHz_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); - ((DCI1_5MHz_TDD_t*)DLSCH_dci)->rah = 0; - size_bytes = sizeof(DCI1_5MHz_TDD_t); - size_bits = sizeof_DCI1_5MHz_TDD_t; - break; - } - - - } - else { - switch(mac_xface->lte_frame_parms->N_RB_DL) { - case 6: - ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); - ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->rah = 0; - size_bytes=sizeof(DCI1_1_5MHz_FDD_t); - size_bits=sizeof_DCI1_1_5MHz_FDD_t; - break; - case 25: - ((DCI1_5MHz_FDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); - ((DCI1_5MHz_FDD_t*)DLSCH_dci)->rah = 0; - size_bytes=sizeof(DCI1_5MHz_FDD_t); - size_bits=sizeof_DCI1_5MHz_FDD_t; - break; - case 50: - ((DCI1_10MHz_FDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); - ((DCI1_10MHz_FDD_t*)DLSCH_dci)->rah = 0; - size_bytes=sizeof(DCI1_10MHz_FDD_t); - size_bits=sizeof_DCI1_10MHz_FDD_t; - break; - case 100: - ((DCI1_20MHz_FDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); - ((DCI1_20MHz_FDD_t*)DLSCH_dci)->rah = 0; - size_bytes=sizeof(DCI1_20MHz_FDD_t); - size_bits=sizeof_DCI1_20MHz_FDD_t; - break; - default: - ((DCI1_5MHz_FDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); - ((DCI1_5MHz_FDD_t*)DLSCH_dci)->rah = 0; - size_bytes=sizeof(DCI1_5MHz_FDD_t); - size_bits=sizeof_DCI1_5MHz_FDD_t; - break; - } - } - - add_ue_spec_dci(DCI_pdu, - DLSCH_dci, - rnti, - size_bytes, - process_ue_cqi (module_idP,ue_mod_id),//aggregation, - size_bits, - format1, - 0); - - break; - case 4: - - //if (nb_rb>10) { - // DCI format 2_2A - ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); - ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->rah = 0; - add_ue_spec_dci(DCI_pdu, - DLSCH_dci, - rnti, - sizeof(DCI2_5MHz_2A_TDD_t), - process_ue_cqi (module_idP,ue_mod_id),//aggregation, - sizeof_DCI2_5MHz_2A_TDD_t, - format2, - 0); - /*} + RA_template = &eNB->common_channels[CC_id].RA_template[i]; + + if (RA_template->generate_rar == 1) { + + //FK: postponed to fill_rar + //RA_template->generate_rar = 0; + + LOG_D(MAC,"[eNB %d] Frame %d, subframeP %d: Generating RAR DCI (proc %d), RA_active %d format 1A (%d,%d))\n", + module_idP,frameP, subframeP,i, + RA_template->RA_active, + RA_template->RA_dci_fmt1, + RA_template->RA_dci_size_bits1); + // randomize frequency allocation for RA + while (1) { + first_rb = (unsigned char)(taus()%(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL-4)); + if ((vrb_map[first_rb] != 1) && (vrb_map[first_rb+3] != 1)) + break; + } + vrb_map[first_rb] = 1; + vrb_map[first_rb+1] = 1; + vrb_map[first_rb+2] = 1; + vrb_map[first_rb+3] = 1; + + if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) { + switch(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->type=1; + ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->vrb_type=0; + ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->ndi=1; + ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->rv=0; + ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->mcs=0; + ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->harq_pid=0; + ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->TPC=1; + ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->padding=0; + ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + rballoc[CC_id] |= mac_xface->get_rballoc(((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->vrb_type, + ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->rballoc); + break; + case 25: + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->type=1; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->vrb_type=0; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->ndi=1; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->rv=0; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->mcs=0; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->harq_pid=0; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->TPC=1; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->padding=0; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + rballoc[CC_id] |= mac_xface->get_rballoc(((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->vrb_type, + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->rballoc); + break; + case 50: + ((DCI1A_10MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->type=1; + ((DCI1A_10MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->vrb_type=0; + ((DCI1A_10MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->ndi=1; + ((DCI1A_10MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->rv=0; + ((DCI1A_10MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->mcs=0; + ((DCI1A_10MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->harq_pid=0; + ((DCI1A_10MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->TPC=1; + ((DCI1A_10MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->padding=0; + ((DCI1A_10MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + rballoc[CC_id] |= mac_xface->get_rballoc(((DCI1A_10MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->vrb_type, + ((DCI1A_10MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->rballoc); + break; + case 100: + ((DCI1A_20MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->type=1; + ((DCI1A_20MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->vrb_type=0; + ((DCI1A_20MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->ndi=1; + ((DCI1A_20MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->rv=0; + ((DCI1A_20MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->mcs=0; + ((DCI1A_20MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->harq_pid=0; + ((DCI1A_20MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->TPC=1; + ((DCI1A_20MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->padding=0; + ((DCI1A_20MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + rballoc[CC_id] |= mac_xface->get_rballoc(((DCI1A_20MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->vrb_type, + ((DCI1A_20MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->rballoc); + break; + default: + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->type=1; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->vrb_type=0; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->ndi=1; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->rv=0; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->mcs=0; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->harq_pid=0; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->TPC=1; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->padding=0; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + rballoc[CC_id] |= mac_xface->get_rballoc(((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->vrb_type, + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu1[0])->rballoc); + break; + } + } + else { + switch(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI1A_1_5MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->type=1; + ((DCI1A_1_5MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->vrb_type=0; + ((DCI1A_1_5MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->ndi=1; + ((DCI1A_1_5MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->rv=0; + ((DCI1A_1_5MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->mcs=0; + ((DCI1A_1_5MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->harq_pid=0; + ((DCI1A_1_5MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->TPC=1; + ((DCI1A_1_5MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->padding=0; + ((DCI1A_1_5MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + rballoc[CC_id] |= mac_xface->get_rballoc(((DCI1A_1_5MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->vrb_type, + ((DCI1A_1_5MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->rballoc); + break; + case 25: + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->type=1; + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->vrb_type=0; + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->ndi=1; + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->rv=0; + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->mcs=0; + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->harq_pid=0; + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->TPC=1; + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->padding=0; + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_UL,first_rb,4); + rballoc[CC_id] |= mac_xface->get_rballoc(((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->vrb_type, + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->rballoc); + break; + case 50: + ((DCI1A_10MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->type=1; + ((DCI1A_10MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->vrb_type=0; + ((DCI1A_10MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->ndi=1; + ((DCI1A_10MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->rv=0; + ((DCI1A_10MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->mcs=0; + ((DCI1A_10MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->harq_pid=0; + ((DCI1A_10MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->TPC=1; + ((DCI1A_10MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->padding=0; + ((DCI1A_10MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + rballoc[CC_id] |= mac_xface->get_rballoc(((DCI1A_10MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->vrb_type, + ((DCI1A_10MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->rballoc); + break; + case 100: + ((DCI1A_20MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->type=1; + ((DCI1A_20MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->vrb_type=0; + ((DCI1A_20MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->ndi=1; + ((DCI1A_20MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->rv=0; + ((DCI1A_20MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->mcs=0; + ((DCI1A_20MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->harq_pid=0; + ((DCI1A_20MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->TPC=1; + ((DCI1A_20MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->padding=0; + ((DCI1A_20MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + rballoc[CC_id] |= mac_xface->get_rballoc(((DCI1A_20MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->vrb_type, + ((DCI1A_20MHz_FDD_t*)&RA_template->RA_alloc_pdu1[0])->rballoc); + break; + default: + break; + } + } + add_common_dci(DCI_pdu, + (void*)&RA_template->RA_alloc_pdu1[0], + RA_template->RA_rnti, + RA_template->RA_dci_size_bytes1, + 2, + RA_template->RA_dci_size_bits1, + RA_template->RA_dci_fmt1, + 1); + + + + LOG_D(MAC,"[eNB %d] Frame %d: Adding common dci for RA%d (RAR) RA_active %d\n",module_idP,frameP,i, + RA_template->RA_active); + } + if (RA_template->generate_Msg4_dci == 1) { + + // randomize frequency allocation for RA + while (1) { + first_rb = (unsigned char)(taus()%(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL-4)); + if ((vrb_map[first_rb] != 1) && (vrb_map[first_rb+3] != 1)) + break; + } + vrb_map[first_rb] = 1; + vrb_map[first_rb+1] = 1; + vrb_map[first_rb+2] = 1; + vrb_map[first_rb+3] = 1; + + if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) { + switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->type=1; + ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->vrb_type=0; + ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->rv=0; + ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->harq_pid=0; + ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->TPC=1; + ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->padding=0; + ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + rballoc[CC_id] |= mac_xface->get_rballoc(((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->vrb_type, + ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->rballoc); + break; + case 25: + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->type=1; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->vrb_type=0; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->rv=0; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->harq_pid=0; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->TPC=1; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->padding=0; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + rballoc[CC_id] |= mac_xface->get_rballoc(((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->vrb_type, + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->rballoc); + break; + case 50: + ((DCI1A_10MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->type=1; + ((DCI1A_10MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->vrb_type=0; + ((DCI1A_10MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->rv=0; + ((DCI1A_10MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->harq_pid=0; + ((DCI1A_10MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->TPC=1; + ((DCI1A_10MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->padding=0; + ((DCI1A_10MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + rballoc[CC_id] |= mac_xface->get_rballoc(((DCI1A_10MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->vrb_type, + ((DCI1A_10MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->rballoc); + break; + case 100: + ((DCI1A_20MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->type=1; + ((DCI1A_20MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->vrb_type=0; + ((DCI1A_20MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->rv=0; + ((DCI1A_20MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->harq_pid=0; + ((DCI1A_20MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->TPC=1; + ((DCI1A_20MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + rballoc[CC_id] |= mac_xface->get_rballoc(((DCI1A_20MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->vrb_type, + ((DCI1A_20MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->rballoc); + break; + default: + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->type=1; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->vrb_type=0; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->rv=0; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->harq_pid=0; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->TPC=1; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->padding=0; + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + rballoc[CC_id] |= mac_xface->get_rballoc(((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->vrb_type, + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->rballoc); + break; + } + } else { - ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); + switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) { + + case 6: + ((DCI1A_1_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->type=1; + ((DCI1A_1_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->vrb_type=0; + ((DCI1A_1_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->rv=0; + ((DCI1A_1_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->harq_pid=0; + ((DCI1A_1_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->TPC=1; + ((DCI1A_1_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->padding=0; + ((DCI1A_1_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + rballoc[CC_id] |= mac_xface->get_rballoc(((DCI1A_1_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->vrb_type, + ((DCI1A_1_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->rballoc); + break; + case 25: + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->type=1; + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->vrb_type=0; + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->rv=0; + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->harq_pid=0; + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->TPC=1; + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->padding=0; + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + rballoc[CC_id] |= mac_xface->get_rballoc(((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->vrb_type, + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->rballoc); + break; + case 50: + ((DCI1A_10MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->type=1; + ((DCI1A_10MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->vrb_type=0; + ((DCI1A_10MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->rv=0; + ((DCI1A_10MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->harq_pid=0; + ((DCI1A_10MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->TPC=1; + ((DCI1A_10MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->padding=0; + ((DCI1A_10MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + rballoc[CC_id] |= mac_xface->get_rballoc(((DCI1A_10MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->vrb_type, + ((DCI1A_10MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->rballoc); + break; + case 100: + ((DCI1A_20MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->type=1; + ((DCI1A_20MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->vrb_type=0; + ((DCI1A_20MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->rv=0; + ((DCI1A_20MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->harq_pid=0; + ((DCI1A_20MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->TPC=1; + ((DCI1A_20MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->padding=0; + ((DCI1A_20MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + rballoc[CC_id] |= mac_xface->get_rballoc(((DCI1A_20MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->vrb_type, + ((DCI1A_20MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->rballoc); + break; + default: + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->type=1; + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->vrb_type=0; + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->rv=0; + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->harq_pid=0; + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->TPC=1; + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL,first_rb,4); + rballoc[CC_id] |= mac_xface->get_rballoc(((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->vrb_type, + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->rballoc); + break; + } + } + add_ue_spec_dci(DCI_pdu, - DLSCH_dci, - rnti, - sizeof(DCI2_5MHz_2A_L10PRB_TDD_t), - 2,//aggregation, - sizeof_DCI2_5MHz_2A_L10PRB_TDD_t, - format2_2A_L10PRB); - }*/ - break; - case 5: - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rah = 0; - - add_ue_spec_dci(DCI_pdu, - DLSCH_dci, - rnti, - sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t), - process_ue_cqi (module_idP,ue_mod_id),//aggregation, - sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t, - format1E_2A_M10PRB, - 0); - break; - - case 6: - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rah = 0; - - add_ue_spec_dci(DCI_pdu, - DLSCH_dci, - rnti, - sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t), - process_ue_cqi (module_idP,ue_mod_id),//aggregation - sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t, - format1E_2A_M10PRB, - 0); - break; - - } + (void*)&RA_template->RA_alloc_pdu2[0], + RA_template->rnti, + RA_template->RA_dci_size_bytes2, + 1, + RA_template->RA_dci_size_bits2, + RA_template->RA_dci_fmt2, + 0); + LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d: Adding ue specific dci (rnti %x) for Msg4\n", + module_idP,frameP,subframeP,RA_template->rnti); + RA_template->generate_Msg4_dci=0; + + } + else if (RA_template->wait_ack_Msg4==1) { + // check HARQ status and retransmit if necessary + LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d: Checking if Msg4 was acknowledged: \n", + module_idP,frameP,subframeP); + // Get candidate harq_pid from PHY + mac_xface->get_ue_active_harq_pid(module_idP,CC_id,RA_template->rnti,subframeP,&harq_pid,&round,0); + if (round>0) { + // we have to schedule a retransmission + if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->ndi=1; + else + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->ndi=1; + // randomize frequency allocation for RA + while (1) { + first_rb = (unsigned char)(taus()%(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL-4)); + if ((vrb_map[first_rb] != 1) && (vrb_map[first_rb+3] != 1)) + break; + } + vrb_map[first_rb] = 1; + vrb_map[first_rb+1] = 1; + vrb_map[first_rb+2] = 1; + vrb_map[first_rb+3] = 1; + if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) { + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_UL,first_rb,4); + rballoc[CC_id] |= mac_xface->get_rballoc(((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->vrb_type, + ((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->rballoc); + } + else { + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->rballoc = mac_xface->computeRIV(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_UL,first_rb,4); + rballoc[CC_id] |= mac_xface->get_rballoc(((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->vrb_type, + ((DCI1A_5MHz_FDD_t*)&RA_template->RA_alloc_pdu2[0])->rballoc); + } + + add_ue_spec_dci(DCI_pdu, + (void*)&RA_template->RA_alloc_pdu2[0], + RA_template->rnti, + RA_template->RA_dci_size_bytes2, + 2, + RA_template->RA_dci_size_bits2, + RA_template->RA_dci_fmt2, + 0); + LOG_W(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d: Msg4 not acknowledged, adding ue specific dci (rnti %x) for RA (Msg4 Retransmission)\n", + module_idP,frameP,subframeP,RA_template->rnti); + } + else { + LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d : Msg4 acknowledged\n",module_idP,frameP,subframeP); + RA_template->wait_ack_Msg4=0; + RA_template->RA_active=FALSE; + } + } } + } // RA is scheduled in this subframeP + + printf("Doing UE_spec DCIs\n"); + // UE specific DCIs + for (UE_id=UE_list->head;UE_id>=0;UE_id=UE_list->next[UE_id]) { + printf("UE_id: %d => status %d\n",UE_id,eNB_dlsch_info[module_idP][UE_id].status); + if (eNB_dlsch_info[module_idP][UE_id].status == S_DL_SCHEDULED) { + + // clear scheduling flag + eNB_dlsch_info[module_idP][UE_id].status = S_DL_WAITING; + rnti = UE_RNTI(module_idP,UE_id); + mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,subframeP,&harq_pid,&round,0); + nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + + DLSCH_dci = (void *)UE_list->UE_template[CC_id][UE_id].DLSCH_DCI[harq_pid]; + + + /// Synchronizing rballoc with rballoc_sub + for(i=0;i<PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RBGS;i++){ + rballoc_sub[i] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][i]; + if(rballoc_sub[i] == 1) + rballoc[CC_id] |= (0x0001<<i); // TO be FIXED!!!!!! + } + + + switch(mac_xface->get_transmission_mode(module_idP,CC_id,rnti)) { + default: + + case 1: + + case 2: + LOG_D(MAC,"[USER-PLANE DEFAULT DRB] Adding UE spec DCI for %d PRBS (%x) => ",nb_rb,rballoc); + if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) { + switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); + ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->rah = 0; + size_bytes = sizeof(DCI1_1_5MHz_TDD_t); + size_bits = sizeof_DCI1_1_5MHz_TDD_t; + break; + case 25: + ((DCI1_5MHz_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); + ((DCI1_5MHz_TDD_t*)DLSCH_dci)->rah = 0; + size_bytes = sizeof(DCI1_5MHz_TDD_t); + size_bits = sizeof_DCI1_5MHz_TDD_t; + break; + case 50: + ((DCI1_10MHz_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); + ((DCI1_10MHz_TDD_t*)DLSCH_dci)->rah = 0; + size_bytes = sizeof(DCI1_10MHz_TDD_t); + size_bits = sizeof_DCI1_10MHz_TDD_t; + break; + case 100: + ((DCI1_20MHz_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); + ((DCI1_20MHz_TDD_t*)DLSCH_dci)->rah = 0; + size_bytes = sizeof(DCI1_20MHz_TDD_t); + size_bits = sizeof_DCI1_20MHz_TDD_t; + break; + default: + ((DCI1_5MHz_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); + ((DCI1_5MHz_TDD_t*)DLSCH_dci)->rah = 0; + size_bytes = sizeof(DCI1_5MHz_TDD_t); + size_bits = sizeof_DCI1_5MHz_TDD_t; + break; + } + + + } + else { + switch(PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); + ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->rah = 0; + size_bytes=sizeof(DCI1_1_5MHz_FDD_t); + size_bits=sizeof_DCI1_1_5MHz_FDD_t; + break; + case 25: + ((DCI1_5MHz_FDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); + ((DCI1_5MHz_FDD_t*)DLSCH_dci)->rah = 0; + size_bytes=sizeof(DCI1_5MHz_FDD_t); + size_bits=sizeof_DCI1_5MHz_FDD_t; + break; + case 50: + ((DCI1_10MHz_FDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); + ((DCI1_10MHz_FDD_t*)DLSCH_dci)->rah = 0; + size_bytes=sizeof(DCI1_10MHz_FDD_t); + size_bits=sizeof_DCI1_10MHz_FDD_t; + break; + case 100: + ((DCI1_20MHz_FDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); + ((DCI1_20MHz_FDD_t*)DLSCH_dci)->rah = 0; + size_bytes=sizeof(DCI1_20MHz_FDD_t); + size_bits=sizeof_DCI1_20MHz_FDD_t; + break; + default: + ((DCI1_5MHz_FDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); + ((DCI1_5MHz_FDD_t*)DLSCH_dci)->rah = 0; + size_bytes=sizeof(DCI1_5MHz_FDD_t); + size_bits=sizeof_DCI1_5MHz_FDD_t; + break; + } + } + + add_ue_spec_dci(DCI_pdu, + DLSCH_dci, + rnti, + size_bytes, + process_ue_cqi (module_idP,UE_id),//aggregation, + size_bits, + format1, + 0); + + break; + case 4: + + //if (nb_rb>10) { + // DCI format 2_2A + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->rah = 0; + add_ue_spec_dci(DCI_pdu, + DLSCH_dci, + rnti, + sizeof(DCI2_5MHz_2A_TDD_t), + process_ue_cqi (module_idP,UE_id),//aggregation, + sizeof_DCI2_5MHz_2A_TDD_t, + format2, + 0); + /*} + else { + ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); + add_ue_spec_dci(DCI_pdu, + DLSCH_dci, + rnti, + sizeof(DCI2_5MHz_2A_L10PRB_TDD_t), + 2,//aggregation, + sizeof_DCI2_5MHz_2A_L10PRB_TDD_t, + format2_2A_L10PRB); + }*/ + break; + case 5: + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rah = 0; + add_ue_spec_dci(DCI_pdu, + DLSCH_dci, + rnti, + sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t), + process_ue_cqi (module_idP,UE_id),//aggregation, + sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t, + format1E_2A_M10PRB, + 0); + break; + + case 6: + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); + ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rah = 0; + + add_ue_spec_dci(DCI_pdu, + DLSCH_dci, + rnti, + sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t), + process_ue_cqi (module_idP,UE_id),//aggregation + sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t, + format1E_2A_M10PRB, + 0); + break; + + } + } + } } - stop_meas(&eNB_mac_inst[module_idP].fill_DLSCH_dci); + stop_meas(&eNB->fill_DLSCH_dci); } +unsigned char *get_dlsch_sdu(module_id_t module_idP, int CC_id, frame_t frameP, rnti_t rntiP, uint8_t TBindex) { + + int UE_id; + eNB_MAC_INST *eNB=&eNB_mac_inst[module_idP]; + + if (rntiP==SI_RNTI) { + LOG_D(MAC,"[eNB %d] Frame %d Get DLSCH sdu for BCCH \n",module_idP,frameP); + + return((unsigned char *)&eNB->common_channels[CC_id].BCCH_pdu.payload[0]); + } + else if ((UE_id = find_UE_id(module_idP,rntiP)) != UE_INDEX_INVALID ){ + LOG_D(MAC,"[eNB %d] Frame %d: CC_id %d Get DLSCH sdu for rnti %x => UE_id %d\n",module_idP,frameP,CC_id,rntiP,UE_id); + return((unsigned char *)&eNB->UE_list.DLSCH_pdu[CC_id][TBindex][UE_id].payload[0]); + } else { + LOG_E(MAC,"[eNB %d] Frame %d: CC_id %d UE with RNTI %x does not exist\n", module_idP,frameP,CC_id,rntiP); + return NULL; + } + +} diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index a567d8af9b..96e0e12af3 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -90,46 +90,57 @@ void init_ue_sched_info(void){ -unsigned char get_ue_weight(module_id_t module_idP, module_id_t ue_mod_idP){ +unsigned char get_ue_weight(module_id_t module_idP, int ue_idP){ - return(eNB_dlsch_info[module_idP][ue_mod_idP].weight); + return(eNB_dlsch_info[module_idP][ue_idP].weight); } -DCI_PDU *get_dci_sdu(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { +DCI_PDU *get_dci_sdu(module_id_t module_idP, int CC_id,frame_t frameP, sub_frame_t subframeP) { - return(&eNB_mac_inst[module_idP].DCI_pdu); + return(&eNB_mac_inst[module_idP].common_channels[CC_id].DCI_pdu); } -module_id_t find_UE_id(module_id_t module_idP, rnti_t rnti) { +int find_UE_id(module_id_t mod_idP, rnti_t rntiP) { - module_id_t ue_mod_id; - - for (ue_mod_id=0;ue_mod_id<NUMBER_OF_UE_MAX;ue_mod_id++) { - // if (mac_get_rrc_status(module_idP,1,ue_mod_id) >= RRC_CONNECTED) { - if (eNB_mac_inst[module_idP].UE_template[ue_mod_id].rnti==rnti) { - return(ue_mod_id); - } + int UE_id; + UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list; + + for (UE_id=UE_list->head;UE_id>=0;UE_id=UE_list->next[UE_id]){ + if (UE_list->UE_template[UE_PCCID(mod_idP,UE_id)][UE_id].rnti==rntiP) { + return(UE_id); + } } - return(module_id_t)(-1); + return(-1); } +int UE_num_active_CC(UE_list_t *listP,int ue_idP) { + return(listP->numactiveCCs[ue_idP]); +} +int UE_PCCID(module_id_t mod_idP,int ue_idP) { + return(eNB_mac_inst[mod_idP].UE_list.pCC_id[ue_idP]); +} -rnti_t find_UE_RNTI(module_id_t module_idP, module_id_t ue_mod_idP) { +rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP) { - return (eNB_mac_inst[module_idP].UE_template[ue_mod_idP].rnti); + rnti_t rnti = eNB_mac_inst[mod_idP].UE_list.UE_template[UE_PCCID(mod_idP,ue_idP)][ue_idP].rnti; + if (rnti>0) + return (rnti); + LOG_E(MAC,"[eNB %d] Couldn't find RNTI for UE %d\n",mod_idP,ue_idP); + mac_xface->macphy_exit(""); + return(0); } -boolean_t is_UE_active(module_id_t module_idP, module_id_t ue_mod_idP ){ - if (eNB_mac_inst[module_idP].UE_template[ue_mod_idP].rnti !=0 ) - return TRUE; - else - return FALSE ; + +boolean_t is_UE_active(module_id_t mod_idP, int ue_idP){ + return(eNB_mac_inst[mod_idP].UE_list.active[ue_idP]); } -uint8_t find_active_UEs(module_id_t module_idP){ + +/* +uint8_t find_active_UEs(module_id_t module_idP,int CC_id){ module_id_t ue_mod_id = 0; rnti_t rnti = 0; @@ -137,110 +148,189 @@ uint8_t find_active_UEs(module_id_t module_idP){ for (ue_mod_id=0;ue_mod_id<NUMBER_OF_UE_MAX;ue_mod_id++) { - if (((rnti=eNB_mac_inst[module_idP].UE_template[ue_mod_id].rnti) !=0)&&(eNB_mac_inst[module_idP].UE_template[ue_mod_id].ul_active==TRUE)){ + if (((rnti=eNB_mac_inst[module_idP][CC_id].UE_template[ue_mod_id].rnti) !=0)&&(eNB_mac_inst[module_idP][CC_id].UE_template[ue_mod_id].ul_active==TRUE)){ if (mac_xface->get_eNB_UE_stats(module_idP,rnti) != NULL){ // check at the phy enb_ue state for this rnti nb_active_ue++; } else { // this ue is removed at the phy => remove it at the mac as well - mac_remove_ue(module_idP, ue_mod_id); + mac_remove_ue(module_idP, CC_id, ue_mod_id); } } } return(nb_active_ue); } - +*/ // get aggregatiob form phy for a give UE -unsigned char process_ue_cqi (module_id_t module_idP, module_id_t ue_mod_idP) { +unsigned char process_ue_cqi (module_id_t module_idP, int ue_idP) { unsigned char aggregation=2; // check the MCS and SNR and set the aggregation accordingly return aggregation; } #ifdef CBA -uint8_t find_num_active_UEs_in_cbagroup(module_id_t module_idP, unsigned char group_id){ +uint8_t find_num_active_UEs_in_cbagroup(module_id_t module_idP, int CC_id,unsigned char group_id){ module_id_t UE_id; rnti_t rnti; unsigned char nb_ue_in_pusch=0; LTE_eNB_UE_stats* eNB_UE_stats; - for (UE_id=group_id;UE_id<NUMBER_OF_UE_MAX;UE_id+=eNB_mac_inst[module_idP].num_active_cba_groups) { + for (UE_id=group_id;UE_id<NUMBER_OF_UE_MAX;UE_id+=eNB_mac_inst[module_idP][CC_id].num_active_cba_groups) { - if (((rnti=eNB_mac_inst[module_idP].UE_template[UE_id].rnti) !=0) && - (eNB_mac_inst[module_idP].UE_template[UE_id].ul_active==TRUE) && + if (((rnti=eNB_mac_inst[module_idP][CC_id].UE_template[UE_id].rnti) !=0) && + (eNB_mac_inst[module_idP][CC_id].UE_template[UE_id].ul_active==TRUE) && (mac_get_rrc_status(module_idP,1,UE_id) > RRC_CONNECTED)){ - // && (UE_is_to_be_scheduled(module_idP,UE_id))) - // check at the phy enb_ue state for this rnti - if ((eNB_UE_stats= mac_xface->get_eNB_UE_stats(module_idP,rnti)) != NULL){ - if ((eNB_UE_stats->mode == PUSCH) && (UE_is_to_be_scheduled(module_idP,UE_id) == 0)){ - nb_ue_in_pusch++; - } - } + // && (UE_is_to_be_scheduled(module_idP,UE_id))) + // check at the phy enb_ue state for this rnti + if ((eNB_UE_stats= mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti)) != NULL){ + if ((eNB_UE_stats->mode == PUSCH) && (UE_is_to_be_scheduled(module_idP,UE_id) == 0)){ + nb_ue_in_pusch++; + } + } } } return(nb_ue_in_pusch); } #endif -int8_t add_new_ue(module_id_t enb_mod_idP, rnti_t rntiP) { - module_id_t ue_mod_id; - int j; +int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP) { + int UE_id; + int j; - for (ue_mod_id=0;ue_mod_id<NUMBER_OF_UE_MAX;ue_mod_id++) { - if (eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].rnti == 0) { - eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].rnti = rntiP; - for (j=0;j<8;j++) { - eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].oldNDI[j] = 0; - eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].oldNDI_UL[j] = 0; - } - eNB_ulsch_info[enb_mod_idP][ue_mod_id].status = S_UL_WAITING; - eNB_dlsch_info[enb_mod_idP][ue_mod_id].status = S_UL_WAITING; - LOG_D(MAC,"[eNB] Add UE_id %d : rnti %x\n",ue_mod_id,eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].rnti); - return((int8_t)ue_mod_id); - } + UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list; + + LOG_D(MAC,"[eNB %d, CC_id %d] Adding UE with rnti %x (next avail %d, num_UEs %d)\n",mod_idP,cc_idP,rntiP,UE_list->avail,UE_list->num_UEs); + + if (UE_list->avail>=0) { + UE_id = UE_list->avail; + UE_list->avail = UE_list->next[UE_list->avail]; + UE_list->next[UE_id] = UE_list->head; + UE_list->head = UE_id; + + UE_list->UE_template[cc_idP][UE_id].rnti = rntiP; + UE_list->numactiveCCs[UE_id] = 1; + UE_list->numactiveULCCs[UE_id] = 1; + UE_list->pCC_id[UE_id] = cc_idP; + UE_list->ordered_CCids[0][UE_id] = cc_idP; + UE_list->ordered_ULCCids[0][UE_id] = cc_idP; + UE_list->num_UEs++; + UE_list->active[UE_id] = TRUE; + + for (j=0;j<8;j++) { + UE_list->UE_template[cc_idP][UE_id].oldNDI[j] = 0; + UE_list->UE_template[cc_idP][UE_id].oldNDI_UL[j] = 0; + } + eNB_ulsch_info[mod_idP][UE_id].status = S_UL_WAITING; + eNB_dlsch_info[mod_idP][UE_id].status = S_UL_WAITING; + LOG_D(MAC,"[eNB %d] Add UE_id %d on Primary CC_id %d: rnti %x\n",mod_idP,UE_id,cc_idP,rntiP); + return(UE_id); } return(-1); } -int8_t mac_remove_ue(module_id_t enb_mod_idP, module_id_t ue_mod_idP) { +int mac_remove_ue(module_id_t mod_idP, int ue_idP) { + + int prev,i; + + UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list; + int pCC_id = UE_PCCID(mod_idP,ue_idP); - LOG_I(MAC,"Removing UE %d (rnti %x)\n",ue_mod_idP,eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].rnti); + LOG_I(MAC,"Removing UE %d from Primary CC_id %d (rnti %x)\n",ue_idP,pCC_id, UE_list->UE_template[pCC_id][ue_idP].rnti); // clear all remaining pending transmissions - eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].bsr_info[LCGID0] = 0; - eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].bsr_info[LCGID1] = 0; - eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].bsr_info[LCGID2] = 0; - eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].bsr_info[LCGID3] = 0; - - eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].ul_SR = 0; - eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].rnti = 0; - eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].ul_active = FALSE; - eNB_ulsch_info[enb_mod_idP][ue_mod_idP].rnti = 0; - eNB_ulsch_info[enb_mod_idP][ue_mod_idP].status = S_UL_NONE; - eNB_dlsch_info[enb_mod_idP][ue_mod_idP].rnti = 0; - eNB_dlsch_info[enb_mod_idP][ue_mod_idP].status = S_DL_NONE; - - rrc_eNB_free_UE_index(enb_mod_idP,ue_mod_idP); - - return(1); + UE_list->UE_template[pCC_id][ue_idP].bsr_info[LCGID0] = 0; + UE_list->UE_template[pCC_id][ue_idP].bsr_info[LCGID1] = 0; + UE_list->UE_template[pCC_id][ue_idP].bsr_info[LCGID2] = 0; + UE_list->UE_template[pCC_id][ue_idP].bsr_info[LCGID3] = 0; + + UE_list->UE_template[pCC_id][ue_idP].ul_SR = 0; + UE_list->UE_template[pCC_id][ue_idP].rnti = 0; + UE_list->UE_template[pCC_id][ue_idP].ul_active = FALSE; + eNB_ulsch_info[mod_idP][ue_idP].rnti = 0; + eNB_ulsch_info[mod_idP][ue_idP].status = S_UL_NONE; + eNB_dlsch_info[mod_idP][ue_idP].rnti = 0; + eNB_dlsch_info[mod_idP][ue_idP].status = S_DL_NONE; + + rrc_eNB_free_UE_index(mod_idP,ue_idP); + + prev = UE_list->head; + for (i=UE_list->head;i>=0;i=UE_list->next[i]) { + if (i == ue_idP) { + // link prev to next in Active list + if (prev==UE_list->head) + UE_list->head = UE_list->next[i]; + else + UE_list->next[prev] = UE_list->next[i]; + // add UE id (i)to available + UE_list->next[i] = UE_list->avail; + UE_list->avail = i; + UE_list->active[i] = FALSE; + return(0); + } + prev=i; + } + + UE_list->num_UEs--; + + return(-1); + } +int prev(UE_list_t *listP, int nodeP) { + int j; + if (nodeP==listP->head) + return(nodeP); + for (j=listP->head;j>=0;j=listP->next[j]) { + if (listP->next[j]==nodeP) + return(j); + } + LOG_E(MAC,"error in prev(), could not find previous in UE_list, should never happen\n"); + return(-1); +} -void SR_indication(module_id_t enb_mod_idP, frame_t frameP, rnti_t rntiP, sub_frame_t subframeP) { +void swap_UEs(UE_list_t *listP,int nodeiP, int nodejP) { - module_id_t ue_mod_id = find_UE_id(enb_mod_idP, rntiP); - - if (ue_mod_id != UE_INDEX_INVALID ) { - LOG_D(MAC,"[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d \n",enb_mod_idP,rntiP,frameP,subframeP, ue_mod_id); - eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].ul_SR = 1; - eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].ul_active = TRUE; + int prev_i,prev_j,next_i; + + prev_i = prev(listP,nodeiP); + prev_j = prev(listP,nodejP); + + next_i = listP->next[nodeiP]; + listP->next[nodeiP] = listP->next[nodejP]; + listP->next[nodejP] = next_i; + + if (nodeiP==listP->head) { + listP->head=nodejP; + } + else { + listP->next[prev_i] = nodejP; + } + + if (nodejP==listP->head) { + listP->head=nodeiP; + } + else { + listP->next[prev_j] = nodeiP; + } + +} + +void SR_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, rnti_t rntiP, sub_frame_t subframeP) { + + int UE_id = find_UE_id(mod_idP, rntiP); + UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list; + + if (UE_id != UE_INDEX_INVALID ) { + LOG_D(MAC,"[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d on CC_id %d\n",mod_idP,rntiP,frameP,subframeP, UE_id,cc_idP); + UE_list->UE_template[cc_idP][UE_id].ul_SR = 1; + UE_list->UE_template[cc_idP][UE_id].ul_active = TRUE; } else { // AssertFatal(0, "find_UE_id(%u,rnti %d) not found", enb_mod_idP, rntiP); // AssertError(0, 0, "Frame %d: find_UE_id(%u,rnti %d) not found\n", frameP, enb_mod_idP, rntiP); - LOG_D(MAC,"[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d (unknown UEid) \n",enb_mod_idP,rntiP,frameP,subframeP, ue_mod_id); + LOG_D(MAC,"[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d (unknown UEid) \n",mod_idP,rntiP,frameP,subframeP, UE_id); } } @@ -397,17 +487,18 @@ void add_ue_spec_dci(DCI_PDU *DCI_pdu,void *pdu,rnti_t rnti,unsigned char dci_si // This has to be updated to include BSR information -uint8_t UE_is_to_be_scheduled(module_id_t module_idP,uint8_t UE_id) { +uint8_t UE_is_to_be_scheduled(module_id_t module_idP,int CC_id,uint8_t UE_id) { + UE_TEMPLATE *UE_template = &eNB_mac_inst[module_idP].UE_list.UE_template[CC_id][UE_id]; // LOG_D(MAC,"[eNB %d][PUSCH] Frame %d subframeP %d Scheduling UE %d\n",module_idP,rnti,frameP,subframeP, // UE_id); - if ((eNB_mac_inst[module_idP].UE_template[UE_id].bsr_info[LCGID0]>0) || - (eNB_mac_inst[module_idP].UE_template[UE_id].bsr_info[LCGID1]>0) || - (eNB_mac_inst[module_idP].UE_template[UE_id].bsr_info[LCGID2]>0) || - (eNB_mac_inst[module_idP].UE_template[UE_id].bsr_info[LCGID3]>0) || - (eNB_mac_inst[module_idP].UE_template[UE_id].ul_SR>0)) // uplink scheduling request + if ((UE_template->bsr_info[LCGID0]>0) || + (UE_template->bsr_info[LCGID1]>0) || + (UE_template->bsr_info[LCGID2]>0) || + (UE_template->bsr_info[LCGID3]>0) || + (UE_template->ul_SR>0)) // uplink scheduling request return(1); else return(0); @@ -416,7 +507,7 @@ uint8_t UE_is_to_be_scheduled(module_id_t module_idP,uint8_t UE_id) { -uint32_t allocate_prbs(module_id_t ue_mod_idP,unsigned char nb_rb, uint32_t *rballoc) { +uint32_t allocate_prbs(int UE_id,unsigned char nb_rb, uint32_t *rballoc) { int i; uint32_t rballoc_dci=0; @@ -487,9 +578,9 @@ uint32_t allocate_prbs_sub(int nb_rb, uint8_t *rballoc) { -void update_ul_dci(module_id_t module_idP,rnti_t rnti,uint8_t dai) { +void update_ul_dci(module_id_t module_idP,int CC_id,rnti_t rnti,uint8_t dai) { - DCI_PDU *DCI_pdu = &eNB_mac_inst[module_idP].DCI_pdu; + DCI_PDU *DCI_pdu = &eNB_mac_inst[module_idP].common_channels[CC_id].DCI_pdu; int i; DCI0_5MHz_TDD_1_6_t *ULSCH_dci = NULL;; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 46fe22f64a..3ff6093711 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -73,6 +73,197 @@ // This table holds the allowable PRB sizes for ULSCH transmissions uint8_t rb_table[33] = {1,2,3,4,5,6,8,9,10,12,15,16,18,20,24,25,27,30,32,36,40,45,48,50,54,60,72,75,80,81,90,96,100}; +void rx_sdu(module_id_t enb_mod_idP,int CC_id,frame_t frameP,rnti_t rntiP,uint8_t *sdu, uint16_t sdu_len) { + + unsigned char rx_ces[MAX_NUM_CE],num_ce,num_sdu,i,*payload_ptr; + unsigned char rx_lcids[NB_RB_MAX]; + unsigned short rx_lengths[NB_RB_MAX]; + int UE_id = find_UE_id(enb_mod_idP,rntiP); + int ii,j; + eNB_MAC_INST *eNB = &eNB_mac_inst[enb_mod_idP]; + UE_list_t *UE_list= &eNB->UE_list; + + start_meas(&eNB->rx_ulsch_sdu); + + if ((UE_id > NUMBER_OF_UE_MAX) || (UE_id == -1) ) + for(ii=0; ii<NB_RB_MAX; ii++) rx_lengths[ii] = 0; + + vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,1); + + LOG_D(MAC,"[eNB %d] Received ULSCH sdu from PHY (rnti %x, UE_id %d), parsing header\n",enb_mod_idP,rntiP,UE_id); + payload_ptr = parse_ulsch_header(sdu,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,sdu_len); + + // control element + for (i=0;i<num_ce;i++) { + + switch (rx_ces[i]) { // implement and process BSR + CRNTI + + case POWER_HEADROOM: + if (UE_id != UE_INDEX_INVALID ){ + UE_list->UE_template[CC_id][UE_id].phr_info = (payload_ptr[0] & 0x3f);// - PHR_MAPPING_OFFSET; + LOG_D(MAC, "[eNB] MAC CE_LCID %d : Received PHR PH = %d (db)\n", rx_ces[i], UE_list->UE_template[CC_id][UE_id].phr_info); + } + payload_ptr+=sizeof(POWER_HEADROOM_CMD); + break; + case CRNTI: + LOG_D(MAC, "[eNB] MAC CE_LCID %d : Received CRNTI %d \n", rx_ces[i], payload_ptr[0]); + payload_ptr+=1; + break; + case TRUNCATED_BSR: + case SHORT_BSR: { + if (UE_id != UE_INDEX_INVALID ){ + uint8_t lcgid; + lcgid = (payload_ptr[0] >> 6); + LOG_D(MAC, "[eNB] MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", + rx_ces[i], lcgid, payload_ptr[0] & 0x3f); + UE_list->UE_template[CC_id][UE_id].bsr_info[lcgid] = (payload_ptr[0] & 0x3f); + } + payload_ptr += 1;//sizeof(SHORT_BSR); // fixme + } break; + case LONG_BSR: + if (UE_id != UE_INDEX_INVALID ){ + UE_list->UE_template[CC_id][UE_id].bsr_info[LCGID0] = ((payload_ptr[0] & 0xFC) >> 2); + UE_list->UE_template[CC_id][UE_id].bsr_info[LCGID1] = + ((payload_ptr[0] & 0x03) << 4) | ((payload_ptr[1] & 0xF0) >> 4); + UE_list->UE_template[CC_id][UE_id].bsr_info[LCGID2] = + ((payload_ptr[1] & 0x0F) << 2) | ((payload_ptr[2] & 0xC0) >> 6); + UE_list->UE_template[CC_id][UE_id].bsr_info[LCGID3] = (payload_ptr[2] & 0x3F); + LOG_D(MAC, "[eNB] MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = " + "%u LCGID2 = %u LCGID3 = %u\n", + rx_ces[i], + UE_list->UE_template[CC_id][UE_id].bsr_info[LCGID0], + UE_list->UE_template[CC_id][UE_id].bsr_info[LCGID1], + UE_list->UE_template[CC_id][UE_id].bsr_info[LCGID2], + UE_list->UE_template[CC_id][UE_id].bsr_info[LCGID3]); + } + payload_ptr += 3;////sizeof(LONG_BSR); + break; + default: + LOG_E(MAC, "[eNB] Received unknown MAC header (0x%02x)\n", rx_ces[i]); + break; + } + } + + for (i=0;i<num_sdu;i++) { + LOG_D(MAC,"SDU Number %d MAC Subheader SDU_LCID %d, length %d\n",i,rx_lcids[i],rx_lengths[i]); + + switch (rx_lcids[i]) { + case CCCH : + LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, Received CCCH: %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n", + enb_mod_idP,frameP, + payload_ptr[0],payload_ptr[1],payload_ptr[2],payload_ptr[3],payload_ptr[4], payload_ptr[5], rntiP); + + for (ii=0;ii<NB_RA_PROC_MAX;ii++) { + LOG_D(MAC,"[RAPROC] Checking proc %d : rnti (%x, %x), active %d\n",ii, + eNB->common_channels[CC_id].RA_template[ii].rnti, rntiP, + eNB->common_channels[CC_id].RA_template[ii].RA_active); + + if ((eNB->common_channels[CC_id].RA_template[ii].rnti==rntiP) && + (eNB->common_channels[CC_id].RA_template[ii].RA_active==TRUE)) { + + //payload_ptr = parse_ulsch_header(msg3,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,msg3_len); + + if (UE_id < 0) { + memcpy(&eNB->common_channels[CC_id].RA_template[ii].cont_res_id[0],payload_ptr,6); + LOG_I(MAC,"[eNB %d][RAPROC] Frame %d CCCH: Received RRCConnectionRequest: length %d, offset %d\n", + enb_mod_idP,frameP,rx_lengths[ii],payload_ptr-sdu); + if ((UE_id=add_new_ue(enb_mod_idP,CC_id,eNB->common_channels[CC_id].RA_template[ii].rnti)) == -1 ) + mac_xface->macphy_exit("[MAC][eNB] Max user count reached\n"); + else + LOG_I(MAC,"[eNB %d][RAPROC] Frame %d Added user with rnti %x => UE %d\n", + enb_mod_idP,frameP,eNB->common_channels[CC_id].RA_template[ii].rnti,UE_id); + } else { + LOG_I(MAC,"[eNB %d][RAPROC] Frame %d CCCH: Received RRCConnectionReestablishment from UE %d: length %d, offset %d\n", + enb_mod_idP,frameP,UE_id,rx_lengths[ii],payload_ptr-sdu); + } + + if (Is_rrc_registered == 1) + mac_rrc_data_ind(enb_mod_idP,frameP,CCCH,(uint8_t *)payload_ptr,rx_lengths[ii],1,enb_mod_idP,0); + + + if (num_ce >0) { // handle msg3 which is not RRCConnectionRequest + // process_ra_message(msg3,num_ce,rx_lcids,rx_ces); + } + + eNB->common_channels[CC_id].RA_template[ii].generate_Msg4 = 1; + eNB->common_channels[CC_id].RA_template[ii].wait_ack_Msg4 = 0; + + + } // if process is active + + } // loop on RA processes + + break; + case DCCH : + case DCCH1 : + // if(eNB_mac_inst[module_idP][CC_id].Dcch_lchan[UE_id].Active==1){ + +#if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sdu)); + for (j=0;j<32;j++) + LOG_T(MAC,"%x ",payload_ptr[j]); + LOG_T(MAC,"\n"); +#endif + + // This check is just to make sure we didn't get a bogus SDU length, to be removed ... + if (rx_lengths[i]<CCCH_PAYLOAD_SIZE_MAX) { + LOG_D(MAC,"[eNB %d] Frame %d : ULSCH -> UL-DCCH, received %d bytes form UE %d on LCID %d(%d) \n", + enb_mod_idP,frameP, rx_lengths[i], UE_id, rx_lcids[i], rx_lcids[i]); + + mac_rlc_data_ind(enb_mod_idP,UE_id, frameP,ENB_FLAG_YES,MBMS_FLAG_NO, + rx_lcids[i], + (char *)payload_ptr, + rx_lengths[i], + 1, + NULL);//(unsigned int*)crc_status); + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_rx[rx_lcids[i]]+=1; + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_rx[rx_lcids[i]]+=rx_lengths[i]; + + } + // } + break; + case DTCH: // default DRB + // if(eNB_mac_inst[module_idP][CC_id].Dcch_lchan[UE_id].Active==1){ + +#if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sdu)); + for (j=0;j<32;j++) + LOG_T(MAC,"%x ",payload_ptr[j]); + LOG_T(MAC,"\n"); +#endif + + LOG_D(MAC,"[eNB %d] Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d (%d)\n", + enb_mod_idP,frameP, rx_lengths[i], UE_id,rx_lcids[i],rx_lcids[i]); + + if ((rx_lengths[i] <SCH_PAYLOAD_SIZE_MAX) && (rx_lengths[i] > 0) ) { // MAX SIZE OF transport block + mac_rlc_data_ind(enb_mod_idP,UE_id, frameP,ENB_FLAG_YES,MBMS_FLAG_NO, + DTCH, + (char *)payload_ptr, + rx_lengths[i], + 1, + NULL);//(unsigned int*)crc_status); + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_rx[rx_lcids[i]]+=1; + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_rx[rx_lcids[i]]+=rx_lengths[i]; + + } + // } + break; + default : //if (rx_lcids[i] >= DTCH) { + UE_list->eNB_UE_stats[CC_id][UE_id].num_errors_rx+=1; + LOG_E(MAC,"[eNB %d] received unsupported or unknown LCID %d from UE %d ", rx_lcids[i], UE_id); + break; + } + payload_ptr+=rx_lengths[i]; + + } + + UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes_rx+=sdu_len; + UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus_rx+=1; + + vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,0); + stop_meas(&eNB->rx_ulsch_sdu); +} + + uint32_t bytes_to_bsr_index(int32_t nbytes) { uint32_t i=0; @@ -81,52 +272,54 @@ uint32_t bytes_to_bsr_index(int32_t nbytes) { return(0); while ((i<BSR_TABLE_SIZE)&& - (BSR_TABLE[i]<=nbytes)){ - i++; + (BSR_TABLE[i]<=nbytes)){ + i++; } return(i-1); } -void add_ue_ulsch_info(module_id_t module_idP, module_id_t ue_mod_idP, sub_frame_t subframeP, UE_ULSCH_STATUS status){ +void add_ue_ulsch_info(module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframeP, UE_ULSCH_STATUS status){ - eNB_ulsch_info[module_idP][ue_mod_idP].rnti = find_UE_RNTI(module_idP,ue_mod_idP); - eNB_ulsch_info[module_idP][ue_mod_idP].subframe = subframeP; - eNB_ulsch_info[module_idP][ue_mod_idP].status = status; + eNB_ulsch_info[module_idP][UE_id].rnti = UE_RNTI(module_idP,UE_id); + eNB_ulsch_info[module_idP][UE_id].subframe = subframeP; + eNB_ulsch_info[module_idP][UE_id].status = status; - eNB_ulsch_info[module_idP][ue_mod_idP].serving_num++; + eNB_ulsch_info[module_idP][UE_id].serving_num++; } -module_id_t schedule_next_ulue(module_id_t module_idP, module_id_t ue_mod_idP, sub_frame_t subframeP){ +// This seems not to be used anymore +/* +int schedule_next_ulue(module_id_t module_idP, int UE_id, sub_frame_t subframeP){ - module_id_t next_ue; + int next_ue; // first phase: scheduling for ACK switch (subframeP) { - // scheduling for subframeP 2: for scheduled user during subframeP 5 and 6 + // scheduling for subframeP 2: for scheduled user during subframeP 5 and 6 case 8: - if ((eNB_dlsch_info[module_idP][ue_mod_idP].status == S_DL_SCHEDULED) && - (eNB_dlsch_info[module_idP][ue_mod_idP].subframe == 5 || eNB_dlsch_info[module_idP][ue_mod_idP].subframe == 6)){ - // set the downlink status - eNB_dlsch_info[module_idP][ue_mod_idP].status = S_DL_BUFFERED; - return ue_mod_idP; + if ((eNB_dlsch_info[module_idP][UE_id].status == S_DL_SCHEDULED) && + (eNB_dlsch_info[module_idP][UE_id].subframe == 5 || eNB_dlsch_info[module_idP][UE_id].subframe == 6)){ + // set the downlink status + eNB_dlsch_info[module_idP][UE_id].status = S_DL_BUFFERED; + return UE_id; } break; // scheduling for subframeP 3: for scheduled user during subframeP 7 and 8 case 9: - if ((eNB_dlsch_info[module_idP][ue_mod_idP].status == S_DL_SCHEDULED) && - (eNB_dlsch_info[module_idP][ue_mod_idP].subframe == 7 || eNB_dlsch_info[module_idP][ue_mod_idP].subframe == 8)){ - eNB_dlsch_info[module_idP][ue_mod_idP].status = S_DL_BUFFERED; - return ue_mod_idP; + if ((eNB_dlsch_info[module_idP][UE_id].status == S_DL_SCHEDULED) && + (eNB_dlsch_info[module_idP][UE_id].subframe == 7 || eNB_dlsch_info[module_idP][UE_id].subframe == 8)){ + eNB_dlsch_info[module_idP][UE_id].status = S_DL_BUFFERED; + return UE_id; } break; // scheduling UL subframeP 4: for scheduled user during subframeP 9 and 0 case 0 : - if ((eNB_dlsch_info[module_idP][ue_mod_idP].status == S_DL_SCHEDULED) && - (eNB_dlsch_info[module_idP][ue_mod_idP].subframe == 9 || eNB_dlsch_info[module_idP][ue_mod_idP].subframe == 0)){ - eNB_dlsch_info[module_idP][ue_mod_idP].status = S_DL_BUFFERED; - return ue_mod_idP; + if ((eNB_dlsch_info[module_idP][UE_id].status == S_DL_SCHEDULED) && + (eNB_dlsch_info[module_idP][UE_id].subframe == 9 || eNB_dlsch_info[module_idP][UE_id].subframe == 0)){ + eNB_dlsch_info[module_idP][UE_id].status = S_DL_BUFFERED; + return UE_id; } break; default: @@ -136,33 +329,33 @@ module_id_t schedule_next_ulue(module_id_t module_idP, module_id_t ue_mod_idP, s // second phase for (next_ue=0; next_ue <NUMBER_OF_UE_MAX; next_ue++ ){ - if (eNB_ulsch_info[module_idP][next_ue].status == S_UL_WAITING ) - return next_ue; - else if (eNB_ulsch_info[module_idP][next_ue].status == S_UL_SCHEDULED){ - eNB_ulsch_info[module_idP][next_ue].status = S_UL_BUFFERED; - } + if (eNB_ulsch_info[module_idP][next_ue].status == S_UL_WAITING ) + return next_ue; + else if (eNB_ulsch_info[module_idP][next_ue].status == S_UL_SCHEDULED){ + eNB_ulsch_info[module_idP][next_ue].status = S_UL_BUFFERED; + } } for (next_ue=0; next_ue <NUMBER_OF_UE_MAX; next_ue++ ){ - if (eNB_ulsch_info[module_idP][next_ue].status != S_UL_NONE )// do this just for active UEs - eNB_ulsch_info[module_idP][next_ue].status = S_UL_WAITING; + if (eNB_ulsch_info[module_idP][next_ue].status != S_UL_NONE )// do this just for active UEs + eNB_ulsch_info[module_idP][next_ue].status = S_UL_WAITING; } next_ue = 0; return next_ue; } - +*/ unsigned char *parse_ulsch_header(unsigned char *mac_header, - unsigned char *num_ce, - unsigned char *num_sdu, - unsigned char *rx_ces, - unsigned char *rx_lcids, - unsigned short *rx_lengths, - unsigned short tb_length) { + unsigned char *num_ce, + unsigned char *num_sdu, + unsigned char *rx_ces, + unsigned char *rx_lcids, + unsigned short *rx_lengths, + unsigned short tb_length) { unsigned char not_done=1,num_ces=0,num_sdus=0,lcid,num_sdu_cnt; unsigned char *mac_header_ptr = mac_header; @@ -170,53 +363,53 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header, while (not_done==1) { - if (((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E == 0) - not_done = 0; - - lcid = ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID; - if (lcid < EXTENDED_POWER_HEADROOM) { - if (not_done==0) { // last MAC SDU, length is implicit - mac_header_ptr++; - length = tb_length-(mac_header_ptr-mac_header)-ce_len; - for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++) - length -= rx_lengths[num_sdu_cnt]; - } - else { - if (((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F == 0) { - length = ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L; - mac_header_ptr += 2;//sizeof(SCH_SUBHEADER_SHORT); - } - else { // F = 1 - length = ((((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB & 0x7f ) << 8 ) | (((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB & 0xff); - mac_header_ptr += 3;//sizeof(SCH_SUBHEADER_LONG); - } - } - LOG_D(MAC,"[eNB] sdu %d lcid %d tb_length %d length %d (offset now %d)\n", - num_sdus,lcid,tb_length, length,mac_header_ptr-mac_header); - rx_lcids[num_sdus] = lcid; - rx_lengths[num_sdus] = length; - num_sdus++; + if (((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E == 0) + not_done = 0; + + lcid = ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID; + if (lcid < EXTENDED_POWER_HEADROOM) { + if (not_done==0) { // last MAC SDU, length is implicit + mac_header_ptr++; + length = tb_length-(mac_header_ptr-mac_header)-ce_len; + for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++) + length -= rx_lengths[num_sdu_cnt]; } - else { // This is a control element subheader POWER_HEADROOM, BSR and CRNTI - if (lcid == SHORT_PADDING) { - mac_header_ptr++; - } - else { - rx_ces[num_ces] = lcid; - num_ces++; - mac_header_ptr++; - if (lcid==LONG_BSR) - ce_len+=3; - else if (lcid==CRNTI) - ce_len+=2; - else if ((lcid==POWER_HEADROOM) || (lcid==TRUNCATED_BSR)|| (lcid== SHORT_BSR)) - ce_len++; - else { - LOG_E(MAC,"unknown CE %d \n", lcid); - exit(-1); - } - } + else { + if (((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F == 0) { + length = ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L; + mac_header_ptr += 2;//sizeof(SCH_SUBHEADER_SHORT); + } + else { // F = 1 + length = ((((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB & 0x7f ) << 8 ) | (((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB & 0xff); + mac_header_ptr += 3;//sizeof(SCH_SUBHEADER_LONG); + } } + LOG_D(MAC,"[eNB] sdu %d lcid %d tb_length %d length %d (offset now %d)\n", + num_sdus,lcid,tb_length, length,mac_header_ptr-mac_header); + rx_lcids[num_sdus] = lcid; + rx_lengths[num_sdus] = length; + num_sdus++; + } + else { // This is a control element subheader POWER_HEADROOM, BSR and CRNTI + if (lcid == SHORT_PADDING) { + mac_header_ptr++; + } + else { + rx_ces[num_ces] = lcid; + num_ces++; + mac_header_ptr++; + if (lcid==LONG_BSR) + ce_len+=3; + else if (lcid==CRNTI) + ce_len+=2; + else if ((lcid==POWER_HEADROOM) || (lcid==TRUNCATED_BSR)|| (lcid== SHORT_BSR)) + ce_len++; + else { + LOG_E(MAC,"unknown CE %d \n", lcid); + exit(-1); + } + } + } } *num_ce = num_ces; *num_sdu = num_sdus; @@ -227,44 +420,52 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header, void schedule_ulsch(module_id_t module_idP, frame_t frameP,unsigned char cooperation_flag,sub_frame_t subframeP, unsigned char sched_subframe,unsigned int *nCCE) {//,int calibration_flag) { - start_meas(&eNB_mac_inst[module_idP].schedule_ulsch); - uint8_t granted_UEs; - unsigned int nCCE_available; - uint16_t first_rb=1,i; - - granted_UEs = find_ulgranted_UEs(module_idP); - nCCE_available = mac_xface->get_nCCE_max(module_idP) - *nCCE; - - // UE data info; - // check which UE has data to transmit - // function to decide the scheduling - // e.g. scheduling_rslt = Greedy(granted_UEs, nb_RB) - - // default function for default scheduling - // - - // output of scheduling, the UE numbers in RBs, where it is in the code??? - // check if RA (Msg3) is active in this subframeP, if so skip the PRBs used for Msg3 - // Msg3 is using 1 PRB so we need to increase first_rb accordingly - // not sure about the break (can there be more than 1 active RA procedure?) - - for (i=0;i<NB_RA_PROC_MAX;i++) { - if ((eNB_mac_inst[module_idP].RA_template[i].RA_active == TRUE) && - (eNB_mac_inst[module_idP].RA_template[i].generate_rar == 0) && - (eNB_mac_inst[module_idP].RA_template[i].Msg3_subframe == sched_subframe)) { - first_rb++; - break; - } - } - schedule_ulsch_rnti(module_idP, cooperation_flag, frameP, subframeP, sched_subframe, granted_UEs, nCCE, &nCCE_available, &first_rb); + unsigned int nCCE_available[MAX_NUM_CCs]; + uint16_t first_rb[MAX_NUM_CCs],i; + int CC_id; + eNB_MAC_INST *eNB=&eNB_mac_inst[module_idP]; + + start_meas(&eNB->schedule_ulsch); + + + for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { + + first_rb[CC_id] = 1; + nCCE_available[CC_id] = mac_xface->get_nCCE_max(module_idP,CC_id) - nCCE[CC_id]; + + // UE data info; + // check which UE has data to transmit + // function to decide the scheduling + // e.g. scheduling_rslt = Greedy(granted_UEs, nb_RB) + + // default function for default scheduling + // + + // output of scheduling, the UE numbers in RBs, where it is in the code??? + // check if RA (Msg3) is active in this subframeP, if so skip the PRBs used for Msg3 + // Msg3 is using 1 PRB so we need to increase first_rb accordingly + // not sure about the break (can there be more than 1 active RA procedure?) + + for (i=0;i<NB_RA_PROC_MAX;i++) { + if ((eNB->common_channels[CC_id].RA_template[i].RA_active == TRUE) && + (eNB->common_channels[CC_id].RA_template[i].generate_rar == 0) && + (eNB->common_channels[CC_id].RA_template[i].Msg3_subframe == sched_subframe)) { + first_rb[CC_id]++; + break; + } + } + } + schedule_ulsch_rnti(module_idP, cooperation_flag, frameP, subframeP, sched_subframe, nCCE, nCCE_available, first_rb); + #ifdef CBA - if ((eNB_mac_inst[module_idP].num_active_cba_groups > 0) && (*nCCE == 0)) - schedule_ulsch_cba_rnti(module_idP, cooperation_flag, frameP, subframeP, sched_subframe, granted_UEs, nCCE, &nCCE_available, &first_rb); + schedule_ulsch_cba_rnti(module_idP, cooperation_flag, frameP, subframeP, sched_subframe, granted_UEs, nCCE, &nCCE_available, &first_rb); #endif - stop_meas(&eNB_mac_inst[module_idP].schedule_ulsch); + + stop_meas(&eNB->schedule_ulsch); + } @@ -274,450 +475,438 @@ void schedule_ulsch_rnti(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, unsigned char sched_subframe, - uint8_t granted_UEs, unsigned int *nCCE, unsigned int *nCCE_available, uint16_t *first_rb){ - module_id_t ue_mod_id = -1; - module_id_t next_ue = -1; + + int UE_id; unsigned char aggregation = 2; rnti_t rnti = -1; uint8_t round = 0; uint8_t harq_pid = 0; void *ULSCH_dci = NULL; LTE_eNB_UE_stats *eNB_UE_stats = NULL; - DCI_PDU *DCI_pdu = &eNB_mac_inst[module_idP].DCI_pdu; + DCI_PDU *DCI_pdu; uint8_t status = 0; uint8_t rb_table_index = -1; uint16_t TBS,i; uint32_t buffer_occupancy; uint32_t tmp_bsr; uint32_t cqi_req,cshift,ndi,mcs,rballoc; + + int n,CC_id; + eNB_MAC_INST *eNB=&eNB_mac_inst[module_idP]; + UE_list_t *UE_list=&eNB->UE_list; + UE_TEMPLATE *UE_template; + int rvidx_tab[4] = {0,3,1,2}; - for (ue_mod_id=0;ue_mod_id<granted_UEs && (*nCCE_available > (1<<aggregation));ue_mod_id++) { - // msg("[MAC][eNB] subframeP %d: checking UE_id %d\n",subframeP,UE_id); - next_ue = ue_mod_id; // find next ue to schedule - // msg("[MAC][eNB] subframeP %d: next ue %d\n",subframeP,next_ue); - rnti = find_UE_RNTI(module_idP,next_ue); // radio network temp id is obtained - // msg("[MAC][eNB] subframeP %d: rnti %x\n",subframeP,rnti); + // loop over all active UEs + for (UE_id=UE_list->head;(UE_id>=0) && (*nCCE_available > (1<<aggregation));UE_id=UE_list->next[UE_id]) { + rnti = UE_RNTI(module_idP,UE_id); // radio network temp id is obtained + if (rnti==0) // if so, go to next UE + continue; + + // loop over all active UL CC_ids for this UE + for (n=0;n<UE_list->numactiveULCCs[UE_id];n++) { + // This is the actual CC_id in the list + CC_id = UE_list->ordered_ULCCids[n][UE_id]; - if (rnti==0) // if so, go to next UE - continue; + DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu; + UE_template = &UE_list->UE_template[CC_id][UE_id]; - eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,rnti); + + eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti); if (eNB_UE_stats==NULL) mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n"); LOG_I(MAC,"[eNB %d] Scheduler Frame %d, subframeP %d, nCCE %d: Checking ULSCH next UE_id %d mode id %d (rnti %x,mode %s), format 0\n", - module_idP,frameP,subframeP,*nCCE,next_ue,module_idP, rnti,mode_string[eNB_UE_stats->mode]); + module_idP,frameP,subframeP,*nCCE,UE_id,module_idP, rnti,mode_string[eNB_UE_stats->mode]); if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel - int8_t ret; - // Get candidate harq_pid from PHY - ret = mac_xface->get_ue_active_harq_pid(module_idP,rnti,subframeP,&harq_pid,&round,1); - LOG_I(MAC,"Got harq_pid %d, round %d, next_ue %d\n",harq_pid,round,next_ue); + int8_t ret; + // Get candidate harq_pid from PHY + ret = mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,subframeP,&harq_pid,&round,1); + LOG_I(MAC,"Got harq_pid %d, round %d, UE_id %d\n",harq_pid,round,UE_id); - /* [SR] 01/07/13: Don't schedule UE if we cannot get harq pid */ + /* [SR] 01/07/13: Don't schedule UE if we cannot get harq pid */ #ifndef EXMIMO_IOT - if ((((UE_is_to_be_scheduled(module_idP,ue_mod_id)>0)) || (round>0) || ((frameP%10)==0)) && (ret == 0)) - // if there is information on bsr of DCCH, DTCH or if there is UL_SR, or if there is a packet to retransmit, or we want to schedule a periodic feedback every 10 frames + if ((((UE_is_to_be_scheduled(module_idP,CC_id,UE_id)>0)) || (round>0) || ((frameP%10)==0)) && (ret == 0)) + // if there is information on bsr of DCCH, DTCH or if there is UL_SR, or if there is a packet to retransmit, or we want to schedule a periodic feedback every 10 frames #else - if (round==0) + if (round==0) #endif - { - LOG_D(MAC,"[eNB %d][PUSCH %x] Frame %d subframeP %d Scheduling UE %d (SR %d)\n", - module_idP,rnti,frameP,subframeP,ue_mod_id, - eNB_mac_inst[module_idP].UE_template[ue_mod_id].ul_SR); - - // reset the scheduling request - eNB_mac_inst[module_idP].UE_template[ue_mod_id].ul_SR = 0; - - aggregation = process_ue_cqi(module_idP,next_ue); // =2 by default!! - // msg("[MAC][eNB] subframeP %d: aggregation %d\n",subframeP,aggregation); - - status = mac_get_rrc_status(module_idP,1,next_ue); - - if (status < RRC_CONNECTED) - cqi_req = 0; - else - cqi_req = 1; - - - if (round > 0) { - ndi = eNB_mac_inst[module_idP].UE_template[ue_mod_id].oldNDI_UL[harq_pid]; - mcs = (rvidx_tab[round&3]) + 29; //not correct for round==4! - } - else { - ndi = 1-eNB_mac_inst[module_idP].UE_template[ue_mod_id].oldNDI_UL[harq_pid]; - eNB_mac_inst[module_idP].UE_template[ue_mod_id].oldNDI_UL[harq_pid]=ndi; - mcs = openair_daq_vars.target_ue_ul_mcs; - } - - LOG_D(MAC,"[eNB %d] ULSCH scheduler: Ndi %d, mcs %d\n",module_idP,ndi,mcs); - - if((cooperation_flag > 0) && (next_ue == 1)) { // Allocation on same set of RBs - // RIV:resource indication value // function in openair1/PHY/LTE_TRANSPORT/dci_tools.c - rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_UL, - ((next_ue-1)*4),//openair_daq_vars.ue_ul_nb_rb), - 4);//openair_daq_vars.ue_ul_nb_rb); - } - else if ((round==0) && (mcs < 29)) { - rb_table_index = 1; - TBS = mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]); - buffer_occupancy = ((eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID0] == 0) && - (eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID1] == 0) && - (eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID2] == 0) && - (eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID3] == 0))? - BSR_TABLE[10] : // This is when we've received SR and buffers are fully served - BSR_TABLE[eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID0]]+ - BSR_TABLE[eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID1]]+ - BSR_TABLE[eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID2]]+ - BSR_TABLE[eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID3]]; // This is when remaining data in UE buffers (even if SR is triggered) - - LOG_D(MAC,"[eNB %d][PUSCH %d/%x] Frame %d subframeP %d Scheduled UE, BSR for LCGID0 %d, LCGID1 %d, LCGID2 %d LCGID3 %d, BO %d\n", - module_idP, - ue_mod_id, - rnti, - frameP, - subframeP, - eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID0], - eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID1], - eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID2], - eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID3], - buffer_occupancy); - - while ((TBS < buffer_occupancy) && - rb_table[rb_table_index]<(mac_xface->lte_frame_parms->N_RB_UL-1-*first_rb)){ - // continue until we've exhauster the UEs request or the total number of available PRBs - /* LOG_I(MAC,"[eNB %d][PUSCH %x] Frame %d subframeP %d Scheduled UE (rb_table_index %d => TBS %d)\n", - module_idP,rnti,frameP,subframeP, - rb_table_index,TBS); - */ - rb_table_index++; - TBS = mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]); - } - - if (rb_table[rb_table_index]>(mac_xface->lte_frame_parms->N_RB_UL-1-*first_rb)) { - rb_table_index--; - TBS = mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]); - } - //rb_table_index = 8; - - LOG_I(MAC,"[eNB %d][PUSCH %d/%x] Frame %d subframeP %d Scheduled UE (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n", - module_idP,ue_mod_id,rnti,frameP,subframeP,mcs, - *first_rb,rb_table[rb_table_index], - rb_table_index,mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]), - harq_pid); - - rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_UL, - *first_rb, - rb_table[rb_table_index]);//openair_daq_vars.ue_ul_nb_rb); - - *first_rb+=rb_table[rb_table_index]; // increment for next UE allocation - eNB_mac_inst[module_idP].UE_template[ue_mod_id].nb_rb_ul[harq_pid] = rb_table[rb_table_index]; //store for possible retransmission - - buffer_occupancy -= mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]); - i = bytes_to_bsr_index((int32_t)buffer_occupancy); - - // Adjust BSR entries for LCGIDs - if (i>0) { - if (eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID0] <= i) { - tmp_bsr = BSR_TABLE[eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID0]]; - eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID0] = 0; - if (BSR_TABLE[eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID1]] <= (buffer_occupancy-tmp_bsr)) { - tmp_bsr += BSR_TABLE[eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID1]]; - eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID1] = 0; - if (BSR_TABLE[eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID2]] <= (buffer_occupancy-tmp_bsr)) { - tmp_bsr += BSR_TABLE[eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID2]]; - eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID2] = 0; - if (BSR_TABLE[eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID3]] <= (buffer_occupancy-tmp_bsr)) { - tmp_bsr += BSR_TABLE[eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID3]]; - eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID3] = 0; - } else { - eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID3] = bytes_to_bsr_index((int32_t)BSR_TABLE[eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID3]] - ((int32_t)buffer_occupancy - (int32_t)tmp_bsr)); - } - } - else { - eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID2] = bytes_to_bsr_index((int32_t)BSR_TABLE[eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID2]] - ((int32_t)buffer_occupancy -(int32_t)tmp_bsr)); - } - } - else { - eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID1] = bytes_to_bsr_index((int32_t)BSR_TABLE[eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID1]] - (int32_t)buffer_occupancy); - } - } - else { - eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID0] = bytes_to_bsr_index((int32_t)BSR_TABLE[eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID0]] - (int32_t)buffer_occupancy); - } - } - else { // we have flushed all buffers so clear bsr - eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID0] = 0; - eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID1] = 0; - eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID2] = 0; - eNB_mac_inst[module_idP].UE_template[ue_mod_id].bsr_info[LCGID3] = 0; - } - - - } // ndi==1 - else { //we schedule a retransmission - LOG_I(MAC,"[eNB %d][PUSCH %d/%x] Frame %d subframeP %d Scheduled UE retransmission (mcs %d, first rb %d, nb_rb %d, TBS %d, harq_pid %d)\n", - module_idP,harq_pid,rnti,frameP,subframeP,mcs, - *first_rb,eNB_mac_inst[module_idP].UE_template[ue_mod_id].nb_rb_ul[harq_pid], - mac_xface->get_TBS_UL(mcs,eNB_mac_inst[module_idP].UE_template[ue_mod_id].nb_rb_ul[harq_pid]), - harq_pid); - - rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_UL, - *first_rb, - eNB_mac_inst[module_idP].UE_template[ue_mod_id].nb_rb_ul[harq_pid]); - - *first_rb+=eNB_mac_inst[module_idP].UE_template[ue_mod_id].nb_rb_ul[harq_pid]; // increment for next UE allocation - } - - // Cyclic shift for DM RS - if(cooperation_flag == 2) { - if(next_ue == 1)// For Distriibuted Alamouti, cyclic shift applied to 2nd UE - cshift = 1; - else - cshift = 0; - } - else - cshift = 0;// values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1) - - if (mac_xface->lte_frame_parms->frame_type == TDD) { - switch (mac_xface->lte_frame_parms->N_RB_UL) { - case 6: - ULSCH_dci = eNB_mac_inst[module_idP].UE_template[next_ue].ULSCH_DCI[harq_pid]; - - ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->type = 0; - ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->hopping = 0; - ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->rballoc = rballoc; - ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->mcs = mcs; - ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->ndi = ndi; - ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->TPC = 1; - ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->cshift = cshift; - ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->padding = 0; - ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->dai = eNB_mac_inst[module_idP].UE_template[next_ue].DAI_ul[sched_subframe]; - ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req = cqi_req; - - add_ue_spec_dci(DCI_pdu, - ULSCH_dci, - rnti, - sizeof(DCI0_1_5MHz_TDD_1_6_t), - aggregation, - sizeof_DCI0_1_5MHz_TDD_1_6_t, - format0, - 0); - break; - default: - case 25: - ULSCH_dci = eNB_mac_inst[module_idP].UE_template[next_ue].ULSCH_DCI[harq_pid]; - - ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->type = 0; - ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->hopping = 0; - ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->rballoc = rballoc; - ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->mcs = mcs; - ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->ndi = ndi; - ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->TPC = 1; - ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->cshift = cshift; - ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->padding = 0; - ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->dai = eNB_mac_inst[module_idP].UE_template[next_ue].DAI_ul[sched_subframe]; - ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req = cqi_req; - - add_ue_spec_dci(DCI_pdu, - ULSCH_dci, - rnti, - sizeof(DCI0_5MHz_TDD_1_6_t), - aggregation, - sizeof_DCI0_5MHz_TDD_1_6_t, - format0, - 0); - break; - case 50: - ULSCH_dci = eNB_mac_inst[module_idP].UE_template[next_ue].ULSCH_DCI[harq_pid]; - - ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->type = 0; - ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->hopping = 0; - ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->rballoc = rballoc; - ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->mcs = mcs; - ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->ndi = ndi; - ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->TPC = 1; - ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->cshift = cshift; - ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->padding = 0; - ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->dai = eNB_mac_inst[module_idP].UE_template[next_ue].DAI_ul[sched_subframe]; - ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req = cqi_req; - - add_ue_spec_dci(DCI_pdu, - ULSCH_dci, - rnti, - sizeof(DCI0_10MHz_TDD_1_6_t), - aggregation, - sizeof_DCI0_10MHz_TDD_1_6_t, - format0, - 0); - break; - case 100: - ULSCH_dci = eNB_mac_inst[module_idP].UE_template[next_ue].ULSCH_DCI[harq_pid]; - - ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->type = 0; - ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->hopping = 0; - ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->rballoc = rballoc; - ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->mcs = mcs; - ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->ndi = ndi; - ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->TPC = 1; - ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->cshift = cshift; - ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->padding = 0; - ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->dai = eNB_mac_inst[module_idP].UE_template[next_ue].DAI_ul[sched_subframe]; - ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req = cqi_req; - - add_ue_spec_dci(DCI_pdu, - ULSCH_dci, - rnti, - sizeof(DCI0_20MHz_TDD_1_6_t), - aggregation, - sizeof_DCI0_20MHz_TDD_1_6_t, - format0, - 0); - break; - } - } - else { //FDD - switch (mac_xface->lte_frame_parms->N_RB_UL) { - case 25: - default: - - ULSCH_dci = eNB_mac_inst[module_idP].UE_template[next_ue].ULSCH_DCI[harq_pid]; - - ((DCI0_5MHz_FDD_t *)ULSCH_dci)->type = 0; - ((DCI0_5MHz_FDD_t *)ULSCH_dci)->hopping = 0; - ((DCI0_5MHz_FDD_t *)ULSCH_dci)->rballoc = rballoc; - ((DCI0_5MHz_FDD_t *)ULSCH_dci)->mcs = mcs; - ((DCI0_5MHz_FDD_t *)ULSCH_dci)->ndi = ndi; - ((DCI0_5MHz_FDD_t *)ULSCH_dci)->TPC = 1; - ((DCI0_5MHz_FDD_t *)ULSCH_dci)->cshift = cshift; - ((DCI0_5MHz_FDD_t *)ULSCH_dci)->padding = 0; - ((DCI0_5MHz_FDD_t *)ULSCH_dci)->cqi_req = cqi_req; - - add_ue_spec_dci(DCI_pdu, - ULSCH_dci, - rnti, - sizeof(DCI0_5MHz_FDD_t), - aggregation, - sizeof_DCI0_5MHz_FDD_t, - format0, - 0); - break; - case 6: - ULSCH_dci = eNB_mac_inst[module_idP].UE_template[next_ue].ULSCH_DCI[harq_pid]; - - ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->type = 0; - ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->hopping = 0; - ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->rballoc = rballoc; - ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->mcs = mcs; - ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->ndi = ndi; - ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->TPC = 1; - ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->cshift = cshift; - ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->padding = 0; - ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->cqi_req = cqi_req; - - add_ue_spec_dci(DCI_pdu, - ULSCH_dci, - rnti, - sizeof(DCI0_1_5MHz_FDD_t), - aggregation, - sizeof_DCI0_1_5MHz_FDD_t, - format0, - 0); - break; - case 50: - ULSCH_dci = eNB_mac_inst[module_idP].UE_template[next_ue].ULSCH_DCI[harq_pid]; - - ((DCI0_10MHz_FDD_t *)ULSCH_dci)->type = 0; - ((DCI0_10MHz_FDD_t *)ULSCH_dci)->hopping = 0; - ((DCI0_10MHz_FDD_t *)ULSCH_dci)->rballoc = rballoc; - ((DCI0_10MHz_FDD_t *)ULSCH_dci)->mcs = mcs; - ((DCI0_10MHz_FDD_t *)ULSCH_dci)->ndi = ndi; - ((DCI0_10MHz_FDD_t *)ULSCH_dci)->TPC = 1; - ((DCI0_10MHz_FDD_t *)ULSCH_dci)->padding = 0; - ((DCI0_10MHz_FDD_t *)ULSCH_dci)->cshift = cshift; - ((DCI0_10MHz_FDD_t *)ULSCH_dci)->cqi_req = cqi_req; - - add_ue_spec_dci(DCI_pdu, - ULSCH_dci, - rnti, - sizeof(DCI0_10MHz_FDD_t), - aggregation, - sizeof_DCI0_10MHz_FDD_t, - format0, - 0); - break; - case 100: - ULSCH_dci = eNB_mac_inst[module_idP].UE_template[next_ue].ULSCH_DCI[harq_pid]; - - ((DCI0_20MHz_FDD_t *)ULSCH_dci)->type = 0; - ((DCI0_20MHz_FDD_t *)ULSCH_dci)->hopping = 0; - ((DCI0_20MHz_FDD_t *)ULSCH_dci)->rballoc = rballoc; - ((DCI0_20MHz_FDD_t *)ULSCH_dci)->mcs = mcs; - ((DCI0_20MHz_FDD_t *)ULSCH_dci)->ndi = ndi; - ((DCI0_20MHz_FDD_t *)ULSCH_dci)->TPC = 1; - ((DCI0_20MHz_FDD_t *)ULSCH_dci)->padding = 0; - ((DCI0_20MHz_FDD_t *)ULSCH_dci)->cshift = cshift; - ((DCI0_20MHz_FDD_t *)ULSCH_dci)->cqi_req = cqi_req; - - add_ue_spec_dci(DCI_pdu, - ULSCH_dci, - rnti, - sizeof(DCI0_20MHz_FDD_t), - aggregation, - sizeof_DCI0_20MHz_FDD_t, - format0, - 0); - break; - - } - } - //#ifdef DEBUG_eNB_SCHEDULER - // dump_dci(mac_xface->lte_frame_parms, - // &DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci-1]); - //#endif - add_ue_ulsch_info(module_idP, - next_ue, - subframeP, - S_UL_SCHEDULED); - - *nCCE = (*nCCE) + (1<<aggregation); - *nCCE_available = mac_xface->get_nCCE_max(module_idP) - *nCCE; - //msg("[MAC][eNB %d][ULSCH Scheduler] Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", module_idP,frameP,subframeP,next_ue); - - //break; // leave loop after first UE is schedule (avoids m - } // UE_is_to_be_scheduled - } // UE is in PUSCH - } // loop over UE_id -} + { + LOG_D(MAC,"[eNB %d][PUSCH %x] Frame %d subframeP %d Scheduling UE %d (SR %d)\n", + module_idP,rnti,frameP,subframeP,UE_id, + UE_template->ul_SR); -uint8_t find_ulgranted_UEs(module_id_t module_idP){ + // reset the scheduling request + UE_template->ul_SR = 0; - // all active users should be granted - return(find_active_UEs(module_idP)); -} + aggregation = process_ue_cqi(module_idP,UE_id); // =2 by default!! + // msg("[MAC][eNB] subframeP %d: aggregation %d\n",subframeP,aggregation); -unsigned char *get_dlsch_sdu(module_id_t module_idP, frame_t frameP, rnti_t rntiP, uint8_t TBindex) { + status = mac_get_rrc_status(module_idP,1,UE_id); - module_id_t ue_mod_id; + if (status < RRC_CONNECTED) + cqi_req = 0; + else + cqi_req = 1; - if (rntiP==SI_RNTI) { - LOG_D(MAC,"[eNB %d] Frame %d Get DLSCH sdu for BCCH \n",module_idP,frameP); - return((unsigned char *)&eNB_mac_inst[module_idP].BCCH_pdu.payload[0]); - } - else if ((ue_mod_id = find_UE_id(module_idP,rntiP)) != UE_INDEX_INVALID ){ - LOG_D(MAC,"[eNB %d] Frame %d: Get DLSCH sdu for rnti %x => UE_id %d\n",module_idP,frameP,rntiP,ue_mod_id); - return((unsigned char *)&eNB_mac_inst[module_idP].DLSCH_pdu[ue_mod_id][TBindex].payload[0]); - } else { - LOG_E(MAC,"[eNB %d] Frame %d: UE with RNTI %x does not exist\n", module_idP,frameP,rntiP); - return NULL; - } + if (round > 0) { + ndi = UE_template->oldNDI_UL[harq_pid]; + mcs = rvidx_tab[round&3] + 29; //not correct for round==4! + } + else { + ndi = 1-UE_template->oldNDI_UL[harq_pid]; + UE_template->oldNDI_UL[harq_pid]=ndi; + mcs = openair_daq_vars.target_ue_ul_mcs; + } + + LOG_D(MAC,"[eNB %d] ULSCH scheduler: Ndi %d, mcs %d\n",module_idP,ndi,mcs); + + if((cooperation_flag > 0) && (UE_id == 1)) { // Allocation on same set of RBs + // RIV:resource indication value // function in openair1/PHY/LTE_TRANSPORT/dci_tools.c + rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_UL, + ((UE_id-1)*4),//openair_daq_vars.ue_ul_nb_rb), + 4);//openair_daq_vars.ue_ul_nb_rb); + } + else if ((round==0) && (mcs < 29)) { + rb_table_index = 1; + TBS = mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]); + buffer_occupancy = ((UE_template->bsr_info[LCGID0] == 0) && + (UE_template->bsr_info[LCGID1] == 0) && + (UE_template->bsr_info[LCGID2] == 0) && + (UE_template->bsr_info[LCGID3] == 0))? + BSR_TABLE[10] : // This is when we've received SR and buffers are fully served + BSR_TABLE[UE_template->bsr_info[LCGID0]]+ + BSR_TABLE[UE_template->bsr_info[LCGID1]]+ + BSR_TABLE[UE_template->bsr_info[LCGID2]]+ + BSR_TABLE[UE_template->bsr_info[LCGID3]]; // This is when remaining data in UE buffers (even if SR is triggered) + + LOG_D(MAC,"[eNB %d][PUSCH %d/%x] Frame %d subframeP %d Scheduled UE, BSR for LCGID0 %d, LCGID1 %d, LCGID2 %d LCGID3 %d, BO %d\n", + module_idP, + UE_id, + rnti, + frameP, + subframeP, + UE_template->bsr_info[LCGID0], + UE_template->bsr_info[LCGID1], + UE_template->bsr_info[LCGID2], + UE_template->bsr_info[LCGID3], + buffer_occupancy); + + while ((TBS < buffer_occupancy) && + rb_table[rb_table_index]<(mac_xface->lte_frame_parms->N_RB_UL-1-*first_rb)){ + // continue until we've exhauster the UEs request or the total number of available PRBs + /* LOG_I(MAC,"[eNB %d][PUSCH %x] Frame %d subframeP %d Scheduled UE (rb_table_index %d => TBS %d)\n", + module_idP,rnti,frameP,subframeP, + rb_table_index,TBS); + */ + rb_table_index++; + TBS = mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]); + } + + if (rb_table[rb_table_index]>(mac_xface->lte_frame_parms->N_RB_UL-1-*first_rb)) { + rb_table_index--; + TBS = mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]); + } + //rb_table_index = 8; + + LOG_I(MAC,"[eNB %d][PUSCH %d/%x] Frame %d subframeP %d Scheduled UE (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n", + module_idP,UE_id,rnti,frameP,subframeP,mcs, + *first_rb,rb_table[rb_table_index], + rb_table_index,mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]), + harq_pid); + + rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_UL, + *first_rb, + rb_table[rb_table_index]);//openair_daq_vars.ue_ul_nb_rb); + + *first_rb+=rb_table[rb_table_index]; // increment for next UE allocation + UE_template->nb_rb_ul[harq_pid] = rb_table[rb_table_index]; //store for possible retransmission + + buffer_occupancy -= mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]); + i = bytes_to_bsr_index((int32_t)buffer_occupancy); + + // Adjust BSR entries for LCGIDs + if (i>0) { + if (UE_template->bsr_info[LCGID0] <= i) { + tmp_bsr = BSR_TABLE[UE_template->bsr_info[LCGID0]]; + UE_template->bsr_info[LCGID0] = 0; + if (BSR_TABLE[UE_template->bsr_info[LCGID1]] <= (buffer_occupancy-tmp_bsr)) { + tmp_bsr += BSR_TABLE[UE_template->bsr_info[LCGID1]]; + UE_template->bsr_info[LCGID1] = 0; + if (BSR_TABLE[UE_template->bsr_info[LCGID2]] <= (buffer_occupancy-tmp_bsr)) { + tmp_bsr += BSR_TABLE[UE_template->bsr_info[LCGID2]]; + UE_template->bsr_info[LCGID2] = 0; + if (BSR_TABLE[UE_template->bsr_info[LCGID3]] <= (buffer_occupancy-tmp_bsr)) { + tmp_bsr += BSR_TABLE[UE_template->bsr_info[LCGID3]]; + UE_template->bsr_info[LCGID3] = 0; + } else { + UE_template->bsr_info[LCGID3] = bytes_to_bsr_index((int32_t)BSR_TABLE[UE_template->bsr_info[LCGID3]] - ((int32_t)buffer_occupancy - (int32_t)tmp_bsr)); + } + } + else { + UE_template->bsr_info[LCGID2] = bytes_to_bsr_index((int32_t)BSR_TABLE[UE_template->bsr_info[LCGID2]] - ((int32_t)buffer_occupancy -(int32_t)tmp_bsr)); + } + } + else { + UE_template->bsr_info[LCGID1] = bytes_to_bsr_index((int32_t)BSR_TABLE[UE_template->bsr_info[LCGID1]] - (int32_t)buffer_occupancy); + } + } + else { + UE_template->bsr_info[LCGID0] = bytes_to_bsr_index((int32_t)BSR_TABLE[UE_template->bsr_info[LCGID0]] - (int32_t)buffer_occupancy); + } + } + else { // we have flushed all buffers so clear bsr + UE_template->bsr_info[LCGID0] = 0; + UE_template->bsr_info[LCGID1] = 0; + UE_template->bsr_info[LCGID2] = 0; + UE_template->bsr_info[LCGID3] = 0; + } + + + + } // ndi==1 + else { //we schedule a retransmission + LOG_I(MAC,"[eNB %d][PUSCH %d/%x] Frame %d subframeP %d Scheduled UE retransmission (mcs %d, first rb %d, nb_rb %d, TBS %d, harq_pid %d)\n", + module_idP,UE_id,rnti,frameP,subframeP,mcs, + *first_rb,UE_template->nb_rb_ul[harq_pid], + mac_xface->get_TBS_UL(mcs,UE_template->nb_rb_ul[harq_pid]), + harq_pid); + + rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_UL, + *first_rb, + UE_template->nb_rb_ul[harq_pid]); + *first_rb+=UE_template->nb_rb_ul[harq_pid]; // increment for next UE allocation + } + + // Cyclic shift for DM RS + if(cooperation_flag == 2) { + if(UE_id == 1)// For Distriibuted Alamouti, cyclic shift applied to 2nd UE + cshift = 1; + else + cshift = 0; + } + else + cshift = 0;// values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1) + + if (mac_xface->lte_frame_parms->frame_type == TDD) { + switch (mac_xface->lte_frame_parms->N_RB_UL) { + case 6: + ULSCH_dci = UE_template->ULSCH_DCI[harq_pid]; + + ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->type = 0; + ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->hopping = 0; + ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->rballoc = rballoc; + ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->mcs = mcs; + ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->ndi = ndi; + ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->TPC = 1; + ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->cshift = cshift; + ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->padding = 0; + ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->dai = UE_template->DAI_ul[sched_subframe]; + ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req = cqi_req; + + add_ue_spec_dci(DCI_pdu, + ULSCH_dci, + rnti, + sizeof(DCI0_1_5MHz_TDD_1_6_t), + aggregation, + sizeof_DCI0_1_5MHz_TDD_1_6_t, + format0, + 0); + break; + default: + case 25: + ULSCH_dci = UE_template->ULSCH_DCI[harq_pid]; + + ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->type = 0; + ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->hopping = 0; + ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->rballoc = rballoc; + ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->mcs = mcs; + ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->ndi = ndi; + ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->TPC = 1; + ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->cshift = cshift; + ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->padding = 0; + ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->dai = UE_template->DAI_ul[sched_subframe]; + ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req = cqi_req; + + add_ue_spec_dci(DCI_pdu, + ULSCH_dci, + rnti, + sizeof(DCI0_5MHz_TDD_1_6_t), + aggregation, + sizeof_DCI0_5MHz_TDD_1_6_t, + format0, + 0); + break; + case 50: + ULSCH_dci = UE_template->ULSCH_DCI[harq_pid]; + + ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->type = 0; + ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->hopping = 0; + ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->rballoc = rballoc; + ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->mcs = mcs; + ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->ndi = ndi; + ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->TPC = 1; + ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->cshift = cshift; + ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->padding = 0; + ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->dai = UE_template->DAI_ul[sched_subframe]; + ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req = cqi_req; + + add_ue_spec_dci(DCI_pdu, + ULSCH_dci, + rnti, + sizeof(DCI0_10MHz_TDD_1_6_t), + aggregation, + sizeof_DCI0_10MHz_TDD_1_6_t, + format0, + 0); + break; + case 100: + ULSCH_dci = UE_template->ULSCH_DCI[harq_pid]; + + ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->type = 0; + ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->hopping = 0; + ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->rballoc = rballoc; + ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->mcs = mcs; + ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->ndi = ndi; + ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->TPC = 1; + ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->cshift = cshift; + ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->padding = 0; + ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->dai = UE_template->DAI_ul[sched_subframe]; + ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req = cqi_req; + + add_ue_spec_dci(DCI_pdu, + ULSCH_dci, + rnti, + sizeof(DCI0_20MHz_TDD_1_6_t), + aggregation, + sizeof_DCI0_20MHz_TDD_1_6_t, + format0, + 0); + break; + } + } + else { //FDD + switch (mac_xface->lte_frame_parms->N_RB_UL) { + case 25: + default: + + ULSCH_dci = UE_template->ULSCH_DCI[harq_pid]; + + ((DCI0_5MHz_FDD_t *)ULSCH_dci)->type = 0; + ((DCI0_5MHz_FDD_t *)ULSCH_dci)->hopping = 0; + ((DCI0_5MHz_FDD_t *)ULSCH_dci)->rballoc = rballoc; + ((DCI0_5MHz_FDD_t *)ULSCH_dci)->mcs = mcs; + ((DCI0_5MHz_FDD_t *)ULSCH_dci)->ndi = ndi; + ((DCI0_5MHz_FDD_t *)ULSCH_dci)->TPC = 1; + ((DCI0_5MHz_FDD_t *)ULSCH_dci)->cshift = cshift; + ((DCI0_5MHz_FDD_t *)ULSCH_dci)->padding = 0; + ((DCI0_5MHz_FDD_t *)ULSCH_dci)->cqi_req = cqi_req; + + add_ue_spec_dci(DCI_pdu, + ULSCH_dci, + rnti, + sizeof(DCI0_5MHz_FDD_t), + aggregation, + sizeof_DCI0_5MHz_FDD_t, + format0, + 0); + break; + case 6: + ULSCH_dci = UE_template->ULSCH_DCI[harq_pid]; + + ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->type = 0; + ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->hopping = 0; + ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->rballoc = rballoc; + ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->mcs = mcs; + ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->ndi = ndi; + ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->TPC = 1; + ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->cshift = cshift; + ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->padding = 0; + ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->cqi_req = cqi_req; + + add_ue_spec_dci(DCI_pdu, + ULSCH_dci, + rnti, + sizeof(DCI0_1_5MHz_FDD_t), + aggregation, + sizeof_DCI0_1_5MHz_FDD_t, + format0, + 0); + break; + case 50: + ULSCH_dci = UE_template->ULSCH_DCI[harq_pid]; + + ((DCI0_10MHz_FDD_t *)ULSCH_dci)->type = 0; + ((DCI0_10MHz_FDD_t *)ULSCH_dci)->hopping = 0; + ((DCI0_10MHz_FDD_t *)ULSCH_dci)->rballoc = rballoc; + ((DCI0_10MHz_FDD_t *)ULSCH_dci)->mcs = mcs; + ((DCI0_10MHz_FDD_t *)ULSCH_dci)->ndi = ndi; + ((DCI0_10MHz_FDD_t *)ULSCH_dci)->TPC = 1; + ((DCI0_10MHz_FDD_t *)ULSCH_dci)->padding = 0; + ((DCI0_10MHz_FDD_t *)ULSCH_dci)->cshift = cshift; + ((DCI0_10MHz_FDD_t *)ULSCH_dci)->cqi_req = cqi_req; + + add_ue_spec_dci(DCI_pdu, + ULSCH_dci, + rnti, + sizeof(DCI0_10MHz_FDD_t), + aggregation, + sizeof_DCI0_10MHz_FDD_t, + format0, + 0); + break; + case 100: + ULSCH_dci = UE_template->ULSCH_DCI[harq_pid]; + + ((DCI0_20MHz_FDD_t *)ULSCH_dci)->type = 0; + ((DCI0_20MHz_FDD_t *)ULSCH_dci)->hopping = 0; + ((DCI0_20MHz_FDD_t *)ULSCH_dci)->rballoc = rballoc; + ((DCI0_20MHz_FDD_t *)ULSCH_dci)->mcs = mcs; + ((DCI0_20MHz_FDD_t *)ULSCH_dci)->ndi = ndi; + ((DCI0_20MHz_FDD_t *)ULSCH_dci)->TPC = 1; + ((DCI0_20MHz_FDD_t *)ULSCH_dci)->padding = 0; + ((DCI0_20MHz_FDD_t *)ULSCH_dci)->cshift = cshift; + ((DCI0_20MHz_FDD_t *)ULSCH_dci)->cqi_req = cqi_req; + + add_ue_spec_dci(DCI_pdu, + ULSCH_dci, + rnti, + sizeof(DCI0_20MHz_FDD_t), + aggregation, + sizeof_DCI0_20MHz_FDD_t, + format0, + 0); + break; + + } + } + //#ifdef DEBUG_eNB_SCHEDULER + // dump_dci(mac_xface->lte_frame_parms, + // &DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci-1]); + //#endif + add_ue_ulsch_info(module_idP, + CC_id, + UE_id, + subframeP, + S_UL_SCHEDULED); + + nCCE[CC_id] = nCCE[CC_id] + (1<<aggregation); + nCCE_available[CC_id] = mac_xface->get_nCCE_max(module_idP,CC_id) - nCCE[CC_id]; + //msg("[MAC][eNB %d][ULSCH Scheduler] Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", module_idP,frameP,subframeP,UE_id); + + //break; // leave loop after first UE is schedule (avoids m + } // UE_is_to_be_scheduled + } // UE is in PUSCH + } // loop of CC_id + } // loop over UE_id } #ifdef CBA @@ -725,7 +914,7 @@ void schedule_ulsch_cba_rnti(module_id_t module_idP, unsigned char cooperation_f DCI0_5MHz_TDD_1_6_t *ULSCH_dci_tdd16; DCI0_5MHz_FDD_t *ULSCH_dci_fdd; - DCI_PDU *DCI_pdu= &eNB_mac_inst[module_idP].DCI_pdu; + DCI_PDU *DCI_pdu; uint8_t rb_table_index=0, aggregation=2; uint32_t rballoc; @@ -735,129 +924,140 @@ void schedule_ulsch_cba_rnti(module_id_t module_idP, unsigned char cooperation_f uint8_t remaining_rbs= available_rbs; uint8_t allocated_rbs; // We compute the weight of each group and initialize some variables - for (cba_group=0;cba_group<eNB_mac_inst[module_idP].num_active_cba_groups;cba_group++) { - // UEs in PUSCH with traffic - weight[cba_group] = find_num_active_UEs_in_cbagroup(module_idP, cba_group); - required_rbs[cba_group] = 0; - num_cba_resources[cba_group]=0; + + + + for (cba_group=0;cba_group<eNB_mac_inst[module_idP][CC_id].num_active_cba_groups;cba_group++) { + // UEs in PUSCH with traffic + weight[cba_group] = find_num_active_UEs_in_cbagroup(module_idP, cba_group); + required_rbs[cba_group] = 0; + num_cba_resources[cba_group]=0; } //LOG_D(MAC, "[eNB ] CBA granted ues are %d\n",granted_UEs ); - for (cba_group=0;cba_group<eNB_mac_inst[module_idP].num_active_cba_groups && (*nCCE_available > (1<<aggregation));cba_group++) { - if (remaining_rbs <= 0 ) - break; - // If the group needs some resource - if ((weight[cba_group] > 0) && eNB_mac_inst[module_idP].cba_rnti[cba_group] != 0){ - // to be refined in case of : granted_UEs >> weight[cba_group]*available_rbs - required_rbs[cba_group] = (uint8_t)ceil((weight[cba_group]*available_rbs)/granted_UEs); - - while (remaining_rbs < required_rbs[cba_group] ) - required_rbs[cba_group]--; - - /* - while (rb_table[rb_table_index] < required_rbs[cba_group]) - rb_table_index++; - - while (rb_table[rb_table_index] > remaining_rbs ) - rb_table_index--; - - remaining_rbs-=rb_table[rb_table_index]; - required_rbs[cba_group]=rb_table[rb_table_index]; - */ - // to be refined - if (weight[cba_group] < required_rbs[cba_group]) - num_cba_resources[cba_group]=(uint8_t)ceil(weight[cba_group]/2.0); - else - num_cba_resources[cba_group]=(uint8_t)ceil(required_rbs[cba_group]/2.0); - - while ((*nCCE) + (1<<aggregation) * num_cba_resources[cba_group] > *nCCE_available) - num_cba_resources[cba_group]--; - - LOG_N(MAC,"[eNB %d] Frame %d, subframeP %d: cba group %d weight/granted_ues %d/%d available/required rb (%d/%d), num resources %d->1 (*scaled down*) \n", - module_idP, frameP, subframeP, cba_group, - weight[cba_group], granted_UEs, available_rbs,required_rbs[cba_group], - num_cba_resources[cba_group]); - - num_cba_resources[cba_group]=1; + for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { + + if ((eNB_mac_inst[module_idP][CC_id].num_active_cba_groups > 0) && (nCCE[CC_id] == 0)) { + DCI_pdu = &eNB_mac_inst[module_idP][CC_id].DCI_pdu; + + for (cba_group=0;cba_group<eNB_mac_inst[module_idP][CC_id].num_active_cba_groups && (nCCE_available[CC_id] > (1<<aggregation));cba_group++) { + if (remaining_rbs <= 0 ) + break; + // If the group needs some resource + if ((weight[cba_group] > 0) && eNB_mac_inst[module_idP][CC_id].cba_rnti[cba_group] != 0){ + // to be refined in case of : granted_UEs >> weight[cba_group]*available_rbs + required_rbs[cba_group] = (uint8_t)ceil((weight[cba_group]*available_rbs)/granted_UEs); + + while (remaining_rbs < required_rbs[cba_group] ) + required_rbs[cba_group]--; + + /* + while (rb_table[rb_table_index] < required_rbs[cba_group]) + rb_table_index++; + + while (rb_table[rb_table_index] > remaining_rbs ) + rb_table_index--; + + remaining_rbs-=rb_table[rb_table_index]; + required_rbs[cba_group]=rb_table[rb_table_index]; + */ + // to be refined + if (weight[cba_group] < required_rbs[cba_group]) + num_cba_resources[cba_group]=(uint8_t)ceil(weight[cba_group]/2.0); + else + num_cba_resources[cba_group]=(uint8_t)ceil(required_rbs[cba_group]/2.0); + + while (nCCE[CC_id] + (1<<aggregation) * num_cba_resources[cba_group] > nCCE_available[CC_id]) + num_cba_resources[cba_group]--; + + LOG_N(MAC,"[eNB %d] Frame %d, subframeP %d: cba group %d weight/granted_ues %d/%d available/required rb (%d/%d), num resources %d->1 (*scaled down*) \n", + module_idP, frameP, subframeP, cba_group, + weight[cba_group], granted_UEs, available_rbs,required_rbs[cba_group], + num_cba_resources[cba_group]); + + num_cba_resources[cba_group]=1; + + } } - } - // phase 2 - for (cba_group=0;cba_group<eNB_mac_inst[module_idP].num_active_cba_groups;cba_group++) { - for (cba_resources=0; cba_resources < num_cba_resources[cba_group]; cba_resources++){ - rb_table_index =0; - // check if there was an allocation for this group in the 1st phase - if (required_rbs[cba_group] == 0 ) - continue; - - while (rb_table[rb_table_index] < (uint8_t) ceil(required_rbs[cba_group] / num_cba_resources[cba_group]) ) - rb_table_index++; - - while (rb_table[rb_table_index] > remaining_rbs ) - rb_table_index--; - - remaining_rbs-=rb_table[rb_table_index]; - allocated_rbs=rb_table[rb_table_index]; - - rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_UL, - *first_rb, - rb_table[rb_table_index]); - - *first_rb+=rb_table[rb_table_index]; - LOG_D(MAC,"[eNB %d] Frame %d, subframeP %d: CBA %d rnti %x, total/required/allocated/remaining rbs (%d/%d/%d/%d), rballoc %d, nCCE (%d/%d)\n", - module_idP, frameP, subframeP, cba_group,eNB_mac_inst[module_idP].cba_rnti[cba_group], - available_rbs, required_rbs[cba_group], allocated_rbs, remaining_rbs,rballoc, - *nCCE_available,*nCCE); - - - if (mac_xface->lte_frame_parms->frame_type == TDD) { - ULSCH_dci_tdd16 = (DCI0_5MHz_TDD_1_6_t *)eNB_mac_inst[module_idP].UE_template[cba_group].ULSCH_DCI[0]; - - ULSCH_dci_tdd16->type = 0; - ULSCH_dci_tdd16->hopping = 0; - ULSCH_dci_tdd16->rballoc = rballoc; - ULSCH_dci_tdd16->mcs = 2; - ULSCH_dci_tdd16->ndi = 1; - ULSCH_dci_tdd16->TPC = 1; - ULSCH_dci_tdd16->cshift = cba_group; - ULSCH_dci_tdd16->dai = eNB_mac_inst[module_idP].UE_template[cba_group].DAI_ul[sched_subframe]; - ULSCH_dci_tdd16->cqi_req = 1; - - //add_ue_spec_dci - add_common_dci(DCI_pdu, - ULSCH_dci_tdd16, - eNB_mac_inst[module_idP].cba_rnti[cba_group], - sizeof(DCI0_5MHz_TDD_1_6_t), - aggregation, - sizeof_DCI0_5MHz_TDD_1_6_t, - format0, - 0); - } - else { - ULSCH_dci_fdd = (DCI0_5MHz_FDD_t *)eNB_mac_inst[module_idP].UE_template[cba_group].ULSCH_DCI[0]; - - ULSCH_dci_fdd->type = 0; - ULSCH_dci_fdd->hopping = 0; - ULSCH_dci_fdd->rballoc = rballoc; - ULSCH_dci_fdd->mcs = 2; - ULSCH_dci_fdd->ndi = 1; - ULSCH_dci_fdd->TPC = 1; - ULSCH_dci_fdd->cshift = 0; - ULSCH_dci_fdd->cqi_req = 1; - - //add_ue_spec_dci - add_common_dci(DCI_pdu, - ULSCH_dci_fdd, - eNB_mac_inst[module_idP].cba_rnti[cba_group], - sizeof(DCI0_5MHz_FDD_t), - aggregation, - sizeof_DCI0_5MHz_FDD_t, - format0, - 0); - } - *nCCE = (*nCCE) + (1<<aggregation) * num_cba_resources[cba_group]; - *nCCE_available = mac_xface->get_nCCE_max(module_idP) - *nCCE; - // break;// for the moment only schedule one + // phase 2 + for (cba_group=0;cba_group<eNB_mac_inst[module_idP][CC_id].num_active_cba_groups;cba_group++) { + for (cba_resources=0; cba_resources < num_cba_resources[cba_group]; cba_resources++){ + rb_table_index =0; + // check if there was an allocation for this group in the 1st phase + if (required_rbs[cba_group] == 0 ) + continue; + + while (rb_table[rb_table_index] < (uint8_t) ceil(required_rbs[cba_group] / num_cba_resources[cba_group]) ) + rb_table_index++; + + while (rb_table[rb_table_index] > remaining_rbs ) + rb_table_index--; + + remaining_rbs-=rb_table[rb_table_index]; + allocated_rbs=rb_table[rb_table_index]; + + rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_UL, + *first_rb, + rb_table[rb_table_index]); + + *first_rb+=rb_table[rb_table_index]; + LOG_D(MAC,"[eNB %d] Frame %d, subframeP %d: CBA %d rnti %x, total/required/allocated/remaining rbs (%d/%d/%d/%d), rballoc %d, nCCE (%d/%d)\n", + module_idP, frameP, subframeP, cba_group,eNB_mac_inst[module_idP][CC_id].cba_rnti[cba_group], + available_rbs, required_rbs[cba_group], allocated_rbs, remaining_rbs,rballoc, + nCCE_available[CC_id],nCCE[CC_id]); + + + if (mac_xface->lte_frame_parms->frame_type == TDD) { + ULSCH_dci_tdd16 = (DCI0_5MHz_TDD_1_6_t *)UE_list->UE_template[CC_id][cba_group].ULSCH_DCI[0]; + + ULSCH_dci_tdd16->type = 0; + ULSCH_dci_tdd16->hopping = 0; + ULSCH_dci_tdd16->rballoc = rballoc; + ULSCH_dci_tdd16->mcs = 2; + ULSCH_dci_tdd16->ndi = 1; + ULSCH_dci_tdd16->TPC = 1; + ULSCH_dci_tdd16->cshift = cba_group; + ULSCH_dci_tdd16->dai = UE_list->UE_template[CC_id][cba_group].DAI_ul[sched_subframe]; + ULSCH_dci_tdd16->cqi_req = 1; + + //add_ue_spec_dci + add_common_dci(DCI_pdu, + ULSCH_dci_tdd16, + eNB_mac_inst[module_idP][CC_id].cba_rnti[cba_group], + sizeof(DCI0_5MHz_TDD_1_6_t), + aggregation, + sizeof_DCI0_5MHz_TDD_1_6_t, + format0, + 0); + } + else { + ULSCH_dci_fdd = (DCI0_5MHz_FDD_t *)UE_list->UE_template[CC_id][cba_group].ULSCH_DCI[0]; + + ULSCH_dci_fdd->type = 0; + ULSCH_dci_fdd->hopping = 0; + ULSCH_dci_fdd->rballoc = rballoc; + ULSCH_dci_fdd->mcs = 2; + ULSCH_dci_fdd->ndi = 1; + ULSCH_dci_fdd->TPC = 1; + ULSCH_dci_fdd->cshift = 0; + ULSCH_dci_fdd->cqi_req = 1; + + //add_ue_spec_dci + add_common_dci(DCI_pdu, + ULSCH_dci_fdd, + eNB_mac_inst[module_idP][CC_id].cba_rnti[cba_group], + sizeof(DCI0_5MHz_FDD_t), + aggregation, + sizeof_DCI0_5MHz_FDD_t, + format0, + 0); + } + nCCE[CC_id] = nCCE[CC_id] + (1<<aggregation) * num_cba_resources[cba_group]; + nCCE_available[CC_id] = mac_xface->get_nCCE_max(module_idP,CC_id) - nCCE[CC_id]; + // break;// for the moment only schedule one + } } + } } } #endif diff --git a/openair2/LAYER2/MAC/l1_helpers.c b/openair2/LAYER2/MAC/l1_helpers.c index dbcf43a020..6e756b6401 100644 --- a/openair2/LAYER2/MAC/l1_helpers.c +++ b/openair2/LAYER2/MAC/l1_helpers.c @@ -41,21 +41,33 @@ #include "UTIL/LOG/log.h" #include "proto.h" -int8_t get_Po_NOMINAL_PUSCH(module_id_t module_idP) { +int8_t get_Po_NOMINAL_PUSCH(module_id_t module_idP,int CC_id) { RACH_ConfigCommon_t *rach_ConfigCommon = NULL; + if (CC_id>0) { + LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n"); + mac_xface->macphy_exit("MAC FATAL CC_id>0"); + return; + } + if (UE_mac_inst[module_idP].radioResourceConfigCommon) rach_ConfigCommon = &UE_mac_inst[module_idP].radioResourceConfigCommon->rach_ConfigCommon; else { - LOG_E(MAC,"[UE %d] FATAL radioResourceConfigCommon is NULL !!!\n",module_idP); + LOG_E(MAC,"[UE %d] CCid %d FATAL radioResourceConfigCommon is NULL !!!\n",module_idP,CC_id); mac_xface->macphy_exit("FATAL radioResourceConfigCommon is NULL"); } return(-120 + (rach_ConfigCommon->powerRampingParameters.preambleInitialReceivedTargetPower<<1) + - get_DELTA_PREAMBLE(module_idP)); + get_DELTA_PREAMBLE(module_idP,CC_id)); } -int8_t get_deltaP_rampup(module_id_t module_idP) { +int8_t get_deltaP_rampup(module_id_t module_idP,int CC_id) { + + if (CC_id>0) { + LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n"); + mac_xface->macphy_exit("MAC FATAL CC_id>0"); + return; + } LOG_D(MAC,"[PUSCH]%d dB\n",UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER<<1); return((int8_t)(UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER<<1)); diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index 379f600580..40e85b9ad5 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -115,6 +115,9 @@ int mac_top_init(int eMBMS_active, uint8_t cba_group_active, uint8_t HO_active){ RA_TEMPLATE *RA_template; UE_TEMPLATE *UE_template; int size_bytes1,size_bytes2,size_bits1,size_bits2; + int CC_id; + int list_el; + UE_list_t *UE_list; LOG_I(MAC,"[MAIN] Init function start:Nb_UE_INST=%d\n",NB_UE_INST); if (NB_UE_INST>0) { @@ -137,19 +140,31 @@ int mac_top_init(int eMBMS_active, uint8_t cba_group_active, uint8_t HO_active){ if (NB_eNB_INST>0) { eNB_mac_inst = (eNB_MAC_INST*)malloc16(NB_eNB_INST*sizeof(eNB_MAC_INST)); if (eNB_mac_inst == NULL){ - LOG_D(MAC,"[MAIN] can't ALLOCATE %d Bytes for %d eNB_MAC_INST with size %d \n",NB_eNB_INST*sizeof(eNB_MAC_INST),NB_eNB_INST,sizeof(eNB_MAC_INST)); + LOG_D(MAC,"[MAIN] can't ALLOCATE %d Bytes for %d eNB_MAC_INST with size %d \n",NB_eNB_INST*sizeof(eNB_MAC_INST*),NB_eNB_INST,sizeof(eNB_MAC_INST)); mac_xface->macphy_exit("[MAC][MAIN] not enough memory for eNB \n"); } - LOG_D(MAC,"[MAIN] ALLOCATE %d Bytes for %d eNB_MAC_INST @ %p\n",NB_eNB_INST*sizeof(eNB_MAC_INST),NB_eNB_INST,eNB_mac_inst); - bzero(eNB_mac_inst,NB_eNB_INST*sizeof(eNB_MAC_INST)); + else{ + LOG_D(MAC,"[MAIN] ALLOCATE %d Bytes for %d eNB_MAC_INST @ %p\n",sizeof(eNB_MAC_INST),NB_eNB_INST,eNB_mac_inst); + bzero(eNB_mac_inst,NB_eNB_INST*sizeof(eNB_MAC_INST)); + } } else eNB_mac_inst = NULL; + // Initialize Linked-List for Active UEs for(Mod_id=0;Mod_id<NB_eNB_INST;Mod_id++){ - + UE_list = &eNB_mac_inst[Mod_id].UE_list; + + UE_list->num_UEs=0; + UE_list->head=-1; + UE_list->avail=0; + for (list_el=0;list_el<NUMBER_OF_UE_MAX-1;list_el++) { + UE_list->next[list_el]=list_el+1; + } + UE_list->next[list_el]=-1; + #ifdef PHY_EMUL - Mac_rlc_xface->Is_cluster_head[Mod_id]=2;//0: MR, 1: CH, 2: not CH neither MR + Mac_rlc_xface->Is_cluster_head[Mod_id]=2;//0: MR, 1: CH, 2: not CH neither MR #endif /*#ifdef Rel10 int n; @@ -181,11 +196,12 @@ int mac_top_init(int eMBMS_active, uint8_t cba_group_active, uint8_t HO_active){ // Set up DCIs for TDD 5MHz Config 1..6 - for (i=0;i<NB_eNB_INST;i++) { + for (i=0;i<NB_eNB_INST;i++) + for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { LOG_D(MAC,"[MAIN][eNB %d] initializing RA_template\n",i); LOG_D(MAC, "[MSC_NEW][FRAME 00000][MAC_eNB][MOD %02d][]\n", i); - RA_template = (RA_TEMPLATE *)&eNB_mac_inst[i].RA_template[0]; + RA_template = (RA_TEMPLATE *)&eNB_mac_inst[i].common_channels[CC_id].RA_template[0]; for (j=0;j<NB_RA_PROC_MAX;j++) { if (mac_xface->lte_frame_parms->frame_type == TDD) { switch (mac_xface->lte_frame_parms->N_RB_DL) { @@ -268,13 +284,13 @@ int mac_top_init(int eMBMS_active, uint8_t cba_group_active, uint8_t HO_active){ } memset (&eNB_mac_inst[i].eNB_stats,0,sizeof(eNB_STATS)); - UE_template = (UE_TEMPLATE *)&eNB_mac_inst[i].UE_template[0]; + UE_template = (UE_TEMPLATE *)&eNB_mac_inst[i].UE_list.UE_template[CC_id][0]; for (j=0;j<NUMBER_OF_UE_MAX;j++) { UE_template[j].rnti=0; // initiallize the eNB to UE statistics - memset (&eNB_mac_inst[i].eNB_UE_stats[j],0,sizeof(eNB_UE_STATS)); + memset (&eNB_mac_inst[i].UE_list.eNB_UE_stats[CC_id][j],0,sizeof(eNB_UE_STATS)); } - } + } //ICIC init param @@ -284,15 +300,16 @@ int mac_top_init(int eMBMS_active, uint8_t cba_group_active, uint8_t HO_active){ srand (time(NULL)); - for(j=0;j<NB_eNB_INST;j++){ - eNB_mac_inst[j].sbmap_conf.first_subframe=0; - eNB_mac_inst[j].sbmap_conf.periodicity=10; - eNB_mac_inst[j].sbmap_conf.sb_size=SB_size; - eNB_mac_inst[j].sbmap_conf.nb_active_sb=1; + for(j=0;j<NB_eNB_INST;j++) + for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++){ + eNB_mac_inst[j][CC_id].sbmap_conf.first_subframe=0; + eNB_mac_inst[j][CC_id].sbmap_conf.periodicity=10; + eNB_mac_inst[j][CC_id].sbmap_conf.sb_size=SB_size; + eNB_mac_inst[j][CC_id].sbmap_conf.nb_active_sb=1; for(i=0;i<NUMBER_OF_SUBBANDS;i++) - eNB_mac_inst[j].sbmap_conf.sbmap[i]=1; + eNB_mac_inst[j][CC_id].sbmap_conf.sbmap[i]=1; - eNB_mac_inst[j].sbmap_conf.sbmap[rand()%NUMBER_OF_SUBBANDS]=0; + eNB_mac_inst[j][CC_id].sbmap_conf.sbmap[rand()%NUMBER_OF_SUBBANDS]=0; } #endif diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index fd025749fc..659c6acd35 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -50,10 +50,6 @@ #include "UTIL/OPT/opt.h" #include "OCG.h" #include "OCG_extern.h" -#include "ARCH/CBMIMO1/DEVICE_DRIVER/extern.h" -#include "ARCH/CBMIMO1/DEVICE_DRIVER/defs.h" -#include "ARCH/CBMIMO1/DEVICE_DRIVER/from_grlib_softregs.h" - #include "RRC/LITE/extern.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" @@ -69,7 +65,7 @@ #ifndef USER_MODE #define msg debug_msg #endif - */ +*/ extern inline unsigned int taus(void); @@ -80,382 +76,436 @@ void store_dlsch_buffer (module_id_t Mod_id, frame_t frameP, sub_frame_t subframeP){ - module_id_t next_ue; + int UE_id,i; rnti_t rnti; - uint16_t i=0; mac_rlc_status_resp_t rlc_status; - unsigned char UE_id,granted_UEs; - - granted_UEs = find_dlgranted_UEs(Mod_id); - - for (UE_id=0;UE_id<granted_UEs;UE_id++){ - eNB_mac_inst[Mod_id].UE_template[UE_id].dl_buffer_total = 0; - eNB_mac_inst[Mod_id].UE_template[UE_id].dl_pdus_total = 0; - for(i=0;i< MAX_NUM_LCID; i++) { - eNB_mac_inst[Mod_id].UE_template[UE_id].dl_buffer_info[i]=0; - eNB_mac_inst[Mod_id].UE_template[UE_id].dl_pdus_in_buffer[i]=0; - eNB_mac_inst[Mod_id].UE_template[UE_id].dl_buffer_head_sdu_creation_time[i]=0; - eNB_mac_inst[Mod_id].UE_template[UE_id].dl_buffer_head_sdu_remaining_size_to_send[i]=0; - } - } - - for (UE_id=0;UE_id<granted_UEs;UE_id++) { - - next_ue = UE_id; - rnti = find_UE_RNTI(Mod_id,next_ue); - if (rnti == 0) - continue; - - for(i=0;i< MAX_NUM_LCID; i++){ // loop over all the logical channels - - rlc_status = mac_rlc_status_ind(Mod_id,next_ue, frameP,ENB_FLAG_YES,MBMS_FLAG_NO,i,0 ); - eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_info[i] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel - eNB_mac_inst[Mod_id].UE_template[next_ue].dl_pdus_in_buffer[i] = rlc_status.pdus_in_buffer; - eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_creation_time[i] = rlc_status.head_sdu_creation_time ; - eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_remaining_size_to_send[i] = rlc_status.head_sdu_remaining_size_to_send; - eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_is_segmented[i] = rlc_status.head_sdu_is_segmented; - eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_total = eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_total + eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_info[i];//storing the total dlsch buffer - eNB_mac_inst[Mod_id].UE_template[next_ue].dl_pdus_total += eNB_mac_inst[Mod_id].UE_template[next_ue].dl_pdus_in_buffer[i]; - + UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list; + UE_TEMPLATE *UE_template; + + for (UE_id=UE_list->head;UE_id>=0;UE_id=UE_list->next[UE_id]){ + + UE_template = &UE_list->UE_template[UE_PCCID(Mod_id,UE_id)][UE_id]; + + // clear logical channel interface variables + UE_template->dl_buffer_total = 0; + UE_template->dl_pdus_total = 0; + for(i=0;i< MAX_NUM_LCID; i++) { + UE_template->dl_buffer_info[i]=0; + UE_template->dl_pdus_in_buffer[i]=0; + UE_template->dl_buffer_head_sdu_creation_time[i]=0; + UE_template->dl_buffer_head_sdu_remaining_size_to_send[i]=0; + } + + rnti = UE_RNTI(Mod_id,UE_id); + + for(i=0;i< MAX_NUM_LCID; i++){ // loop over all the logical channels + + rlc_status = mac_rlc_status_ind(Mod_id,UE_id, frameP,ENB_FLAG_YES,MBMS_FLAG_NO,i,0 ); + UE_template->dl_buffer_info[i] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel + UE_template->dl_pdus_in_buffer[i] = rlc_status.pdus_in_buffer; + UE_template->dl_buffer_head_sdu_creation_time[i] = rlc_status.head_sdu_creation_time ; + UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = rlc_status.head_sdu_remaining_size_to_send; + UE_template->dl_buffer_head_sdu_is_segmented[i] = rlc_status.head_sdu_is_segmented; + UE_template->dl_buffer_total = UE_template->dl_buffer_total + UE_template->dl_buffer_info[i];//storing the total dlsch buffer + UE_template->dl_pdus_total += UE_template->dl_pdus_in_buffer[i]; + #ifdef DEBUG_eNB_SCHEDULER - /* note for dl_buffer_head_sdu_remaining_size_to_send[i] : - * 0 if head SDU has not been segmented (yet), else remaining size not already segmented and sent - */ - if (eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_info[i]>0) - LOG_D(MAC,"[eNB %d] Frame %d Subframe %d : RLC status for UE %d in LCID%d: total of %d pdus and %d size, head sdu queuing time %d, remaining size %d, is segmeneted %d \n", - Mod_id, frameP, subframeP, next_ue, - i, eNB_mac_inst[Mod_id].UE_template[next_ue].dl_pdus_in_buffer[i],eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_info[i], - eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_creation_time[i], - eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_remaining_size_to_send[i], - eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_is_segmented[i] - ); + /* note for dl_buffer_head_sdu_remaining_size_to_send[i] : + * 0 if head SDU has not been segmented (yet), else remaining size not already segmented and sent + */ + if (UE_template->dl_buffer_info[i]>0) + LOG_D(MAC,"[eNB %d] Frame %d Subframe %d : RLC status for UE %d in LCID%d: total of %d pdus and size %d, head sdu queuing time %d, remaining size %d, is segmeneted %d \n", + Mod_id, frameP, subframeP, UE_id, + i, UE_template->dl_pdus_in_buffer[i],UE_template->dl_buffer_info[i], + UE_template->dl_buffer_head_sdu_creation_time[i], + UE_template->dl_buffer_head_sdu_remaining_size_to_send[i], + UE_template->dl_buffer_head_sdu_is_segmented[i] + ); #endif - - } + + } #ifdef DEBUG_eNB_SCHEDULER - if ( eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_total>0) - LOG_D(MAC,"[eNB %d] Frame %d Subframe %d : RLC status for UE %d : total DL buffer size %d and total number of pdu %d \n", - Mod_id, frameP, subframeP, next_ue, - eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_total, - eNB_mac_inst[Mod_id].UE_template[next_ue].dl_pdus_total - ); + if ( UE_template->dl_buffer_total>0) + LOG_D(MAC,"[eNB %d] Frame %d Subframe %d : RLC status for UE %d : total DL buffer size %d and total number of pdu %d \n", + Mod_id, frameP, subframeP, UE_id, + UE_template->dl_buffer_total, + UE_template->dl_pdus_total + ); #endif } } // This function returns the estimated number of RBs required by each UE for downlink scheduling -void assign_rbs_required (module_id_t Mod_id, - frame_t frameP, - sub_frame_t subframe, - uint16_t *nb_rbs_required){ +void assign_rbs_required (module_id_t Mod_id, + frame_t frameP, + sub_frame_t subframe, + uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], + int min_rb_unit[MAX_NUM_CCs]){ - module_id_t next_ue; - rnti_t rnti; - uint16_t TBS = 0; - LTE_eNB_UE_stats *eNB_UE_stats = NULL; - module_id_t ue_inst; - unsigned char granted_UEs; - - granted_UEs = find_dlgranted_UEs(Mod_id); + rnti_t rnti; + uint16_t TBS = 0; + LTE_eNB_UE_stats *eNB_UE_stats[MAX_NUM_CCs]; + int UE_id,n,i,j,CC_id,pCCid,tmp; + UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list; - for (ue_inst=0;ue_inst<granted_UEs;ue_inst++){ - nb_rbs_required[ue_inst] = 0; //initialization - } + // clear rb allocations across all CC_ids + for (UE_id=UE_list->head;UE_id>=0;UE_id=UE_list->next[UE_id]){ - for (ue_inst=0;ue_inst<granted_UEs;ue_inst++) { + pCCid = UE_PCCID(Mod_id,UE_id); - next_ue = ue_inst; - rnti = find_UE_RNTI(Mod_id,next_ue); - if (rnti == 0) - continue; + //update CQI information across component carriers + for (n=0;n<UE_list->numactiveCCs[UE_id];n++) { - eNB_UE_stats = mac_xface->get_eNB_UE_stats(Mod_id,rnti); - //if(eNB_UE_stats == NULL) - //continue; + CC_id = UE_list->ordered_CCids[n][UE_id]; + eNB_UE_stats[CC_id] = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti); - switch(eNB_UE_stats->DL_cqi[0]) - { + switch(eNB_UE_stats[CC_id]->DL_cqi[0]) { case 0: - eNB_UE_stats->dlsch_mcs1 = 0; - break; + eNB_UE_stats[CC_id]->dlsch_mcs1 = 0; + break; case 1: - eNB_UE_stats->dlsch_mcs1 = 0; - break; + eNB_UE_stats[CC_id]->dlsch_mcs1 = 0; + break; case 2: - eNB_UE_stats->dlsch_mcs1 = 0; - break; + eNB_UE_stats[CC_id]->dlsch_mcs1 = 0; + break; case 3: - eNB_UE_stats->dlsch_mcs1 = 2; - break; + eNB_UE_stats[CC_id]->dlsch_mcs1 = 2; + break; case 4: - eNB_UE_stats->dlsch_mcs1 = 4; - break; + eNB_UE_stats[CC_id]->dlsch_mcs1 = 4; + break; case 5: - eNB_UE_stats->dlsch_mcs1 = 6; - break; + eNB_UE_stats[CC_id]->dlsch_mcs1 = 6; + break; case 6: - eNB_UE_stats->dlsch_mcs1 = 8; - break; + eNB_UE_stats[CC_id]->dlsch_mcs1 = 8; + break; case 7: - eNB_UE_stats->dlsch_mcs1 = 11; - break; + eNB_UE_stats[CC_id]->dlsch_mcs1 = 11; + break; case 8: - eNB_UE_stats->dlsch_mcs1 = 13; - break; + eNB_UE_stats[CC_id]->dlsch_mcs1 = 13; + break; case 9: - eNB_UE_stats->dlsch_mcs1 = 16; - break; + eNB_UE_stats[CC_id]->dlsch_mcs1 = 16; + break; case 10: - eNB_UE_stats->dlsch_mcs1 = 18; - break; + eNB_UE_stats[CC_id]->dlsch_mcs1 = 18; + break; case 11: - eNB_UE_stats->dlsch_mcs1 = 20; - break; + eNB_UE_stats[CC_id]->dlsch_mcs1 = 20; + break; case 12: - eNB_UE_stats->dlsch_mcs1 = 22; - break; + eNB_UE_stats[CC_id]->dlsch_mcs1 = 22; + break; case 13: - eNB_UE_stats->dlsch_mcs1 = 22;//25 - break; + eNB_UE_stats[CC_id]->dlsch_mcs1 = 25; + break; case 14: - eNB_UE_stats->dlsch_mcs1 = 22;//27 - break; + eNB_UE_stats[CC_id]->dlsch_mcs1 = 27; + break; case 15: - eNB_UE_stats->dlsch_mcs1 = 22;//28 - break; + eNB_UE_stats[CC_id]->dlsch_mcs1 = 28; + break; default: - printf("Invalid CQI"); - exit(-1); + LOG_E(MAC,"preprocessor.c assign_rbs_required(): Invalid CQI %d, should not happen",eNB_UE_stats[CC_id]->DL_cqi[0]); + exit(-1); } - - - - if ((mac_get_rrc_status(Mod_id,1,next_ue) < RRC_RECONFIGURED)){ - nb_rbs_required[next_ue] = mac_xface->lte_frame_parms->N_RB_DL; - continue; + } + + // provide the list of CCs sorted according to MCS + for (i=0;i<UE_list->numactiveCCs[UE_id];i++) { + for (j=i+1;j<UE_list->numactiveCCs[UE_id];j++) { + if (eNB_UE_stats[UE_list->ordered_CCids[i][UE_id]]->dlsch_mcs1 > + eNB_UE_stats[UE_list->ordered_CCids[j][UE_id]]->dlsch_mcs1) { + tmp = UE_list->ordered_CCids[i][UE_id]; + UE_list->ordered_CCids[i][UE_id] = UE_list->ordered_CCids[j][UE_id]; + UE_list->ordered_CCids[j][UE_id] = tmp; + } } + } + + + + if ((mac_get_rrc_status(Mod_id,1,UE_id) < RRC_RECONFIGURED)){ // If we still don't have a default radio bearer + nb_rbs_required[pCCid][UE_id] = PHY_vars_eNB_g[Mod_id][pCCid]->lte_frame_parms.N_RB_DL; + continue; + } + + if (UE_list->UE_template[UE_id]->dl_buffer_total> 0) { + for (i=0;i<UE_list->numactiveCCs[UE_id];i++) { + CC_id = UE_list->ordered_CCids[i][UE_id]; + + if (eNB_UE_stats[CC_id]->dlsch_mcs1==0) nb_rbs_required[CC_id][UE_id] = 4; // don't let the TBS get too small + else nb_rbs_required[CC_id][UE_id] = min_rb_unit[CC_id]; + + TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1,nb_rbs_required[CC_id][UE_id]); + + while (TBS < UE_list->UE_template[UE_id]->dl_buffer_total) { + nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id]; + if (nb_rbs_required[CC_id][UE_id]>PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL) { + TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1,PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL); + nb_rbs_required[CC_id][UE_id] = PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL;// calculating required number of RBs for each UE + break; + } + TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1,nb_rbs_required[CC_id][UE_id]); + } + } + } + } +} - if (eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_total> 0) { - - if (eNB_UE_stats->dlsch_mcs1==0) nb_rbs_required[next_ue] = 4; // don't let the TBS get too small - else nb_rbs_required[next_ue] = 2; - TBS = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_rbs_required[next_ue]); +// This function scans all CC_ids for a particular UE to find the maximum round index of its HARQ processes - while (TBS < eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_total) { - nb_rbs_required[next_ue] += 2; - if (nb_rbs_required[next_ue]>mac_xface->lte_frame_parms->N_RB_DL) { - TBS = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,mac_xface->lte_frame_parms->N_RB_DL); - nb_rbs_required[next_ue] = mac_xface->lte_frame_parms->N_RB_DL;// calculating required number of RBs for each UE - break; - } - TBS = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_rbs_required[next_ue]); - } +int maxround(module_id_t Mod_id,uint16_t rnti,sub_frame_t subframe) { - } + uint8_t round,round_max=0,harq_pid; + int CC_id; + for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++){ + mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,subframe,&harq_pid,&round,0); + if (round > round_max) + round_max = round; } -} - - -// This fuction sorts the UE in order their dlsch buffer and CQI -void sort_UEs (module_id_t Mod_id, - sub_frame_t subframe, - module_id_t *UE_id_sorted){ - - module_id_t next_ue1,next_ue2; - unsigned char round1=0,round2=0,harq_pid1=0,harq_pid2=0; - module_id_t ue_inst; - uint16_t granted_UEs,i=0,ii=0,j=0; - rnti_t rnti1,rnti2; - LTE_eNB_UE_stats *eNB_UE_stats1 = NULL; - LTE_eNB_UE_stats *eNB_UE_stats2 = NULL; +} +// This function scans all CC_ids for a particular UE to find the maximum DL CQI - granted_UEs = find_dlgranted_UEs(Mod_id); +int maxcqi(module_id_t Mod_id,uint16_t rnti) { + LTE_eNB_UE_stats *eNB_UE_stats = NULL; + int CC_id; + int CQI = 0; - for (ue_inst=0;ue_inst<granted_UEs;ue_inst++) { - UE_id_sorted[i] = ue_inst; - i++; + for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++){ + eNB_UE_stats = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti); + if (eNB_UE_stats->DL_cqi[0] > CQI) + CQI = eNB_UE_stats->DL_cqi[0]; } - for(i=0; i < granted_UEs;i++){ + return(CQI); +} - next_ue1 = UE_id_sorted[i]; - rnti1 = find_UE_RNTI(Mod_id,next_ue1); - if(rnti1 == 0) - continue; +// This fuction sorts the UE in order their dlsch buffer and CQI +void sort_UEs (module_id_t Mod_id, + sub_frame_t subframe) { - eNB_UE_stats1 = mac_xface->get_eNB_UE_stats(Mod_id,rnti1); - mac_xface->get_ue_active_harq_pid(Mod_id,rnti1,subframe,&harq_pid1,&round1,0); + int UE_id1,UE_id2; + int pCC_id1,pCC_id2; + int cqi1,cqi2,round1,round2; + int i=0,ii=0,j=0; + rnti_t rnti1,rnti2; + UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list; - for(ii=i+1;ii<granted_UEs;ii++){ + for (i=UE_list->head;i>=0;i=UE_list->next[i]) { - next_ue2 = UE_id_sorted[ii]; + rnti1 = UE_RNTI(Mod_id,i); + if(rnti1 == 0) + continue; - rnti2 = find_UE_RNTI(Mod_id,next_ue2); - if(rnti2 == 0) - continue; + UE_id1 = i; + pCC_id1 = UE_PCCID(Mod_id,UE_id1); + cqi1 = maxcqi(Mod_id,rnti1); // + round1 = maxround(Mod_id,rnti1,subframe); - eNB_UE_stats2 = mac_xface->get_eNB_UE_stats(Mod_id,rnti2); - mac_xface->get_ue_active_harq_pid(Mod_id,rnti2,subframe,&harq_pid2,&round2,0); + for(ii=UE_list->next[i];ii>=0;ii=UE_list->next[ii]){ - if(round2 > round1){ - UE_id_sorted[i] = next_ue2; - UE_id_sorted[ii] = next_ue1; - } - else if (round2 == round1){ - for(j=0;j<MAX_NUM_LCID;j++){ + UE_id2 = ii; + rnti2 = UE_RNTI(Mod_id,UE_id2); + if(rnti2 == 0) + continue; - if(eNB_mac_inst[Mod_id].UE_template[next_ue1].dl_buffer_info[j] < eNB_mac_inst[Mod_id].UE_template[next_ue2].dl_buffer_info[j]){ - UE_id_sorted[i] = next_ue2; - UE_id_sorted[ii] = next_ue1; - break; - } - else if((j == MAX_NUM_LCID-1)) - { - /* The goal is to sort by priority. - * We use the priority of DTCH logical - * channel. - */ - /*if(eNB_mac_inst[Mod_id].UE_sched_ctrl[next_ue1].priority[3]<eNB_mac_inst[Mod_id].UE_sched_ctrl[next_ue2].priority[3]) - { - UE_id_sorted[i] = next_ue2; - UE_id_sorted[ii] = next_ue1; - } //if the priority is the same then sort by CQI - else if(eNB_mac_inst[Mod_id].UE_sched_ctrl[next_ue1].priority[3]==eNB_mac_inst[Mod_id].UE_sched_ctrl[next_ue2].priority[3]){*/ + cqi2 = maxcqi(Mod_id,rnti2); + round2 = maxround(Mod_id,rnti2,subframe); //mac_xface->get_ue_active_harq_pid(Mod_id,rnti2,subframe,&harq_pid2,&round2,0); + pCC_id2 = UE_PCCID(Mod_id,UE_id2); - if(eNB_UE_stats1->DL_cqi[0] < eNB_UE_stats2->DL_cqi[0]){ - UE_id_sorted[i] = next_ue2; - UE_id_sorted[ii] = next_ue1; - } - //} - } - } - } + if(round2 > round1){ // Check first if one of the UEs has an active HARQ process which needs service and swap order + swap_UEs(UE_list,UE_id1,UE_id2); } + else if (round2 == round1){ + // RK->NN : I guess this is for fairness in the scheduling. This doesn't make sense unless all UEs have the same configuration of logical channels. This should be done on the sum of all information that has to be sent. And still it wouldn't ensure fairness. It should be based on throughput seen by each UE or maybe using the head_sdu_creation_time, i.e. swap UEs if one is waiting longer for service. + // for(j=0;j<MAX_NUM_LCID;j++){ + // if (eNB_mac_inst[Mod_id][pCC_id1].UE_template[UE_id1].dl_buffer_info[j] < + // eNB_mac_inst[Mod_id][pCC_id2].UE_template[UE_id2].dl_buffer_info[j]){ + if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total < + UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total){ + swap_UEs(UE_list,UE_id1,UE_id2); + // break; + } + else if (cqi1 < cqi2){ + swap_UEs(UE_list,UE_id1,UE_id2); + } + + + // if((j == MAX_NUM_LCID-1)) + // { + + /* The goal is to sort by priority. + * We use the priority of DTCH logical + * channel. + */ + /*if(eNB_mac_inst[Mod_id][CC_id].UE_sched_ctrl[UE_id1].priority[3]<eNB_mac_inst[Mod_id][CC_id].UE_sched_ctrl[UE_id2].priority[3]) + { + UE_id_sorted[i] = UE_id2; + UE_id_sorted[ii] = UE_id1; + } //if the priority is the same then sort by CQI + else if(eNB_mac_inst[Mod_id][CC_id].UE_sched_ctrl[UE_id1].priority[3]==eNB_mac_inst[Mod_id][CC_id].UE_sched_ctrl[UE_id2].priority[3]){*/ + + + //} + // } + } + } } } + + // This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done -void dlsch_scheduler_pre_processor (module_id_t Mod_id, - frame_t frameP, - sub_frame_t subframeP, - uint8_t *dl_pow_off, - uint16_t *pre_nb_available_rbs, - int N_RBGS, - unsigned char rballoc_sub_UE[NUMBER_OF_UE_MAX][N_RBGS_MAX]){ - - unsigned char next_ue,next_ue1,next_ue2,rballoc_sub[mac_xface->lte_frame_parms->N_RBGS],harq_pid=0,harq_pid1=0,harq_pid2=0,round=0,round1=0,round2=0,total_ue_count=0; - unsigned char MIMO_mode_indicator[mac_xface->lte_frame_parms->N_RBGS]; - module_id_t UE_id, i; - module_id_t UE_id_sorted[NUMBER_OF_UE_MAX]; - module_id_t granted_UEs; +void dlsch_scheduler_pre_processor (module_id_t Mod_id, + frame_t frameP, + sub_frame_t subframeP, + uint8_t dl_pow_off[MAX_NUM_CCs][NUMBER_OF_UE_MAX], + uint16_t pre_nb_available_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX], + int N_RBGS[MAX_NUM_CCs], + unsigned char rballoc_sub_UE[MAX_NUM_CCs][NUMBER_OF_UE_MAX][N_RBGS_MAX], + int *mbsfn_flag){ + + unsigned char rballoc_sub[MAX_NUM_CCs][13],harq_pid=0,harq_pid1=0,harq_pid2=0,round=0,round1=0,round2=0,total_ue_count[MAX_NUM_CCs]; + unsigned char MIMO_mode_indicator[MAX_NUM_CCs][13]; + int UE_id, UE_id2, i; uint16_t ii,j; - uint16_t nb_rbs_required[NUMBER_OF_UE_MAX]; - uint16_t nb_rbs_required_remaining[NUMBER_OF_UE_MAX]; - uint16_t nb_rbs_required_remaining_1[NUMBER_OF_UE_MAX]; + uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; + uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; + uint16_t nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; uint16_t i1,i2,i3,r1=0; - uint16_t average_rbs_per_user=0; + uint16_t average_rbs_per_user[MAX_NUM_CCs]; rnti_t rnti,rnti1,rnti2; LTE_eNB_UE_stats *eNB_UE_stats1 = NULL; LTE_eNB_UE_stats *eNB_UE_stats2 = NULL; - uint16_t min_rb_unit; - - - switch (mac_xface->lte_frame_parms->N_RB_DL) { - case 6: - min_rb_unit=1; - break; - case 25: - min_rb_unit=2; - break; - case 50: - min_rb_unit=3; - break; - case 100: - min_rb_unit=4; - break; - default: - min_rb_unit=2; - break; + int min_rb_unit[MAX_NUM_CCs]; + + int CC_id; + UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list; + + + for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { + + if (mbsfn_flag[CC_id]>0) // If this CC is allocated for MBSFN skip it here + continue; + + switch (PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL) { + case 6: + min_rb_unit[CC_id]=1; + break; + case 25: + min_rb_unit[CC_id]=2; + break; + case 50: + min_rb_unit[CC_id]=3; + break; + case 100: + min_rb_unit[CC_id]=4; + break; + default: + min_rb_unit[CC_id]=2; + break; + } + + // Initialize scheduling information for all active UEs + for (i=UE_list->head;i>=0;i=UE_list->next[i]) { + UE_id = i; + + nb_rbs_required[CC_id][UE_id] = 0; + dl_pow_off[CC_id][UE_id] =2; + pre_nb_available_rbs[CC_id][UE_id] = 0; + nb_rbs_required_remaining[CC_id][UE_id] = 0; + for(j=0;j<N_RBGS[CC_id];j++) + { + MIMO_mode_indicator[CC_id][j] = 2; + rballoc_sub[CC_id][j] = 0; + rballoc_sub_UE[CC_id][UE_id][j] = 0; + } + } } - granted_UEs = find_dlgranted_UEs(Mod_id); - - - for(i=0;i<NUMBER_OF_UE_MAX;i++){ - nb_rbs_required[i] = 0; - UE_id_sorted[i] = i; - dl_pow_off[i] =2; - pre_nb_available_rbs[i] = 0; - nb_rbs_required_remaining[i] = 0; - for(j=0;j<N_RBGS;j++) - { - MIMO_mode_indicator[j] = 2; - rballoc_sub[j] = 0; - rballoc_sub_UE[i][j] = 0; - } - } - - //printf("SUCCESS %d",mac_xface->lte_frame_parms->N_RBGS); - //exit(-1); // Store the DLSCH buffer for each logical channel store_dlsch_buffer (Mod_id,frameP,subframeP); - // Calculate the number of RBs required by each UE on the basis of logical channel's buffer - assign_rbs_required (Mod_id,frameP,subframeP,nb_rbs_required); + assign_rbs_required (Mod_id,frameP,subframeP,nb_rbs_required,min_rb_unit); // Sorts the user on the basis of dlsch logical channel buffer and CQI - sort_UEs (Mod_id,subframeP,UE_id_sorted); - //printf ("Frame:%d,SUCCESS %d[%d] %d[%d]\n",frameP,UE_id_sorted[0],nb_rbs_required[UE_id_sorted[0]],UE_id_sorted[1],nb_rbs_required[UE_id_sorted[1]]); - - for (i=0;i<granted_UEs;i++){ - rnti = find_UE_RNTI(Mod_id,i); - if(rnti == 0) - continue; - mac_xface->get_ue_active_harq_pid(Mod_id,rnti,subframeP,&harq_pid,&round,0); + sort_UEs (Mod_id,subframeP); + + + // loop over all active UEs + for (i=UE_list->head;i>=0;i=UE_list->next[i]) { + + UE_id = i; + + + rnti = UE_RNTI(Mod_id,UE_id); + if(rnti == 0) + continue; + + for (ii=0;ii<UE_num_active_CC(UE_list,UE_id);ii++) { + CC_id = UE_list->ordered_CCids[ii][UE_id]; + + total_ue_count[CC_id]=0; + average_rbs_per_user[CC_id]=0; + + + mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,subframeP,&harq_pid,&round,0); if(round>0) - nb_rbs_required[i] = eNB_mac_inst[Mod_id].UE_template[i].nb_rb[harq_pid]; - //nb_rbs_required_remaining[i] = nb_rbs_required[i]; - if(nb_rbs_required[i] > 0) - total_ue_count = total_ue_count + 1; - } + nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + //nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id]; + if (nb_rbs_required[CC_id][UE_id] > 0) { + total_ue_count[CC_id] = total_ue_count[CC_id] + 1; + } + // hypotetical assignement - /* - * If schedule is enabled and if the priority of the UEs is modified - * The average rbs per logical channel per user will depend on the level of - * priority. Concerning the hypothetical assignement, we should assign more - * rbs to prioritized users. Maybe, we can do a mapping between the - * average rbs per user and the level of priority or multiply the average rbs - * per user by a coefficient which represents the degree of priority. - */ - if((total_ue_count > 0) && ( min_rb_unit * total_ue_count <= mac_xface->lte_frame_parms->N_RB_DL ) ) - average_rbs_per_user = (uint16_t) ceil(mac_xface->lte_frame_parms->N_RB_DL/total_ue_count); - else - average_rbs_per_user = min_rb_unit; - - for(i=0;i<granted_UEs;i++){ + /* + * If schedule is enabled and if the priority of the UEs is modified + * The average rbs per logical channel per user will depend on the level of + * priority. Concerning the hypothetical assignement, we should assign more + * rbs to prioritized users. Maybe, we can do a mapping between the + * average rbs per user and the level of priority or multiply the average rbs + * per user by a coefficient which represents the degree of priority. + */ + + + if((total_ue_count[CC_id] > 0) && ( min_rb_unit[CC_id] * total_ue_count[CC_id] <= PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL ) ) + average_rbs_per_user[CC_id] = (uint16_t) ceil(PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL/total_ue_count[CC_id]); + else + average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; + } + } + + for(i=UE_list->head;i>=0;i=UE_list->next[i]){ + for (ii=0;ii<UE_num_active_CC(UE_list,UE_id);ii++) { + CC_id = UE_list->ordered_CCids[ii][UE_id]; // control channel if (mac_get_rrc_status(Mod_id,1,i) < RRC_RECONFIGURED) - nb_rbs_required_remaining_1[i] = nb_rbs_required[i]; + nb_rbs_required_remaining_1[CC_id][i] = nb_rbs_required[CC_id][i]; else - nb_rbs_required_remaining_1[i] = cmin(average_rbs_per_user,nb_rbs_required[i]); + nb_rbs_required_remaining_1[CC_id][i] = cmin(average_rbs_per_user[CC_id],nb_rbs_required[CC_id][i]); + } } @@ -464,325 +514,347 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id, // 2nd round: remaining RBs are allocated to high priority UEs for(r1=0;r1<2;r1++){ - for(i=0; i<granted_UEs;i++) - { - if(r1 == 0) - nb_rbs_required_remaining[i] = nb_rbs_required_remaining_1[i]; - else // rb required based only on the buffer - rb allloctaed in the 1st round + extra reaming rb form the 1st round - nb_rbs_required_remaining[i] = nb_rbs_required[i]-nb_rbs_required_remaining_1[i]+nb_rbs_required_remaining[i]; - } - // retransmission in control channels - for (i = 0 ;i<granted_UEs; i++){ - - next_ue = UE_id_sorted[i]; - rnti = find_UE_RNTI(Mod_id,next_ue); - if(rnti == 0) - continue; - mac_xface->get_ue_active_harq_pid(Mod_id,rnti,subframeP,&harq_pid,&round,0); - - if ((mac_get_rrc_status(Mod_id,1,next_ue) < RRC_RECONFIGURED) && (round >0)) { - - - - for(j=0;j<N_RBGS;j++){ - - if((rballoc_sub[j] == 0) && (rballoc_sub_UE[next_ue][j] == 0) && (nb_rbs_required_remaining[next_ue]>0)){ - - rballoc_sub[j] = 1; - rballoc_sub_UE[next_ue][j] = 1; - - MIMO_mode_indicator[j] = 1; - - if(mac_xface->get_transmission_mode(Mod_id,rnti)==5) - dl_pow_off[next_ue] = 1; - // if the total rb is odd - if ((j == N_RBGS-1) && - ((mac_xface->lte_frame_parms->N_RB_DL == 25)|| - (mac_xface->lte_frame_parms->N_RB_DL == 50))) { - nb_rbs_required_remaining[next_ue] = nb_rbs_required_remaining[next_ue] - min_rb_unit+1; - pre_nb_available_rbs[next_ue] = pre_nb_available_rbs[next_ue] + min_rb_unit - 1; - } - else { - nb_rbs_required_remaining[next_ue] = nb_rbs_required_remaining[next_ue] - min_rb_unit; - pre_nb_available_rbs[next_ue] = pre_nb_available_rbs[next_ue] + min_rb_unit; - } - } - } - } + for(i=UE_list->head; i>=0;i=UE_list->next[i]) { + for (ii=0;ii<UE_num_active_CC(UE_list,UE_id);ii++) { + CC_id = UE_list->ordered_CCids[ii][UE_id]; + + if(r1 == 0) + nb_rbs_required_remaining[CC_id][i] = nb_rbs_required_remaining_1[CC_id][i]; + else // rb required based only on the buffer - rb allloctaed in the 1st round + extra reaming rb form the 1st round + nb_rbs_required_remaining[CC_id][i] = nb_rbs_required[CC_id][i]-nb_rbs_required_remaining_1[CC_id][i]+nb_rbs_required_remaining[CC_id][i]; } - - - - // retransmission in data channels - for (i = 0 ;i<granted_UEs; i++){ - - next_ue = UE_id_sorted[i]; - rnti = find_UE_RNTI(Mod_id,next_ue); - if(rnti == 0) - continue; - mac_xface->get_ue_active_harq_pid(Mod_id,rnti,subframeP,&harq_pid,&round,0); - - if ((mac_get_rrc_status(Mod_id,1,next_ue) >= RRC_RECONFIGURED) && (round > 0)) { - - - - for(j=0;j<N_RBGS;j++){ - - if((rballoc_sub[j] == 0) && (rballoc_sub_UE[next_ue][j] == 0) && (nb_rbs_required_remaining[next_ue]>0)){ - - rballoc_sub[j] = 1; - rballoc_sub_UE[next_ue][j] = 1; - - MIMO_mode_indicator[j] = 1; - - if(mac_xface->get_transmission_mode(Mod_id,rnti)==5) - dl_pow_off[next_ue] = 1; - - if((j == N_RBGS-1) && - ((mac_xface->lte_frame_parms->N_RB_DL == 25)|| - (mac_xface->lte_frame_parms->N_RB_DL == 50))){ - nb_rbs_required_remaining[next_ue] = nb_rbs_required_remaining[next_ue] - min_rb_unit + 1; - pre_nb_available_rbs[next_ue] = pre_nb_available_rbs[next_ue] + min_rb_unit - 1; - } - else { - nb_rbs_required_remaining[next_ue] = nb_rbs_required_remaining[next_ue] - min_rb_unit; - pre_nb_available_rbs[next_ue] = pre_nb_available_rbs[next_ue] + min_rb_unit; - } - } - } - } + } + // retransmission in control channels + for(i=UE_list->head; i>=0;i=UE_list->next[i]) { + UE_id = i; + for (ii=0;ii<UE_num_active_CC(UE_list,UE_id);ii++) { + CC_id = UE_list->ordered_CCids[ii][UE_id]; + + + rnti = UE_RNTI(Mod_id,UE_id); + if(rnti == 0) + continue; + mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,subframeP,&harq_pid,&round,0); + + if ((mac_get_rrc_status(Mod_id,1,UE_id) < RRC_RECONFIGURED) && (round >0)) { + for(j=0;j<N_RBGS[CC_id];j++){ + + if((rballoc_sub[CC_id][j] == 0) && (rballoc_sub_UE[CC_id][UE_id][j] == 0) && (nb_rbs_required_remaining[UE_id]>0)){ + + rballoc_sub[CC_id][j] = 1; + rballoc_sub_UE[CC_id][UE_id][j] = 1; + + MIMO_mode_indicator[CC_id][j] = 1; + + if(mac_xface->get_transmission_mode(Mod_id,CC_id,rnti)==5) + dl_pow_off[CC_id][UE_id] = 1; + // if the total rb is odd + if ((j == N_RBGS[CC_id]-1) && + ((PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL == 25)|| + (PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL == 50))) { + nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id]+1; + pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + min_rb_unit[CC_id] - 1; + } + else { + nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id]; + pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + min_rb_unit[CC_id]; + } + } + } + } } - - - // control channel in the 1st transmission - for (i = 0 ;i<granted_UEs; i++){ - - next_ue = UE_id_sorted[i]; - rnti = find_UE_RNTI(Mod_id,next_ue); - if(rnti == 0) - continue; - mac_xface->get_ue_active_harq_pid(Mod_id,rnti,subframeP,&harq_pid,&round,0); - - if ((mac_get_rrc_status(Mod_id,1,next_ue) < RRC_RECONFIGURED) && (round == 0)) { - - - - - for(j=0;j<N_RBGS;j++){ - - if((rballoc_sub[j] == 0) && (rballoc_sub_UE[next_ue][j] == 0) && (nb_rbs_required_remaining[next_ue]>0)){ - - rballoc_sub[j] = 1; - rballoc_sub_UE[next_ue][j] = 1; - - MIMO_mode_indicator[j] = 1; - - if(mac_xface->get_transmission_mode(Mod_id,rnti)==5) - dl_pow_off[next_ue] = 1; - - if((j == N_RBGS-1) && - ((mac_xface->lte_frame_parms->N_RB_DL == 25)|| - (mac_xface->lte_frame_parms->N_RB_DL == 50))){ - nb_rbs_required_remaining[next_ue] = nb_rbs_required_remaining[next_ue] - min_rb_unit + 1; - pre_nb_available_rbs[next_ue] = pre_nb_available_rbs[next_ue] + min_rb_unit - 1; - } - else { - nb_rbs_required_remaining[next_ue] = nb_rbs_required_remaining[next_ue] - min_rb_unit; - pre_nb_available_rbs[next_ue] = pre_nb_available_rbs[next_ue] + min_rb_unit; - } - } - } - } + } + + + // retransmission in data channels + + for(i=UE_list->head; i>=0;i=UE_list->next[i]) { + UE_id = i; + for (ii=0;ii<UE_num_active_CC(UE_list,UE_id);ii++) { + CC_id = UE_list->ordered_CCids[ii][UE_id]; + + rnti = UE_RNTI(Mod_id,UE_id); + if(rnti == 0) + continue; + mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,subframeP,&harq_pid,&round,0); + + if ((mac_get_rrc_status(Mod_id,1,UE_id) >= RRC_RECONFIGURED) && (round > 0)) { + + for(j=0;j<N_RBGS[CC_id];j++){ + + if((rballoc_sub[CC_id][j] == 0) && (rballoc_sub_UE[CC_id][UE_id][j] == 0) && (nb_rbs_required_remaining[UE_id]>0)){ + + rballoc_sub[CC_id][j] = 1; + rballoc_sub_UE[CC_id][UE_id][j] = 1; + + MIMO_mode_indicator[CC_id][j] = 1; + + if(mac_xface->get_transmission_mode(Mod_id,CC_id,rnti)==5) + dl_pow_off[CC_id][UE_id] = 1; + + if((j == N_RBGS[CC_id]-1) && + ((PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL == 25)|| + (PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL == 50))){ + nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id] + 1; + pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + min_rb_unit[CC_id] - 1; + } + else { + nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id]; + pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + min_rb_unit[CC_id]; + } + } + } + } } - - - - // data chanel TM5 - for (i = 0 ;i<granted_UEs; i++){ - - - next_ue1 = UE_id_sorted[i]; - rnti1 = find_UE_RNTI(Mod_id,next_ue1); - if(rnti1 == 0) - continue; - - eNB_UE_stats1 = mac_xface->get_eNB_UE_stats(Mod_id,rnti1); - - mac_xface->get_ue_active_harq_pid(Mod_id,rnti1,subframeP,&harq_pid1,&round1,0); - - if ((mac_get_rrc_status(Mod_id,1,next_ue1) >= RRC_RECONFIGURED) && (round1==0) && (mac_xface->get_transmission_mode(Mod_id,rnti1)==5) && (dl_pow_off[next_ue1] != 1)) { - - - for(j=0;j<N_RBGS;j+=2){ - - if((((j == (N_RBGS-1))&& (rballoc_sub[j] == 0) && (rballoc_sub_UE[next_ue1][j] == 0)) || ((j < (N_RBGS-1)) && (rballoc_sub[j+1] == 0) && (rballoc_sub_UE[next_ue1][j+1] == 0))) && (nb_rbs_required_remaining[next_ue1]>0)){ - - for (ii = i+1;ii < granted_UEs;ii++) { - - next_ue2 = UE_id_sorted[ii]; - rnti2 = find_UE_RNTI(Mod_id,next_ue2); - if(rnti2 == 0) - continue; - - eNB_UE_stats2 = mac_xface->get_eNB_UE_stats(Mod_id,rnti2); - mac_xface->get_ue_active_harq_pid(Mod_id,rnti2,subframeP,&harq_pid2,&round2,0); - - if ((mac_get_rrc_status(Mod_id,1,next_ue2) >= RRC_RECONFIGURED) && (round2==0) && (mac_xface->get_transmission_mode(Mod_id,rnti2)==5) && (dl_pow_off[next_ue2] != 1)) { - - if((((j == (N_RBGS-1)) && (rballoc_sub_UE[next_ue2][j] == 0)) || ((j < (N_RBGS-1)) && (rballoc_sub_UE[next_ue2][j+1] == 0))) && (nb_rbs_required_remaining[next_ue2]>0)){ - - if((((eNB_UE_stats2->DL_pmi_single^eNB_UE_stats1->DL_pmi_single)<<(14-j))&0xc000)== 0x4000){ //MU-MIMO only for 25 RBs configuration - - rballoc_sub[j] = 1; - rballoc_sub_UE[next_ue1][j] = 1; - rballoc_sub_UE[next_ue2][j] = 1; - MIMO_mode_indicator[j] = 0; - - if (j< N_RBGS-1) { - rballoc_sub[j+1] = 1; - rballoc_sub_UE[next_ue1][j+1] = 1; - rballoc_sub_UE[next_ue2][j+1] = 1; - MIMO_mode_indicator[j+1] = 0; - } - - dl_pow_off[next_ue1] = 0; - dl_pow_off[next_ue2] = 0; - - - - - if ((j == N_RBGS-1) && - ((mac_xface->lte_frame_parms->N_RB_DL == 25) || - (mac_xface->lte_frame_parms->N_RB_DL == 50))){ - nb_rbs_required_remaining[next_ue1] = nb_rbs_required_remaining[next_ue1] - min_rb_unit+1; - pre_nb_available_rbs[next_ue1] = pre_nb_available_rbs[next_ue1] + min_rb_unit-1; - nb_rbs_required_remaining[next_ue2] = nb_rbs_required_remaining[next_ue2] - min_rb_unit+1; - pre_nb_available_rbs[next_ue2] = pre_nb_available_rbs[next_ue2] + min_rb_unit-1; - } - else { - nb_rbs_required_remaining[next_ue1] = nb_rbs_required_remaining[next_ue1] - 4; - pre_nb_available_rbs[next_ue1] = pre_nb_available_rbs[next_ue1] + 4; - nb_rbs_required_remaining[next_ue2] = nb_rbs_required_remaining[next_ue2] - 4; - pre_nb_available_rbs[next_ue2] = pre_nb_available_rbs[next_ue2] + 4; - } - break; - } - } - } - } - } - } - } + } + + // control channel in the 1st transmission + + for(i=UE_list->head; i>=0;i=UE_list->next[i]) { + UE_id = i; + for (ii=0;ii<UE_num_active_CC(UE_list,UE_id);ii++) { + CC_id = UE_list->ordered_CCids[ii][UE_id]; + + + rnti = UE_RNTI(Mod_id,UE_id); + if(rnti == 0) + continue; + mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,subframeP,&harq_pid,&round,0); + + if ((mac_get_rrc_status(Mod_id,1,UE_id) < RRC_RECONFIGURED) && (round == 0)) { + + + + + for(j=0;j<N_RBGS[CC_id];j++){ + + if((rballoc_sub[CC_id][j] == 0) && (rballoc_sub_UE[CC_id][UE_id][j] == 0) && (nb_rbs_required_remaining[CC_id][UE_id]>0)){ + + rballoc_sub[CC_id][j] = 1; + rballoc_sub_UE[CC_id][UE_id][j] = 1; + + MIMO_mode_indicator[CC_id][j] = 1; + + if(mac_xface->get_transmission_mode(Mod_id,CC_id,rnti)==5) + dl_pow_off[CC_id][UE_id] = 1; + + if((j == N_RBGS[CC_id]-1) && + ((PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL == 25)|| + (PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL == 50))){ + nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id] + 1; + pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + min_rb_unit[CC_id] - 1; + } + else { + nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id]; + pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + min_rb_unit[CC_id]; + } + } + } + } } - // data channel for all TM - for (i = 0;i<granted_UEs; i++){ - - next_ue = UE_id_sorted[i]; - rnti = find_UE_RNTI(Mod_id,next_ue); - if (rnti == 0) - continue; - - mac_xface->get_ue_active_harq_pid(Mod_id,rnti,subframeP,&harq_pid,&round,0); - - if ((mac_get_rrc_status(Mod_id,1,next_ue) >= RRC_RECONFIGURED) && (round==0)) { - - - for(j=0;j<N_RBGS;j++){ - - if((rballoc_sub[j] == 0) && (rballoc_sub_UE[next_ue][j] == 0) && (nb_rbs_required_remaining[next_ue]>0)){ - - - switch (mac_xface->get_transmission_mode(Mod_id,rnti)) { - case 1: - case 2: - case 4: - case 6: - rballoc_sub[j] = 1; - rballoc_sub_UE[next_ue][j] = 1; - - MIMO_mode_indicator[j] = 1; - - if((j == N_RBGS-1) && - ((mac_xface->lte_frame_parms->N_RB_DL == 25)|| - (mac_xface->lte_frame_parms->N_RB_DL == 50))){ - nb_rbs_required_remaining[next_ue] = nb_rbs_required_remaining[next_ue] - min_rb_unit+1; - pre_nb_available_rbs[next_ue] = pre_nb_available_rbs[next_ue] +min_rb_unit-1; - } - else { - nb_rbs_required_remaining[next_ue] = nb_rbs_required_remaining[next_ue] - min_rb_unit; - pre_nb_available_rbs[next_ue] = pre_nb_available_rbs[next_ue] + min_rb_unit; - } - - break; - case 5: - if (dl_pow_off[next_ue] != 0){ - - dl_pow_off[next_ue] = 1; - - rballoc_sub[j] = 1; - rballoc_sub_UE[next_ue][j] = 1; - - MIMO_mode_indicator[j] = 1; - - if((j == N_RBGS-1) && - ((mac_xface->lte_frame_parms->N_RB_DL == 25)|| - (mac_xface->lte_frame_parms->N_RB_DL == 50))){ - nb_rbs_required_remaining[next_ue] = nb_rbs_required_remaining[next_ue] - min_rb_unit+1; - pre_nb_available_rbs[next_ue] = pre_nb_available_rbs[next_ue] + min_rb_unit-1; - } - else { - nb_rbs_required_remaining[next_ue] = nb_rbs_required_remaining[next_ue] - min_rb_unit; - pre_nb_available_rbs[next_ue] = pre_nb_available_rbs[next_ue] + min_rb_unit; - } - } - break; - default: - break; - } - } - } - } + } + + + // data chanel TM5 + for(i=UE_list->head; i>=0;i=UE_list->next[i]) { + UE_id = i; + for (ii=0;ii<UE_num_active_CC(UE_list,UE_id);ii++) { + CC_id = UE_list->ordered_CCids[ii][UE_id]; + + + rnti1 = UE_RNTI(Mod_id,UE_id); + if(rnti1 == 0) + continue; + + eNB_UE_stats1 = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti1); + + mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti1,subframeP,&harq_pid1,&round1,0); + + if ((mac_get_rrc_status(Mod_id,1,UE_id) >= RRC_RECONFIGURED) && (round1==0) && (mac_xface->get_transmission_mode(Mod_id,CC_id,rnti1)==5) && (dl_pow_off[CC_id][UE_id] != 1)) { + + + for(j=0;j<N_RBGS[CC_id];j+=2){ + + if((((j == (N_RBGS[CC_id]-1))&& (rballoc_sub[CC_id][j] == 0) && (rballoc_sub_UE[CC_id][UE_id][j] == 0)) || ((j < (N_RBGS[CC_id]-1)) && (rballoc_sub[CC_id][j+1] == 0) && (rballoc_sub_UE[CC_id][UE_id][j+1] == 0))) && (nb_rbs_required_remaining[CC_id][UE_id]>0)){ + + for (ii = UE_list->next[i+1];ii >=0;ii=UE_list->next[ii]) { + + UE_id2 = ii; + rnti2 = UE_RNTI(Mod_id,UE_id2); + if(rnti2 == 0) + continue; + + eNB_UE_stats2 = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti2); + mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,subframeP,&harq_pid2,&round2,0); + + if ((mac_get_rrc_status(Mod_id,1,UE_id2) >= RRC_RECONFIGURED) && (round2==0) && (mac_xface->get_transmission_mode(Mod_id,CC_id,rnti2)==5) && (dl_pow_off[CC_id][UE_id2] != 1)) { + + if((((j == (N_RBGS[CC_id]-1)) && (rballoc_sub_UE[CC_id][UE_id2][j] == 0)) || ((j < (N_RBGS[CC_id]-1)) && (rballoc_sub_UE[CC_id][UE_id2][j+1] == 0))) && (nb_rbs_required_remaining[CC_id][UE_id2]>0)){ + + if((((eNB_UE_stats2->DL_pmi_single^eNB_UE_stats1->DL_pmi_single)<<(14-j))&0xc000)== 0x4000){ //MU-MIMO only for 25 RBs configuration + + rballoc_sub[CC_id][j] = 1; + rballoc_sub_UE[CC_id][UE_id][j] = 1; + rballoc_sub_UE[CC_id][UE_id2][j] = 1; + MIMO_mode_indicator[CC_id][j] = 0; + + if (j< N_RBGS[CC_id]-1) { + rballoc_sub[CC_id][j+1] = 1; + rballoc_sub_UE[CC_id][UE_id][j+1] = 1; + rballoc_sub_UE[CC_id][UE_id2][j+1] = 1; + MIMO_mode_indicator[CC_id][j+1] = 0; + } + + dl_pow_off[CC_id][UE_id] = 0; + dl_pow_off[CC_id][UE_id2] = 0; + + + + + if ((j == N_RBGS[CC_id]-1) && + ((PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL == 25) || + (PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL == 50))){ + nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id]+1; + pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + min_rb_unit[CC_id]-1; + nb_rbs_required_remaining[CC_id][UE_id2] = nb_rbs_required_remaining[CC_id][UE_id2] - min_rb_unit[CC_id]+1; + pre_nb_available_rbs[CC_id][UE_id2] = pre_nb_available_rbs[CC_id][UE_id2] + min_rb_unit[CC_id]-1; + } + else { + nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - 4; + pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + 4; + nb_rbs_required_remaining[CC_id][UE_id2] = nb_rbs_required_remaining[CC_id][UE_id2] - 4; + pre_nb_available_rbs[CC_id][UE_id2] = pre_nb_available_rbs[CC_id][UE_id2] + 4; + } + break; + } + } + } + } + + } + } + } } + } + // data channel for all TM + + for(i=UE_list->head; i>=0;i=UE_list->next[i]) { + for (ii=0;ii<UE_num_active_CC(UE_list,UE_id);ii++) { + CC_id = UE_list->ordered_CCids[ii][UE_id]; + UE_id = i; + + rnti = UE_RNTI(Mod_id,UE_id); + if (rnti == 0) + continue; + + mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,subframeP,&harq_pid,&round,0); + + if ((mac_get_rrc_status(Mod_id,1,UE_id) >= RRC_RECONFIGURED) && (round==0)) { + + + for(j=0;j<N_RBGS[CC_id];j++){ + + if((rballoc_sub[CC_id][j] == 0) && (rballoc_sub_UE[CC_id][UE_id][j] == 0) && (nb_rbs_required_remaining[CC_id][UE_id]>0)){ + + + switch (mac_xface->get_transmission_mode(Mod_id,CC_id,rnti)) { + case 1: + case 2: + case 4: + case 6: + rballoc_sub[CC_id][j] = 1; + rballoc_sub_UE[CC_id][UE_id][j] = 1; + + MIMO_mode_indicator[CC_id][j] = 1; + + if((j == N_RBGS[CC_id]-1) && + ((PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL == 25)|| + (PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL == 50))){ + nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id]+1; + pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] +min_rb_unit[CC_id]-1; + } + else { + nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id]; + pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + min_rb_unit[CC_id]; + } + + break; + case 5: + if (dl_pow_off[CC_id][UE_id] != 0){ + + dl_pow_off[CC_id][UE_id] = 1; + + rballoc_sub[CC_id][j] = 1; + rballoc_sub_UE[CC_id][UE_id][j] = 1; + + MIMO_mode_indicator[CC_id][j] = 1; + + if((j == N_RBGS[CC_id]-1) && + ((PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL == 25)|| + (PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL == 50))){ + nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id]+1; + pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + min_rb_unit[CC_id]-1; + } + else { + nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id]; + pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + min_rb_unit[CC_id]; + } + } + break; + default: + break; + } + } + } + } + } + } } - i1=0; - i2=0; - i3=0; - for (j=0;j<N_RBGS;j++){ - if(MIMO_mode_indicator[j] == 2) - i1 = i1+1; - else if(MIMO_mode_indicator[j] == 1) - i2 = i2+1; - else if(MIMO_mode_indicator[j] == 0) - i3 = i3+1; + // This has to be revisited!!!! + for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { + i1=0; + i2=0; + i3=0; + for (j=0;j<N_RBGS[CC_id];j++){ + if(MIMO_mode_indicator[CC_id][j] == 2) + i1 = i1+1; + else if(MIMO_mode_indicator[CC_id][j] == 1) + i2 = i2+1; + else if(MIMO_mode_indicator[CC_id][j] == 0) + i3 = i3+1; + } + + + if((i1 < N_RBGS[CC_id]) && (i2>0) && (i3==0)) + PHY_vars_eNB_g[Mod_id][CC_id]->check_for_SUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->check_for_SUMIMO_transmissions + 1; + + if(i3 == N_RBGS[CC_id] && i1==0 && i2==0) + PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions + 1; + + if((i1 < N_RBGS[CC_id]) && (i3 > 0)) + PHY_vars_eNB_g[Mod_id][CC_id]->check_for_MUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->check_for_MUMIMO_transmissions + 1; + + PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions + 1; + + } - - if((i1 < N_RBGS) && (i2>0) && (i3==0)) - PHY_vars_eNB_g[Mod_id]->check_for_SUMIMO_transmissions = PHY_vars_eNB_g[Mod_id]->check_for_SUMIMO_transmissions + 1; - - if(i3 == N_RBGS && i1==0 && i2==0) - PHY_vars_eNB_g[Mod_id]->FULL_MUMIMO_transmissions = PHY_vars_eNB_g[Mod_id]->FULL_MUMIMO_transmissions + 1; - - if((i1 < N_RBGS) && (i3 > 0)) - PHY_vars_eNB_g[Mod_id]->check_for_MUMIMO_transmissions = PHY_vars_eNB_g[Mod_id]->check_for_MUMIMO_transmissions + 1; - - PHY_vars_eNB_g[Mod_id]->check_for_total_transmissions = PHY_vars_eNB_g[Mod_id]->check_for_total_transmissions + 1; - - - - - for(UE_id=0;UE_id<granted_UEs;UE_id++){ + for(i=UE_list->head; i>=0;i=UE_list->next[i]) { + for (ii=0;ii<UE_num_active_CC(UE_list,UE_id);ii++) { + CC_id = UE_list->ordered_CCids[ii][UE_id]; + UE_id = i; //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id]; LOG_D(MAC,"******************Scheduling Information for UE%d ************************\n",UE_id); - LOG_D(MAC,"dl power offset UE%d = %d \n",UE_id,dl_pow_off[UE_id]); + LOG_D(MAC,"dl power offset UE%d = %d \n",UE_id,dl_pow_off[CC_id][UE_id]); LOG_D(MAC,"***********RB Alloc for every subband for UE%d ***********\n",UE_id); - for(j=0;j<N_RBGS;j++){ - //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[i] = rballoc_sub_UE[UE_id][i]; - LOG_D(MAC,"RB Alloc for UE%d and Subband%d = %d\n",UE_id,j,rballoc_sub_UE[UE_id][j]); + for(j=0;j<N_RBGS[CC_id];j++){ + //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[i] = rballoc_sub_UE[CC_id][UE_id][i]; + LOG_D(MAC,"RB Alloc for UE%d and Subband%d = %d\n",UE_id,j,rballoc_sub_UE[CC_id][UE_id][j]); } - //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[UE_id]; - LOG_D(MAC,"Total RBs allocated for UE%d = %d\n",UE_id,pre_nb_available_rbs[UE_id]); + //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id]; + LOG_D(MAC,"Total RBs allocated for UE%d = %d\n",UE_id,pre_nb_available_rbs[CC_id][UE_id]); + } } } diff --git a/openair2/LAYER2/MAC/proto.h b/openair2/LAYER2/MAC/proto.h index 3beee62a27..3791e631ec 100644 --- a/openair2/LAYER2/MAC/proto.h +++ b/openair2/LAYER2/MAC/proto.h @@ -51,7 +51,7 @@ for the message. @param nprb Pointer to current PRB count @param nCCE Pointer to current nCCE count */ -void schedule_RA(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,uint8_t Msg3_subframe,uint8_t *nprb,unsigned int *nCCE); +void schedule_RA(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,uint8_t Msg3_subframe,unsigned int *nprb,unsigned int *nCCE); /** \brief First stage of SI Scheduling. Gets a SI SDU from RRC if available and computes the MCS required to transport it as a function of the SDU length. It assumes a length less than or equal to 64 bytes (MCS 6, 3 PRBs). @param Mod_id Instance ID of eNB @@ -61,7 +61,7 @@ void schedule_RA(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,uint @param nprb Pointer to current PRB count @param nCCE Pointer to current nCCE count */ -void schedule_SI(module_id_t module_idP,frame_t frameP,uint8_t *nprb,unsigned int *nCCE); +void schedule_SI(module_id_t module_idP,frame_t frameP,unsigned int *nprb,unsigned int *nCCE); /** \brief MBMS scheduling: Checking the position for MBSFN subframes. Create MSI, transfer MCCH from RRC to MAC, transfer MTCHs from RLC to MAC. Multiplexing MSI,MCCH&MTCHs. Return 1 if there are MBSFN data being allocated, otherwise return 0; @param Mod_id Instance ID of eNB @@ -101,7 +101,7 @@ void schedule_ulsch(module_id_t module_idP,frame_t frameP,unsigned char cooperat @param sched_subframe Subframe number where PUSCH is transmitted (for DAI lookup) @param nCCE Pointer to current nCCE count */ -void schedule_ulsch_rnti(module_id_t module_idP, unsigned char cooperation_flag, frame_t frameP, sub_frame_t subframe, unsigned char sched_subframe, uint8_t granted_UEs, unsigned int *nCCE, unsigned int *nCCE_available, uint16_t *first_rb); +void schedule_ulsch_rnti(module_id_t module_idP, unsigned char cooperation_flag, frame_t frameP, sub_frame_t subframe, unsigned char sched_subframe, unsigned int *nCCE, unsigned int *nCCE_available, uint16_t *first_rb); /** \brief ULSCH Scheduling for CBA RNTI TDD config (config 1-6). @param Mod_id Instance ID of eNB @@ -120,7 +120,7 @@ void schedule_ulsch_cba_rnti(module_id_t module_idP, unsigned char cooperation_f @param RA_scheduled RA was scheduled in this subframe @param mbsfn_flag Indicates that this subframe is for MCH/MCCH */ -void fill_DLSCH_dci(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,uint32_t rballoc,uint8_t RA_scheduled,int mbsfn_flag); +void fill_DLSCH_dci(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,uint32_t *rballoc,uint8_t RA_scheduled,int *mbsfn_flag); /** \brief UE specific DLSCH scheduling. Retrieves next ue to be schduled from round-robin scheduler and gets the appropriate harq_pid for the subframe from PHY. If the process is active and requires a retransmission, it schedules the retransmission with the same PRB count and MCS as the first transmission. Otherwise it consults RLC for DCCH/DTCH SDUs (status with maximum number of available PRBS), builds the MAC header (timing advance sent by default) and copies @param Mod_id Instance ID of eNB @@ -130,25 +130,25 @@ void fill_DLSCH_dci(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,u @param nCCE_used Number of CCE used by SI/RA @param mbsfn_flag Indicates that MCH/MCCH is in this subframe */ -void schedule_ue_spec(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,uint16_t nb_rb_used0,unsigned int *nCCE_used,int mbsfn_flag); +void schedule_ue_spec(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,unsigned int *nb_rb_used0,unsigned int *nCCE_used,int *mbsfn_flag); /** \brief Function for UE/PHY to compute PUSCH transmit power in power-control procedure. @param Mod_id Module id of UE @returns Po_NOMINAL_PUSCH (PREAMBLE_RECEIVED_TARGET_POWER+DELTA_PREAMBLE */ -int8_t get_Po_NOMINAL_PUSCH(module_id_t module_idP); +int8_t get_Po_NOMINAL_PUSCH(module_id_t module_idP,int CC_id); /** \brief Function to compute DELTA_PREAMBLE from 36.321 (for RA power ramping procedure and Msg3 PUSCH power control policy) @param Mod_id Module id of UE @returns DELTA_PREAMBLE */ -int8_t get_DELTA_PREAMBLE(module_id_t module_idP); +int8_t get_DELTA_PREAMBLE(module_id_t module_idP,int CC_id); /** \brief Function for compute deltaP_rampup from 36.321 (for RA power ramping procedure and Msg3 PUSCH power control policy) @param Mod_id Module id of UE @returns deltaP_rampup */ -int8_t get_deltaP_rampup(module_id_t module_idP); +int8_t get_deltaP_rampup(module_id_t module_idP,int CC_id); //main.c @@ -186,10 +186,11 @@ void mac_UE_out_of_sync_ind(module_id_t module_idP,frame_t frameP, uint16_t eNB_ void dlsch_scheduler_pre_processor (module_id_t module_idP, frame_t frameP, sub_frame_t subframe, - uint8_t *dl_pow_off, - uint16_t *pre_nb_available_rbs, - int N_RBGS, - unsigned char rballoc_sub_UE[NUMBER_OF_UE_MAX][N_RBGS_MAX]); + uint8_t dl_pow_off[MAX_NUM_CCs][NUMBER_OF_UE_MAX], + uint16_t pre_nb_available_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX], + int N_RBGS[MAX_NUM_CCs], + unsigned char rballoc_sub_UE[MAX_NUM_CCs][NUMBER_OF_UE_MAX][N_RBGS_MAX], + int *mbsfn_flag); /* \brief Function to trigger the eNB scheduling procedure. It is called by PHY at the beginning of each subframe, \f$n$\f and generates all DLSCH allocations for subframe \f$n\f$ and ULSCH allocations for subframe \f$n+k$\f. The resultant DCI_PDU is @@ -205,17 +206,18 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, uint8_t cooperation_flag, /* \brief Function to retrieve result of scheduling (DCI) in current subframe. Can be called an arbitrary numeber of times after eNB_dlsch_ulsch_scheduler in a given subframe. @param Mod_id Instance ID of eNB +@param CC_id Component Carrier Index @param subframe Index of current subframe @returns Pointer to generated DCI for subframe */ -DCI_PDU *get_dci_sdu(module_id_t module_idP,frame_t frameP,sub_frame_t subframe); +DCI_PDU *get_dci_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subframe); /* \brief Function to indicate a received preamble on PRACH. It initiates the RA procedure. @param Mod_id Instance ID of eNB @param preamble_index index of the received RA request @param timing_offset Offset in samples of the received PRACH w.r.t. eNB timing. This is used to */ -void initiate_ra_proc(module_id_t module_idP,frame_t frameP, uint16_t preamble_index,int16_t timing_offset,uint8_t sect_id,sub_frame_t subframe,uint8_t f_id); +void initiate_ra_proc(module_id_t module_idP,int CC_id,frame_t frameP, uint16_t preamble_index,int16_t timing_offset,uint8_t sect_id,sub_frame_t subframe,uint8_t f_id); /* \brief Function in eNB to fill RAR pdu when requested by PHY. This provides a single RAR SDU for the moment and returns the t-CRNTI. @param Mod_id Instance ID of eNB @@ -224,39 +226,40 @@ void initiate_ra_proc(module_id_t module_idP,frame_t frameP, uint16_t preamble_i @returns t_CRNTI */ uint16_t fill_rar(module_id_t module_idP, - frame_t frameP, - uint8_t *dlsch_buffer, - uint16_t N_RB_UL, - uint8_t input_buffer_length); + int CC_id, + frame_t frameP, + uint8_t *dlsch_buffer, + uint16_t N_RB_UL, + uint8_t input_buffer_length); /* \brief This function indicates the end of RA procedure and provides the l3msg received on ULSCH. @param Mod_id Instance ID of eNB @param rnti RNTI of UE transmitting l3msg @param l3msg Pointer to received l3msg */ -void terminate_ra_proc(module_id_t module_idP,frame_t frameP, rnti_t rnti, uint8_t *l3msg, uint16_t l3msg_len); +void terminate_ra_proc(module_id_t module_idP,int CC_id,frame_t frameP, rnti_t rnti, uint8_t *l3msg, uint16_t l3msg_len); /* \brief Function to indicate a failed RA response. It removes all temporary variables related to the initial connection of a UE @param Mod_id Instance ID of eNB @param preamble_index index of the received RA request. */ -void cancel_ra_proc(module_id_t module_idP,frame_t frameP, uint16_t preamble_index); +void cancel_ra_proc(module_id_t module_idP,int CC_id,frame_t frameP, uint16_t preamble_index); /* \brief Function to indicate a received SDU on ULSCH. @param Mod_id Instance ID of eNB @param rnti RNTI of UE transmitting the SR @param sdu Pointer to received SDU */ -void rx_sdu(module_id_t module_idP, frame_t frameP, rnti_t rnti, uint8_t *sdu, uint16_t sdu_len); +void rx_sdu(module_id_t module_idP, int CC_id,frame_t frameP, rnti_t rnti, uint8_t *sdu, uint16_t sdu_len); /* \brief Function to indicate a scheduled schduling request (SR) was received by eNB. @param Mod_id Instance ID of eNB @param rnti RNTI of UE transmitting the SR @param subframe Index of subframe where SR was received */ -void SR_indication(module_id_t module_idP,frame_t frameP,rnti_t rnti, sub_frame_t subframe); +void SR_indication(module_id_t module_idP,int CC_id,frame_t frameP,rnti_t rnti, sub_frame_t subframe); -uint8_t *get_dlsch_sdu(module_id_t module_idP,frame_t frameP,rnti_t rnti,uint8_t TBindex); +uint8_t *get_dlsch_sdu(module_id_t module_idP,int CC_id,frame_t frameP,rnti_t rnti,uint8_t TBindex); /* \brief Function to retrieve MCH transport block and MCS used for MCH in this MBSFN subframe. Returns null if no MCH is to be transmitted @param Mod_id Instance ID of eNB @@ -265,7 +268,7 @@ uint8_t *get_dlsch_sdu(module_id_t module_idP,frame_t frameP,rnti_t rnti,uint8_t @param mcs Pointer to mcs used by PHY (to be filled by MAC) @returns Pointer to MCH transport block and mcs for subframe */ -MCH_PDU *get_mch_sdu(uint8_t Mod_id,uint32_t frame,uint32_t subframe); +MCH_PDU *get_mch_sdu(uint8_t Mod_id,uint32_t frame,sub_frame_t subframe); //added for ALU icic purpose @@ -277,33 +280,32 @@ void UpdateSBnumber(module_id_t module_idP); void ue_mac_reset (module_id_t module_idP,uint8_t eNB_index); void ue_init_mac (module_id_t module_idP); void init_ue_sched_info(void); -void add_ue_ulsch_info (module_id_t module_idP, module_id_t ue_mod_idP, sub_frame_t subframe,UE_ULSCH_STATUS status); -void add_ue_dlsch_info (module_id_t module_idP, module_id_t ue_mod_idP, sub_frame_t subframe,UE_DLSCH_STATUS status); -module_id_t find_UE_id (module_id_t module_idP, rnti_t rnti) ; -rnti_t find_UE_RNTI (module_id_t module_idP, module_id_t ue_mod_idP); -uint8_t find_active_UEs (module_id_t module_idP); -boolean_t is_UE_active (module_id_t module_idP, module_id_t ue_mod_idP ); -uint8_t find_ulgranted_UEs(module_id_t module_idP); -uint8_t find_dlgranted_UEs(module_id_t module_idP); -uint8_t process_ue_cqi (module_id_t module_idP, module_id_t ue_mod_idP); +void add_ue_ulsch_info (module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframe,UE_ULSCH_STATUS status); +void add_ue_dlsch_info (module_id_t module_idP, int CC_id,int UE_id, sub_frame_t subframe,UE_DLSCH_STATUS status); +int find_UE_id (module_id_t module_idP, rnti_t rnti) ; +rnti_t UE_RNTI (module_id_t module_idP, int UE_id); +int UE_PCCID (module_id_t module_idP, int UE_id); +uint8_t find_active_UEs (module_id_t module_idP); +boolean_t is_UE_active (module_id_t module_idP, int UE_id); +uint8_t process_ue_cqi (module_id_t module_idP, int UE_id); int8_t find_active_UEs_with_traffic(module_id_t module_idP); uint8_t find_num_active_UEs_in_cbagroup(module_id_t module_idP, unsigned char group_id); -uint8_t UE_is_to_be_scheduled(module_id_t module_idP,uint8_t UE_id); +uint8_t UE_is_to_be_scheduled(module_id_t module_idP,int CC_id,uint8_t UE_id); /** \brief Round-robin scheduler for ULSCH traffic. @param Mod_id Instance ID for eNB @param subframe Subframe number on which to act @returns UE index that is to be scheduled if needed/room */ -module_id_t schedule_next_ulue(module_id_t module_idP, module_id_t ue_mod_idP,sub_frame_t subframe); +module_id_t schedule_next_ulue(module_id_t module_idP, int UE_id,sub_frame_t subframe); /** \brief Round-robin scheduler for DLSCH traffic. @param Mod_id Instance ID for eNB @param subframe Subframe number on which to act @returns UE index that is to be scheduled if needed/room */ -module_id_t schedule_next_dlue(module_id_t module_idP, sub_frame_t subframe); +int schedule_next_dlue(module_id_t module_idP, sub_frame_t subframe); /* \brief Allocates a set of PRBS for a particular UE. This is a simple function for the moment, later it should process frequency-domain CQI information and/or PMI information. Currently it just returns the first PRBS that are available in the subframe based on the number requested. @param UE_id Index of UE on which to act @@ -311,7 +313,7 @@ module_id_t schedule_next_dlue(module_id_t module_idP, sub_frame_t subframe); @param rballoc Pointer to bit-map of current PRB allocation given to previous users/control channels. This is updated for subsequent calls to the routine. @returns an rballoc bitmap for resource type 0 allocation (DCI). */ -uint32_t allocate_prbs(module_id_t ue_mod_idP,uint8_t nb_rb, uint32_t *rballoc); +uint32_t allocate_prbs(int UE_id,uint8_t nb_rb, uint32_t *rballoc); /* \fn uint32_t req_new_ulsch(module_id_t module_idP) \brief check for a new transmission in any drb @@ -322,22 +324,23 @@ uint32_t req_new_ulsch(module_id_t module_idP); /* \brief Get SR payload (0,1) from UE MAC @param Mod_id Instance id of UE in machine +@param CC_id Component Carrier index @param eNB_id Index of eNB that UE is attached to @param rnti C_RNTI of UE @param subframe subframe number @returns 0 for no SR, 1 for SR */ -uint32_t ue_get_SR(module_id_t module_idP, frame_t frameP, uint8_t eNB_id,rnti_t rnti,sub_frame_t subframe); +uint32_t ue_get_SR(module_id_t module_idP, int CC_id,frame_t frameP, uint8_t eNB_id,rnti_t rnti,sub_frame_t subframe); -uint8_t get_ue_weight(module_id_t module_idP, module_id_t ue_mod_idP); +uint8_t get_ue_weight(module_id_t module_idP, int UE_id); // UE functions void mac_out_of_sync_ind(module_id_t module_idP, frame_t frameP, uint16_t CH_index); -void ue_decode_si(module_id_t module_idP, frame_t frame, uint8_t CH_index, void *pdu, uint16_t len); +void ue_decode_si(module_id_t module_idP, int CC_id,frame_t frame, uint8_t CH_index, void *pdu, uint16_t len); -void ue_send_sdu(module_id_t module_idP, frame_t frame, uint8_t *sdu,uint16_t sdu_len,uint8_t CH_index); +void ue_send_sdu(module_id_t module_idP, int CC_id,frame_t frame, uint8_t *sdu,uint16_t sdu_len,uint8_t CH_index); #ifdef Rel10 @@ -370,14 +373,15 @@ int ue_query_mch(uint8_t Mod_id,uint32_t frame,sub_frame_t subframe, uint8_t eNB @param subframe subframe number @returns 0 for no SR, 1 for SR */ -void ue_get_sdu(module_id_t module_idP, frame_t frameP, sub_frame_t subframe, uint8_t eNB_index,uint8_t *ulsch_buffer,uint16_t buflen,uint8_t *access_mode); +void ue_get_sdu(module_id_t module_idP, int CC_id,frame_t frameP, sub_frame_t subframe, uint8_t eNB_index,uint8_t *ulsch_buffer,uint16_t buflen,uint8_t *access_mode); /* \brief Function called by PHY to retrieve information to be transmitted using the RA procedure. If the UE is not in PUSCH mode for a particular eNB index, this is assumed to be an Msg3 and MAC attempts to retrieves the CCCH message from RRC. If the UE is in PUSCH mode for a particular eNB index and PUCCH format 0 (Scheduling Request) is not activated, the MAC may use this resource for random-access to transmit a BSR along with the C-RNTI control element (see 5.1.4 from 36.321) @param Mod_id Index of UE instance +@param Mod_id Component Carrier Index @param New_Msg3 Flag to indicate this call is for a new Msg3 @param subframe Index of subframe for PRACH transmission (0 ... 9) @returns A pointer to a PRACH_RESOURCES_t */ -PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,frame_t frameP,uint8_t new_Msg3,sub_frame_t subframe); +PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP,uint8_t new_Msg3,sub_frame_t subframe); /* \brief Function called by PHY to process the received RAR. It checks that the preamble matches what was sent by the eNB and provides the timing advance and t-CRNTI. @param Mod_id Index of UE instance @@ -387,7 +391,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,frame_t frameP,uint8_t new random-access procedure @returns timing advance or 0xffff if preamble doesn't match */ -uint16_t ue_process_rar(module_id_t module_idP, frame_t frameP,uint8_t *dlsch_buffer,uint16_t *t_crnti,uint8_t preamble_index); +uint16_t ue_process_rar(module_id_t module_idP, int CC_id,frame_t frameP,uint8_t *dlsch_buffer,uint16_t *t_crnti,uint8_t preamble_index); /* \brief Generate header for UL-SCH. This function parses the desired control elements and sdus and generates the header as described @@ -440,8 +444,8 @@ uint8_t *parse_ulsch_header(uint8_t *mac_header, int l2_init(LTE_DL_FRAME_PARMS *frame_parms,int eMBMS_active, uint8_t cba_group_active, uint8_t HO_active); int mac_init(void); -int8_t add_new_ue(module_id_t module_idP, rnti_t rnti); -int8_t mac_remove_ue(module_id_t enb_mod_idP, module_id_t ue_mod_idP); +int add_new_ue(module_id_t Mod_id, int CC_id, rnti_t rnti); +int mac_remove_ue(module_id_t Mod_id, int UE_id); /*! \fn UE_L2_state_t ue_scheduler(module_id_t module_idP,frame_t frameP, sub_frame_t subframe, lte_subframe_t direction,uint8_t eNB_index) \brief UE scheduler where all the ue background tasks are done. This function performs the following: 1) Trigger PDCP every 5ms 2) Call RRC for link status return to PHY3) Perform SR/BSR procedures for scheduling feedback 4) Perform PHR procedures. @@ -470,7 +474,7 @@ int use_cba_access(module_id_t module_idP,frame_t frameP,sub_frame_t subframe, u */ int get_bsr_lcgid (module_id_t module_idP); -/*! \fn uint8_t get_bsr_len (module_id_t module_idP, uint16_t bufflen); +/*! \fn uint8_t get_bsr_len (module_id_t module_idP,uint16_t bufflen); \brief determine whether the bsr is short or long assuming that the MAC pdu is built \param[in] Mod_id instance of the UE \param[in] bufflen size of phy transport block @@ -554,25 +558,27 @@ int get_sf_prohibitPHR_Timer(uint8_t prohibitPHR_Timer); */ int get_db_dl_PathlossChange(uint8_t dl_PathlossChange); -/*! \fn uint8_t get_phr_mapping (module_id_t module_idP, uint8_t eNB_index) +/*! \fn uint8_t get_phr_mapping (module_id_t module_idP, int CC_id,uint8_t eNB_index) \brief get phr mapping as described in 36.313 \param[in] Mod_id index of eNB +\param[in] CC_id Component Carrier Index \return phr mapping */ -uint8_t get_phr_mapping (module_id_t module_idP, uint8_t eNB_index); +uint8_t get_phr_mapping (module_id_t module_idP, int CC_id, uint8_t eNB_index); /*! \fn void update_phr (module_id_t module_idP) \brief update/reset the phr timers \param[in] Mod_id index of eNB +\param[in] CC_id Component carrier index \return void */ -void update_phr (module_id_t module_idP); +void update_phr (module_id_t module_idP,int CC_id); /*! \brief Function to indicate Msg3 transmission/retransmission which initiates/reset Contention Resolution Timer \param[in] Mod_id Instance index of UE \param[in] eNB_id Index of eNB */ -void Msg3_tx(module_id_t module_idP,frame_t frameP,uint8_t eNB_id); +void Msg3_tx(module_id_t module_idP,int CC_id,frame_t frameP,uint8_t eNB_id); /*! \brief Function to indicate the transmission of msg1/rach @@ -580,7 +586,7 @@ void Msg3_tx(module_id_t module_idP,frame_t frameP,uint8_t eNB_id); \param[in] eNB_id Index of eNB */ -void Msg1_tx(module_id_t module_idP,frame_t frameP, uint8_t eNB_id); +void Msg1_tx(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_id); void dl_phy_sync_success(module_id_t module_idP, frame_t frameP, @@ -603,5 +609,5 @@ void add_common_dci(DCI_PDU *DCI_pdu, uint32_t allocate_prbs_sub(int nb_rb, uint8_t *rballoc); -void update_ul_dci(module_id_t module_idP,rnti_t rnti,uint8_t dai); +void update_ul_dci(module_id_t module_idP,int CC_id,rnti_t rnti,uint8_t dai); #endif diff --git a/openair2/LAYER2/MAC/ra_procedures.c b/openair2/LAYER2/MAC/ra_procedures.c index 54a98407eb..a779c32415 100644 --- a/openair2/LAYER2/MAC/ra_procedures.c +++ b/openair2/LAYER2/MAC/ra_procedures.c @@ -57,7 +57,13 @@ extern inline unsigned int taus(void); -int8_t get_DELTA_PREAMBLE(module_id_t module_idP) { +int8_t get_DELTA_PREAMBLE(module_id_t module_idP,int CC_id) { + + if (CC_id>0) { + LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n"); + mac_xface->macphy_exit("MAC FATAL CC_id>0"); + return; + } uint8_t prachConfigIndex = UE_mac_inst[module_idP].radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_ConfigIndex; uint8_t preambleformat; @@ -96,12 +102,13 @@ int8_t get_DELTA_PREAMBLE(module_id_t module_idP) { } -/// This routine implements Section 5.1.2 (Random Access Resource Selection) from 36.321 +/// This routine implements Section 5.1.2 (UE Random Access Resource Selection) from 36.321 void get_prach_resources(module_id_t module_idP, - uint8_t eNB_index, - uint8_t t_id, - uint8_t first_Msg3, - RACH_ConfigDedicated_t *rach_ConfigDedicated) { + int CC_id, + uint8_t eNB_index, + uint8_t t_id, + uint8_t first_Msg3, + RACH_ConfigDedicated_t *rach_ConfigDedicated) { uint8_t Msg3_size = UE_mac_inst[module_idP].RA_Msg3_size; PRACH_RESOURCES_t *prach_resources = &UE_mac_inst[module_idP].RA_prach_resources; @@ -109,6 +116,12 @@ void get_prach_resources(module_id_t module_idP, uint8_t noGroupB = 0; uint8_t f_id = 0,num_prach=0; + if (CC_id>0) { + LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n"); + mac_xface->macphy_exit("MAC FATAL CC_id>0"); + return; + } + if (UE_mac_inst[module_idP].radioResourceConfigCommon) rach_ConfigCommon = &UE_mac_inst[module_idP].radioResourceConfigCommon->rach_ConfigCommon; else { @@ -156,7 +169,7 @@ void get_prach_resources(module_id_t module_idP, UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0; UE_mac_inst[module_idP].RA_usedGroupA = 0; } - UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER = get_Po_NOMINAL_PUSCH(module_idP); + UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER = get_Po_NOMINAL_PUSCH(module_idP,CC_id); } else { // Msg3 is being retransmitted if (UE_mac_inst[module_idP].RA_usedGroupA == 1) { @@ -187,7 +200,13 @@ void get_prach_resources(module_id_t module_idP, UE_mac_inst[module_idP].RA_prach_resources.ra_RNTI = 1 + t_id + 10*f_id; } -void Msg1_tx(module_id_t module_idP,frame_t frameP, uint8_t eNB_id) { +void Msg1_tx(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_id) { + + if (CC_id>0) { + LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n"); + mac_xface->macphy_exit("MAC FATAL CC_id>0"); + return; + } // start contention resolution timer UE_mac_inst[module_idP].RA_attempt_number++; @@ -202,7 +221,13 @@ void Msg1_tx(module_id_t module_idP,frame_t frameP, uint8_t eNB_id) { } -void Msg3_tx(module_id_t module_idP,frame_t frameP, uint8_t eNB_id) { +void Msg3_tx(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_id) { + + if (CC_id>0) { + LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n"); + mac_xface->macphy_exit("MAC FATAL CC_id>0"); + return; + } // start contention resolution timer LOG_I(MAC,"[UE %d][RAPROC] Frame %d : Msg3_tx: Setting contention resolution timer\n",module_idP,frameP); @@ -220,11 +245,11 @@ void Msg3_tx(module_id_t module_idP,frame_t frameP, uint8_t eNB_id) { } -PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,frame_t frameP, uint8_t eNB_indexP,sub_frame_t subframeP){ +PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_indexP,sub_frame_t subframeP){ uint8_t Size=0; - UE_MODE_t UE_mode = mac_xface->get_ue_mode(module_idP,eNB_indexP); + UE_MODE_t UE_mode = mac_xface->get_ue_mode(module_idP,0,eNB_indexP); uint8_t lcid = CCCH; uint16_t Size16; struct RACH_ConfigCommon *rach_ConfigCommon = (struct RACH_ConfigCommon *)NULL; @@ -234,6 +259,12 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,frame_t frameP, uint8_t eN uint16_t sdu_lengths[8]; uint8_t ulsch_buff[MAX_ULSCH_PAYLOAD_BYTES]; + if (CC_id>0) { + LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n"); + mac_xface->macphy_exit("MAC FATAL CC_id>0"); + return; + } + if (UE_mode == PRACH) { if (UE_mac_inst[module_idP].radioResourceConfigCommon) rach_ConfigCommon = &UE_mac_inst[module_idP].radioResourceConfigCommon->rach_ConfigCommon; @@ -243,6 +274,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,frame_t frameP, uint8_t eN if (Is_rrc_registered == 1) { if (UE_mac_inst[module_idP].RA_active == 0) { + printf("RA not active\n"); // check if RRC is ready to initiate the RA procedure Size = mac_rrc_data_req(module_idP, frameP, @@ -279,7 +311,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,frame_t frameP, uint8_t eN UE_mac_inst[module_idP].RA_backoff_frame = frameP; UE_mac_inst[module_idP].RA_backoff_subframe = subframeP; // Fill in preamble and PRACH resource - get_prach_resources(module_idP,eNB_indexP,subframeP,1,NULL); + get_prach_resources(module_idP,CC_id,eNB_indexP,subframeP,1,NULL); generate_ulsch_header((uint8_t*)&UE_mac_inst[module_idP].CCCH_pdu.payload[0], // mac header 1, // num sdus @@ -335,7 +367,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,frame_t frameP, uint8_t eN UE_mac_inst[module_idP].RA_backoff_frame = frameP; UE_mac_inst[module_idP].RA_backoff_subframe = subframeP; // Fill in preamble and PRACH resource - get_prach_resources(module_idP,eNB_indexP,subframeP,1,NULL); + get_prach_resources(module_idP,CC_id,eNB_indexP,subframeP,1,NULL); generate_ulsch_header((uint8_t*)ulsch_buff, // mac header 1, // num sdus 0, // short pading @@ -385,13 +417,13 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,frame_t frameP, uint8_t eN LOG_D(MAC,"[UE %d] Frame %d: Maximum number of RACH attempts (%d)\n",module_idP,frameP,rach_ConfigCommon->ra_SupervisionInfo.preambleTransMax); // send message to RRC UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER=1; - UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER = get_Po_NOMINAL_PUSCH(module_idP); + UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER = get_Po_NOMINAL_PUSCH(module_idP,CC_id); } UE_mac_inst[module_idP].RA_window_cnt = 2+ rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize; UE_mac_inst[module_idP].RA_backoff_cnt = 0; // Fill in preamble and PRACH resource - get_prach_resources(module_idP,eNB_indexP,subframeP,0,NULL); + get_prach_resources(module_idP,CC_id,eNB_indexP,subframeP,0,NULL); return(&UE_mac_inst[module_idP].RA_prach_resources); } } @@ -403,648 +435,3 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,frame_t frameP, uint8_t eN } return(NULL); } - -void cancel_ra_proc(module_id_t module_idP, frame_t frameP, rnti_t rnti) { - unsigned char i; - LOG_I(MAC,"[eNB %d][RAPROC] Frame %d Cancelling RA procedure for UE rnti %x\n",module_idP,frameP,rnti); - - for (i=0;i<NB_RA_PROC_MAX;i++) { - if (rnti == eNB_mac_inst[module_idP].RA_template[i].rnti) { - eNB_mac_inst[module_idP].RA_template[i].RA_active=FALSE; - eNB_mac_inst[module_idP].RA_template[i].generate_rar=0; - eNB_mac_inst[module_idP].RA_template[i].generate_Msg4=0; - eNB_mac_inst[module_idP].RA_template[i].wait_ack_Msg4=0; - eNB_mac_inst[module_idP].RA_template[i].timing_offset=0; - eNB_mac_inst[module_idP].RA_template[i].RRC_timer=20; - eNB_mac_inst[module_idP].RA_template[i].rnti = 0; - } - } -} - -void terminate_ra_proc(module_id_t module_idP,frame_t frameP,rnti_t rnti,unsigned char *msg3, uint16_t msg3_len) { - - unsigned char rx_ces[MAX_NUM_CE],num_ce,num_sdu,i,*payload_ptr; - unsigned char rx_lcids[NB_RB_MAX]; - uint16_t rx_lengths[NB_RB_MAX]; - int8_t UE_id; - - LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, Received msg3 %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n", - module_idP,frameP, - msg3[3],msg3[4],msg3[5],msg3[6],msg3[7], msg3[8], rnti); - - for (i=0;i<NB_RA_PROC_MAX;i++) { - LOG_D(MAC,"[RAPROC] Checking proc %d : rnti (%x, %x), active %d\n",i, - eNB_mac_inst[module_idP].RA_template[i].rnti, rnti, - eNB_mac_inst[module_idP].RA_template[i].RA_active); - if ((eNB_mac_inst[module_idP].RA_template[i].rnti==rnti) && - (eNB_mac_inst[module_idP].RA_template[i].RA_active==TRUE)) { - - payload_ptr = parse_ulsch_header(msg3,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,msg3_len); - LOG_D(MAC,"[eNB %d][RAPROC] Frame %d Received CCCH: length %d, offset %d\n", - module_idP,frameP,rx_lengths[0],payload_ptr-msg3); - if (/*(num_ce == 0) &&*/ (num_sdu==1) && (rx_lcids[0] == CCCH)) { // This is an RRCConnectionRequest/Restablishment - memcpy(&eNB_mac_inst[module_idP].RA_template[i].cont_res_id[0],payload_ptr,6); - LOG_D(MAC,"[eNB %d][RAPROC] Frame %d Received CCCH: length %d, offset %d\n", - module_idP,frameP,rx_lengths[0],payload_ptr-msg3); - UE_id=add_new_ue(module_idP,eNB_mac_inst[module_idP].RA_template[i].rnti); - if (UE_id==-1) { - mac_xface->macphy_exit("[MAC][eNB] Max user count reached\n"); - } - else { - LOG_I(MAC,"[eNB %d][RAPROC] Frame %d Added user with rnti %x => UE %d\n", - module_idP,frameP,eNB_mac_inst[module_idP].RA_template[i].rnti,UE_id); - } - - if (Is_rrc_registered == 1) - mac_rrc_data_ind(module_idP,frameP,CCCH,(uint8_t *)payload_ptr,rx_lengths[0],1,module_idP,0); - // add_user. This is needed to have the rnti for configuring UE (PHY). The UE is removed if RRC - // doesn't provide a CCCH SDU - - } - else if (num_ce >0) { // handle msg3 which is not RRCConnectionRequest - // process_ra_message(msg3,num_ce,rx_lcids,rx_ces); - } - - eNB_mac_inst[module_idP].RA_template[i].generate_Msg4 = 1; - eNB_mac_inst[module_idP].RA_template[i].wait_ack_Msg4 = 0; - - return; - } // if process is active - - } // loop on RA processes -} - -void rx_sdu(module_id_t enb_mod_idP,frame_t frameP,rnti_t rntiP,uint8_t *sdu, uint16_t sdu_len) { - - unsigned char rx_ces[MAX_NUM_CE],num_ce,num_sdu,i,*payload_ptr; - unsigned char rx_lcids[NB_RB_MAX]; - unsigned short rx_lengths[NB_RB_MAX]; - module_id_t ue_mod_id = find_UE_id(enb_mod_idP,rntiP); - int ii,j; - start_meas(&eNB_mac_inst[enb_mod_idP].rx_ulsch_sdu); - - if ((ue_mod_id > NUMBER_OF_UE_MAX) || (ue_mod_id == -1) || (ue_mod_id == 255) ) - - for(ii=0; ii<NB_RB_MAX; ii++) rx_lengths[ii] = 0; - - vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,1); - - LOG_D(MAC,"[eNB %d] Received ULSCH sdu from PHY (rnti %x, UE_id %d), parsing header\n",enb_mod_idP,rntiP,ue_mod_id); - payload_ptr = parse_ulsch_header(sdu,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,sdu_len); - - // control element - for (i=0;i<num_ce;i++) { - - switch (rx_ces[i]) { // implement and process BSR + CRNTI + - case POWER_HEADROOM: - if (ue_mod_id != UE_INDEX_INVALID ){ - eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].phr_info = (payload_ptr[0] & 0x3f);// - PHR_MAPPING_OFFSET; - LOG_D(MAC, "[eNB] MAC CE_LCID %d : Received PHR PH = %d (db)\n", rx_ces[i], eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].phr_info); - } - payload_ptr+=sizeof(POWER_HEADROOM_CMD); - break; - case CRNTI: - LOG_D(MAC, "[eNB] MAC CE_LCID %d : Received CRNTI %d \n", rx_ces[i], payload_ptr[0]); - payload_ptr+=1; - break; - case TRUNCATED_BSR: - case SHORT_BSR: { - if (ue_mod_id != UE_INDEX_INVALID ){ - uint8_t lcgid; - lcgid = (payload_ptr[0] >> 6); - LOG_D(MAC, "[eNB] MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", - rx_ces[i], lcgid, payload_ptr[0] & 0x3f); - eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].bsr_info[lcgid] = (payload_ptr[0] & 0x3f); - } - payload_ptr += 1;//sizeof(SHORT_BSR); // fixme - } break; - case LONG_BSR: - if (ue_mod_id != UE_INDEX_INVALID ){ - eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].bsr_info[LCGID0] = ((payload_ptr[0] & 0xFC) >> 2); - eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].bsr_info[LCGID1] = - ((payload_ptr[0] & 0x03) << 4) | ((payload_ptr[1] & 0xF0) >> 4); - eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].bsr_info[LCGID2] = - ((payload_ptr[1] & 0x0F) << 2) | ((payload_ptr[2] & 0xC0) >> 6); - eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].bsr_info[LCGID3] = (payload_ptr[2] & 0x3F); - LOG_D(MAC, "[eNB] MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = " - "%u LCGID2 = %u LCGID3 = %u\n", - rx_ces[i], - eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].bsr_info[LCGID0], - eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].bsr_info[LCGID1], - eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].bsr_info[LCGID2], - eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].bsr_info[LCGID3]); - } - payload_ptr += 3;////sizeof(LONG_BSR); - break; - default: - LOG_E(MAC, "[eNB] Received unknown MAC header (0x%02x)\n", rx_ces[i]); - break; - } - } - - for (i=0;i<num_sdu;i++) { - LOG_D(MAC,"SDU Number %d MAC Subheader SDU_LCID %d, length %d\n",i,rx_lcids[i],rx_lengths[i]); - - switch (rx_lcids[i]) { - case CCCH : - LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, Received CCCH: %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n", - enb_mod_idP,frameP, - payload_ptr[0],payload_ptr[1],payload_ptr[2],payload_ptr[3],payload_ptr[4], payload_ptr[5], rntiP); - - for (ii=0;ii<NB_RA_PROC_MAX;ii++) { - LOG_D(MAC,"[RAPROC] Checking proc %d : rnti (%x, %x), active %d\n",ii, - eNB_mac_inst[enb_mod_idP].RA_template[ii].rnti, rntiP, - eNB_mac_inst[enb_mod_idP].RA_template[ii].RA_active); - - if ((eNB_mac_inst[enb_mod_idP].RA_template[ii].rnti==rntiP) && - (eNB_mac_inst[enb_mod_idP].RA_template[ii].RA_active==TRUE)) { - - //payload_ptr = parse_ulsch_header(msg3,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,msg3_len); - - if (ue_mod_id == UE_INDEX_INVALID) { - memcpy(&eNB_mac_inst[enb_mod_idP].RA_template[ii].cont_res_id[0],payload_ptr,6); - LOG_I(MAC,"[eNB %d][RAPROC] Frame %d CCCH: Received RRCConnectionRequest: length %d, offset %d\n", - enb_mod_idP,frameP,rx_lengths[ii],payload_ptr-sdu); - if ((ue_mod_id=add_new_ue(enb_mod_idP,eNB_mac_inst[enb_mod_idP].RA_template[ii].rnti)) == -1 ) - mac_xface->macphy_exit("[MAC][eNB] Max user count reached\n"); - else - LOG_I(MAC,"[eNB %d][RAPROC] Frame %d Added user with rnti %x => UE %d\n", - enb_mod_idP,frameP,eNB_mac_inst[enb_mod_idP].RA_template[ii].rnti,ue_mod_id); - } else { - LOG_I(MAC,"[eNB %d][RAPROC] Frame %d CCCH: Received RRCConnectionReestablishment from UE %d: length %d, offset %d\n", - enb_mod_idP,frameP,ue_mod_id,rx_lengths[ii],payload_ptr-sdu); - } - - if (Is_rrc_registered == 1) - mac_rrc_data_ind(enb_mod_idP,frameP,CCCH,(uint8_t *)payload_ptr,rx_lengths[ii],1,enb_mod_idP,0); - - - if (num_ce >0) { // handle msg3 which is not RRCConnectionRequest - // process_ra_message(msg3,num_ce,rx_lcids,rx_ces); - } - - eNB_mac_inst[enb_mod_idP].RA_template[ii].generate_Msg4 = 1; - eNB_mac_inst[enb_mod_idP].RA_template[ii].wait_ack_Msg4 = 0; - - - } // if process is active - - } // loop on RA processes - - break; - case DCCH : - case DCCH1 : - // if(eNB_mac_inst[module_idP].Dcch_lchan[UE_id].Active==1){ - -#if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sdu)); - for (j=0;j<32;j++) - LOG_T(MAC,"%x ",payload_ptr[j]); - LOG_T(MAC,"\n"); -#endif - - // This check is just to make sure we didn't get a bogus SDU length, to be removed ... - if (rx_lengths[i]<CCCH_PAYLOAD_SIZE_MAX) { - LOG_D(MAC,"[eNB %d] Frame %d : ULSCH -> UL-DCCH, received %d bytes form UE %d on LCID %d(%d) \n", - enb_mod_idP,frameP, rx_lengths[i], ue_mod_id, rx_lcids[i], rx_lcids[i]); - - mac_rlc_data_ind(enb_mod_idP,ue_mod_id, frameP,ENB_FLAG_YES,MBMS_FLAG_NO, - rx_lcids[i], - (char *)payload_ptr, - rx_lengths[i], - 1, - NULL);//(unsigned int*)crc_status); - eNB_mac_inst[enb_mod_idP].eNB_UE_stats[ue_mod_id].num_pdu_rx[rx_lcids[i]]+=1; - eNB_mac_inst[enb_mod_idP].eNB_UE_stats[ue_mod_id].num_bytes_rx[rx_lcids[i]]+=rx_lengths[i]; - - } - // } - break; - case DTCH: // default DRB - // if(eNB_mac_inst[module_idP].Dcch_lchan[UE_id].Active==1){ - -#if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sdu)); - for (j=0;j<32;j++) - LOG_T(MAC,"%x ",payload_ptr[j]); - LOG_T(MAC,"\n"); -#endif - - LOG_D(MAC,"[eNB %d] Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d (%d)\n", - enb_mod_idP,frameP, rx_lengths[i], ue_mod_id,rx_lcids[i],rx_lcids[i]); - - if ((rx_lengths[i] <SCH_PAYLOAD_SIZE_MAX) && (rx_lengths[i] > 0) ) { // MAX SIZE OF transport block - mac_rlc_data_ind(enb_mod_idP,ue_mod_id, frameP,ENB_FLAG_YES,MBMS_FLAG_NO, - DTCH, - (char *)payload_ptr, - rx_lengths[i], - 1, - NULL);//(unsigned int*)crc_status); - eNB_mac_inst[enb_mod_idP].eNB_UE_stats[ue_mod_id].num_pdu_rx[rx_lcids[i]]+=1; - eNB_mac_inst[enb_mod_idP].eNB_UE_stats[ue_mod_id].num_bytes_rx[rx_lcids[i]]+=rx_lengths[i]; - - } - // } - break; - default : //if (rx_lcids[i] >= DTCH) { - eNB_mac_inst[enb_mod_idP].eNB_UE_stats[ue_mod_id].num_errors_rx+=1; - LOG_E(MAC,"[eNB %d] received unsupported or unknown LCID %d from UE %d ", rx_lcids[i], ue_mod_id); - break; - } - payload_ptr+=rx_lengths[i]; - - } - - eNB_mac_inst[enb_mod_idP].eNB_UE_stats[ue_mod_id].total_pdu_bytes_rx+=sdu_len; - eNB_mac_inst[enb_mod_idP].eNB_UE_stats[ue_mod_id].total_num_pdus_rx+=1; - - vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,0); - stop_meas(&eNB_mac_inst[enb_mod_idP].rx_ulsch_sdu); -} - -// First stage of Random-Access Scheduling -void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP,unsigned char Msg3_subframe,unsigned char *nprb,unsigned int *nCCE) { - - start_meas(&eNB_mac_inst[module_idP].schedule_ra); - RA_TEMPLATE *RA_template = (RA_TEMPLATE *)&eNB_mac_inst[module_idP].RA_template[0]; - unsigned char i;//,harq_pid,round; - uint16_t rrc_sdu_length; - unsigned char lcid,offset; - module_id_t UE_id= UE_INDEX_INVALID; - unsigned short TBsize = -1; - unsigned short msg4_padding,msg4_post_padding,msg4_header; - - for (i=0;i<NB_RA_PROC_MAX;i++) { - - if (RA_template[i].RA_active == TRUE) { - - LOG_I(MAC,"[eNB %d][RAPROC] RA %d is active (generate RAR %d, generate_Msg4 %d, wait_ack_Msg4 %d, rnti %x)\n", - module_idP,i,RA_template[i].generate_rar,RA_template[i].generate_Msg4,RA_template[i].wait_ack_Msg4, RA_template[i].rnti); - - if (RA_template[i].generate_rar == 1) { - *nprb= (*nprb) + 3; - *nCCE = (*nCCE) + 4; - RA_template[i].Msg3_subframe=Msg3_subframe; - } - else if (RA_template[i].generate_Msg4 == 1) { - - // check for Msg4 Message - UE_id = find_UE_id(module_idP,RA_template[i].rnti); - if (Is_rrc_registered == 1) { - - // Get RRCConnectionSetup for Piggyback - rrc_sdu_length = mac_rrc_data_req(module_idP, - frameP, - CCCH,1, - &eNB_mac_inst[module_idP].CCCH_pdu.payload[0], - 1, - module_idP, - 0); // not used in this case - if (rrc_sdu_length == -1) - mac_xface->macphy_exit("[MAC][eNB Scheduler] CCCH not allocated\n"); - else { - //msg("[MAC][eNB %d] Frame %d, subframeP %d: got %d bytes from RRC\n",module_idP,frameP, subframeP,rrc_sdu_length); - } - } - - LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d: UE_id %d, Is_rrc_registered %d, rrc_sdu_length %d\n", - module_idP,frameP, subframeP,UE_id, Is_rrc_registered,rrc_sdu_length); - - if (rrc_sdu_length>0) { - LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RA proc %d, RNTI %x)\n", - module_idP,frameP, subframeP,i,RA_template[i].rnti); - - //msg("[MAC][eNB %d][RAPROC] Frame %d, subframeP %d: Received %d bytes for Msg4: \n",module_idP,frameP,subframeP,rrc_sdu_length); - // for (j=0;j<rrc_sdu_length;j++) - // msg("%x ",(unsigned char)eNB_mac_inst[module_idP].CCCH_pdu.payload[j]); - // msg("\n"); - // msg("[MAC][eNB] Frame %d, subframeP %d: Generated DLSCH (Msg4) DCI, format 1A, for UE %d\n",frameP, subframeP,UE_id); - // Schedule Reflection of Connection request - - - - // Compute MCS for 3 PRB - msg4_header = 1+6+1; // CR header, CR CE, SDU header - - if (mac_xface->lte_frame_parms->frame_type == TDD) { - - switch (mac_xface->lte_frame_parms->N_RB_DL) { - case 6: - ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1; - - if ((rrc_sdu_length+msg4_header) <= 22) { - ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4; - TBsize = 22; - } - else if ((rrc_sdu_length+msg4_header) <= 28) { - ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5; - TBsize = 28; - } - else if ((rrc_sdu_length+msg4_header) <= 32) { - ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6; - TBsize = 32; - } - else if ((rrc_sdu_length+msg4_header) <= 41) { - ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7; - TBsize = 41; - } - else if ((rrc_sdu_length+msg4_header) <= 49) { - ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8; - TBsize = 49; - } - else if ((rrc_sdu_length+msg4_header) <= 57) { - ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9; - TBsize = 57; - } - break; - case 25: - - ((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1; - - if ((rrc_sdu_length+msg4_header) <= 22) { - ((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4; - TBsize = 22; - } - else if ((rrc_sdu_length+msg4_header) <= 28) { - ((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5; - TBsize = 28; - } - else if ((rrc_sdu_length+msg4_header) <= 32) { - ((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6; - TBsize = 32; - } - else if ((rrc_sdu_length+msg4_header) <= 41) { - ((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7; - TBsize = 41; - } - else if ((rrc_sdu_length+msg4_header) <= 49) { - ((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8; - TBsize = 49; - } - else if ((rrc_sdu_length+msg4_header) <= 57) { - ((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9; - TBsize = 57; - } - break; - case 50: - - ((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1; - - if ((rrc_sdu_length+msg4_header) <= 22) { - ((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4; - TBsize = 22; - } - else if ((rrc_sdu_length+msg4_header) <= 28) { - ((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5; - TBsize = 28; - } - else if ((rrc_sdu_length+msg4_header) <= 32) { - ((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6; - TBsize = 32; - } - else if ((rrc_sdu_length+msg4_header) <= 41) { - ((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7; - TBsize = 41; - } - else if ((rrc_sdu_length+msg4_header) <= 49) { - ((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8; - TBsize = 49; - } - else if ((rrc_sdu_length+msg4_header) <= 57) { - ((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9; - TBsize = 57; - } - break; - case 100: - - ((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1; - - if ((rrc_sdu_length+msg4_header) <= 22) { - ((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4; - TBsize = 22; - } - else if ((rrc_sdu_length+msg4_header) <= 28) { - ((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5; - TBsize = 28; - } - else if ((rrc_sdu_length+msg4_header) <= 32) { - ((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6; - TBsize = 32; - } - else if ((rrc_sdu_length+msg4_header) <= 41) { - ((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7; - TBsize = 41; - } - else if ((rrc_sdu_length+msg4_header) <= 49) { - ((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8; - TBsize = 49; - } - else if ((rrc_sdu_length+msg4_header) <= 57) { - ((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9; - TBsize = 57; - } - break; - } - } - else { // FDD DCI - switch (mac_xface->lte_frame_parms->N_RB_DL) { - case 6: - ((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1; - - if ((rrc_sdu_length+msg4_header) <= 22) { - ((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4; - TBsize = 22; - } - else if ((rrc_sdu_length+msg4_header) <= 28) { - ((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5; - TBsize = 28; - } - else if ((rrc_sdu_length+msg4_header) <= 32) { - ((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6; - TBsize = 32; - } - else if ((rrc_sdu_length+msg4_header) <= 41) { - ((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7; - TBsize = 41; - } - else if ((rrc_sdu_length+msg4_header) <= 49) { - ((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8; - TBsize = 49; - } - else if ((rrc_sdu_length+msg4_header) <= 57) { - ((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9; - TBsize = 57; - } - break; - case 25: - ((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1; - - if ((rrc_sdu_length+msg4_header) <= 22) { - ((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4; - TBsize = 22; - } - else if ((rrc_sdu_length+msg4_header) <= 28) { - ((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5; - TBsize = 28; - } - else if ((rrc_sdu_length+msg4_header) <= 32) { - ((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6; - TBsize = 32; - } - else if ((rrc_sdu_length+msg4_header) <= 41) { - ((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7; - TBsize = 41; - } - else if ((rrc_sdu_length+msg4_header) <= 49) { - ((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8; - TBsize = 49; - } - else if ((rrc_sdu_length+msg4_header) <= 57) { - ((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9; - TBsize = 57; - } - break; - case 50: - ((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1; - - if ((rrc_sdu_length+msg4_header) <= 22) { - ((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4; - TBsize = 22; - } - else if ((rrc_sdu_length+msg4_header) <= 28) { - ((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5; - TBsize = 28; - } - else if ((rrc_sdu_length+msg4_header) <= 32) { - ((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6; - TBsize = 32; - } - else if ((rrc_sdu_length+msg4_header) <= 41) { - ((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7; - TBsize = 41; - } - else if ((rrc_sdu_length+msg4_header) <= 49) { - ((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8; - TBsize = 49; - } - else if ((rrc_sdu_length+msg4_header) <= 57) { - ((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9; - TBsize = 57; - } - break; - case 100: - ((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1; - - if ((rrc_sdu_length+msg4_header) <= 22) { - ((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4; - TBsize = 22; - } - else if ((rrc_sdu_length+msg4_header) <= 28) { - ((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5; - TBsize = 28; - } - else if ((rrc_sdu_length+msg4_header) <= 32) { - ((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6; - TBsize = 32; - } - else if ((rrc_sdu_length+msg4_header) <= 41) { - ((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7; - TBsize = 41; - } - else if ((rrc_sdu_length+msg4_header) <= 49) { - ((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8; - TBsize = 49; - } - else if ((rrc_sdu_length+msg4_header) <= 57) { - ((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9; - TBsize = 57; - } - break; - } - } - RA_template[i].generate_Msg4=0; - RA_template[i].generate_Msg4_dci=1; - RA_template[i].wait_ack_Msg4=1; - RA_template[i].RA_active = FALSE; - lcid=0; - - if ((TBsize - rrc_sdu_length - msg4_header) <= 2) { - msg4_padding = TBsize - rrc_sdu_length - msg4_header; - msg4_post_padding = 0; - } - else { - msg4_padding = 0; - msg4_post_padding = TBsize - rrc_sdu_length - msg4_header -1; - } - LOG_I(MAC,"[eNB %d][RAPROC] Frame %d subframeP %d Msg4 : TBS %d, sdu_len %d, msg4_header %d, msg4_padding %d, msg4_post_padding %d\n", - module_idP,frameP,subframeP,TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding); - offset = generate_dlsch_header((unsigned char*)eNB_mac_inst[module_idP].DLSCH_pdu[(unsigned char)UE_id][0].payload[0], - 1, //num_sdus - &rrc_sdu_length, // - &lcid, // sdu_lcid - 255, // no drx - 0, // no timing advance - RA_template[i].cont_res_id, // contention res id - msg4_padding, // no padding - msg4_post_padding); - - memcpy((void*)&eNB_mac_inst[module_idP].DLSCH_pdu[(unsigned char)UE_id][0].payload[0][(unsigned char)offset], - &eNB_mac_inst[module_idP].CCCH_pdu.payload[0], - rrc_sdu_length); - -#if defined(USER_MODE) && defined(OAI_EMU) - if (oai_emulation.info.opt_enabled){ - trace_pdu(1, (uint8_t *)eNB_mac_inst[module_idP].DLSCH_pdu[(unsigned char)UE_id][0].payload[0], - rrc_sdu_length, UE_id, 3, find_UE_RNTI(module_idP, UE_id), - eNB_mac_inst[module_idP].subframe,0,0); - LOG_D(OPT,"[eNB %d][DLSCH] Frame %d trace pdu for rnti %x with size %d\n", - module_idP, frameP, find_UE_RNTI(module_idP,UE_id), rrc_sdu_length); - } -#endif - *nprb= (*nprb) + 3; - *nCCE = (*nCCE) + 4; - } - //try here - } - /* - else if (eNB_mac_inst[module_idP].RA_template[i].wait_ack_Msg4==1) { - // check HARQ status and retransmit if necessary - LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d: Checking if Msg4 was acknowledged :\n",module_idP,frameP,subframeP); - // Get candidate harq_pid from PHY - mac_xface->get_ue_active_harq_pid(module_idP,eNB_mac_inst[module_idP].RA_template[i].rnti,subframeP,&harq_pid,&round,0); - if (round>0) { - *nprb= (*nprb) + 3; - *nCCE = (*nCCE) + 4; - } - } - */ - } - } - stop_meas(&eNB_mac_inst[module_idP].schedule_ra); -} - -void initiate_ra_proc(module_id_t module_idP, frame_t frameP, uint16_t preamble_index,int16_t timing_offset,uint8_t sect_id,sub_frame_t subframeP,uint8_t f_id) { - - uint8_t i; - - LOG_I(MAC,"[eNB %d][RAPROC] Frame %d Initiating RA procedure for preamble index %d\n",module_idP,frameP,preamble_index); - - for (i=0;i<NB_RA_PROC_MAX;i++) { - if (eNB_mac_inst[module_idP].RA_template[i].RA_active==FALSE) { - eNB_mac_inst[module_idP].RA_template[i].RA_active=TRUE; - eNB_mac_inst[module_idP].RA_template[i].generate_rar=1; - eNB_mac_inst[module_idP].RA_template[i].generate_Msg4=0; - eNB_mac_inst[module_idP].RA_template[i].wait_ack_Msg4=0; - eNB_mac_inst[module_idP].RA_template[i].timing_offset=timing_offset; - // Put in random rnti (to be replaced with proper procedure!!) - eNB_mac_inst[module_idP].RA_template[i].rnti = taus(); - eNB_mac_inst[module_idP].RA_template[i].RA_rnti = 1+subframeP+(10*f_id); - eNB_mac_inst[module_idP].RA_template[i].preamble_index = preamble_index; - LOG_D(MAC,"[eNB %d][RAPROC] Frame %d Activating RAR generation for process %d, rnti %x, RA_active %d\n", - module_idP,frameP,i,eNB_mac_inst[module_idP].RA_template[i].rnti, - eNB_mac_inst[module_idP].RA_template[i].RA_active); - - return; - } - } -} diff --git a/openair2/LAYER2/MAC/rar_tools.c b/openair2/LAYER2/MAC/rar_tools.c index 58b152135d..15460c7b0f 100644 --- a/openair2/LAYER2/MAC/rar_tools.c +++ b/openair2/LAYER2/MAC/rar_tools.c @@ -57,6 +57,7 @@ extern unsigned short RIV2first_rb_LUT25[512]; extern inline unsigned int taus(void); unsigned short fill_rar(module_id_t module_idP, + int CC_id, frame_t frameP, uint8_t *dlsch_buffer, uint16_t N_RB_UL, @@ -70,9 +71,9 @@ unsigned short fill_rar(module_id_t module_idP, uint8_t mcs,TPC,ULdelay,cqireq; for (i=0;i<NB_RA_PROC_MAX;i++) { - if (eNB_mac_inst[module_idP].RA_template[i].generate_rar == 1) { + if (eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[i].generate_rar == 1) { ra_idx=i; - eNB_mac_inst[module_idP].RA_template[i].generate_rar = 0; + eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[i].generate_rar = 0; break; } } @@ -80,24 +81,24 @@ unsigned short fill_rar(module_id_t module_idP, // subheader fixed rarh->E = 0; // First and last RAR rarh->T = 1; // 0 for E/T/R/R/BI subheader, 1 for E/T/RAPID subheader - rarh->RAPID = eNB_mac_inst[module_idP].RA_template[ra_idx].preamble_index; // Respond to Preamble 0 only for the moment + rarh->RAPID = eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].preamble_index; // Respond to Preamble 0 only for the moment /* rar->R = 0; - rar->Timing_Advance_Command = eNB_mac_inst[module_idP].RA_template[ra_idx].timing_offset/4; + rar->Timing_Advance_Command = eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset/4; rar->hopping_flag = 0; rar->rb_alloc = mac_xface->computeRIV(N_RB_UL,12,2); // 2 RB rar->mcs = 2; // mcs 2 rar->TPC = 4; // 2 dB power adjustment rar->UL_delay = 0; rar->cqi_req = 1; - rar->t_crnti = eNB_mac_inst[module_idP].RA_template[ra_idx].rnti; + rar->t_crnti = eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].rnti; */ - rar[4] = (uint8_t)(eNB_mac_inst[module_idP].RA_template[ra_idx].rnti>>8); - rar[5] = (uint8_t)(eNB_mac_inst[module_idP].RA_template[ra_idx].rnti&0xff); - eNB_mac_inst[module_idP].RA_template[ra_idx].timing_offset = 0; - //eNB_mac_inst[module_idP].RA_template[ra_idx].timing_offset /= 16; - rar[0] = (uint8_t)(eNB_mac_inst[module_idP].RA_template[ra_idx].timing_offset>>(2+4)); // 7 MSBs of timing advance + divide by 4 - rar[1] = (uint8_t)(eNB_mac_inst[module_idP].RA_template[ra_idx].timing_offset<<(4-2))&0xf0; // 4 LSBs of timing advance + divide by 4 + rar[4] = (uint8_t)(eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].rnti>>8); + rar[5] = (uint8_t)(eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].rnti&0xff); + eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset = 0; + //eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset /= 16; + rar[0] = (uint8_t)(eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset>>(2+4)); // 7 MSBs of timing advance + divide by 4 + rar[1] = (uint8_t)(eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset<<(4-2))&0xf0; // 4 LSBs of timing advance + divide by 4 rballoc = mac_xface->computeRIV(N_RB_UL,1,1); // first PRB only for UL Grant rar[1] |= (rballoc>>7)&7; // Hopping = 0 (bit 3), 3 MSBs of rballoc rar[2] = ((uint8_t)(rballoc&0xff))<<1; // 7 LSBs of rballoc @@ -111,28 +112,33 @@ unsigned short fill_rar(module_id_t module_idP, LOG_I(MAC,"[eNB %d][RAPROC] Frame %d Generating RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for ra_idx %d, CRNTI %x,preamble %d/%d,TIMING OFFSET %d\n",module_idP,frameP, *(uint8_t*)rarh,rar[0],rar[1],rar[2],rar[3],rar[4],rar[5], ra_idx, - eNB_mac_inst[module_idP].RA_template[ra_idx].rnti, - rarh->RAPID,eNB_mac_inst[module_idP].RA_template[0].preamble_index, - eNB_mac_inst[module_idP].RA_template[ra_idx].timing_offset); + eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].rnti, + rarh->RAPID,eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[0].preamble_index, + eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset); #if defined(USER_MODE) && defined(OAI_EMU) if (oai_emulation.info.opt_enabled){ trace_pdu(1, dlsch_buffer, input_buffer_length, module_idP, 2, 1, eNB_mac_inst[module_idP].subframe, 0, 0); LOG_I(OPT,"[eNB %d][RAPROC] RAR Frame %d trace pdu for rnti %x and rapid %d size %d\n", - module_idP, frameP, eNB_mac_inst[module_idP].RA_template[ra_idx].rnti, + module_idP, frameP, eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].rnti, rarh->RAPID, input_buffer_length); } #endif - return(eNB_mac_inst[module_idP].RA_template[ra_idx].rnti); + return(eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].rnti); } -uint16_t ue_process_rar(module_id_t module_idP, frame_t frameP, uint8_t *dlsch_buffer,rnti_t *t_crnti,uint8_t preamble_index) { +uint16_t ue_process_rar(module_id_t module_idP, int CC_id,frame_t frameP, uint8_t *dlsch_buffer,rnti_t *t_crnti,uint8_t preamble_index) { RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *)dlsch_buffer; // RAR_PDU *rar = (RAR_PDU *)(dlsch_buffer+1); uint8_t *rar = (uint8_t *)(dlsch_buffer+1); + if (CC_id>0) { + LOG_W(MAC,"Should not have received RAR on secondary CCs! \n"); + return(0xffff); + } + LOG_I(MAC,"[eNB %d][RAPROC] Frame %d Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n",module_idP,frameP, *(uint8_t*)rarh,rar[0],rar[1],rar[2],rar[3],rar[4],rar[5], rarh->RAPID,preamble_index); diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index 673b3ef581..710efb0e60 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -95,10 +95,8 @@ extern inline unsigned int taus(void); void ue_init_mac(module_id_t module_idP){ int i; - // default values as deined in 36.331 sec 9.2.2 LOG_I(MAC,"[UE%d] Applying default macMainConfig\n",module_idP); - //UE_mac_inst[module_idP].scheduling_info.macConfig=NULL; UE_mac_inst[module_idP].scheduling_info.retxBSR_Timer= MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf2560; UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer=MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity; @@ -118,10 +116,10 @@ void ue_init_mac(module_id_t module_idP){ UE_mac_inst[module_idP].scheduling_info.periodicPHR_SF = get_sf_perioidicPHR_Timer(UE_mac_inst[module_idP].scheduling_info.periodicPHR_Timer); UE_mac_inst[module_idP].scheduling_info.prohibitPHR_SF = get_sf_prohibitPHR_Timer(UE_mac_inst[module_idP].scheduling_info.prohibitPHR_Timer); UE_mac_inst[module_idP].scheduling_info.PathlossChange_db = get_db_dl_PathlossChange(UE_mac_inst[module_idP].scheduling_info.PathlossChange); - + for (i=0; i < MAX_NUM_LCID; i++){ - LOG_D(MAC,"[UE%d] Applying default logical channel config for LCGID %d\n",module_idP,i); - UE_mac_inst[module_idP].scheduling_info.Bj[i]=-1; + LOG_D(MAC,"[UE%d] Applying default logical channel config for LCGID %d\n",module_idP,i); + UE_mac_inst[module_idP].scheduling_info.Bj[i]=-1; UE_mac_inst[module_idP].scheduling_info.bucket_size[i]=-1; if (i < DTCH) // initilize all control channels lcgid to 0 UE_mac_inst[module_idP].scheduling_info.LCGID[i]=0; @@ -131,13 +129,14 @@ void ue_init_mac(module_id_t module_idP){ } } + unsigned char *parse_header(unsigned char *mac_header, - unsigned char *num_ce, - unsigned char *num_sdu, - unsigned char *rx_ces, - unsigned char *rx_lcids, - unsigned short *rx_lengths, - unsigned short tb_length) { + unsigned char *num_ce, + unsigned char *num_sdu, + unsigned char *rx_ces, + unsigned char *rx_lcids, + unsigned short *rx_lengths, + unsigned short tb_length) { unsigned char not_done=1,num_ces=0,num_sdus=0,lcid, num_sdu_cnt; unsigned char *mac_header_ptr = mac_header; @@ -203,7 +202,7 @@ unsigned char *parse_header(unsigned char *mac_header, return(mac_header_ptr); } -uint32_t ue_get_SR(module_id_t module_idP,frame_t frameP,uint8_t eNB_id,uint16_t rnti, sub_frame_t subframe) { +uint32_t ue_get_SR(module_id_t module_idP,int CC_id,frame_t frameP,uint8_t eNB_id,uint16_t rnti, sub_frame_t subframe) { // no UL-SCH resources available for this tti && UE has a valid PUCCH resources for SR configuration for this tti // int MGL=6;// measurement gap length in ms @@ -213,6 +212,12 @@ uint32_t ue_get_SR(module_id_t module_idP,frame_t frameP,uint8_t eNB_id,uint16_t DevCheck(module_idP < NB_UE_INST, module_idP, NB_UE_INST, 0); + if (CC_id>0) { + LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n"); + mac_xface->macphy_exit("MAC FATAL CC_id>0"); + return; + } + // determin the measurement gap LOG_D(MAC,"[UE %d][SR %x] Frame %d subframe %d PHY asks for SR (SR_COUNTER/dsr_TransMax %d/%d), SR_pending %d\n", module_idP,rnti,frameP,subframe, @@ -269,7 +274,7 @@ uint32_t ue_get_SR(module_id_t module_idP,frame_t frameP,uint8_t eNB_id,uint16_t } } -void ue_send_sdu(module_id_t module_idP,frame_t frameP,uint8_t *sdu,uint16_t sdu_len,uint8_t eNB_index) { +void ue_send_sdu(module_id_t module_idP,int CC_id,frame_t frameP,uint8_t *sdu,uint16_t sdu_len,uint8_t eNB_index) { unsigned char rx_ces[MAX_NUM_CE],num_ce,num_sdu,i,*payload_ptr; unsigned char rx_lcids[NB_RB_MAX]; @@ -319,14 +324,14 @@ void ue_send_sdu(module_id_t module_idP,frame_t frameP,uint8_t *sdu,uint16_t sdu for (i=0;i<6;i++) if (tx_sdu[i] != payload_ptr[i]) { LOG_E(MAC,"[UE %d][RAPROC] Contention detected, RA failed\n",module_idP); - mac_xface->ra_failed(module_idP,eNB_index); + mac_xface->ra_failed(module_idP,CC_id,eNB_index); UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0; vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT); return; } LOG_I(MAC,"[UE %d][RAPROC] Frame %d : Clearing contention resolution timer\n"); UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0; - mac_xface->ra_succeeded(module_idP,eNB_index); + mac_xface->ra_succeeded(module_idP,CC_id,eNB_index); } payload_ptr+=6; break; @@ -418,7 +423,7 @@ void ue_send_sdu(module_id_t module_idP,frame_t frameP,uint8_t *sdu,uint16_t sdu stop_meas(&UE_mac_inst[module_idP].rx_dlsch_sdu); } -void ue_decode_si(module_id_t module_idP,frame_t frameP, uint8_t eNB_index, void *pdu,uint16_t len) { +void ue_decode_si(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_index, void *pdu,uint16_t len) { start_meas(&UE_mac_inst[module_idP].rx_si); vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_IN); @@ -439,14 +444,14 @@ void ue_decode_si(module_id_t module_idP,frame_t frameP, uint8_t eNB_index, void #ifdef Rel10 unsigned char *parse_mch_header(unsigned char *mac_header, - unsigned char *num_sdu, - unsigned char *rx_lcids, - unsigned short *rx_lengths, - unsigned short tb_length) { + unsigned char *num_sdu, + unsigned char *rx_lcids, + unsigned short *rx_lengths, + unsigned short tb_length) { unsigned char not_done=1, num_sdus=0, lcid, i; unsigned char *mac_header_ptr = mac_header; unsigned short length; - + while (not_done == 1) { if (((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E == 0) { not_done = 0; @@ -789,16 +794,16 @@ int ue_query_mch(module_id_t module_idP, uint32_t frameP, uint32_t subframe, uin #endif unsigned char generate_ulsch_header(uint8_t *mac_header, - uint8_t num_sdus, - uint8_t short_padding, - uint16_t *sdu_lengths, - uint8_t *sdu_lcids, - POWER_HEADROOM_CMD *power_headroom, - uint16_t *crnti, - BSR_SHORT *truncated_bsr, - BSR_SHORT *short_bsr, - BSR_LONG *long_bsr, - unsigned short post_padding) { + uint8_t num_sdus, + uint8_t short_padding, + uint16_t *sdu_lengths, + uint8_t *sdu_lcids, + POWER_HEADROOM_CMD *power_headroom, + uint16_t *crnti, + BSR_SHORT *truncated_bsr, + BSR_SHORT *short_bsr, + BSR_LONG *long_bsr, + unsigned short post_padding) { SCH_SUBHEADER_FIXED *mac_header_ptr = (SCH_SUBHEADER_FIXED *)mac_header; unsigned char first_element=0,last_size=0,i; @@ -1030,7 +1035,7 @@ unsigned char generate_ulsch_header(uint8_t *mac_header, } -void ue_get_sdu(module_id_t module_idP,frame_t frameP,sub_frame_t subframe, uint8_t eNB_index,uint8_t *ulsch_buffer,uint16_t buflen, uint8_t *access_mode) { +void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subframe, uint8_t eNB_index,uint8_t *ulsch_buffer,uint16_t buflen, uint8_t *access_mode) { mac_rlc_status_resp_t rlc_status; uint8_t dcch_header_len=0,dcch1_header_len=0,dtch_header_len=0; @@ -1053,6 +1058,12 @@ void ue_get_sdu(module_id_t module_idP,frame_t frameP,sub_frame_t subframe, uint int j; // used for padding // Compute header length + if (CC_id>0) { + LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n"); + mac_xface->macphy_exit("MAC FATAL CC_id>0"); + return; + } + start_meas(&UE_mac_inst[module_idP].tx_ulsch_sdu); vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GET_SDU, VCD_FUNCTION_IN); @@ -1217,11 +1228,11 @@ void ue_get_sdu(module_id_t module_idP,frame_t frameP,sub_frame_t subframe, uint // build PHR and update the timers if (phr_ce_len == sizeof(POWER_HEADROOM_CMD)){ - phr_p->PH = get_phr_mapping(module_idP,eNB_index); - phr_p->R = 0; - LOG_D(MAC,"[UE %d] Frame %d report PHR with mapping (%d->%d) for LCID %d\n", - module_idP,frameP, mac_xface->get_PHR(module_idP,eNB_index), phr_p->PH,POWER_HEADROOM); - update_phr(module_idP); + phr_p->PH = get_phr_mapping(module_idP,CC_id,eNB_index); + phr_p->R = 0; + LOG_D(MAC,"[UE %d] Frame %d report PHR with mapping (%d->%d) for LCID %d\n", + module_idP,frameP, mac_xface->get_PHR(module_idP,CC_id,eNB_index), phr_p->PH,POWER_HEADROOM); + update_phr(module_idP,CC_id); }else phr_p=NULL; @@ -1416,7 +1427,7 @@ UE_L2_STATE_t ue_scheduler(module_id_t module_idP,frame_t frameP, sub_frame_t su UE_mac_inst[module_idP].RA_active = 0; // Signal PHY to quit RA procedure LOG_E(MAC,"Module id %u Contention resolution timer expired, RA failed\n", module_idP); - mac_xface->ra_failed(module_idP,eNB_indexP); + mac_xface->ra_failed(module_idP,0,eNB_indexP); } } @@ -1573,6 +1584,7 @@ uint8_t get_bsr_len (module_id_t module_idP, uint16_t buflen) { uint8_t bsr_len=0, num_lcgid=0; int pdu = 0; + for (lcgid=0; lcgid < MAX_NUM_LCGID; lcgid++ ) { if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid] > 0 ) pdu += (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid] + bsr_len + 2); //2 = sizeof(SCH_SUBHEADER_SHORT) @@ -1597,6 +1609,8 @@ boolean_t update_bsr(module_id_t module_idP, frame_t frameP, uint8_t lcid, uint mac_rlc_status_resp_t rlc_status; boolean_t sr_pending = FALSE; + + if ((lcg_id < 0) || (lcg_id > MAX_NUM_LCGID) ) return sr_pending; // fixme: need a better way to reset @@ -1754,23 +1768,34 @@ int get_ms_bucketsizeduration(uint8_t bucketsizeduration){ } } -void update_phr(module_id_t module_idP){ +void update_phr(module_id_t module_idP,int CC_id){ + + if (CC_id>0) { + LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n"); + mac_xface->macphy_exit("MAC FATAL CC_id>0"); + return; + } UE_mac_inst[module_idP].PHR_reporting_active =0; UE_mac_inst[module_idP].scheduling_info.periodicPHR_SF = get_sf_perioidicPHR_Timer(UE_mac_inst[module_idP].scheduling_info.periodicPHR_Timer); UE_mac_inst[module_idP].scheduling_info.prohibitPHR_SF = get_sf_prohibitPHR_Timer(UE_mac_inst[module_idP].scheduling_info.prohibitPHR_Timer); // LOG_D(MAC,"phr %d %d\n ",UE_mac_inst[module_idP].scheduling_info.periodicPHR_SF, UE_mac_inst[module_idP].scheduling_info.prohibitPHR_SF); } -uint8_t get_phr_mapping (module_id_t module_idP, uint8_t eNB_index){ +uint8_t get_phr_mapping (module_id_t module_idP, int CC_id, uint8_t eNB_index){ + if (CC_id>0) { + LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n"); + mac_xface->macphy_exit("MAC FATAL CC_id>0"); + return; + } //power headroom reporting range is from -23 ...+40 dB, as described in 36313 //note: mac_xface->get_Po_NOMINAL_PUSCH(module_idP) is float - if (mac_xface->get_PHR(module_idP,eNB_index) < -23) + if (mac_xface->get_PHR(module_idP,CC_id,eNB_index) < -23) return 0; - else if (mac_xface->get_PHR(module_idP,eNB_index) >= 40) + else if (mac_xface->get_PHR(module_idP,CC_id,eNB_index) >= 40) return 63; else // -23 to 40 - return (uint8_t) mac_xface->get_PHR(module_idP,eNB_index) + PHR_MAPPING_OFFSET; + return (uint8_t) mac_xface->get_PHR(module_idP,CC_id,eNB_index) + PHR_MAPPING_OFFSET; } int get_sf_perioidicPHR_Timer(uint8_t perioidicPHR_Timer){ diff --git a/openair2/LAYER2/MAC/vars.h b/openair2/LAYER2/MAC/vars.h index 50480021a3..16caaaf2e6 100644 --- a/openair2/LAYER2/MAC/vars.h +++ b/openair2/LAYER2/MAC/vars.h @@ -61,6 +61,11 @@ UE_MAC_INST *UE_mac_inst; //[NB_MODULE_MAX]; eNB_MAC_INST *eNB_mac_inst; //[NB_MODULE_MAX]; MAC_RLC_XFACE *Mac_rlc_xface; +/// Primary component carrier index of eNB +int pCC_id[NUMBER_OF_eNB_MAX]; + + + eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8 eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8 diff --git a/openair2/LAYER2/Makefile.inc b/openair2/LAYER2/Makefile.inc index c599b27e4f..c6c40ade23 100644 --- a/openair2/LAYER2/Makefile.inc +++ b/openair2/LAYER2/Makefile.inc @@ -89,6 +89,7 @@ MAC_OBJS += $(MAC_DIR)/eNB_scheduler_ulsch.o MAC_OBJS += $(MAC_DIR)/eNB_scheduler_mch.o MAC_OBJS += $(MAC_DIR)/eNB_scheduler_bch.o MAC_OBJS += $(MAC_DIR)/eNB_scheduler_primitives.o +MAC_OBJS += $(MAC_DIR)/eNB_scheduler_RA.o MAC_OBJS += $(MAC_DIR)/pre_processor.o MAC_OBJS += $(MAC_DIR)/config.o diff --git a/openair2/LAYER2/openair2_proc.c b/openair2/LAYER2/openair2_proc.c index e9e3135b5e..559d571e3b 100644 --- a/openair2/LAYER2/openair2_proc.c +++ b/openair2/LAYER2/openair2_proc.c @@ -68,74 +68,81 @@ static mapping rrc_status_names[] = { int dump_eNB_l2_stats(char *buffer, int length){ - uint8_t eNB_id,UE_id,number_of_cards; + int eNB_id,UE_id,number_of_cards; int len= length; - + int CC_id=0; + int i; + #ifdef EXMIMO number_of_cards=1; #else number_of_cards=NB_eNB_INST; #endif - + eNB_MAC_INST *eNB; + UE_list_t *UE_list; for (eNB_id=0;eNB_id<number_of_cards;eNB_id++) { /* reset the values */ - eNB_mac_inst[eNB_id].eNB_stats.dlsch_bitrate= 0; + eNB = &eNB_mac_inst[eNB_id]; + UE_list = &eNB->UE_list; + + eNB->eNB_stats.dlsch_bitrate= 0; len += sprintf(&buffer[len],"eNB %d Frame %d: Active UEs %d, Available PRBs %d, nCCE %d \n", - eNB_id, eNB_mac_inst[eNB_id].frame, - eNB_mac_inst[eNB_id].eNB_stats.num_dlactive_UEs, - eNB_mac_inst[eNB_id].eNB_stats.available_prbs, - eNB_mac_inst[eNB_id].eNB_stats.available_ncces); + eNB_id, eNB->frame, + eNB->eNB_stats.num_dlactive_UEs, + eNB->eNB_stats.available_prbs, + eNB->eNB_stats.available_ncces); - eNB_mac_inst[eNB_id].eNB_stats.dlsch_bitrate=((eNB_mac_inst[eNB_id].eNB_stats.dlsch_bytes_tx*8)/((eNB_mac_inst[eNB_id].frame + 1)*10)); - eNB_mac_inst[eNB_id].eNB_stats.total_dlsch_pdus_tx+=eNB_mac_inst[eNB_id].eNB_stats.dlsch_pdus_tx; - eNB_mac_inst[eNB_id].eNB_stats.total_dlsch_bytes_tx+=eNB_mac_inst[eNB_id].eNB_stats.dlsch_bytes_tx; - eNB_mac_inst[eNB_id].eNB_stats.total_dlsch_bitrate=((eNB_mac_inst[eNB_id].eNB_stats.total_dlsch_bytes_tx*8)/((eNB_mac_inst[eNB_id].frame + 1)*10)); + eNB->eNB_stats.dlsch_bitrate=((eNB->eNB_stats.dlsch_bytes_tx*8)/((eNB->frame + 1)*10)); + eNB->eNB_stats.total_dlsch_pdus_tx+=eNB->eNB_stats.dlsch_pdus_tx; + eNB->eNB_stats.total_dlsch_bytes_tx+=eNB->eNB_stats.dlsch_bytes_tx; + eNB->eNB_stats.total_dlsch_bitrate=((eNB->eNB_stats.total_dlsch_bytes_tx*8)/((eNB->frame + 1)*10)); len += sprintf(&buffer[len],"DLSCH bitrate (TTI %u, avg %u) kbps, Transmitted bytes (TTI %u, total %u), Transmitted PDU (TTI %u, total %u) \n", - eNB_mac_inst[eNB_id].eNB_stats.dlsch_bitrate, - eNB_mac_inst[eNB_id].eNB_stats.total_dlsch_bitrate, - eNB_mac_inst[eNB_id].eNB_stats.dlsch_bytes_tx, - eNB_mac_inst[eNB_id].eNB_stats.total_dlsch_bytes_tx, - eNB_mac_inst[eNB_id].eNB_stats.dlsch_pdus_tx, - eNB_mac_inst[eNB_id].eNB_stats.total_dlsch_pdus_tx); + eNB->eNB_stats.dlsch_bitrate, + eNB->eNB_stats.total_dlsch_bitrate, + eNB->eNB_stats.dlsch_bytes_tx, + eNB->eNB_stats.total_dlsch_bytes_tx, + eNB->eNB_stats.dlsch_pdus_tx, + eNB->eNB_stats.total_dlsch_pdus_tx); len += sprintf(&buffer[len],"\n"); - for (UE_id=0;UE_id<NUMBER_OF_UE_MAX;UE_id++) { - if (eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].crnti > 0 ) { - eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].dlsch_bitrate=((eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].TBS*8)/((eNB_mac_inst[eNB_id].frame + 1)*10)); - eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_dlsch_bitrate= ((eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_pdu_bytes*8)/((eNB_mac_inst[eNB_id].frame + 1)*10)); - eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_overhead_bytes+= eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].overhead_bytes; - eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].avg_overhead_bytes=((eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_overhead_bytes*8)/((eNB_mac_inst[eNB_id].frame + 1)*10)); + for (UE_id=UE_list->head;UE_id>0;UE_id=UE_list->next[UE_id]) { + for (i=0;i<UE_list->numactiveCCs[UE_id];i++) { + CC_id=UE_list->ordered_CCids[i][UE_id]; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_bitrate=((UE_list->eNB_UE_stats[CC_id][UE_id].TBS*8)/((eNB->frame + 1)*10)); + UE_list->eNB_UE_stats[CC_id][UE_id].total_dlsch_bitrate= ((UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes*8)/((eNB->frame + 1)*10)); + UE_list->eNB_UE_stats[CC_id][UE_id].total_overhead_bytes+= UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes; + UE_list->eNB_UE_stats[CC_id][UE_id].avg_overhead_bytes=((UE_list->eNB_UE_stats[CC_id][UE_id].total_overhead_bytes*8)/((eNB->frame + 1)*10)); len += sprintf(&buffer[len],"UE %d %s, RNTI %x : CQI %d, MCS(%d->%d), RB(tx %d, retx %d, total %d), ncce (tx %d, retx %d) \n ", UE_id, - map_int_to_str(rrc_status_names, eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].rrc_status), - eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].crnti, - eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].dl_cqi, - eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].dlsch_mcs1, - eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].dlsch_mcs2, - eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].rbs_used, - eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].rbs_used_retx, - eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_rbs_used, - eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].ncce_used, - eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].ncce_used_retx + map_int_to_str(rrc_status_names, UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status), + UE_list->eNB_UE_stats[CC_id][UE_id].crnti, + UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi, + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1, + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2, + UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used, + UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx, + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used, + UE_list->eNB_UE_stats[CC_id][UE_id].ncce_used, + UE_list->eNB_UE_stats[CC_id][UE_id].ncce_used_retx ); len += sprintf(&buffer[len], "[MAC] DLSCH bitrate (TTI %d, avg %d), Transmitted bytes " "(TTI %d, total %"PRIu64"), Total Transmitted PDU %d, Overhead " "(TTI %"PRIu64", total %"PRIu64", avg %"PRIu64, - eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].dlsch_bitrate, - eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_dlsch_bitrate, - eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].TBS, - eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_pdu_bytes, - eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_num_pdus, - eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].overhead_bytes, - eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_overhead_bytes, - eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].avg_overhead_bytes + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_bitrate, + UE_list->eNB_UE_stats[CC_id][UE_id].total_dlsch_bitrate, + UE_list->eNB_UE_stats[CC_id][UE_id].TBS, + UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes, + UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus, + UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes, + UE_list->eNB_UE_stats[CC_id][UE_id].total_overhead_bytes, + UE_list->eNB_UE_stats[CC_id][UE_id].avg_overhead_bytes ); } diff --git a/openair2/PHY_INTERFACE/defs.h b/openair2/PHY_INTERFACE/defs.h index f2d1199b57..ae6369bee8 100755 --- a/openair2/PHY_INTERFACE/defs.h +++ b/openair2/PHY_INTERFACE/defs.h @@ -70,43 +70,43 @@ typedef struct // eNB functions /// Invoke dlsch/ulsch scheduling procedure for new subframe - void (*eNB_dlsch_ulsch_scheduler)(module_id_t Mod_id, uint8_t cooperation_flag, frame_t frameP, sub_frame_t subframeP);//, int calibration_flag); + void (*eNB_dlsch_ulsch_scheduler)(module_id_t Mod_id,uint8_t cooperation_flag, frame_t frameP, sub_frame_t subframeP);//, int calibration_flag); /// Fill random access response sdu, passing timing advance - uint16_t (*fill_rar)(module_id_t Mod_id,frame_t frameP,uint8_t *dlsch_buffer,uint16_t N_RB_UL, uint8_t input_buffer_length); + uint16_t (*fill_rar)(module_id_t Mod_id,int CC_id,frame_t frameP,uint8_t *dlsch_buffer,uint16_t N_RB_UL, uint8_t input_buffer_length); /// Terminate the RA procedure upon reception of l3msg on ulsch - void (*terminate_ra_proc)(module_id_t Mod_id,frame_t frameP,uint16_t UE_id, uint8_t *l3msg, uint16_t l3msg_len); + void (*terminate_ra_proc)(module_id_t Mod_id,int CC_id,frame_t frameP,uint16_t UE_id, uint8_t *l3msg, uint16_t l3msg_len); /// Initiate the RA procedure upon reception (hypothetical) of a valid preamble - void (*initiate_ra_proc)(module_id_t Mod_id,frame_t frameP,uint16_t preamble,int16_t timing_offset,uint8_t sect_id,uint8_t subframe,uint8_t f_id); + void (*initiate_ra_proc)(module_id_t Mod_id,int CC_id,frame_t frameP,uint16_t preamble,int16_t timing_offset,uint8_t sect_id,sub_frame_t subframe,uint8_t f_id); /// cancel an ongoing RA procedure - void (*cancel_ra_proc)(module_id_t Mod_id,frame_t frameP,uint16_t preamble); + void (*cancel_ra_proc)(module_id_t Mod_id,int CC_id,frame_t frameP,uint16_t preamble); /// Get DCI for current subframe from MAC - DCI_PDU* (*get_dci_sdu)(module_id_t Mod_id,frame_t frameP,sub_frame_t subframe); + DCI_PDU* (*get_dci_sdu)(module_id_t Mod_id,int CC_id,frame_t frameP,sub_frame_t subframe); /// Get DLSCH sdu for particular RNTI and Transport block index - uint8_t* (*get_dlsch_sdu)(module_id_t Mod_id,frame_t frameP,rnti_t rnti,uint8_t TB_index); + uint8_t* (*get_dlsch_sdu)(module_id_t Mod_id,int CC_id,frame_t frameP,rnti_t rnti,uint8_t TB_index); /// Send ULSCH sdu to MAC for given rnti - void (*rx_sdu)(module_id_t Mod_id,frame_t frameP,rnti_t rnti, uint8_t *sdu,uint16_t sdu_len); + void (*rx_sdu)(module_id_t Mod_id,int CC_id,frame_t frameP,rnti_t rnti, uint8_t *sdu,uint16_t sdu_len); /// Indicate failure to synch to external source void (*mrbch_phy_sync_failure) (module_id_t Mod_id,frame_t frameP, uint8_t free_eNB_index); /// Indicate Scheduling Request from UE - void (*SR_indication)(module_id_t Mod_id,frame_t frameP,rnti_t rnti,sub_frame_t subframe); + void (*SR_indication)(module_id_t Mod_id,int CC_id,frame_t frameP,rnti_t rnti,sub_frame_t subframe); /// Configure Common PHY parameters from SIB1 - void (*phy_config_sib1_eNB)(module_id_t Mod_id, + void (*phy_config_sib1_eNB)(module_id_t Mod_id,int CC_id, TDD_Config_t *tdd_config, uint8_t SIwindowsize, uint16_t SIperiod); /// Configure Common PHY parameters from SIB2 - void (*phy_config_sib2_eNB)(module_id_t Mod_id, + void (*phy_config_sib2_eNB)(module_id_t Mod_id, int CC_id, RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, ARFCN_ValueEUTRA_t *ul_CArrierFreq, long *ul_Bandwidth, @@ -115,12 +115,12 @@ typedef struct #ifdef Rel10 /// Configure Common PHY parameters from SIB13 - void (*phy_config_sib13_eNB)(module_id_t Mod_id,int mbsfn_Area_idx, + void (*phy_config_sib13_eNB)(module_id_t Mod_id,int CC_id, int mbsfn_Area_idx, long mbsfn_AreaId_r9); #endif /// PHY-Config-Dedicated eNB - void (*phy_config_dedicated_eNB)(module_id_t Mod_id,rnti_t rnti, + void (*phy_config_dedicated_eNB)(module_id_t Mod_id,int CC_id,rnti_t rnti, struct PhysicalConfigDedicated *physicalConfigDedicated); #ifdef Rel10 @@ -139,10 +139,10 @@ typedef struct void (*out_of_sync_ind)(module_id_t Mod_id,frame_t frameP,uint16_t eNB_index); /// Send a received SI sdu - void (*ue_decode_si)(module_id_t Mod_id,frame_t frameP, uint8_t CH_index, void *pdu, uint16_t len); + void (*ue_decode_si)(module_id_t Mod_id,int CC_id,frame_t frameP, uint8_t CH_index, void *pdu, uint16_t len); /// Send a received DLSCH sdu to MAC - void (*ue_send_sdu)(module_id_t Mod_id,frame_t frameP,uint8_t *sdu,uint16_t sdu_len,uint8_t CH_index); + void (*ue_send_sdu)(module_id_t Mod_id,int CC_id,frame_t frameP,uint8_t *sdu,uint16_t sdu_len,uint8_t CH_index); #ifdef Rel10 /// Send a received MCH sdu to MAC @@ -150,20 +150,20 @@ typedef struct /// Function to check if UE PHY needs to decode MCH for MAC /// get the sync area id, and teturn MCS value if need to decode, otherwise -1 - int (*ue_query_mch)(module_id_t Mod_id,frame_t frameP,sub_frame_t subframe,uint8_t eNB_index,uint8_t *sync_area, uint8_t *mcch_active); + int (*ue_query_mch)(module_id_t Mod_id,int CC_id,frame_t frameP,sub_frame_t subframe,uint8_t eNB_index,uint8_t *sync_area, uint8_t *mcch_active); #endif /// Retrieve ULSCH sdu from MAC - void (*ue_get_sdu)(module_id_t Mod_id,frame_t frameP,sub_frame_t subframe, uint8_t CH_index,uint8_t *ulsch_buffer,uint16_t buflen,uint8_t *access_mode); + void (*ue_get_sdu)(module_id_t Mod_id,int CC_id,frame_t frameP,sub_frame_t subframe, uint8_t CH_index,uint8_t *ulsch_buffer,uint16_t buflen,uint8_t *access_mode); /// Retrieve RRCConnectionReq from MAC - PRACH_RESOURCES_t* (*ue_get_rach)(module_id_t Mod_id,frame_t frameP,uint8_t Msg3_flag,sub_frame_t subframe); + PRACH_RESOURCES_t* (*ue_get_rach)(module_id_t Mod_id,int CC_id,frame_t frameP,uint8_t Msg3_flag,sub_frame_t subframe); /// Process Random-Access Response - uint16_t (*ue_process_rar)(module_id_t Mod_id,frame_t frameP,uint8_t *dlsch_buffer,uint16_t *t_crnti,uint8_t preamble_index); + uint16_t (*ue_process_rar)(module_id_t Mod_id,int CC_id,frame_t frameP,uint8_t *dlsch_buffer,uint16_t *t_crnti,uint8_t preamble_index); /// Get SR payload (0,1) from UE MAC - uint32_t (*ue_get_SR)(module_id_t Mod_id,frame_t frameP,uint8_t eNB_id,rnti_t rnti,sub_frame_t subframe); + uint32_t (*ue_get_SR)(module_id_t Mod_id,int CC_id,frame_t frameP,uint8_t eNB_id,rnti_t rnti,sub_frame_t subframe); /// Indicate synchronization with valid PBCH void (*dl_phy_sync_success) (module_id_t Mod_id,frame_t frameP, uint8_t CH_index,uint8_t first_sync); @@ -172,17 +172,17 @@ typedef struct UE_L2_STATE_t (*ue_scheduler)(module_id_t Mod_id, frame_t frameP,sub_frame_t subframe, lte_subframe_t direction,uint8_t eNB_id); /// PHY-Config-Dedicated UE - void (*phy_config_dedicated_ue)(module_id_t Mod_id,uint8_t CH_index, + void (*phy_config_dedicated_ue)(module_id_t Mod_id,int CC_id,uint8_t CH_index, struct PhysicalConfigDedicated *physicalConfigDedicated); /// Configure Common PHY parameters from SIB1 - void (*phy_config_sib1_ue)(module_id_t Mod_id,uint8_t CH_index, + void (*phy_config_sib1_ue)(module_id_t Mod_id,int CC_id,uint8_t CH_index, TDD_Config_t *tdd_config, uint8_t SIwindowsize, uint16_t SIperiod); /// Configure Common PHY parameters from SIB2 - void (*phy_config_sib2_ue)(module_id_t Mod_id,uint8_t CH_index, + void (*phy_config_sib2_ue)(module_id_t Mod_id,int CC_id,uint8_t CH_index, RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, ARFCN_ValueEUTRA_t *ul_CArrierFreq, long *ul_Bandwidth, @@ -200,19 +200,19 @@ typedef struct uint8_t ho_failed); /// Function to indicate failure of contention resolution or RA procedure - void (*ra_failed)(module_id_t Mod_id,uint8_t eNB_index); + void (*ra_failed)(module_id_t Mod_id,int CC_id,uint8_t eNB_index); /// Function to indicate success of contention resolution or RA procedure - void (*ra_succeeded)(module_id_t Mod_id,uint8_t eNB_index); + void (*ra_succeeded)(module_id_t Mod_id,int CC_id, uint8_t eNB_index); /// Function to indicate the transmission of msg1/rach to MAC - void (*Msg1_transmitted)(module_id_t Mod_id,frame_t frameP,uint8_t eNB_id); + void (*Msg1_transmitted)(module_id_t Mod_id,int CC_id,frame_t frameP,uint8_t eNB_id); /// Function to indicate Msg3 transmission/retransmission which initiates/reset Contention Resolution Timer - void (*Msg3_transmitted)(module_id_t Mod_id,frame_t frameP,uint8_t eNB_id); + void (*Msg3_transmitted)(module_id_t Mod_id,int CC_id,frame_t frameP,uint8_t eNB_id); /// Function to pass inter-cell measurement parameters to PHY (cell Ids) - void (*phy_config_meas_ue)(module_id_t Mod_id,uint8_t eNB_index,uint8_t n_adj_cells,uint32_t *adj_cell_id); + void (*phy_config_meas_ue)(module_id_t Mod_id,int CC_id,uint8_t eNB_index,uint8_t n_adj_cells,uint32_t *adj_cell_id); // PHY Helper Functions @@ -226,22 +226,22 @@ typedef struct uint16_t (*get_TBS_UL)(uint8_t mcs, uint16_t nb_rb); /// Function to retrieve the HARQ round index for a particular UL/DLSCH and harq_pid - int (*get_ue_active_harq_pid)(module_id_t Mod_id, rnti_t rnti, uint8_t subframe, uint8_t *harq_pid, uint8_t *round, uint8_t ul_flag); + int (*get_ue_active_harq_pid)(module_id_t Mod_id, int CC_id,rnti_t rnti, uint8_t subframe, uint8_t *harq_pid, uint8_t *round, uint8_t ul_flag); /// Function to retrieve number of CCE - uint16_t (*get_nCCE_max)(module_id_t Mod_id); + uint16_t (*get_nCCE_max)(module_id_t Mod_id,int CC_id); /// Function to retrieve number of PRB in an rb_alloc uint32_t (*get_nb_rb)(uint8_t ra_header, uint32_t rb_alloc, int n_rb_dl); /// Function to retrieve transmission mode for UE - uint8_t (*get_transmission_mode)(module_id_t Mod_id,rnti_t rnti); + uint8_t (*get_transmission_mode)(module_id_t Mod_id,int CC_id,rnti_t rnti); /// Function to retrieve rb_alloc bitmap from dci rballoc field and VRB type uint32_t (*get_rballoc)(uint8_t vrb_type, uint16_t rb_alloc_dci); /// Function for UE MAC to retrieve current PHY connectivity mode (PRACH,RA_RESPONSE,PUSCH) - UE_MODE_t (*get_ue_mode)(module_id_t Mod_id,uint8_t eNB_index); + UE_MODE_t (*get_ue_mode)(module_id_t Mod_id,int CC_id,uint8_t eNB_index); /// Function for UE MAC to retrieve measured Path Loss int16_t (*get_PL)(module_id_t Mod_id,uint8_t eNB_index); @@ -278,17 +278,17 @@ typedef struct // MAC Helper functions /// Function for UE/PHY to compute PUSCH transmit power in power-control procedure (Po_NOMINAL_PUSCH parameter) - int8_t (*get_Po_NOMINAL_PUSCH)(module_id_t Mod_id); + int8_t (*get_Po_NOMINAL_PUSCH)(module_id_t Mod_id,int CC_id); /// Function for UE/PHY to compute PUSCH transmit power in power-control procedure (deltaP_rampup parameter) - int8_t (*get_deltaP_rampup)(module_id_t Mod_id); + int8_t (*get_deltaP_rampup)(module_id_t Mod_id,int CC_id); /// Function for UE/PHY to compute PHR - int8_t (*get_PHR)(module_id_t Mod_id, uint8_t eNB_index); + int8_t (*get_PHR)(module_id_t Mod_id, int CC_id,uint8_t eNB_index); void (*process_timing_advance)(module_id_t Mod_id,int16_t timing_advance); - LTE_eNB_UE_stats* (*get_eNB_UE_stats)(module_id_t Mod_id, rnti_t rnti); + LTE_eNB_UE_stats* (*get_eNB_UE_stats)(module_id_t Mod_id, int CC_id, rnti_t rnti); unsigned char is_cluster_head; unsigned char is_primary_cluster_head; diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index fd4796ba32..0b47305433 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -2455,8 +2455,8 @@ void rrc_eNB_generate_RRCConnectionSetup( eNB_rrc_inst[enb_mod_idP].Srb0.Tx_buffer.payload_size = do_RRCConnectionSetup(enb_mod_idP, (uint8_t *) eNB_rrc_inst[enb_mod_idP].Srb0.Tx_buffer.Payload, - mac_xface->get_transmission_mode(enb_mod_idP, - find_UE_RNTI + mac_xface->get_transmission_mode(enb_mod_idP,0, //CC_id 0!!!! + UE_RNTI (enb_mod_idP, ue_mod_idP)), ue_mod_idP, -- 2.26.2