Commit 83c3acd0 authored by Raymond Knopp's avatar Raymond Knopp

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@5699 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 1ae40bac
...@@ -63,6 +63,7 @@ void ue_mac_reset(module_id_t module_idP,uint8_t eNB_index) { ...@@ -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[0] = 0;
UE_mac_inst[module_idP].scheduling_info.Bj[1] = 0; UE_mac_inst[module_idP].scheduling_info.Bj[1] = 0;
UE_mac_inst[module_idP].scheduling_info.Bj[2] = 0; UE_mac_inst[module_idP].scheduling_info.Bj[2] = 0;
//Stopping all timers //Stopping all timers
//timeAlignmentTimer expires //timeAlignmentTimer expires
...@@ -74,45 +75,50 @@ void ue_mac_reset(module_id_t module_idP,uint8_t eNB_index) { ...@@ -74,45 +75,50 @@ void ue_mac_reset(module_id_t module_idP,uint8_t eNB_index) {
// cancel all pending SRs // cancel all pending SRs
UE_mac_inst[module_idP].scheduling_info.SR_pending=0; UE_mac_inst[module_idP].scheduling_info.SR_pending=0;
UE_mac_inst[module_idP].scheduling_info.SR_COUNTER=0; UE_mac_inst[module_idP].scheduling_info.SR_COUNTER=0;
// stop ongoing RACH procedure // stop ongoing RACH procedure
// discard explicitly signaled ra_PreambleIndex and ra_RACH_MaskIndex, if any // 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_PreambleIndex = 0; // check!
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0; 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 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, 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, RadioResourceConfigCommonSIB_t *radioResourceConfigCommon,
struct PhysicalConfigDedicated *physicalConfigDedicated, 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
#ifdef Rel10 #ifdef Rel10
,uint8_t MBMS_Flag, SCellToAddMod_r10_t *sCellToAddMod_r10,
MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10,
PMCH_InfoList_r9_t *pmch_InfoList #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 #endif
#ifdef CBA #ifdef CBA
,uint8_t num_active_cba_groups, ,uint8_t num_active_cba_groups,
uint16_t cba_rnti uint16_t cba_rnti
#endif #endif
) { ) {
int i; int i,CC_id;
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN); 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 ...@@ -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){ if (physicalConfigDedicated == NULL){
LOG_I(MAC,"[CONFIG][eNB %d] Configuring MAC/PHY\n",Mod_id); LOG_I(MAC,"[CONFIG][eNB %d] Configuring MAC/PHY\n",Mod_id);
} else{ } 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 ((tdd_Config!=NULL)||(SIwindowsize!=NULL)||(SIperiod!=NULL)){
if (eNB_flagP==1) 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 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) { 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 ...@@ -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.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.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); 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 { else {
UE_mac_inst[Mod_id].radioResourceConfigCommon = radioResourceConfigCommon; 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 // 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 ...@@ -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 (physicalConfigDedicated != NULL) {
if (eNB_flagP==1){ 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{ }else{
mac_xface->phy_config_dedicated_ue(Mod_id,eNB_index,physicalConfigDedicated); mac_xface->phy_config_dedicated_ue(Mod_id,0,eNB_index,physicalConfigDedicated);
UE_mac_inst[Mod_id].physicalConfigDedicated=physicalConfigDedicated; // for SR proc 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 (eNB_flagP == 0) {
if (measObj!= NULL) { 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 ...@@ -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; 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]); 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) { 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 ...@@ -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 (mbsfn_SubframeConfigList != NULL) {
if (eNB_flagP == 1) { if (eNB_flagP == 1) {
LOG_I(MAC,"[eNB %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n", Mod_id, mbsfn_SubframeConfigList->list.count); 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++) { 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, 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 #ifdef Rel10
eNB_mac_inst[Mod_id].MBMS_flag = MBMS_Flag; eNB_mac_inst[Mod_id].common_channels[0].MBMS_flag = MBMS_Flag;
#endif #endif
} }
else { // UE 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 ...@@ -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) { if (eNB_flagP == 1) {
// One eNB could be part of multiple mbsfn syc area, this could change over time so reset each time // 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); 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++) { 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, 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); 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,i,eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mbsfn_AreaId_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 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 ...@@ -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]; 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, 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); 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 ...@@ -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); 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++) { 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, 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, 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, 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 // 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); LOG_I(MAC, "PMCH[%d] Number of session (MTCH) is: %d\n",i, eNB_mac_inst[Mod_id].mbms_SessionList[i]->list.count);
} }
} }
......
...@@ -64,6 +64,7 @@ ...@@ -64,6 +64,7 @@
#include "MBSFN-AreaInfoList-r9.h" #include "MBSFN-AreaInfoList-r9.h"
#include "MBSFN-SubframeConfigList.h" #include "MBSFN-SubframeConfigList.h"
#include "PMCH-InfoList-r9.h" #include "PMCH-InfoList-r9.h"
#include "SCellToAddMod-r10.h"
#endif #endif
//#ifdef PHY_EMUL //#ifdef PHY_EMUL
...@@ -620,14 +621,28 @@ typedef struct{ ...@@ -620,14 +621,28 @@ typedef struct{
}SBMAP_CONF; }SBMAP_CONF;
//end ALU's algo //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{ 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 /// Outgoing DCI for PHY generated by eNB scheduler
DCI_PDU DCI_pdu; DCI_PDU DCI_pdu;
/// Outgoing BCCH pdu for PHY /// Outgoing BCCH pdu for PHY
...@@ -636,11 +651,6 @@ typedef struct{ ...@@ -636,11 +651,6 @@ typedef struct{
uint32_t BCCH_alloc_pdu; uint32_t BCCH_alloc_pdu;
/// Outgoing CCCH pdu for PHY /// Outgoing CCCH pdu for PHY
CCCH_PDU CCCH_pdu; 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]; RA_TEMPLATE RA_template[NB_RA_PROC_MAX];
/// BCCH active flag /// BCCH active flag
uint8_t bcch_active; uint8_t bcch_active;
...@@ -674,16 +684,25 @@ typedef struct{ ...@@ -674,16 +684,25 @@ typedef struct{
uint8_t num_active_cba_groups; uint8_t num_active_cba_groups;
uint16_t cba_rnti[NUM_MAX_CBA_GROUP]; uint16_t cba_rnti[NUM_MAX_CBA_GROUP];
#endif #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 ///subband bitmap configuration
SBMAP_CONF sbmap_conf; SBMAP_CONF sbmap_conf;
/// active flag for Other lcid /// 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_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 // MAC function execution peformance profiler
time_stats_t eNB_scheduler; time_stats_t eNB_scheduler;
time_stats_t schedule_si; time_stats_t schedule_si;
...@@ -766,6 +785,10 @@ typedef struct{ ...@@ -766,6 +785,10 @@ typedef struct{
struct RACH_ConfigDedicated *rach_ConfigDedicated; struct RACH_ConfigDedicated *rach_ConfigDedicated;
/// pointer to RRC PHY configuration /// pointer to RRC PHY configuration
struct PhysicalConfigDedicated *physicalConfigDedicated; struct PhysicalConfigDedicated *physicalConfigDedicated;
#ifdef Rel10
/// pointer to RRC PHY configuration SCEll
struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10;
#endif
/// pointer to TDD Configuration (NULL for FDD) /// pointer to TDD Configuration (NULL for FDD)
TDD_Config_t *tdd_Config; TDD_Config_t *tdd_Config;
/// Number of adjacent cells to measure /// Number of adjacent cells to measure
...@@ -912,6 +935,10 @@ int rrc_mac_config_req(module_id_t module_idP, ...@@ -912,6 +935,10 @@ int rrc_mac_config_req(module_id_t module_idP,
uint8_t eNB_index, uint8_t eNB_index,
RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, RadioResourceConfigCommonSIB_t *radioResourceConfigCommon,
struct PhysicalConfigDedicated *physicalConfigDedicated, struct PhysicalConfigDedicated *physicalConfigDedicated,
#ifdef Rel10
SCellToAddMod_r10_t *sCellToAddMod_r10,
//struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10,
#endif
MeasObjectToAddMod_t **measObj, MeasObjectToAddMod_t **measObj,
MAC_MainConfig_t *mac_MainConfig, MAC_MainConfig_t *mac_MainConfig,
long logicalChannelIdentity, long logicalChannelIdentity,
......
...@@ -83,10 +83,10 @@ ...@@ -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) { 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); start_meas(&eNB_mac_inst[module_idP].eNB_scheduler);
unsigned char nprb=0; unsigned int nprb[MAX_NUM_CCs];
unsigned int nCCE=0; unsigned int nCCE[MAX_NUM_CCs];
int mbsfn_status=0; int mbsfn_status[MAX_NUM_CCs];
uint32_t RBalloc=0; uint32_t RBalloc[MAX_NUM_CCs];
#ifdef EXMIMO #ifdef EXMIMO
int ret; int ret;
#endif #endif
...@@ -96,12 +96,22 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, ...@@ -96,12 +96,22 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
instance_t instance; instance_t instance;
int result; int result;
#endif #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); 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); 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) #if defined(ENABLE_ITTI)
do { do {
// Checks if a message has been sent to MAC sub-task // 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, ...@@ -154,16 +164,18 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
#endif #endif
// clear DCI and BCCH contents before scheduling // clear DCI and BCCH contents before scheduling
DCI_pdu->Num_common_dci = 0; for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
DCI_pdu->Num_ue_spec_dci = 0; DCI_pdu[CC_id]->Num_common_dci = 0;
eNB_mac_inst[module_idP].bcch_active = 0; DCI_pdu[CC_id]->Num_ue_spec_dci = 0;
eNB_mac_inst[module_idP].common_channels[CC_id].bcch_active = 0;
#ifdef Rel10 #ifdef Rel10
eNB_mac_inst[module_idP].mcch_active =0; eNB_mac_inst[module_idP].common_channels.mcch_active =0;
#endif #endif
eNB_mac_inst[module_idP].frame = frameP; eNB_mac_inst[module_idP].frame = frameP;
eNB_mac_inst[module_idP].subframe = subframeP; eNB_mac_inst[module_idP].subframe = subframeP;
}
//if (subframeP%5 == 0) //if (subframeP%5 == 0)
#ifdef EXMIMO #ifdef EXMIMO
...@@ -180,10 +192,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, ...@@ -180,10 +192,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
#endif #endif
#ifdef Rel10 #ifdef Rel10
if (eNB_mac_inst[module_idP].MBMS_flag >0) { for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
start_meas(&eNB_mac_inst[module_idP].schedule_mch); if (eNB_mac_inst[module_idP].common_channels.MBMS_flag >0) {
mbsfn_status = schedule_MBMS(module_idP,frameP,subframeP); start_meas(&eNB_mac_inst[module_idP].common_channels.schedule_mch);
stop_meas(&eNB_mac_inst[module_idP].schedule_mch); mbsfn_status = schedule_MBMS(module_idP,CC_id,frameP,subframeP);
stop_meas(&eNB_mac_inst[module_idP][CC-id].schedule_mch);
}
} }
#endif #endif
...@@ -193,18 +207,18 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, ...@@ -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 ULSCH for FDD or subframeP 4 (TDD config 0,3,6)
// Schedule Normal DLSCH // 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 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 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 == 3) ||
(mac_xface->lte_frame_parms->tdd_config == 6)) (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); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status);
break; break;
...@@ -216,11 +230,11 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, ...@@ -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) { switch (mac_xface->lte_frame_parms->tdd_config) {
case 0: case 0:
case 1: 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); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break; break;
case 6: 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); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break; break;
default: default:
...@@ -228,8 +242,8 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, ...@@ -228,8 +242,8 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
} }
} }
else { //FDD else { //FDD
schedule_ulsch(module_idP,frameP,cooperation_flag,1,5,&nCCE); schedule_ulsch(module_idP,frameP,cooperation_flag,1,5,nCCE);
// 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,subframeP,RBalloc,0,mbsfn_status); // fill_DLSCH_dci(module_idP,subframeP,RBalloc,0,mbsfn_status);
} }
break; break;
...@@ -238,8 +252,8 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, ...@@ -238,8 +252,8 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
// TDD, nothing // TDD, nothing
// FDD, normal UL/DLSCH // FDD, normal UL/DLSCH
if (mac_xface->lte_frame_parms->frame_type == FDD) { //FDD if (mac_xface->lte_frame_parms->frame_type == FDD) { //FDD
schedule_ulsch(module_idP,frameP,cooperation_flag,2,6,&nCCE); schedule_ulsch(module_idP,frameP,cooperation_flag,2,6,nCCE);
// 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,subframeP,RBalloc,0,mbsfn_status); // fill_DLSCH_dci(module_idP,subframeP,RBalloc,0,mbsfn_status);
} }
break; break;
...@@ -251,9 +265,9 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, ...@@ -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) { if (mac_xface->lte_frame_parms->frame_type == TDD) {
switch (mac_xface->lte_frame_parms->tdd_config) { switch (mac_xface->lte_frame_parms->tdd_config) {
case 2: case 2:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7,&nCCE); schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7,nCCE);
case 5: 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); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break; break;
default: default:
...@@ -261,7 +275,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, ...@@ -261,7 +275,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
} }
} }
else { //FDD 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); // schedule_ue_spec(module_idP,subframeP,0,0,mbsfn_status);
// fill_DLSCH_dci(module_idP,subframeP,RBalloc,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, ...@@ -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 if (mac_xface->lte_frame_parms->frame_type == 1) { // TDD
switch (mac_xface->lte_frame_parms->tdd_config) { switch (mac_xface->lte_frame_parms->tdd_config) {
case 1: case 1:
// schedule_RA(module_idP,frameP,subframeP,&nprb,&nCCE); // schedule_RA(module_idP,frameP,subframeP,nprb,nCCE);
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8,&nCCE); schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8,nCCE);
case 2: case 2:
case 4: case 4:
case 5: 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); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status);
break; break;
default: default:
...@@ -288,10 +302,10 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, ...@@ -288,10 +302,10 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
} }
else { else {
if (mac_xface->lte_frame_parms->frame_type == FDD) { //FDD if (mac_xface->lte_frame_parms->frame_type == FDD) { //FDD
schedule_RA(module_idP, frameP, subframeP, 0, &nprb, &nCCE); schedule_RA(module_idP,frameP, subframeP, 0, nprb, nCCE);
// schedule_ulsch(module_idP, frameP, cooperation_flag, 4, 8, &nCCE); // schedule_ulsch(module_idP, frameP, cooperation_flag, 4, 8, nCCE);
//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); 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, ...@@ -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 Config 0,6 ULSCH for subframes 9,3 resp.
// TDD normal DLSCH // TDD normal DLSCH
// FDD normal UL/DLSCH // FDD normal UL/DLSCH
schedule_SI(module_idP,frameP,&nprb,&nCCE); schedule_SI(module_idP,frameP,nprb,nCCE);
//schedule_RA(module_idP,frameP,subframeP,5,&nprb,&nCCE); //schedule_RA(module_idP,frameP,subframeP,5,nprb,nCCE);
if ((mac_xface->lte_frame_parms->frame_type == FDD) ) { if ((mac_xface->lte_frame_parms->frame_type == FDD) ) {
// schedule_RA(module_idP,frameP,subframeP,1,&nprb,&nCCE); // schedule_RA(module_idP,frameP,subframeP,1,nprb,nCCE);
// schedule_ulsch(module_idP,frameP,cooperation_flag,5,9,&nCCE); // schedule_ulsch(module_idP,frameP,cooperation_flag,5,9,nCCE);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
} }
else if ((mac_xface->lte_frame_parms->tdd_config == 0) || // TDD Config 0 else if ((mac_xface->lte_frame_parms->tdd_config == 0) || // TDD Config 0
(mac_xface->lte_frame_parms->tdd_config == 6)) { // TDD Config 6 (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); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
} }
else { 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); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
} }
break; break;
...@@ -330,23 +344,23 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, ...@@ -330,23 +344,23 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
case 0: case 0:
break; break;
case 1: case 1:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2,&nCCE); schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2,nCCE);
// 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); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break; break;
case 6: case 6:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,&nCCE); schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,nCCE);
// 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); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break; break;
case 5: case 5:
schedule_RA(module_idP,frameP,subframeP,2,&nprb,&nCCE); schedule_RA(module_idP,frameP,subframeP,2,nprb,nCCE);
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); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status);
break; break;
case 3: case 3:
case 4: 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); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break; break;
...@@ -355,8 +369,8 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, ...@@ -355,8 +369,8 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
} }
} }
else { //FDD else { //FDD
// schedule_ulsch(module_idP,frameP,cooperation_flag,6,0,&nCCE); // schedule_ulsch(module_idP,frameP,cooperation_flag,6,0,nCCE);
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); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
} }
break; break;
...@@ -368,12 +382,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, ...@@ -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) { switch (mac_xface->lte_frame_parms->tdd_config) {
case 3: case 3:
case 4: case 4:
// schedule_RA(module_idP,frameP,subframeP,3,&nprb,&nCCE); // 3 = Msg3 subframeP, not // 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_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); //1,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); //1,mbsfn_status);
break; break;
case 5: 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); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break; break;
default: default:
...@@ -381,8 +395,8 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, ...@@ -381,8 +395,8 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
} }
} }
else { //FDD else { //FDD
// schedule_ulsch(module_idP,frameP,cooperation_flag,7,1,&nCCE); // schedule_ulsch(module_idP,frameP,cooperation_flag,7,1,nCCE);
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); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
} }
break; break;
...@@ -398,9 +412,9 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, ...@@ -398,9 +412,9 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
case 4: case 4:
case 5: case 5:
// schedule_RA(module_idP,subframeP,&nprb,&nCCE); // schedule_RA(module_idP,subframeP,nprb,nCCE);
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2,&nCCE); schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,0,&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); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break; break;
default: default:
...@@ -408,8 +422,8 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, ...@@ -408,8 +422,8 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
} }
} }
else { //FDD else { //FDD
// schedule_ulsch(module_idP,frameP,cooperation_flag,8,2,&nCCE); // schedule_ulsch(module_idP,frameP,cooperation_flag,8,2,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,0,&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); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
} }
break; break;
...@@ -419,27 +433,27 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, ...@@ -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) { if (mac_xface->lte_frame_parms->frame_type == TDD) {
switch (mac_xface->lte_frame_parms->tdd_config) { switch (mac_xface->lte_frame_parms->tdd_config) {
case 1: case 1:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,&nCCE); schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,nCCE);
schedule_RA(module_idP,frameP,subframeP,7,&nprb,&nCCE); // 7 = Msg3 subframeP, not 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_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status);
break; break;
case 3: case 3:
case 4: case 4:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,&nCCE); schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,0,&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); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break; break;
case 6: case 6:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4,&nCCE); schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4,nCCE);
//schedule_RA(module_idP,frameP,subframeP,&nprb,&nCCE); //schedule_RA(module_idP,frameP,subframeP,nprb,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,0,&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); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break; break;
case 2: case 2:
case 5: case 5:
//schedule_RA(module_idP,frameP,subframeP,&nprb,&nCCE); //schedule_RA(module_idP,frameP,subframeP,nprb,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,0,&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); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break; break;
default: default:
...@@ -447,16 +461,17 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, ...@@ -447,16 +461,17 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
} }
} }
else { //FDD else { //FDD
// schedule_ulsch(module_idP,frameP,cooperation_flag,9,3,&nCCE); // schedule_ulsch(module_idP,frameP,cooperation_flag,9,3,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,0,&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); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
} }
break; break;
} }
DCI_pdu->nCCE = nCCE; for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++)
LOG_D(MAC,"frameP %d, subframeP %d nCCE %d\n",frameP,subframeP,nCCE); 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); 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); stop_meas(&eNB_mac_inst[module_idP].eNB_scheduler);
......
/*******************************************************************************
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
}
...@@ -70,25 +70,33 @@ ...@@ -70,25 +70,33 @@
#define DEBUG_eNB_SCHEDULER 1 #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; unsigned char bcch_sdu_length;
int mcs = -1; int mcs = -1;
void *BCCH_alloc_pdu=(void*)&eNB_mac_inst[module_idP].BCCH_alloc_pdu; void *BCCH_alloc_pdu;
int CC_id;
bcch_sdu_length = mac_rrc_data_req(module_idP, eNB_MAC_INST *eNB = &eNB_mac_inst[module_idP];
frameP,
BCCH,1, start_meas(&eNB->schedule_si);
&eNB_mac_inst[module_idP].BCCH_pdu.payload[0],
1, for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
module_idP,
0); // not used in this case BCCH_alloc_pdu=(void*)&eNB->common_channels[CC_id].BCCH_alloc_pdu;
if (bcch_sdu_length > 0) {
LOG_D(MAC,"[eNB %d] Frame %d : BCCH->DLSCH, Received %d bytes \n",module_idP,frameP,bcch_sdu_length); 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))) if (bcch_sdu_length <= (mac_xface->get_TBS_DL(0,3)))
mcs=0; mcs=0;
else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(1,3))) 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 ...@@ -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))) else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(8,3)))
mcs=8; mcs=8;
if (mac_xface->lte_frame_parms->frame_type == TDD) { if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) {
switch (mac_xface->lte_frame_parms->N_RB_DL) { switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) {
case 6: case 6:
((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs; ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs;
break; break;
case 25: case 25:
((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs; ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs;
break; break;
case 50: case 50:
((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs; ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs;
break; break;
case 100: case 100:
((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs; ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs;
break; break;
} }
} }
else { else {
switch (mac_xface->lte_frame_parms->N_RB_DL) { switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) {
case 6: case 6:
((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs; ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs;
break; break;
case 25: case 25:
((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs; ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs;
break; break;
case 50: case 50:
((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs; ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs;
break; break;
case 100: case 100:
((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs; ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs;
break; break;
} }
} }
#if defined(USER_MODE) && defined(OAI_EMU) #if defined(USER_MODE) && defined(OAI_EMU)
if (oai_emulation.info.opt_enabled) { if (oai_emulation.info.opt_enabled) {
trace_pdu(1, trace_pdu(1,
&eNB_mac_inst[module_idP].BCCH_pdu.payload[0], &eNB->common_channels[CC_id].BCCH_pdu.payload[0],
bcch_sdu_length, bcch_sdu_length,
0xffff, 0xffff,
4, 4,
0xffff, 0xffff,
eNB_mac_inst[module_idP].subframe, eNB->subframe,
0, 0,
0); 0);
} }
LOG_D(OPT,"[eNB %d][BCH] Frame %d trace pdu for rnti %x with size %d\n", 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 #endif
if (mac_xface->lte_frame_parms->frame_type == TDD) { 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", LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH->DLSCH (TDD) for SI %d bytes (mcs %d, rb 3, TBS %d)\n",
frameP, frameP,
bcch_sdu_length, bcch_sdu_length,
mcs, mcs,
mac_xface->get_TBS_DL(mcs,3)); mac_xface->get_TBS_DL(mcs,3));
} }
else { 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, frameP,
bcch_sdu_length, bcch_sdu_length,
mcs, mcs,
mac_xface->get_TBS_DL(mcs,3)); mac_xface->get_TBS_DL(mcs,3));
} }
eNB_mac_inst[module_idP].bcch_active=1; eNB->common_channels[CC_id].bcch_active=1;
*nprb=3; nprbP[CC_id]=3;
*nCCE=4; nCCEP[CC_id]=4;
} }
else { else {
eNB_mac_inst[module_idP].bcch_active=0; eNB->common_channels[CC_id].bcch_active=0;
*nprb=0; nprbP[CC_id]=0;
*nCCE=0; nCCEP[CC_id]=0;
//LOG_D(MAC,"[eNB %d] Frame %d : BCCH not active \n",Mod_id,frame); //LOG_D(MAC,"[eNB %d] Frame %d : BCCH not active \n",Mod_id,frame);
}
} }
// this might be misleading when bcch is inactive // this might be misleading when bcch is inactive
stop_meas(&eNB_mac_inst[module_idP].schedule_si); stop_meas(&eNB->schedule_si);
return; return;
} }
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -90,46 +90,57 @@ void init_ue_sched_info(void){ ...@@ -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; int UE_id;
UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list;
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) { for (UE_id=UE_list->head;UE_id>=0;UE_id=UE_list->next[UE_id]){
if (eNB_mac_inst[module_idP].UE_template[ue_mod_id].rnti==rnti) { if (UE_list->UE_template[UE_PCCID(mod_idP,UE_id)][UE_id].rnti==rntiP) {
return(ue_mod_id); 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 ) boolean_t is_UE_active(module_id_t mod_idP, int ue_idP){
return TRUE; return(eNB_mac_inst[mod_idP].UE_list.active[ue_idP]);
else
return FALSE ;
} }
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; module_id_t ue_mod_id = 0;
rnti_t rnti = 0; rnti_t rnti = 0;
...@@ -137,110 +148,189 @@ uint8_t find_active_UEs(module_id_t module_idP){ ...@@ -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++) { 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 if (mac_xface->get_eNB_UE_stats(module_idP,rnti) != NULL){ // check at the phy enb_ue state for this rnti
nb_active_ue++; nb_active_ue++;
} }
else { // this ue is removed at the phy => remove it at the mac as well 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); return(nb_active_ue);
} }
*/
// get aggregatiob form phy for a give 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; unsigned char aggregation=2;
// check the MCS and SNR and set the aggregation accordingly // check the MCS and SNR and set the aggregation accordingly
return aggregation; return aggregation;
} }
#ifdef CBA #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; module_id_t UE_id;
rnti_t rnti; rnti_t rnti;
unsigned char nb_ue_in_pusch=0; unsigned char nb_ue_in_pusch=0;
LTE_eNB_UE_stats* eNB_UE_stats; 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) && if (((rnti=eNB_mac_inst[module_idP][CC_id].UE_template[UE_id].rnti) !=0) &&
(eNB_mac_inst[module_idP].UE_template[UE_id].ul_active==TRUE) && (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)){ (mac_get_rrc_status(module_idP,1,UE_id) > RRC_CONNECTED)){
// && (UE_is_to_be_scheduled(module_idP,UE_id))) // && (UE_is_to_be_scheduled(module_idP,UE_id)))
// check at the phy enb_ue state for this rnti // 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= 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)){ if ((eNB_UE_stats->mode == PUSCH) && (UE_is_to_be_scheduled(module_idP,UE_id) == 0)){
nb_ue_in_pusch++; nb_ue_in_pusch++;
} }
} }
} }
} }
return(nb_ue_in_pusch); return(nb_ue_in_pusch);
} }
#endif #endif
int8_t add_new_ue(module_id_t enb_mod_idP, rnti_t rntiP) { int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP) {
module_id_t ue_mod_id; int UE_id;
int j; int j;
for (ue_mod_id=0;ue_mod_id<NUMBER_OF_UE_MAX;ue_mod_id++) { UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list;
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; 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);
for (j=0;j<8;j++) {
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].oldNDI[j] = 0; if (UE_list->avail>=0) {
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].oldNDI_UL[j] = 0; UE_id = UE_list->avail;
} UE_list->avail = UE_list->next[UE_list->avail];
eNB_ulsch_info[enb_mod_idP][ue_mod_id].status = S_UL_WAITING; UE_list->next[UE_id] = UE_list->head;
eNB_dlsch_info[enb_mod_idP][ue_mod_id].status = S_UL_WAITING; UE_list->head = UE_id;
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->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); 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 // clear all remaining pending transmissions
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].bsr_info[LCGID0] = 0; UE_list->UE_template[pCC_id][ue_idP].bsr_info[LCGID0] = 0;
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].bsr_info[LCGID1] = 0; UE_list->UE_template[pCC_id][ue_idP].bsr_info[LCGID1] = 0;
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].bsr_info[LCGID2] = 0; UE_list->UE_template[pCC_id][ue_idP].bsr_info[LCGID2] = 0;
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].bsr_info[LCGID3] = 0; UE_list->UE_template[pCC_id][ue_idP].bsr_info[LCGID3] = 0;
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].ul_SR = 0; UE_list->UE_template[pCC_id][ue_idP].ul_SR = 0;
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].rnti = 0; UE_list->UE_template[pCC_id][ue_idP].rnti = 0;
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].ul_active = FALSE; UE_list->UE_template[pCC_id][ue_idP].ul_active = FALSE;
eNB_ulsch_info[enb_mod_idP][ue_mod_idP].rnti = 0; eNB_ulsch_info[mod_idP][ue_idP].rnti = 0;
eNB_ulsch_info[enb_mod_idP][ue_mod_idP].status = S_UL_NONE; eNB_ulsch_info[mod_idP][ue_idP].status = S_UL_NONE;
eNB_dlsch_info[enb_mod_idP][ue_mod_idP].rnti = 0; eNB_dlsch_info[mod_idP][ue_idP].rnti = 0;
eNB_dlsch_info[enb_mod_idP][ue_mod_idP].status = S_DL_NONE; eNB_dlsch_info[mod_idP][ue_idP].status = S_DL_NONE;
rrc_eNB_free_UE_index(enb_mod_idP,ue_mod_idP); rrc_eNB_free_UE_index(mod_idP,ue_idP);
return(1); 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); int prev_i,prev_j,next_i;
if (ue_mod_id != UE_INDEX_INVALID ) { prev_i = prev(listP,nodeiP);
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); prev_j = prev(listP,nodejP);
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; 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 { } else {
// AssertFatal(0, "find_UE_id(%u,rnti %d) not found", enb_mod_idP, rntiP); // 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); // 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 ...@@ -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 // 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, // LOG_D(MAC,"[eNB %d][PUSCH] Frame %d subframeP %d Scheduling UE %d\n",module_idP,rnti,frameP,subframeP,
// UE_id); // UE_id);
if ((eNB_mac_inst[module_idP].UE_template[UE_id].bsr_info[LCGID0]>0) || if ((UE_template->bsr_info[LCGID0]>0) ||
(eNB_mac_inst[module_idP].UE_template[UE_id].bsr_info[LCGID1]>0) || (UE_template->bsr_info[LCGID1]>0) ||
(eNB_mac_inst[module_idP].UE_template[UE_id].bsr_info[LCGID2]>0) || (UE_template->bsr_info[LCGID2]>0) ||
(eNB_mac_inst[module_idP].UE_template[UE_id].bsr_info[LCGID3]>0) || (UE_template->bsr_info[LCGID3]>0) ||
(eNB_mac_inst[module_idP].UE_template[UE_id].ul_SR>0)) // uplink scheduling request (UE_template->ul_SR>0)) // uplink scheduling request
return(1); return(1);
else else
return(0); return(0);
...@@ -416,7 +507,7 @@ uint8_t UE_is_to_be_scheduled(module_id_t module_idP,uint8_t UE_id) { ...@@ -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; int i;
uint32_t rballoc_dci=0; uint32_t rballoc_dci=0;
...@@ -487,9 +578,9 @@ uint32_t allocate_prbs_sub(int nb_rb, uint8_t *rballoc) { ...@@ -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; int i;
DCI0_5MHz_TDD_1_6_t *ULSCH_dci = NULL;; DCI0_5MHz_TDD_1_6_t *ULSCH_dci = NULL;;
......
...@@ -73,6 +73,197 @@ ...@@ -73,6 +73,197 @@
// This table holds the allowable PRB sizes for ULSCH transmissions // 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}; 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 bytes_to_bsr_index(int32_t nbytes) {
uint32_t i=0; uint32_t i=0;
...@@ -81,52 +272,54 @@ uint32_t bytes_to_bsr_index(int32_t nbytes) { ...@@ -81,52 +272,54 @@ uint32_t bytes_to_bsr_index(int32_t nbytes) {
return(0); return(0);
while ((i<BSR_TABLE_SIZE)&& while ((i<BSR_TABLE_SIZE)&&
(BSR_TABLE[i]<=nbytes)){ (BSR_TABLE[i]<=nbytes)){
i++; i++;
} }
return(i-1); 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_id].rnti = UE_RNTI(module_idP,UE_id);
eNB_ulsch_info[module_idP][ue_mod_idP].subframe = subframeP; eNB_ulsch_info[module_idP][UE_id].subframe = subframeP;
eNB_ulsch_info[module_idP][ue_mod_idP].status = status; 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 // first phase: scheduling for ACK
switch (subframeP) { 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: case 8:
if ((eNB_dlsch_info[module_idP][ue_mod_idP].status == S_DL_SCHEDULED) && if ((eNB_dlsch_info[module_idP][UE_id].status == S_DL_SCHEDULED) &&
(eNB_dlsch_info[module_idP][ue_mod_idP].subframe == 5 || eNB_dlsch_info[module_idP][ue_mod_idP].subframe == 6)){ (eNB_dlsch_info[module_idP][UE_id].subframe == 5 || eNB_dlsch_info[module_idP][UE_id].subframe == 6)){
// set the downlink status // set the downlink status
eNB_dlsch_info[module_idP][ue_mod_idP].status = S_DL_BUFFERED; eNB_dlsch_info[module_idP][UE_id].status = S_DL_BUFFERED;
return ue_mod_idP; return UE_id;
} }
break; break;
// scheduling for subframeP 3: for scheduled user during subframeP 7 and 8 // scheduling for subframeP 3: for scheduled user during subframeP 7 and 8
case 9: case 9:
if ((eNB_dlsch_info[module_idP][ue_mod_idP].status == S_DL_SCHEDULED) && if ((eNB_dlsch_info[module_idP][UE_id].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_id].subframe == 7 || eNB_dlsch_info[module_idP][UE_id].subframe == 8)){
eNB_dlsch_info[module_idP][ue_mod_idP].status = S_DL_BUFFERED; eNB_dlsch_info[module_idP][UE_id].status = S_DL_BUFFERED;
return ue_mod_idP; return UE_id;
} }
break; break;
// scheduling UL subframeP 4: for scheduled user during subframeP 9 and 0 // scheduling UL subframeP 4: for scheduled user during subframeP 9 and 0
case 0 : case 0 :
if ((eNB_dlsch_info[module_idP][ue_mod_idP].status == S_DL_SCHEDULED) && if ((eNB_dlsch_info[module_idP][UE_id].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_id].subframe == 9 || eNB_dlsch_info[module_idP][UE_id].subframe == 0)){
eNB_dlsch_info[module_idP][ue_mod_idP].status = S_DL_BUFFERED; eNB_dlsch_info[module_idP][UE_id].status = S_DL_BUFFERED;
return ue_mod_idP; return UE_id;
} }
break; break;
default: default:
...@@ -136,33 +329,33 @@ module_id_t schedule_next_ulue(module_id_t module_idP, module_id_t ue_mod_idP, s ...@@ -136,33 +329,33 @@ module_id_t schedule_next_ulue(module_id_t module_idP, module_id_t ue_mod_idP, s
// second phase // second phase
for (next_ue=0; next_ue <NUMBER_OF_UE_MAX; next_ue++ ){ for (next_ue=0; next_ue <NUMBER_OF_UE_MAX; next_ue++ ){
if (eNB_ulsch_info[module_idP][next_ue].status == S_UL_WAITING ) if (eNB_ulsch_info[module_idP][next_ue].status == S_UL_WAITING )
return next_ue; return next_ue;
else if (eNB_ulsch_info[module_idP][next_ue].status == S_UL_SCHEDULED){ else if (eNB_ulsch_info[module_idP][next_ue].status == S_UL_SCHEDULED){
eNB_ulsch_info[module_idP][next_ue].status = S_UL_BUFFERED; eNB_ulsch_info[module_idP][next_ue].status = S_UL_BUFFERED;
} }
} }
for (next_ue=0; next_ue <NUMBER_OF_UE_MAX; next_ue++ ){ 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 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; eNB_ulsch_info[module_idP][next_ue].status = S_UL_WAITING;
} }
next_ue = 0; next_ue = 0;
return next_ue; return next_ue;
} }
*/
unsigned char *parse_ulsch_header(unsigned char *mac_header, unsigned char *parse_ulsch_header(unsigned char *mac_header,
unsigned char *num_ce, unsigned char *num_ce,
unsigned char *num_sdu, unsigned char *num_sdu,
unsigned char *rx_ces, unsigned char *rx_ces,
unsigned char *rx_lcids, unsigned char *rx_lcids,
unsigned short *rx_lengths, unsigned short *rx_lengths,
unsigned short tb_length) { unsigned short tb_length) {
unsigned char not_done=1,num_ces=0,num_sdus=0,lcid,num_sdu_cnt; unsigned char not_done=1,num_ces=0,num_sdus=0,lcid,num_sdu_cnt;
unsigned char *mac_header_ptr = mac_header; unsigned char *mac_header_ptr = mac_header;
...@@ -170,53 +363,53 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header, ...@@ -170,53 +363,53 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header,
while (not_done==1) { while (not_done==1) {
if (((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E == 0) if (((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E == 0)
not_done = 0; not_done = 0;
lcid = ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID; lcid = ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID;
if (lcid < EXTENDED_POWER_HEADROOM) { if (lcid < EXTENDED_POWER_HEADROOM) {
if (not_done==0) { // last MAC SDU, length is implicit if (not_done==0) { // last MAC SDU, length is implicit
mac_header_ptr++; mac_header_ptr++;
length = tb_length-(mac_header_ptr-mac_header)-ce_len; length = tb_length-(mac_header_ptr-mac_header)-ce_len;
for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++) for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++)
length -= rx_lengths[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++;
} }
else { // This is a control element subheader POWER_HEADROOM, BSR and CRNTI else {
if (lcid == SHORT_PADDING) { if (((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F == 0) {
mac_header_ptr++; length = ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L;
} mac_header_ptr += 2;//sizeof(SCH_SUBHEADER_SHORT);
else { }
rx_ces[num_ces] = lcid; else { // F = 1
num_ces++; length = ((((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB & 0x7f ) << 8 ) | (((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB & 0xff);
mac_header_ptr++; mac_header_ptr += 3;//sizeof(SCH_SUBHEADER_LONG);
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);
}
}
} }
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_ce = num_ces;
*num_sdu = num_sdus; *num_sdu = num_sdus;
...@@ -227,44 +420,52 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header, ...@@ -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) { 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 #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 #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, ...@@ -274,450 +475,438 @@ void schedule_ulsch_rnti(module_id_t module_idP,
frame_t frameP, frame_t frameP,
sub_frame_t subframeP, sub_frame_t subframeP,
unsigned char sched_subframe, unsigned char sched_subframe,
uint8_t granted_UEs,
unsigned int *nCCE, unsigned int *nCCE,
unsigned int *nCCE_available, unsigned int *nCCE_available,
uint16_t *first_rb){ uint16_t *first_rb){
module_id_t ue_mod_id = -1;
module_id_t next_ue = -1; int UE_id;
unsigned char aggregation = 2; unsigned char aggregation = 2;
rnti_t rnti = -1; rnti_t rnti = -1;
uint8_t round = 0; uint8_t round = 0;
uint8_t harq_pid = 0; uint8_t harq_pid = 0;
void *ULSCH_dci = NULL; void *ULSCH_dci = NULL;
LTE_eNB_UE_stats *eNB_UE_stats = 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 status = 0;
uint8_t rb_table_index = -1; uint8_t rb_table_index = -1;
uint16_t TBS,i; uint16_t TBS,i;
uint32_t buffer_occupancy; uint32_t buffer_occupancy;
uint32_t tmp_bsr; uint32_t tmp_bsr;
uint32_t cqi_req,cshift,ndi,mcs,rballoc; 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}; 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); // loop over all active UEs
next_ue = ue_mod_id; // find next ue to schedule for (UE_id=UE_list->head;(UE_id>=0) && (*nCCE_available > (1<<aggregation));UE_id=UE_list->next[UE_id]) {
// msg("[MAC][eNB] subframeP %d: next ue %d\n",subframeP,next_ue); rnti = UE_RNTI(module_idP,UE_id); // radio network temp id is obtained
rnti = find_UE_RNTI(module_idP,next_ue); // radio network temp id is obtained if (rnti==0) // if so, go to next UE
// msg("[MAC][eNB] subframeP %d: rnti %x\n",subframeP,rnti); 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 DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu;
continue; 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) 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");
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", 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 if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel
int8_t ret; int8_t ret;
// Get candidate harq_pid from PHY // Get candidate harq_pid from PHY
ret = mac_xface->get_ue_active_harq_pid(module_idP,rnti,subframeP,&harq_pid,&round,1); 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, next_ue %d\n",harq_pid,round,next_ue); 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 #ifndef EXMIMO_IOT
if ((((UE_is_to_be_scheduled(module_idP,ue_mod_id)>0)) || (round>0) || ((frameP%10)==0)) && (ret == 0)) 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 // 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 #else
if (round==0) if (round==0)
#endif #endif
{ {
LOG_D(MAC,"[eNB %d][PUSCH %x] Frame %d subframeP %d Scheduling UE %d (SR %d)\n", 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, module_idP,rnti,frameP,subframeP,UE_id,
eNB_mac_inst[module_idP].UE_template[ue_mod_id].ul_SR); UE_template->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
}
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 aggregation = process_ue_cqi(module_idP,UE_id); // =2 by default!!
return(find_active_UEs(module_idP)); // 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 #ifdef CBA
...@@ -725,7 +914,7 @@ void schedule_ulsch_cba_rnti(module_id_t module_idP, unsigned char cooperation_f ...@@ -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_TDD_1_6_t *ULSCH_dci_tdd16;
DCI0_5MHz_FDD_t *ULSCH_dci_fdd; 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; uint8_t rb_table_index=0, aggregation=2;
uint32_t rballoc; uint32_t rballoc;
...@@ -735,129 +924,140 @@ void schedule_ulsch_cba_rnti(module_id_t module_idP, unsigned char cooperation_f ...@@ -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 remaining_rbs= available_rbs;
uint8_t allocated_rbs; uint8_t allocated_rbs;
// We compute the weight of each group and initialize some variables // 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; for (cba_group=0;cba_group<eNB_mac_inst[module_idP][CC_id].num_active_cba_groups;cba_group++) {
num_cba_resources[cba_group]=0; // 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 ); //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
// phase 2 for (cba_group=0;cba_group<eNB_mac_inst[module_idP][CC_id].num_active_cba_groups;cba_group++) {
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++){
for (cba_resources=0; cba_resources < num_cba_resources[cba_group]; cba_resources++){ rb_table_index =0;
rb_table_index =0; // check if there was an allocation for this group in the 1st phase
// check if there was an allocation for this group in the 1st phase if (required_rbs[cba_group] == 0 )
if (required_rbs[cba_group] == 0 ) continue;
continue;
while (rb_table[rb_table_index] < (uint8_t) ceil(required_rbs[cba_group] / num_cba_resources[cba_group]) )
while (rb_table[rb_table_index] < (uint8_t) ceil(required_rbs[cba_group] / num_cba_resources[cba_group]) ) rb_table_index++;
rb_table_index++;
while (rb_table[rb_table_index] > remaining_rbs )
while (rb_table[rb_table_index] > remaining_rbs ) rb_table_index--;
rb_table_index--;
remaining_rbs-=rb_table[rb_table_index];
remaining_rbs-=rb_table[rb_table_index]; allocated_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,
rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_UL, *first_rb,
*first_rb, rb_table[rb_table_index]);
rb_table[rb_table_index]);
*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",
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],
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,
available_rbs, required_rbs[cba_group], allocated_rbs, remaining_rbs,rballoc, nCCE_available[CC_id],nCCE[CC_id]);
*nCCE_available,*nCCE);
if (mac_xface->lte_frame_parms->frame_type == TDD) {
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 = (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->type = 0; ULSCH_dci_tdd16->hopping = 0;
ULSCH_dci_tdd16->hopping = 0; ULSCH_dci_tdd16->rballoc = rballoc;
ULSCH_dci_tdd16->rballoc = rballoc; ULSCH_dci_tdd16->mcs = 2;
ULSCH_dci_tdd16->mcs = 2; ULSCH_dci_tdd16->ndi = 1;
ULSCH_dci_tdd16->ndi = 1; ULSCH_dci_tdd16->TPC = 1;
ULSCH_dci_tdd16->TPC = 1; ULSCH_dci_tdd16->cshift = cba_group;
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->dai = eNB_mac_inst[module_idP].UE_template[cba_group].DAI_ul[sched_subframe]; ULSCH_dci_tdd16->cqi_req = 1;
ULSCH_dci_tdd16->cqi_req = 1;
//add_ue_spec_dci
//add_ue_spec_dci add_common_dci(DCI_pdu,
add_common_dci(DCI_pdu, ULSCH_dci_tdd16,
ULSCH_dci_tdd16, eNB_mac_inst[module_idP][CC_id].cba_rnti[cba_group],
eNB_mac_inst[module_idP].cba_rnti[cba_group], sizeof(DCI0_5MHz_TDD_1_6_t),
sizeof(DCI0_5MHz_TDD_1_6_t), aggregation,
aggregation, sizeof_DCI0_5MHz_TDD_1_6_t,
sizeof_DCI0_5MHz_TDD_1_6_t, format0,
format0, 0);
0); }
} else {
else { ULSCH_dci_fdd = (DCI0_5MHz_FDD_t *)UE_list->UE_template[CC_id][cba_group].ULSCH_DCI[0];
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->type = 0; ULSCH_dci_fdd->hopping = 0;
ULSCH_dci_fdd->hopping = 0; ULSCH_dci_fdd->rballoc = rballoc;
ULSCH_dci_fdd->rballoc = rballoc; ULSCH_dci_fdd->mcs = 2;
ULSCH_dci_fdd->mcs = 2; ULSCH_dci_fdd->ndi = 1;
ULSCH_dci_fdd->ndi = 1; ULSCH_dci_fdd->TPC = 1;
ULSCH_dci_fdd->TPC = 1; ULSCH_dci_fdd->cshift = 0;
ULSCH_dci_fdd->cshift = 0; ULSCH_dci_fdd->cqi_req = 1;
ULSCH_dci_fdd->cqi_req = 1;
//add_ue_spec_dci
//add_ue_spec_dci add_common_dci(DCI_pdu,
add_common_dci(DCI_pdu, ULSCH_dci_fdd,
ULSCH_dci_fdd, eNB_mac_inst[module_idP][CC_id].cba_rnti[cba_group],
eNB_mac_inst[module_idP].cba_rnti[cba_group], sizeof(DCI0_5MHz_FDD_t),
sizeof(DCI0_5MHz_FDD_t), aggregation,
aggregation, sizeof_DCI0_5MHz_FDD_t,
sizeof_DCI0_5MHz_FDD_t, format0,
format0, 0);
0); }
} nCCE[CC_id] = nCCE[CC_id] + (1<<aggregation) * num_cba_resources[cba_group];
*nCCE = (*nCCE) + (1<<aggregation) * num_cba_resources[cba_group]; nCCE_available[CC_id] = mac_xface->get_nCCE_max(module_idP,CC_id) - nCCE[CC_id];
*nCCE_available = mac_xface->get_nCCE_max(module_idP) - *nCCE; // break;// for the moment only schedule one
// break;// for the moment only schedule one }
} }
}
} }
} }
#endif #endif
...@@ -41,21 +41,33 @@ ...@@ -41,21 +41,33 @@
#include "UTIL/LOG/log.h" #include "UTIL/LOG/log.h"
#include "proto.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; 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) if (UE_mac_inst[module_idP].radioResourceConfigCommon)
rach_ConfigCommon = &UE_mac_inst[module_idP].radioResourceConfigCommon->rach_ConfigCommon; rach_ConfigCommon = &UE_mac_inst[module_idP].radioResourceConfigCommon->rach_ConfigCommon;
else { 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"); mac_xface->macphy_exit("FATAL radioResourceConfigCommon is NULL");
} }
return(-120 + (rach_ConfigCommon->powerRampingParameters.preambleInitialReceivedTargetPower<<1) + 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); 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)); return((int8_t)(UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER<<1));
......
...@@ -115,6 +115,9 @@ int mac_top_init(int eMBMS_active, uint8_t cba_group_active, uint8_t HO_active){ ...@@ -115,6 +115,9 @@ int mac_top_init(int eMBMS_active, uint8_t cba_group_active, uint8_t HO_active){
RA_TEMPLATE *RA_template; RA_TEMPLATE *RA_template;
UE_TEMPLATE *UE_template; UE_TEMPLATE *UE_template;
int size_bytes1,size_bytes2,size_bits1,size_bits2; 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); LOG_I(MAC,"[MAIN] Init function start:Nb_UE_INST=%d\n",NB_UE_INST);
if (NB_UE_INST>0) { 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){ ...@@ -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) { if (NB_eNB_INST>0) {
eNB_mac_inst = (eNB_MAC_INST*)malloc16(NB_eNB_INST*sizeof(eNB_MAC_INST)); eNB_mac_inst = (eNB_MAC_INST*)malloc16(NB_eNB_INST*sizeof(eNB_MAC_INST));
if (eNB_mac_inst == NULL){ 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"); 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); else{
bzero(eNB_mac_inst,NB_eNB_INST*sizeof(eNB_MAC_INST)); 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 else
eNB_mac_inst = NULL; eNB_mac_inst = NULL;
// Initialize Linked-List for Active UEs
for(Mod_id=0;Mod_id<NB_eNB_INST;Mod_id++){ 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 #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 #endif
/*#ifdef Rel10 /*#ifdef Rel10
int n; int n;
...@@ -181,11 +196,12 @@ int mac_top_init(int eMBMS_active, uint8_t cba_group_active, uint8_t HO_active){ ...@@ -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 // 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,"[MAIN][eNB %d] initializing RA_template\n",i);
LOG_D(MAC, "[MSC_NEW][FRAME 00000][MAC_eNB][MOD %02d][]\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++) { for (j=0;j<NB_RA_PROC_MAX;j++) {
if (mac_xface->lte_frame_parms->frame_type == TDD) { if (mac_xface->lte_frame_parms->frame_type == TDD) {
switch (mac_xface->lte_frame_parms->N_RB_DL) { 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){ ...@@ -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)); 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++) { for (j=0;j<NUMBER_OF_UE_MAX;j++) {
UE_template[j].rnti=0; UE_template[j].rnti=0;
// initiallize the eNB to UE statistics // 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 //ICIC init param
...@@ -284,15 +300,16 @@ int mac_top_init(int eMBMS_active, uint8_t cba_group_active, uint8_t HO_active){ ...@@ -284,15 +300,16 @@ int mac_top_init(int eMBMS_active, uint8_t cba_group_active, uint8_t HO_active){
srand (time(NULL)); srand (time(NULL));
for(j=0;j<NB_eNB_INST;j++){ for(j=0;j<NB_eNB_INST;j++)
eNB_mac_inst[j].sbmap_conf.first_subframe=0; for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++){
eNB_mac_inst[j].sbmap_conf.periodicity=10; eNB_mac_inst[j][CC_id].sbmap_conf.first_subframe=0;
eNB_mac_inst[j].sbmap_conf.sb_size=SB_size; eNB_mac_inst[j][CC_id].sbmap_conf.periodicity=10;
eNB_mac_inst[j].sbmap_conf.nb_active_sb=1; 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++) 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 #endif
......
...@@ -50,10 +50,6 @@ ...@@ -50,10 +50,6 @@
#include "UTIL/OPT/opt.h" #include "UTIL/OPT/opt.h"
#include "OCG.h" #include "OCG.h"
#include "OCG_extern.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/LITE/extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
...@@ -69,7 +65,7 @@ ...@@ -69,7 +65,7 @@
#ifndef USER_MODE #ifndef USER_MODE
#define msg debug_msg #define msg debug_msg
#endif #endif
*/ */
extern inline unsigned int taus(void); extern inline unsigned int taus(void);
...@@ -80,382 +76,436 @@ void store_dlsch_buffer (module_id_t Mod_id, ...@@ -80,382 +76,436 @@ void store_dlsch_buffer (module_id_t Mod_id,
frame_t frameP, frame_t frameP,
sub_frame_t subframeP){ sub_frame_t subframeP){
module_id_t next_ue; int UE_id,i;
rnti_t rnti; rnti_t rnti;
uint16_t i=0;
mac_rlc_status_resp_t rlc_status; mac_rlc_status_resp_t rlc_status;
unsigned char UE_id,granted_UEs; UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
UE_TEMPLATE *UE_template;
granted_UEs = find_dlgranted_UEs(Mod_id);
for (UE_id=UE_list->head;UE_id>=0;UE_id=UE_list->next[UE_id]){
for (UE_id=0;UE_id<granted_UEs;UE_id++){
eNB_mac_inst[Mod_id].UE_template[UE_id].dl_buffer_total = 0; UE_template = &UE_list->UE_template[UE_PCCID(Mod_id,UE_id)][UE_id];
eNB_mac_inst[Mod_id].UE_template[UE_id].dl_pdus_total = 0;
for(i=0;i< MAX_NUM_LCID; i++) { // clear logical channel interface variables
eNB_mac_inst[Mod_id].UE_template[UE_id].dl_buffer_info[i]=0; UE_template->dl_buffer_total = 0;
eNB_mac_inst[Mod_id].UE_template[UE_id].dl_pdus_in_buffer[i]=0; UE_template->dl_pdus_total = 0;
eNB_mac_inst[Mod_id].UE_template[UE_id].dl_buffer_head_sdu_creation_time[i]=0; for(i=0;i< MAX_NUM_LCID; i++) {
eNB_mac_inst[Mod_id].UE_template[UE_id].dl_buffer_head_sdu_remaining_size_to_send[i]=0; 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;
for (UE_id=0;UE_id<granted_UEs;UE_id++) { }
next_ue = UE_id; rnti = UE_RNTI(Mod_id,UE_id);
rnti = find_UE_RNTI(Mod_id,next_ue);
if (rnti == 0) for(i=0;i< MAX_NUM_LCID; i++){ // loop over all the logical channels
continue;
rlc_status = mac_rlc_status_ind(Mod_id,UE_id, frameP,ENB_FLAG_YES,MBMS_FLAG_NO,i,0 );
for(i=0;i< MAX_NUM_LCID; i++){ // loop over all the logical channels 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;
rlc_status = mac_rlc_status_ind(Mod_id,next_ue, frameP,ENB_FLAG_YES,MBMS_FLAG_NO,i,0 ); UE_template->dl_buffer_head_sdu_creation_time[i] = rlc_status.head_sdu_creation_time ;
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 UE_template->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_pdus_in_buffer[i] = rlc_status.pdus_in_buffer; UE_template->dl_buffer_head_sdu_is_segmented[i] = rlc_status.head_sdu_is_segmented;
eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_creation_time[i] = rlc_status.head_sdu_creation_time ; UE_template->dl_buffer_total = UE_template->dl_buffer_total + UE_template->dl_buffer_info[i];//storing the total dlsch buffer
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; UE_template->dl_pdus_total += UE_template->dl_pdus_in_buffer[i];
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];
#ifdef DEBUG_eNB_SCHEDULER #ifdef DEBUG_eNB_SCHEDULER
/* note for dl_buffer_head_sdu_remaining_size_to_send[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 * 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) 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 %d size, head sdu queuing time %d, remaining size %d, is segmeneted %d \n", 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, next_ue, Mod_id, frameP, subframeP, UE_id,
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], i, UE_template->dl_pdus_in_buffer[i],UE_template->dl_buffer_info[i],
eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_creation_time[i], UE_template->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], UE_template->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] UE_template->dl_buffer_head_sdu_is_segmented[i]
); );
#endif #endif
} }
#ifdef DEBUG_eNB_SCHEDULER #ifdef DEBUG_eNB_SCHEDULER
if ( eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_total>0) 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", 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, Mod_id, frameP, subframeP, UE_id,
eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_total, UE_template->dl_buffer_total,
eNB_mac_inst[Mod_id].UE_template[next_ue].dl_pdus_total UE_template->dl_pdus_total
); );
#endif #endif
} }
} }
// This function returns the estimated number of RBs required by each UE for downlink scheduling // This function returns the estimated number of RBs required by each UE for downlink scheduling
void assign_rbs_required (module_id_t Mod_id, void assign_rbs_required (module_id_t Mod_id,
frame_t frameP, frame_t frameP,
sub_frame_t subframe, sub_frame_t subframe,
uint16_t *nb_rbs_required){ 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;
rnti_t rnti; uint16_t TBS = 0;
uint16_t TBS = 0; LTE_eNB_UE_stats *eNB_UE_stats[MAX_NUM_CCs];
LTE_eNB_UE_stats *eNB_UE_stats = NULL; int UE_id,n,i,j,CC_id,pCCid,tmp;
module_id_t ue_inst; UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
unsigned char granted_UEs;
granted_UEs = find_dlgranted_UEs(Mod_id);
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; //update CQI information across component carriers
rnti = find_UE_RNTI(Mod_id,next_ue); for (n=0;n<UE_list->numactiveCCs[UE_id];n++) {
if (rnti == 0)
continue;
eNB_UE_stats = mac_xface->get_eNB_UE_stats(Mod_id,rnti); CC_id = UE_list->ordered_CCids[n][UE_id];
//if(eNB_UE_stats == NULL)
//continue;
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: case 0:
eNB_UE_stats->dlsch_mcs1 = 0; eNB_UE_stats[CC_id]->dlsch_mcs1 = 0;
break; break;
case 1: case 1:
eNB_UE_stats->dlsch_mcs1 = 0; eNB_UE_stats[CC_id]->dlsch_mcs1 = 0;
break; break;
case 2: case 2:
eNB_UE_stats->dlsch_mcs1 = 0; eNB_UE_stats[CC_id]->dlsch_mcs1 = 0;
break; break;
case 3: case 3:
eNB_UE_stats->dlsch_mcs1 = 2; eNB_UE_stats[CC_id]->dlsch_mcs1 = 2;
break; break;
case 4: case 4:
eNB_UE_stats->dlsch_mcs1 = 4; eNB_UE_stats[CC_id]->dlsch_mcs1 = 4;
break; break;
case 5: case 5:
eNB_UE_stats->dlsch_mcs1 = 6; eNB_UE_stats[CC_id]->dlsch_mcs1 = 6;
break; break;
case 6: case 6:
eNB_UE_stats->dlsch_mcs1 = 8; eNB_UE_stats[CC_id]->dlsch_mcs1 = 8;
break; break;
case 7: case 7:
eNB_UE_stats->dlsch_mcs1 = 11; eNB_UE_stats[CC_id]->dlsch_mcs1 = 11;
break; break;
case 8: case 8:
eNB_UE_stats->dlsch_mcs1 = 13; eNB_UE_stats[CC_id]->dlsch_mcs1 = 13;
break; break;
case 9: case 9:
eNB_UE_stats->dlsch_mcs1 = 16; eNB_UE_stats[CC_id]->dlsch_mcs1 = 16;
break; break;
case 10: case 10:
eNB_UE_stats->dlsch_mcs1 = 18; eNB_UE_stats[CC_id]->dlsch_mcs1 = 18;
break; break;
case 11: case 11:
eNB_UE_stats->dlsch_mcs1 = 20; eNB_UE_stats[CC_id]->dlsch_mcs1 = 20;
break; break;
case 12: case 12:
eNB_UE_stats->dlsch_mcs1 = 22; eNB_UE_stats[CC_id]->dlsch_mcs1 = 22;
break; break;
case 13: case 13:
eNB_UE_stats->dlsch_mcs1 = 22;//25 eNB_UE_stats[CC_id]->dlsch_mcs1 = 25;
break; break;
case 14: case 14:
eNB_UE_stats->dlsch_mcs1 = 22;//27 eNB_UE_stats[CC_id]->dlsch_mcs1 = 27;
break; break;
case 15: case 15:
eNB_UE_stats->dlsch_mcs1 = 22;//28 eNB_UE_stats[CC_id]->dlsch_mcs1 = 28;
break; break;
default: default:
printf("Invalid CQI"); LOG_E(MAC,"preprocessor.c assign_rbs_required(): Invalid CQI %d, should not happen",eNB_UE_stats[CC_id]->DL_cqi[0]);
exit(-1); exit(-1);
} }
}
// provide the list of CCs sorted according to MCS
if ((mac_get_rrc_status(Mod_id,1,next_ue) < RRC_RECONFIGURED)){ for (i=0;i<UE_list->numactiveCCs[UE_id];i++) {
nb_rbs_required[next_ue] = mac_xface->lte_frame_parms->N_RB_DL; for (j=i+1;j<UE_list->numactiveCCs[UE_id];j++) {
continue; 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) { int maxround(module_id_t Mod_id,uint16_t rnti,sub_frame_t subframe) {
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]);
}
} 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++) { for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++){
UE_id_sorted[i] = ue_inst; eNB_UE_stats = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti);
i++; 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); UE_id1 = i;
if(rnti2 == 0) pCC_id1 = UE_PCCID(Mod_id,UE_id1);
continue; 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_id2 = ii;
UE_id_sorted[i] = next_ue2; rnti2 = UE_RNTI(Mod_id,UE_id2);
UE_id_sorted[ii] = next_ue1; if(rnti2 == 0)
} continue;
else if (round2 == round1){
for(j=0;j<MAX_NUM_LCID;j++){
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]){ cqi2 = maxcqi(Mod_id,rnti2);
UE_id_sorted[i] = next_ue2; round2 = maxround(Mod_id,rnti2,subframe); //mac_xface->get_ue_active_harq_pid(Mod_id,rnti2,subframe,&harq_pid2,&round2,0);
UE_id_sorted[ii] = next_ue1; pCC_id2 = UE_PCCID(Mod_id,UE_id2);
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]){*/
if(eNB_UE_stats1->DL_cqi[0] < eNB_UE_stats2->DL_cqi[0]){ if(round2 > round1){ // Check first if one of the UEs has an active HARQ process which needs service and swap order
UE_id_sorted[i] = next_ue2; swap_UEs(UE_list,UE_id1,UE_id2);
UE_id_sorted[ii] = next_ue1;
}
//}
}
}
}
} }
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 // 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, void dlsch_scheduler_pre_processor (module_id_t Mod_id,
frame_t frameP, frame_t frameP,
sub_frame_t subframeP, sub_frame_t subframeP,
uint8_t *dl_pow_off, uint8_t dl_pow_off[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
uint16_t *pre_nb_available_rbs, uint16_t pre_nb_available_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
int N_RBGS, int N_RBGS[MAX_NUM_CCs],
unsigned char rballoc_sub_UE[NUMBER_OF_UE_MAX][N_RBGS_MAX]){ unsigned char rballoc_sub_UE[MAX_NUM_CCs][NUMBER_OF_UE_MAX][N_RBGS_MAX],
int *mbsfn_flag){
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]; 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];
module_id_t UE_id, i; unsigned char MIMO_mode_indicator[MAX_NUM_CCs][13];
module_id_t UE_id_sorted[NUMBER_OF_UE_MAX]; int UE_id, UE_id2, i;
module_id_t granted_UEs;
uint16_t ii,j; uint16_t ii,j;
uint16_t nb_rbs_required[NUMBER_OF_UE_MAX]; uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
uint16_t nb_rbs_required_remaining[NUMBER_OF_UE_MAX]; uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
uint16_t nb_rbs_required_remaining_1[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 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; rnti_t rnti,rnti1,rnti2;
LTE_eNB_UE_stats *eNB_UE_stats1 = NULL; LTE_eNB_UE_stats *eNB_UE_stats1 = NULL;
LTE_eNB_UE_stats *eNB_UE_stats2 = NULL; LTE_eNB_UE_stats *eNB_UE_stats2 = NULL;
uint16_t min_rb_unit; int min_rb_unit[MAX_NUM_CCs];
int CC_id;
switch (mac_xface->lte_frame_parms->N_RB_DL) { UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
case 6:
min_rb_unit=1;
break; for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
case 25:
min_rb_unit=2; if (mbsfn_flag[CC_id]>0) // If this CC is allocated for MBSFN skip it here
break; continue;
case 50:
min_rb_unit=3; switch (PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL) {
break; case 6:
case 100: min_rb_unit[CC_id]=1;
min_rb_unit=4; break;
break; case 25:
default: min_rb_unit[CC_id]=2;
min_rb_unit=2; break;
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 the DLSCH buffer for each logical channel
store_dlsch_buffer (Mod_id,frameP,subframeP); store_dlsch_buffer (Mod_id,frameP,subframeP);
// Calculate the number of RBs required by each UE on the basis of logical channel's buffer // 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 // Sorts the user on the basis of dlsch logical channel buffer and CQI
sort_UEs (Mod_id,subframeP,UE_id_sorted); sort_UEs (Mod_id,subframeP);
//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++){ // loop over all active UEs
rnti = find_UE_RNTI(Mod_id,i); for (i=UE_list->head;i>=0;i=UE_list->next[i]) {
if(rnti == 0)
continue; UE_id = i;
mac_xface->get_ue_active_harq_pid(Mod_id,rnti,subframeP,&harq_pid,&round,0);
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) if(round>0)
nb_rbs_required[i] = eNB_mac_inst[Mod_id].UE_template[i].nb_rb[harq_pid]; nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
//nb_rbs_required_remaining[i] = nb_rbs_required[i]; //nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id];
if(nb_rbs_required[i] > 0) if (nb_rbs_required[CC_id][UE_id] > 0) {
total_ue_count = total_ue_count + 1; total_ue_count[CC_id] = total_ue_count[CC_id] + 1;
} }
// hypotetical assignement // hypotetical assignement
/* /*
* If schedule is enabled and if the priority of the UEs is modified * 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 * The average rbs per logical channel per user will depend on the level of
* priority. Concerning the hypothetical assignement, we should assign more * priority. Concerning the hypothetical assignement, we should assign more
* rbs to prioritized users. Maybe, we can do a mapping between the * 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 * 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. * 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 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 = min_rb_unit; 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
for(i=0;i<granted_UEs;i++){ 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 // control channel
if (mac_get_rrc_status(Mod_id,1,i) < RRC_RECONFIGURED) 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 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, ...@@ -464,325 +514,347 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id,
// 2nd round: remaining RBs are allocated to high priority UEs // 2nd round: remaining RBs are allocated to high priority UEs
for(r1=0;r1<2;r1++){ for(r1=0;r1<2;r1++){
for(i=0; i<granted_UEs;i++) 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++) {
if(r1 == 0) CC_id = UE_list->ordered_CCids[ii][UE_id];
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 if(r1 == 0)
nb_rbs_required_remaining[i] = nb_rbs_required[i]-nb_rbs_required_remaining_1[i]+nb_rbs_required_remaining[i]; 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
// retransmission in control channels 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];
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;
}
}
}
}
} }
}
// retransmission in control channels
for(i=UE_list->head; i>=0;i=UE_list->next[i]) {
// retransmission in data channels UE_id = i;
for (i = 0 ;i<granted_UEs; i++){ for (ii=0;ii<UE_num_active_CC(UE_list,UE_id);ii++) {
CC_id = UE_list->ordered_CCids[ii][UE_id];
next_ue = UE_id_sorted[i];
rnti = find_UE_RNTI(Mod_id,next_ue);
if(rnti == 0) rnti = UE_RNTI(Mod_id,UE_id);
continue; if(rnti == 0)
mac_xface->get_ue_active_harq_pid(Mod_id,rnti,subframeP,&harq_pid,&round,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,next_ue) >= RRC_RECONFIGURED) && (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++){
for(j=0;j<N_RBGS;j++){ if((rballoc_sub[CC_id][j] == 0) && (rballoc_sub_UE[CC_id][UE_id][j] == 0) && (nb_rbs_required_remaining[UE_id]>0)){
if((rballoc_sub[j] == 0) && (rballoc_sub_UE[next_ue][j] == 0) && (nb_rbs_required_remaining[next_ue]>0)){ rballoc_sub[CC_id][j] = 1;
rballoc_sub_UE[CC_id][UE_id][j] = 1;
rballoc_sub[j] = 1;
rballoc_sub_UE[next_ue][j] = 1; MIMO_mode_indicator[CC_id][j] = 1;
MIMO_mode_indicator[j] = 1; if(mac_xface->get_transmission_mode(Mod_id,CC_id,rnti)==5)
dl_pow_off[CC_id][UE_id] = 1;
if(mac_xface->get_transmission_mode(Mod_id,rnti)==5) // if the total rb is odd
dl_pow_off[next_ue] = 1; if ((j == N_RBGS[CC_id]-1) &&
((PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL == 25)||
if((j == N_RBGS-1) && (PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL == 50))) {
((mac_xface->lte_frame_parms->N_RB_DL == 25)|| nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id]+1;
(mac_xface->lte_frame_parms->N_RB_DL == 50))){ 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[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[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id];
else { pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + min_rb_unit[CC_id];
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; }
} }
} }
}
}
} }
}
// control channel in the 1st transmission
for (i = 0 ;i<granted_UEs; i++){ // retransmission in data channels
next_ue = UE_id_sorted[i]; for(i=UE_list->head; i>=0;i=UE_list->next[i]) {
rnti = find_UE_RNTI(Mod_id,next_ue); UE_id = i;
if(rnti == 0) for (ii=0;ii<UE_num_active_CC(UE_list,UE_id);ii++) {
continue; CC_id = UE_list->ordered_CCids[ii][UE_id];
mac_xface->get_ue_active_harq_pid(Mod_id,rnti,subframeP,&harq_pid,&round,0);
rnti = UE_RNTI(Mod_id,UE_id);
if ((mac_get_rrc_status(Mod_id,1,next_ue) < RRC_RECONFIGURED) && (round == 0)) { 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;j++){
for(j=0;j<N_RBGS[CC_id];j++){
if((rballoc_sub[j] == 0) && (rballoc_sub_UE[next_ue][j] == 0) && (nb_rbs_required_remaining[next_ue]>0)){
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[j] = 1;
rballoc_sub_UE[next_ue][j] = 1; rballoc_sub[CC_id][j] = 1;
rballoc_sub_UE[CC_id][UE_id][j] = 1;
MIMO_mode_indicator[j] = 1;
MIMO_mode_indicator[CC_id][j] = 1;
if(mac_xface->get_transmission_mode(Mod_id,rnti)==5)
dl_pow_off[next_ue] = 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-1) &&
((mac_xface->lte_frame_parms->N_RB_DL == 25)|| if((j == N_RBGS[CC_id]-1) &&
(mac_xface->lte_frame_parms->N_RB_DL == 50))){ ((PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL == 25)||
nb_rbs_required_remaining[next_ue] = nb_rbs_required_remaining[next_ue] - min_rb_unit + 1; (PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL == 50))){
pre_nb_available_rbs[next_ue] = pre_nb_available_rbs[next_ue] + min_rb_unit - 1; 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[next_ue] = nb_rbs_required_remaining[next_ue] - min_rb_unit; else {
pre_nb_available_rbs[next_ue] = pre_nb_available_rbs[next_ue] + min_rb_unit; 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
// data chanel TM5
for (i = 0 ;i<granted_UEs; i++){ 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++) {
next_ue1 = UE_id_sorted[i]; CC_id = UE_list->ordered_CCids[ii][UE_id];
rnti1 = find_UE_RNTI(Mod_id,next_ue1);
if(rnti1 == 0)
continue; rnti = UE_RNTI(Mod_id,UE_id);
if(rnti == 0)
eNB_UE_stats1 = mac_xface->get_eNB_UE_stats(Mod_id,rnti1); continue;
mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,subframeP,&harq_pid,&round,0);
mac_xface->get_ue_active_harq_pid(Mod_id,rnti1,subframeP,&harq_pid1,&round1,0);
if ((mac_get_rrc_status(Mod_id,1,UE_id) < RRC_RECONFIGURED) && (round == 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){
for(j=0;j<N_RBGS[CC_id];j++){
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)){
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)){
for (ii = i+1;ii < granted_UEs;ii++) {
rballoc_sub[CC_id][j] = 1;
next_ue2 = UE_id_sorted[ii]; rballoc_sub_UE[CC_id][UE_id][j] = 1;
rnti2 = find_UE_RNTI(Mod_id,next_ue2);
if(rnti2 == 0) MIMO_mode_indicator[CC_id][j] = 1;
continue;
if(mac_xface->get_transmission_mode(Mod_id,CC_id,rnti)==5)
eNB_UE_stats2 = mac_xface->get_eNB_UE_stats(Mod_id,rnti2); dl_pow_off[CC_id][UE_id] = 1;
mac_xface->get_ue_active_harq_pid(Mod_id,rnti2,subframeP,&harq_pid2,&round2,0);
if((j == N_RBGS[CC_id]-1) &&
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)) { ((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))){
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)){ 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;
if((((eNB_UE_stats2->DL_pmi_single^eNB_UE_stats1->DL_pmi_single)<<(14-j))&0xc000)== 0x4000){ //MU-MIMO only for 25 RBs configuration }
else {
rballoc_sub[j] = 1; nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id];
rballoc_sub_UE[next_ue1][j] = 1; pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + min_rb_unit[CC_id];
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;
}
}
}
}
}
}
}
} }
// data channel for all TM }
for (i = 0;i<granted_UEs; i++){
next_ue = UE_id_sorted[i]; // data chanel TM5
rnti = find_UE_RNTI(Mod_id,next_ue); for(i=UE_list->head; i>=0;i=UE_list->next[i]) {
if (rnti == 0) UE_id = i;
continue; for (ii=0;ii<UE_num_active_CC(UE_list,UE_id);ii++) {
CC_id = UE_list->ordered_CCids[ii][UE_id];
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)) { rnti1 = UE_RNTI(Mod_id,UE_id);
if(rnti1 == 0)
continue;
for(j=0;j<N_RBGS;j++){
eNB_UE_stats1 = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti1);
if((rballoc_sub[j] == 0) && (rballoc_sub_UE[next_ue][j] == 0) && (nb_rbs_required_remaining[next_ue]>0)){
mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti1,subframeP,&harq_pid1,&round1,0);
switch (mac_xface->get_transmission_mode(Mod_id,rnti)) { 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)) {
case 1:
case 2:
case 4: for(j=0;j<N_RBGS[CC_id];j+=2){
case 6:
rballoc_sub[j] = 1; 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)){
rballoc_sub_UE[next_ue][j] = 1;
for (ii = UE_list->next[i+1];ii >=0;ii=UE_list->next[ii]) {
MIMO_mode_indicator[j] = 1;
UE_id2 = ii;
if((j == N_RBGS-1) && rnti2 = UE_RNTI(Mod_id,UE_id2);
((mac_xface->lte_frame_parms->N_RB_DL == 25)|| if(rnti2 == 0)
(mac_xface->lte_frame_parms->N_RB_DL == 50))){ continue;
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; 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);
else {
nb_rbs_required_remaining[next_ue] = nb_rbs_required_remaining[next_ue] - min_rb_unit; 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)) {
pre_nb_available_rbs[next_ue] = pre_nb_available_rbs[next_ue] + min_rb_unit;
} 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)){
break; if((((eNB_UE_stats2->DL_pmi_single^eNB_UE_stats1->DL_pmi_single)<<(14-j))&0xc000)== 0x4000){ //MU-MIMO only for 25 RBs configuration
case 5:
if (dl_pow_off[next_ue] != 0){ rballoc_sub[CC_id][j] = 1;
rballoc_sub_UE[CC_id][UE_id][j] = 1;
dl_pow_off[next_ue] = 1; rballoc_sub_UE[CC_id][UE_id2][j] = 1;
MIMO_mode_indicator[CC_id][j] = 0;
rballoc_sub[j] = 1;
rballoc_sub_UE[next_ue][j] = 1; if (j< N_RBGS[CC_id]-1) {
rballoc_sub[CC_id][j+1] = 1;
MIMO_mode_indicator[j] = 1; rballoc_sub_UE[CC_id][UE_id][j+1] = 1;
rballoc_sub_UE[CC_id][UE_id2][j+1] = 1;
if((j == N_RBGS-1) && MIMO_mode_indicator[CC_id][j+1] = 0;
((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; dl_pow_off[CC_id][UE_id] = 0;
pre_nb_available_rbs[next_ue] = pre_nb_available_rbs[next_ue] + min_rb_unit-1; dl_pow_off[CC_id][UE_id2] = 0;
}
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;
} if ((j == N_RBGS[CC_id]-1) &&
} ((PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL == 25) ||
break; (PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL == 50))){
default: nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id]+1;
break; 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; // This has to be revisited!!!!
i2=0; for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
i3=0; i1=0;
for (j=0;j<N_RBGS;j++){ i2=0;
if(MIMO_mode_indicator[j] == 2) i3=0;
i1 = i1+1; for (j=0;j<N_RBGS[CC_id];j++){
else if(MIMO_mode_indicator[j] == 1) if(MIMO_mode_indicator[CC_id][j] == 2)
i2 = i2+1; i1 = i1+1;
else if(MIMO_mode_indicator[j] == 0) else if(MIMO_mode_indicator[CC_id][j] == 1)
i3 = i3+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;
} }
for(i=UE_list->head; i>=0;i=UE_list->next[i]) {
if((i1 < N_RBGS) && (i2>0) && (i3==0)) for (ii=0;ii<UE_num_active_CC(UE_list,UE_id);ii++) {
PHY_vars_eNB_g[Mod_id]->check_for_SUMIMO_transmissions = PHY_vars_eNB_g[Mod_id]->check_for_SUMIMO_transmissions + 1; CC_id = UE_list->ordered_CCids[ii][UE_id];
UE_id = i;
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++){
//PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id]; //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,"******************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); LOG_D(MAC,"***********RB Alloc for every subband for UE%d ***********\n",UE_id);
for(j=0;j<N_RBGS;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[UE_id][i]; //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[UE_id][j]); 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]; //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[UE_id]); LOG_D(MAC,"Total RBs allocated for UE%d = %d\n",UE_id,pre_nb_available_rbs[CC_id][UE_id]);
}
} }
} }
...@@ -51,7 +51,7 @@ for the message. ...@@ -51,7 +51,7 @@ for the message.
@param nprb Pointer to current PRB count @param nprb Pointer to current PRB count
@param nCCE Pointer to current nCCE 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). /** \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 @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 ...@@ -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 nprb Pointer to current PRB count
@param nCCE Pointer to current nCCE 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; /** \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 @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 ...@@ -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 sched_subframe Subframe number where PUSCH is transmitted (for DAI lookup)
@param nCCE Pointer to current nCCE count @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). /** \brief ULSCH Scheduling for CBA RNTI TDD config (config 1-6).
@param Mod_id Instance ID of eNB @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 ...@@ -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 RA_scheduled RA was scheduled in this subframe
@param mbsfn_flag Indicates that this subframe is for MCH/MCCH @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 /** \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 @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 ...@@ -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 nCCE_used Number of CCE used by SI/RA
@param mbsfn_flag Indicates that MCH/MCCH is in this subframe @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. /** \brief Function for UE/PHY to compute PUSCH transmit power in power-control procedure.
@param Mod_id Module id of UE @param Mod_id Module id of UE
@returns Po_NOMINAL_PUSCH (PREAMBLE_RECEIVED_TARGET_POWER+DELTA_PREAMBLE @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) /** \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 @param Mod_id Module id of UE
@returns DELTA_PREAMBLE @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) /** \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 @param Mod_id Module id of UE
@returns deltaP_rampup @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 //main.c
...@@ -186,10 +186,11 @@ void mac_UE_out_of_sync_ind(module_id_t module_idP,frame_t frameP, uint16_t eNB_ ...@@ -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, void dlsch_scheduler_pre_processor (module_id_t module_idP,
frame_t frameP, frame_t frameP,
sub_frame_t subframe, sub_frame_t subframe,
uint8_t *dl_pow_off, uint8_t dl_pow_off[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
uint16_t *pre_nb_available_rbs, uint16_t pre_nb_available_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
int N_RBGS, int N_RBGS[MAX_NUM_CCs],
unsigned char rballoc_sub_UE[NUMBER_OF_UE_MAX][N_RBGS_MAX]); 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 /* \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 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, ...@@ -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 /* \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. in a given subframe.
@param Mod_id Instance ID of eNB @param Mod_id Instance ID of eNB
@param CC_id Component Carrier Index
@param subframe Index of current subframe @param subframe Index of current subframe
@returns Pointer to generated DCI for 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. /* \brief Function to indicate a received preamble on PRACH. It initiates the RA procedure.
@param Mod_id Instance ID of eNB @param Mod_id Instance ID of eNB
@param preamble_index index of the received RA request @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 @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. /* \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 @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 ...@@ -224,39 +226,40 @@ void initiate_ra_proc(module_id_t module_idP,frame_t frameP, uint16_t preamble_i
@returns t_CRNTI @returns t_CRNTI
*/ */
uint16_t fill_rar(module_id_t module_idP, uint16_t fill_rar(module_id_t module_idP,
frame_t frameP, int CC_id,
uint8_t *dlsch_buffer, frame_t frameP,
uint16_t N_RB_UL, uint8_t *dlsch_buffer,
uint8_t input_buffer_length); 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. /* \brief This function indicates the end of RA procedure and provides the l3msg received on ULSCH.
@param Mod_id Instance ID of eNB @param Mod_id Instance ID of eNB
@param rnti RNTI of UE transmitting l3msg @param rnti RNTI of UE transmitting l3msg
@param l3msg Pointer to received 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 /* \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 Mod_id Instance ID of eNB
@param preamble_index index of the received RA request. @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. /* \brief Function to indicate a received SDU on ULSCH.
@param Mod_id Instance ID of eNB @param Mod_id Instance ID of eNB
@param rnti RNTI of UE transmitting the SR @param rnti RNTI of UE transmitting the SR
@param sdu Pointer to received SDU @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. /* \brief Function to indicate a scheduled schduling request (SR) was received by eNB.
@param Mod_id Instance ID of eNB @param Mod_id Instance ID of eNB
@param rnti RNTI of UE transmitting the SR @param rnti RNTI of UE transmitting the SR
@param subframe Index of subframe where SR was received @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 /* \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 @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 ...@@ -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) @param mcs Pointer to mcs used by PHY (to be filled by MAC)
@returns Pointer to MCH transport block and mcs for subframe @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 //added for ALU icic purpose
...@@ -277,33 +280,32 @@ void UpdateSBnumber(module_id_t module_idP); ...@@ -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_mac_reset (module_id_t module_idP,uint8_t eNB_index);
void ue_init_mac (module_id_t module_idP); void ue_init_mac (module_id_t module_idP);
void init_ue_sched_info(void); 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_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, module_id_t ue_mod_idP, sub_frame_t subframe,UE_DLSCH_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);
module_id_t find_UE_id (module_id_t module_idP, rnti_t rnti) ; int 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); rnti_t UE_RNTI (module_id_t module_idP, int UE_id);
uint8_t find_active_UEs (module_id_t module_idP); int UE_PCCID (module_id_t module_idP, int UE_id);
boolean_t is_UE_active (module_id_t module_idP, module_id_t ue_mod_idP ); uint8_t find_active_UEs (module_id_t module_idP);
uint8_t find_ulgranted_UEs(module_id_t module_idP); boolean_t is_UE_active (module_id_t module_idP, int UE_id);
uint8_t find_dlgranted_UEs(module_id_t module_idP); uint8_t process_ue_cqi (module_id_t module_idP, int UE_id);
uint8_t process_ue_cqi (module_id_t module_idP, module_id_t ue_mod_idP);
int8_t find_active_UEs_with_traffic(module_id_t module_idP); 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 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. /** \brief Round-robin scheduler for ULSCH traffic.
@param Mod_id Instance ID for eNB @param Mod_id Instance ID for eNB
@param subframe Subframe number on which to act @param subframe Subframe number on which to act
@returns UE index that is to be scheduled if needed/room @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. /** \brief Round-robin scheduler for DLSCH traffic.
@param Mod_id Instance ID for eNB @param Mod_id Instance ID for eNB
@param subframe Subframe number on which to act @param subframe Subframe number on which to act
@returns UE index that is to be scheduled if needed/room @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. /* \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 @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); ...@@ -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. @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). @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) /* \fn uint32_t req_new_ulsch(module_id_t module_idP)
\brief check for a new transmission in any drb \brief check for a new transmission in any drb
...@@ -322,22 +324,23 @@ uint32_t req_new_ulsch(module_id_t module_idP); ...@@ -322,22 +324,23 @@ uint32_t req_new_ulsch(module_id_t module_idP);
/* \brief Get SR payload (0,1) from UE MAC /* \brief Get SR payload (0,1) from UE MAC
@param Mod_id Instance id of UE in machine @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 eNB_id Index of eNB that UE is attached to
@param rnti C_RNTI of UE @param rnti C_RNTI of UE
@param subframe subframe number @param subframe subframe number
@returns 0 for no SR, 1 for SR @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 // UE functions
void mac_out_of_sync_ind(module_id_t module_idP, frame_t frameP, uint16_t CH_index); 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 #ifdef Rel10
...@@ -370,14 +373,15 @@ int ue_query_mch(uint8_t Mod_id,uint32_t frame,sub_frame_t subframe, uint8_t eNB ...@@ -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 @param subframe subframe number
@returns 0 for no SR, 1 for SR @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) /* \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 Index of UE instance
@param Mod_id Component Carrier Index
@param New_Msg3 Flag to indicate this call is for a new Msg3 @param New_Msg3 Flag to indicate this call is for a new Msg3
@param subframe Index of subframe for PRACH transmission (0 ... 9) @param subframe Index of subframe for PRACH transmission (0 ... 9)
@returns A pointer to a PRACH_RESOURCES_t */ @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. /* \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 @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 ...@@ -387,7 +391,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,frame_t frameP,uint8_t new
random-access procedure random-access procedure
@returns timing advance or 0xffff if preamble doesn't match @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 /* \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, ...@@ -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 l2_init(LTE_DL_FRAME_PARMS *frame_parms,int eMBMS_active, uint8_t cba_group_active, uint8_t HO_active);
int mac_init(void); int mac_init(void);
int8_t add_new_ue(module_id_t module_idP, rnti_t rnti); int add_new_ue(module_id_t Mod_id, int CC_id, rnti_t rnti);
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_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) /*! \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. \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 ...@@ -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); 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 \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] Mod_id instance of the UE
\param[in] bufflen size of phy transport block \param[in] bufflen size of phy transport block
...@@ -554,25 +558,27 @@ int get_sf_prohibitPHR_Timer(uint8_t prohibitPHR_Timer); ...@@ -554,25 +558,27 @@ int get_sf_prohibitPHR_Timer(uint8_t prohibitPHR_Timer);
*/ */
int get_db_dl_PathlossChange(uint8_t dl_PathlossChange); 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 \brief get phr mapping as described in 36.313
\param[in] Mod_id index of eNB \param[in] Mod_id index of eNB
\param[in] CC_id Component Carrier Index
\return phr mapping \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) /*! \fn void update_phr (module_id_t module_idP)
\brief update/reset the phr timers \brief update/reset the phr timers
\param[in] Mod_id index of eNB \param[in] Mod_id index of eNB
\param[in] CC_id Component carrier index
\return void \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 /*! \brief Function to indicate Msg3 transmission/retransmission which initiates/reset Contention Resolution Timer
\param[in] Mod_id Instance index of UE \param[in] Mod_id Instance index of UE
\param[in] eNB_id Index of eNB \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 /*! \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); ...@@ -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 \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, void dl_phy_sync_success(module_id_t module_idP,
frame_t frameP, frame_t frameP,
...@@ -603,5 +609,5 @@ void add_common_dci(DCI_PDU *DCI_pdu, ...@@ -603,5 +609,5 @@ void add_common_dci(DCI_PDU *DCI_pdu,
uint32_t allocate_prbs_sub(int nb_rb, uint8_t *rballoc); 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 #endif
...@@ -57,7 +57,13 @@ ...@@ -57,7 +57,13 @@
extern inline unsigned int taus(void); 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 prachConfigIndex = UE_mac_inst[module_idP].radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_ConfigIndex;
uint8_t preambleformat; uint8_t preambleformat;
...@@ -96,12 +102,13 @@ int8_t get_DELTA_PREAMBLE(module_id_t module_idP) { ...@@ -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, void get_prach_resources(module_id_t module_idP,
uint8_t eNB_index, int CC_id,
uint8_t t_id, uint8_t eNB_index,
uint8_t first_Msg3, uint8_t t_id,
RACH_ConfigDedicated_t *rach_ConfigDedicated) { uint8_t first_Msg3,
RACH_ConfigDedicated_t *rach_ConfigDedicated) {
uint8_t Msg3_size = UE_mac_inst[module_idP].RA_Msg3_size; 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; 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, ...@@ -109,6 +116,12 @@ void get_prach_resources(module_id_t module_idP,
uint8_t noGroupB = 0; uint8_t noGroupB = 0;
uint8_t f_id = 0,num_prach=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) if (UE_mac_inst[module_idP].radioResourceConfigCommon)
rach_ConfigCommon = &UE_mac_inst[module_idP].radioResourceConfigCommon->rach_ConfigCommon; rach_ConfigCommon = &UE_mac_inst[module_idP].radioResourceConfigCommon->rach_ConfigCommon;
else { else {
...@@ -156,7 +169,7 @@ void get_prach_resources(module_id_t module_idP, ...@@ -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_prach_resources.ra_RACH_MaskIndex = 0;
UE_mac_inst[module_idP].RA_usedGroupA = 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 else { // Msg3 is being retransmitted
if (UE_mac_inst[module_idP].RA_usedGroupA == 1) { if (UE_mac_inst[module_idP].RA_usedGroupA == 1) {
...@@ -187,7 +200,13 @@ void get_prach_resources(module_id_t module_idP, ...@@ -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; 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 // start contention resolution timer
UE_mac_inst[module_idP].RA_attempt_number++; 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) { ...@@ -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 // start contention resolution timer
LOG_I(MAC,"[UE %d][RAPROC] Frame %d : Msg3_tx: Setting contention resolution timer\n",module_idP,frameP); 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) { ...@@ -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; 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; uint8_t lcid = CCCH;
uint16_t Size16; uint16_t Size16;
struct RACH_ConfigCommon *rach_ConfigCommon = (struct RACH_ConfigCommon *)NULL; 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 ...@@ -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]; uint16_t sdu_lengths[8];
uint8_t ulsch_buff[MAX_ULSCH_PAYLOAD_BYTES]; 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_mode == PRACH) {
if (UE_mac_inst[module_idP].radioResourceConfigCommon) if (UE_mac_inst[module_idP].radioResourceConfigCommon)
rach_ConfigCommon = &UE_mac_inst[module_idP].radioResourceConfigCommon->rach_ConfigCommon; 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 ...@@ -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 (Is_rrc_registered == 1) {
if (UE_mac_inst[module_idP].RA_active == 0) { if (UE_mac_inst[module_idP].RA_active == 0) {
printf("RA not active\n");
// check if RRC is ready to initiate the RA procedure // check if RRC is ready to initiate the RA procedure
Size = mac_rrc_data_req(module_idP, Size = mac_rrc_data_req(module_idP,
frameP, frameP,
...@@ -279,7 +311,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,frame_t frameP, uint8_t eN ...@@ -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_frame = frameP;
UE_mac_inst[module_idP].RA_backoff_subframe = subframeP; UE_mac_inst[module_idP].RA_backoff_subframe = subframeP;
// Fill in preamble and PRACH resource // 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 generate_ulsch_header((uint8_t*)&UE_mac_inst[module_idP].CCCH_pdu.payload[0], // mac header
1, // num sdus 1, // num sdus
...@@ -335,7 +367,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,frame_t frameP, uint8_t eN ...@@ -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_frame = frameP;
UE_mac_inst[module_idP].RA_backoff_subframe = subframeP; UE_mac_inst[module_idP].RA_backoff_subframe = subframeP;
// Fill in preamble and PRACH resource // 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 generate_ulsch_header((uint8_t*)ulsch_buff, // mac header
1, // num sdus 1, // num sdus
0, // short pading 0, // short pading
...@@ -385,13 +417,13 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,frame_t frameP, uint8_t eN ...@@ -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); 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 // send message to RRC
UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER=1; 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_window_cnt = 2+ rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize;
UE_mac_inst[module_idP].RA_backoff_cnt = 0; UE_mac_inst[module_idP].RA_backoff_cnt = 0;
// Fill in preamble and PRACH resource // 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); 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 ...@@ -403,648 +435,3 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,frame_t frameP, uint8_t eN
} }
return(NULL); 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;
}
}
}
...@@ -57,6 +57,7 @@ extern unsigned short RIV2first_rb_LUT25[512]; ...@@ -57,6 +57,7 @@ extern unsigned short RIV2first_rb_LUT25[512];
extern inline unsigned int taus(void); extern inline unsigned int taus(void);
unsigned short fill_rar(module_id_t module_idP, unsigned short fill_rar(module_id_t module_idP,
int CC_id,
frame_t frameP, frame_t frameP,
uint8_t *dlsch_buffer, uint8_t *dlsch_buffer,
uint16_t N_RB_UL, uint16_t N_RB_UL,
...@@ -70,9 +71,9 @@ unsigned short fill_rar(module_id_t module_idP, ...@@ -70,9 +71,9 @@ unsigned short fill_rar(module_id_t module_idP,
uint8_t mcs,TPC,ULdelay,cqireq; uint8_t mcs,TPC,ULdelay,cqireq;
for (i=0;i<NB_RA_PROC_MAX;i++) { 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; 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; break;
} }
} }
...@@ -80,24 +81,24 @@ unsigned short fill_rar(module_id_t module_idP, ...@@ -80,24 +81,24 @@ unsigned short fill_rar(module_id_t module_idP,
// subheader fixed // subheader fixed
rarh->E = 0; // First and last RAR 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->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->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->hopping_flag = 0;
rar->rb_alloc = mac_xface->computeRIV(N_RB_UL,12,2); // 2 RB rar->rb_alloc = mac_xface->computeRIV(N_RB_UL,12,2); // 2 RB
rar->mcs = 2; // mcs 2 rar->mcs = 2; // mcs 2
rar->TPC = 4; // 2 dB power adjustment rar->TPC = 4; // 2 dB power adjustment
rar->UL_delay = 0; rar->UL_delay = 0;
rar->cqi_req = 1; 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[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].RA_template[ra_idx].rnti&0xff); rar[5] = (uint8_t)(eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].rnti&0xff);
eNB_mac_inst[module_idP].RA_template[ra_idx].timing_offset = 0; eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset = 0;
//eNB_mac_inst[module_idP].RA_template[ra_idx].timing_offset /= 16; //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].RA_template[ra_idx].timing_offset>>(2+4)); // 7 MSBs of timing advance + divide by 4 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].RA_template[ra_idx].timing_offset<<(4-2))&0xf0; // 4 LSBs 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 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[1] |= (rballoc>>7)&7; // Hopping = 0 (bit 3), 3 MSBs of rballoc
rar[2] = ((uint8_t)(rballoc&0xff))<<1; // 7 LSBs 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, ...@@ -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, 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], *(uint8_t*)rarh,rar[0],rar[1],rar[2],rar[3],rar[4],rar[5],
ra_idx, ra_idx,
eNB_mac_inst[module_idP].RA_template[ra_idx].rnti, eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].rnti,
rarh->RAPID,eNB_mac_inst[module_idP].RA_template[0].preamble_index, rarh->RAPID,eNB_mac_inst[module_idP].common_channels[CC_id].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].timing_offset);
#if defined(USER_MODE) && defined(OAI_EMU) #if defined(USER_MODE) && defined(OAI_EMU)
if (oai_emulation.info.opt_enabled){ if (oai_emulation.info.opt_enabled){
trace_pdu(1, dlsch_buffer, input_buffer_length, module_idP, 2, 1, trace_pdu(1, dlsch_buffer, input_buffer_length, module_idP, 2, 1,
eNB_mac_inst[module_idP].subframe, 0, 0); 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", 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); rarh->RAPID, input_buffer_length);
} }
#endif #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; RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *)dlsch_buffer;
// RAR_PDU *rar = (RAR_PDU *)(dlsch_buffer+1); // RAR_PDU *rar = (RAR_PDU *)(dlsch_buffer+1);
uint8_t *rar = (uint8_t *)(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, 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], *(uint8_t*)rarh,rar[0],rar[1],rar[2],rar[3],rar[4],rar[5],
rarh->RAPID,preamble_index); rarh->RAPID,preamble_index);
......
...@@ -95,10 +95,8 @@ extern inline unsigned int taus(void); ...@@ -95,10 +95,8 @@ extern inline unsigned int taus(void);
void ue_init_mac(module_id_t module_idP){ void ue_init_mac(module_id_t module_idP){
int i; int i;
// default values as deined in 36.331 sec 9.2.2 // default values as deined in 36.331 sec 9.2.2
LOG_I(MAC,"[UE%d] Applying default macMainConfig\n",module_idP); 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.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.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; 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){ ...@@ -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.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.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); 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++){ 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); 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.Bj[i]=-1;
UE_mac_inst[module_idP].scheduling_info.bucket_size[i]=-1; UE_mac_inst[module_idP].scheduling_info.bucket_size[i]=-1;
if (i < DTCH) // initilize all control channels lcgid to 0 if (i < DTCH) // initilize all control channels lcgid to 0
UE_mac_inst[module_idP].scheduling_info.LCGID[i]=0; UE_mac_inst[module_idP].scheduling_info.LCGID[i]=0;
...@@ -131,13 +129,14 @@ void ue_init_mac(module_id_t module_idP){ ...@@ -131,13 +129,14 @@ void ue_init_mac(module_id_t module_idP){
} }
} }
unsigned char *parse_header(unsigned char *mac_header, unsigned char *parse_header(unsigned char *mac_header,
unsigned char *num_ce, unsigned char *num_ce,
unsigned char *num_sdu, unsigned char *num_sdu,
unsigned char *rx_ces, unsigned char *rx_ces,
unsigned char *rx_lcids, unsigned char *rx_lcids,
unsigned short *rx_lengths, unsigned short *rx_lengths,
unsigned short tb_length) { unsigned short tb_length) {
unsigned char not_done=1,num_ces=0,num_sdus=0,lcid, num_sdu_cnt; unsigned char not_done=1,num_ces=0,num_sdus=0,lcid, num_sdu_cnt;
unsigned char *mac_header_ptr = mac_header; unsigned char *mac_header_ptr = mac_header;
...@@ -203,7 +202,7 @@ unsigned char *parse_header(unsigned char *mac_header, ...@@ -203,7 +202,7 @@ unsigned char *parse_header(unsigned char *mac_header,
return(mac_header_ptr); 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 // 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 // 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 ...@@ -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); 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 // 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", 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, 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 ...@@ -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_ces[MAX_NUM_CE],num_ce,num_sdu,i,*payload_ptr;
unsigned char rx_lcids[NB_RB_MAX]; 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 ...@@ -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++) for (i=0;i<6;i++)
if (tx_sdu[i] != payload_ptr[i]) { if (tx_sdu[i] != payload_ptr[i]) {
LOG_E(MAC,"[UE %d][RAPROC] Contention detected, RA failed\n",module_idP); 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; 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); vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT);
return; return;
} }
LOG_I(MAC,"[UE %d][RAPROC] Frame %d : Clearing contention resolution timer\n"); LOG_I(MAC,"[UE %d][RAPROC] Frame %d : Clearing contention resolution timer\n");
UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0; 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; payload_ptr+=6;
break; break;
...@@ -418,7 +423,7 @@ void ue_send_sdu(module_id_t module_idP,frame_t frameP,uint8_t *sdu,uint16_t sdu ...@@ -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); 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); 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); 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 ...@@ -439,14 +444,14 @@ void ue_decode_si(module_id_t module_idP,frame_t frameP, uint8_t eNB_index, void
#ifdef Rel10 #ifdef Rel10
unsigned char *parse_mch_header(unsigned char *mac_header, unsigned char *parse_mch_header(unsigned char *mac_header,
unsigned char *num_sdu, unsigned char *num_sdu,
unsigned char *rx_lcids, unsigned char *rx_lcids,
unsigned short *rx_lengths, unsigned short *rx_lengths,
unsigned short tb_length) { unsigned short tb_length) {
unsigned char not_done=1, num_sdus=0, lcid, i; unsigned char not_done=1, num_sdus=0, lcid, i;
unsigned char *mac_header_ptr = mac_header; unsigned char *mac_header_ptr = mac_header;
unsigned short length; unsigned short length;
while (not_done == 1) { while (not_done == 1) {
if (((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E == 0) { if (((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E == 0) {
not_done = 0; not_done = 0;
...@@ -789,16 +794,16 @@ int ue_query_mch(module_id_t module_idP, uint32_t frameP, uint32_t subframe, uin ...@@ -789,16 +794,16 @@ int ue_query_mch(module_id_t module_idP, uint32_t frameP, uint32_t subframe, uin
#endif #endif
unsigned char generate_ulsch_header(uint8_t *mac_header, unsigned char generate_ulsch_header(uint8_t *mac_header,
uint8_t num_sdus, uint8_t num_sdus,
uint8_t short_padding, uint8_t short_padding,
uint16_t *sdu_lengths, uint16_t *sdu_lengths,
uint8_t *sdu_lcids, uint8_t *sdu_lcids,
POWER_HEADROOM_CMD *power_headroom, POWER_HEADROOM_CMD *power_headroom,
uint16_t *crnti, uint16_t *crnti,
BSR_SHORT *truncated_bsr, BSR_SHORT *truncated_bsr,
BSR_SHORT *short_bsr, BSR_SHORT *short_bsr,
BSR_LONG *long_bsr, BSR_LONG *long_bsr,
unsigned short post_padding) { unsigned short post_padding) {
SCH_SUBHEADER_FIXED *mac_header_ptr = (SCH_SUBHEADER_FIXED *)mac_header; SCH_SUBHEADER_FIXED *mac_header_ptr = (SCH_SUBHEADER_FIXED *)mac_header;
unsigned char first_element=0,last_size=0,i; unsigned char first_element=0,last_size=0,i;
...@@ -1030,7 +1035,7 @@ unsigned char generate_ulsch_header(uint8_t *mac_header, ...@@ -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; mac_rlc_status_resp_t rlc_status;
uint8_t dcch_header_len=0,dcch1_header_len=0,dtch_header_len=0; 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 ...@@ -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 int j; // used for padding
// Compute header length // 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); 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); 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 ...@@ -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 // build PHR and update the timers
if (phr_ce_len == sizeof(POWER_HEADROOM_CMD)){ if (phr_ce_len == sizeof(POWER_HEADROOM_CMD)){
phr_p->PH = get_phr_mapping(module_idP,eNB_index); phr_p->PH = get_phr_mapping(module_idP,CC_id,eNB_index);
phr_p->R = 0; phr_p->R = 0;
LOG_D(MAC,"[UE %d] Frame %d report PHR with mapping (%d->%d) for LCID %d\n", 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); module_idP,frameP, mac_xface->get_PHR(module_idP,CC_id,eNB_index), phr_p->PH,POWER_HEADROOM);
update_phr(module_idP); update_phr(module_idP,CC_id);
}else }else
phr_p=NULL; 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 ...@@ -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; UE_mac_inst[module_idP].RA_active = 0;
// Signal PHY to quit RA procedure // Signal PHY to quit RA procedure
LOG_E(MAC,"Module id %u Contention resolution timer expired, RA failed\n", module_idP); 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) { ...@@ -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; uint8_t bsr_len=0, num_lcgid=0;
int pdu = 0; int pdu = 0;
for (lcgid=0; lcgid < MAX_NUM_LCGID; lcgid++ ) { for (lcgid=0; lcgid < MAX_NUM_LCGID; lcgid++ ) {
if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid] > 0 ) 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) 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 ...@@ -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; mac_rlc_status_resp_t rlc_status;
boolean_t sr_pending = FALSE; boolean_t sr_pending = FALSE;
if ((lcg_id < 0) || (lcg_id > MAX_NUM_LCGID) ) if ((lcg_id < 0) || (lcg_id > MAX_NUM_LCGID) )
return sr_pending; return sr_pending;
// fixme: need a better way to reset // fixme: need a better way to reset
...@@ -1754,23 +1768,34 @@ int get_ms_bucketsizeduration(uint8_t bucketsizeduration){ ...@@ -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].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.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.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); // 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 //power headroom reporting range is from -23 ...+40 dB, as described in 36313
//note: mac_xface->get_Po_NOMINAL_PUSCH(module_idP) is float //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; 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; return 63;
else // -23 to 40 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){ int get_sf_perioidicPHR_Timer(uint8_t perioidicPHR_Timer){
......
...@@ -61,6 +61,11 @@ UE_MAC_INST *UE_mac_inst; //[NB_MODULE_MAX]; ...@@ -61,6 +61,11 @@ UE_MAC_INST *UE_mac_inst; //[NB_MODULE_MAX];
eNB_MAC_INST *eNB_mac_inst; //[NB_MODULE_MAX]; eNB_MAC_INST *eNB_mac_inst; //[NB_MODULE_MAX];
MAC_RLC_XFACE *Mac_rlc_xface; 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_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 eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8
......
...@@ -89,6 +89,7 @@ MAC_OBJS += $(MAC_DIR)/eNB_scheduler_ulsch.o ...@@ -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_mch.o
MAC_OBJS += $(MAC_DIR)/eNB_scheduler_bch.o MAC_OBJS += $(MAC_DIR)/eNB_scheduler_bch.o
MAC_OBJS += $(MAC_DIR)/eNB_scheduler_primitives.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)/pre_processor.o
MAC_OBJS += $(MAC_DIR)/config.o MAC_OBJS += $(MAC_DIR)/config.o
......
...@@ -68,74 +68,81 @@ static mapping rrc_status_names[] = { ...@@ -68,74 +68,81 @@ static mapping rrc_status_names[] = {
int dump_eNB_l2_stats(char *buffer, int length){ 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 len= length;
int CC_id=0;
int i;
#ifdef EXMIMO #ifdef EXMIMO
number_of_cards=1; number_of_cards=1;
#else #else
number_of_cards=NB_eNB_INST; number_of_cards=NB_eNB_INST;
#endif #endif
eNB_MAC_INST *eNB;
UE_list_t *UE_list;
for (eNB_id=0;eNB_id<number_of_cards;eNB_id++) { for (eNB_id=0;eNB_id<number_of_cards;eNB_id++) {
/* reset the values */ /* 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", 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_id, eNB->frame,
eNB_mac_inst[eNB_id].eNB_stats.num_dlactive_UEs, eNB->eNB_stats.num_dlactive_UEs,
eNB_mac_inst[eNB_id].eNB_stats.available_prbs, eNB->eNB_stats.available_prbs,
eNB_mac_inst[eNB_id].eNB_stats.available_ncces); 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->eNB_stats.dlsch_bitrate=((eNB->eNB_stats.dlsch_bytes_tx*8)/((eNB->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->eNB_stats.total_dlsch_pdus_tx+=eNB->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->eNB_stats.total_dlsch_bytes_tx+=eNB->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.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", 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->eNB_stats.dlsch_bitrate,
eNB_mac_inst[eNB_id].eNB_stats.total_dlsch_bitrate, eNB->eNB_stats.total_dlsch_bitrate,
eNB_mac_inst[eNB_id].eNB_stats.dlsch_bytes_tx, eNB->eNB_stats.dlsch_bytes_tx,
eNB_mac_inst[eNB_id].eNB_stats.total_dlsch_bytes_tx, eNB->eNB_stats.total_dlsch_bytes_tx,
eNB_mac_inst[eNB_id].eNB_stats.dlsch_pdus_tx, eNB->eNB_stats.dlsch_pdus_tx,
eNB_mac_inst[eNB_id].eNB_stats.total_dlsch_pdus_tx); eNB->eNB_stats.total_dlsch_pdus_tx);
len += sprintf(&buffer[len],"\n"); len += sprintf(&buffer[len],"\n");
for (UE_id=0;UE_id<NUMBER_OF_UE_MAX;UE_id++) { for (UE_id=UE_list->head;UE_id>0;UE_id=UE_list->next[UE_id]) {
if (eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].crnti > 0 ) { for (i=0;i<UE_list->numactiveCCs[UE_id];i++) {
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)); CC_id=UE_list->ordered_CCids[i][UE_id];
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)); 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));
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; 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));
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)); 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 ", 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, UE_id,
map_int_to_str(rrc_status_names, eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].rrc_status), map_int_to_str(rrc_status_names, UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status),
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].crnti, UE_list->eNB_UE_stats[CC_id][UE_id].crnti,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].dl_cqi, UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].dlsch_mcs1, UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].dlsch_mcs2, UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].rbs_used, UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].rbs_used_retx, UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_rbs_used, UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].ncce_used, UE_list->eNB_UE_stats[CC_id][UE_id].ncce_used,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].ncce_used_retx UE_list->eNB_UE_stats[CC_id][UE_id].ncce_used_retx
); );
len += sprintf(&buffer[len], len += sprintf(&buffer[len],
"[MAC] DLSCH bitrate (TTI %d, avg %d), Transmitted bytes " "[MAC] DLSCH bitrate (TTI %d, avg %d), Transmitted bytes "
"(TTI %d, total %"PRIu64"), Total Transmitted PDU %d, Overhead " "(TTI %d, total %"PRIu64"), Total Transmitted PDU %d, Overhead "
"(TTI %"PRIu64", total %"PRIu64", avg %"PRIu64, "(TTI %"PRIu64", total %"PRIu64", avg %"PRIu64,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].dlsch_bitrate, UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_bitrate,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_dlsch_bitrate, UE_list->eNB_UE_stats[CC_id][UE_id].total_dlsch_bitrate,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].TBS, UE_list->eNB_UE_stats[CC_id][UE_id].TBS,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_pdu_bytes, UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_num_pdus, UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].overhead_bytes, UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_overhead_bytes, UE_list->eNB_UE_stats[CC_id][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].avg_overhead_bytes
); );
} }
......
...@@ -70,43 +70,43 @@ typedef struct ...@@ -70,43 +70,43 @@ typedef struct
// eNB functions // eNB functions
/// Invoke dlsch/ulsch scheduling procedure for new subframe /// 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 /// 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 /// 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 /// 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 /// 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 /// 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 /// 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 /// 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 /// 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); void (*mrbch_phy_sync_failure) (module_id_t Mod_id,frame_t frameP, uint8_t free_eNB_index);
/// Indicate Scheduling Request from UE /// 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 /// 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, TDD_Config_t *tdd_config,
uint8_t SIwindowsize, uint8_t SIwindowsize,
uint16_t SIperiod); uint16_t SIperiod);
/// Configure Common PHY parameters from SIB2 /// 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, RadioResourceConfigCommonSIB_t *radioResourceConfigCommon,
ARFCN_ValueEUTRA_t *ul_CArrierFreq, ARFCN_ValueEUTRA_t *ul_CArrierFreq,
long *ul_Bandwidth, long *ul_Bandwidth,
...@@ -115,12 +115,12 @@ typedef struct ...@@ -115,12 +115,12 @@ typedef struct
#ifdef Rel10 #ifdef Rel10
/// Configure Common PHY parameters from SIB13 /// 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); long mbsfn_AreaId_r9);
#endif #endif
/// PHY-Config-Dedicated eNB /// 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); struct PhysicalConfigDedicated *physicalConfigDedicated);
#ifdef Rel10 #ifdef Rel10
...@@ -139,10 +139,10 @@ typedef struct ...@@ -139,10 +139,10 @@ typedef struct
void (*out_of_sync_ind)(module_id_t Mod_id,frame_t frameP,uint16_t eNB_index); void (*out_of_sync_ind)(module_id_t Mod_id,frame_t frameP,uint16_t eNB_index);
/// Send a received SI sdu /// 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 /// 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 #ifdef Rel10
/// Send a received MCH sdu to MAC /// Send a received MCH sdu to MAC
...@@ -150,20 +150,20 @@ typedef struct ...@@ -150,20 +150,20 @@ typedef struct
/// Function to check if UE PHY needs to decode MCH for MAC /// 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 /// 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 #endif
/// Retrieve ULSCH sdu from MAC /// 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 /// 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 /// 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 /// 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 /// 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); 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 ...@@ -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); 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 /// 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); struct PhysicalConfigDedicated *physicalConfigDedicated);
/// Configure Common PHY parameters from SIB1 /// 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, TDD_Config_t *tdd_config,
uint8_t SIwindowsize, uint8_t SIwindowsize,
uint16_t SIperiod); uint16_t SIperiod);
/// Configure Common PHY parameters from SIB2 /// 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, RadioResourceConfigCommonSIB_t *radioResourceConfigCommon,
ARFCN_ValueEUTRA_t *ul_CArrierFreq, ARFCN_ValueEUTRA_t *ul_CArrierFreq,
long *ul_Bandwidth, long *ul_Bandwidth,
...@@ -200,19 +200,19 @@ typedef struct ...@@ -200,19 +200,19 @@ typedef struct
uint8_t ho_failed); uint8_t ho_failed);
/// Function to indicate failure of contention resolution or RA procedure /// 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 /// 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 /// 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 /// 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) /// 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 // PHY Helper Functions
...@@ -226,22 +226,22 @@ typedef struct ...@@ -226,22 +226,22 @@ typedef struct
uint16_t (*get_TBS_UL)(uint8_t mcs, uint16_t nb_rb); 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 /// 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 /// 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 /// 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); uint32_t (*get_nb_rb)(uint8_t ra_header, uint32_t rb_alloc, int n_rb_dl);
/// Function to retrieve transmission mode for UE /// 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 /// 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); 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) /// 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 /// Function for UE MAC to retrieve measured Path Loss
int16_t (*get_PL)(module_id_t Mod_id,uint8_t eNB_index); int16_t (*get_PL)(module_id_t Mod_id,uint8_t eNB_index);
...@@ -278,17 +278,17 @@ typedef struct ...@@ -278,17 +278,17 @@ typedef struct
// MAC Helper functions // MAC Helper functions
/// Function for UE/PHY to compute PUSCH transmit power in power-control procedure (Po_NOMINAL_PUSCH parameter) /// 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) /// 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 /// 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); 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_cluster_head;
unsigned char is_primary_cluster_head; unsigned char is_primary_cluster_head;
......
...@@ -2455,8 +2455,8 @@ void rrc_eNB_generate_RRCConnectionSetup( ...@@ -2455,8 +2455,8 @@ void rrc_eNB_generate_RRCConnectionSetup(
eNB_rrc_inst[enb_mod_idP].Srb0.Tx_buffer.payload_size = eNB_rrc_inst[enb_mod_idP].Srb0.Tx_buffer.payload_size =
do_RRCConnectionSetup(enb_mod_idP, do_RRCConnectionSetup(enb_mod_idP,
(uint8_t *) eNB_rrc_inst[enb_mod_idP].Srb0.Tx_buffer.Payload, (uint8_t *) eNB_rrc_inst[enb_mod_idP].Srb0.Tx_buffer.Payload,
mac_xface->get_transmission_mode(enb_mod_idP, mac_xface->get_transmission_mode(enb_mod_idP,0, //CC_id 0!!!!
find_UE_RNTI UE_RNTI
(enb_mod_idP, (enb_mod_idP,
ue_mod_idP)), ue_mod_idP)),
ue_mod_idP, ue_mod_idP,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment