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) {
UE_mac_inst[module_idP].scheduling_info.Bj[0] = 0;
UE_mac_inst[module_idP].scheduling_info.Bj[1] = 0;
UE_mac_inst[module_idP].scheduling_info.Bj[2] = 0;
//Stopping all timers
//timeAlignmentTimer expires
......@@ -81,6 +82,7 @@ void ue_mac_reset(module_id_t module_idP,uint8_t eNB_index) {
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = 0; // check!
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0;
ue_init_mac(module_idP); //This will hopefully do the rest of the MAC reset procedure
}
......@@ -88,6 +90,10 @@ void ue_mac_reset(module_id_t module_idP,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,
struct PhysicalConfigDedicated *physicalConfigDedicated,
#ifdef Rel10
SCellToAddMod_r10_t *sCellToAddMod_r10,
//struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10,
#endif
MeasObjectToAddMod_t **measObj,
MAC_MainConfig_t *mac_MainConfig,
long logicalChannelIdentity,
......@@ -112,7 +118,7 @@ int rrc_mac_config_req(module_id_t Mod_id, eNB_flag_t eNB_flagP,uint8_t UE_id,ui
#endif
) {
int i;
int i,CC_id;
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN);
......@@ -124,15 +130,15 @@ int rrc_mac_config_req(module_id_t Mod_id, eNB_flag_t eNB_flagP,uint8_t UE_id,ui
if (physicalConfigDedicated == NULL){
LOG_I(MAC,"[CONFIG][eNB %d] Configuring MAC/PHY\n",Mod_id);
} else{
LOG_I(MAC,"[CONFIG][eNB %d] Configuring MAC/PHY for UE %d (%x)\n",Mod_id,UE_id,find_UE_RNTI(Mod_id,UE_id));
LOG_I(MAC,"[CONFIG][eNB %d] Configuring MAC/PHY for UE %d (%x)\n",Mod_id,UE_id,UE_RNTI(Mod_id,UE_id));
}
}
if ((tdd_Config!=NULL)||(SIwindowsize!=NULL)||(SIperiod!=NULL)){
if (eNB_flagP==1)
mac_xface->phy_config_sib1_eNB(Mod_id,tdd_Config,*SIwindowsize,*SIperiod);
mac_xface->phy_config_sib1_eNB(Mod_id,0,tdd_Config,*SIwindowsize,*SIperiod);
else
mac_xface->phy_config_sib1_ue(Mod_id,eNB_index,tdd_Config,*SIwindowsize,*SIperiod);
mac_xface->phy_config_sib1_ue(Mod_id,0,eNB_index,tdd_Config,*SIwindowsize,*SIperiod);
}
if (radioResourceConfigCommon!=NULL) {
......@@ -146,11 +152,11 @@ int rrc_mac_config_req(module_id_t Mod_id, eNB_flag_t eNB_flagP,uint8_t UE_id,ui
LOG_I(MAC,"[CONFIG]pusch_config_common.groupAssignmentPUSCH = %ld\n",radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH);
LOG_I(MAC,"[CONFIG]pusch_config_common.sequenceHoppingEnabled = %d\n",radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled);
LOG_I(MAC,"[CONFIG]pusch_config_common.cyclicShift = %ld\n",radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift);
mac_xface->phy_config_sib2_eNB(Mod_id,radioResourceConfigCommon,ul_CarrierFreq,ul_Bandwidth,additionalSpectrumEmission,mbsfn_SubframeConfigList);
mac_xface->phy_config_sib2_eNB(Mod_id,0,radioResourceConfigCommon,ul_CarrierFreq,ul_Bandwidth,additionalSpectrumEmission,mbsfn_SubframeConfigList);
}
else {
UE_mac_inst[Mod_id].radioResourceConfigCommon = radioResourceConfigCommon;
mac_xface->phy_config_sib2_ue(Mod_id,eNB_index,radioResourceConfigCommon,ul_CarrierFreq,ul_Bandwidth,additionalSpectrumEmission,mbsfn_SubframeConfigList);
mac_xface->phy_config_sib2_ue(Mod_id,0,eNB_index,radioResourceConfigCommon,ul_CarrierFreq,ul_Bandwidth,additionalSpectrumEmission,mbsfn_SubframeConfigList);
}
}
// SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters->logicalChannelGroup
......@@ -229,12 +235,24 @@ int rrc_mac_config_req(module_id_t Mod_id, eNB_flag_t eNB_flagP,uint8_t UE_id,ui
if (physicalConfigDedicated != NULL) {
if (eNB_flagP==1){
mac_xface->phy_config_dedicated_eNB(Mod_id,find_UE_RNTI(Mod_id,UE_id),physicalConfigDedicated);
mac_xface->phy_config_dedicated_eNB(Mod_id,0,UE_RNTI(Mod_id,UE_id),physicalConfigDedicated);
}else{
mac_xface->phy_config_dedicated_ue(Mod_id,eNB_index,physicalConfigDedicated);
mac_xface->phy_config_dedicated_ue(Mod_id,0,eNB_index,physicalConfigDedicated);
UE_mac_inst[Mod_id].physicalConfigDedicated=physicalConfigDedicated; // for SR proc
}
}
#ifdef Rel10
if (sCellToAddMod_r10 != NULL) {
if (eNB_flag==1){
mac_xface->phy_config_dedicated_scell_eNB(Mod_id,UE_RNTI(Mod_id,UE_id),sCellToAddMod_r10,1);
}
else {
mac_xface->phy_config_dedicated_scell_ue(Mod_id,eNB_index,sCellToAddMod_r10,1);
UE_mac_inst[Mod_id].physicalConfigDedicatedSCell_r10 = sCellToAddMod_r10->radioResourceConfigDedicatedSCell_r10->physicalConfigDedicatedSCell_r10; // using SCell index 0
}
}
#endif
if (eNB_flagP == 0) {
if (measObj!= NULL) {
......@@ -245,7 +263,7 @@ int rrc_mac_config_req(module_id_t Mod_id, eNB_flag_t eNB_flagP,uint8_t UE_id,ui
UE_mac_inst[Mod_id].adj_cell_id[i] = measObj[0]->measObject.choice.measObjectEUTRA.cellsToAddModList->list.array[i]->physCellId;
LOG_I(MAC,"Cell %d : Nid_cell %d\n",i,UE_mac_inst[Mod_id].adj_cell_id[i]);
}
mac_xface->phy_config_meas_ue(Mod_id,eNB_index,UE_mac_inst[Mod_id].n_adj_cells,UE_mac_inst[Mod_id].adj_cell_id);
mac_xface->phy_config_meas_ue(Mod_id,0,eNB_index,UE_mac_inst[Mod_id].n_adj_cells,UE_mac_inst[Mod_id].adj_cell_id);
}
/*
if (quantityConfig != NULL) {
......@@ -334,14 +352,14 @@ int rrc_mac_config_req(module_id_t Mod_id, eNB_flag_t eNB_flagP,uint8_t UE_id,ui
if (mbsfn_SubframeConfigList != NULL) {
if (eNB_flagP == 1) {
LOG_I(MAC,"[eNB %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n", Mod_id, mbsfn_SubframeConfigList->list.count);
eNB_mac_inst[Mod_id].num_sf_allocation_pattern= mbsfn_SubframeConfigList->list.count;
eNB_mac_inst[Mod_id].common_channels[0].num_sf_allocation_pattern= mbsfn_SubframeConfigList->list.count;
for (i=0; i<mbsfn_SubframeConfigList->list.count; i++) {
eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[i] = mbsfn_SubframeConfigList->list.array[i];
eNB_mac_inst[Mod_id].common_channels[0].mbsfn_SubframeConfig[i] = mbsfn_SubframeConfigList->list.array[i];
LOG_I(MAC, "[eNB %d][CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", Mod_id, i,
eNB_mac_inst[Mod_id].mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]);
eNB_mac_inst[Mod_id].common_channels[0].mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]);
}
#ifdef Rel10
eNB_mac_inst[Mod_id].MBMS_flag = MBMS_Flag;
eNB_mac_inst[Mod_id].common_channels[0].MBMS_flag = MBMS_Flag;
#endif
}
else { // UE
......@@ -361,12 +379,12 @@ int rrc_mac_config_req(module_id_t Mod_id, eNB_flag_t eNB_flagP,uint8_t UE_id,ui
if (eNB_flagP == 1) {
// One eNB could be part of multiple mbsfn syc area, this could change over time so reset each time
LOG_I(MAC,"[eNB %d][CONFIG] Received %d MBSFN Area Info\n", Mod_id, mbsfn_AreaInfoList->list.count);
eNB_mac_inst[Mod_id].num_active_mbsfn_area = mbsfn_AreaInfoList->list.count;
eNB_mac_inst[Mod_id].common_channels[0].num_active_mbsfn_area = mbsfn_AreaInfoList->list.count;
for (i =0; i< mbsfn_AreaInfoList->list.count; i++) {
eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i] = mbsfn_AreaInfoList->list.array[i];
eNB_mac_inst[Mod_id].common_channels[0].mbsfn_AreaInfo[i] = mbsfn_AreaInfoList->list.array[i];
LOG_I(MAC,"[eNB %d][CONFIG] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n", Mod_id,i,
eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9);
mac_xface->phy_config_sib13_eNB(Mod_id,i,eNB_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9);
eNB_mac_inst[Mod_id].common_channels[0].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9);
mac_xface->phy_config_sib13_eNB(Mod_id,0,i,eNB_mac_inst[Mod_id].common_channels[0].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9);
}
}
else { // UE
......@@ -376,7 +394,7 @@ int rrc_mac_config_req(module_id_t Mod_id, eNB_flag_t eNB_flagP,uint8_t UE_id,ui
UE_mac_inst[Mod_id].mbsfn_AreaInfo[i] = mbsfn_AreaInfoList->list.array[i];
LOG_I(MAC,"[UE %d] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n",Mod_id, i,
UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9);
mac_xface->phy_config_sib13_ue(Mod_id,eNB_index,i,UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9);
mac_xface->phy_config_sib13_ue(Mod_id,0,eNB_index,i,UE_mac_inst[Mod_id].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9);
}
}
}
......@@ -391,17 +409,17 @@ int rrc_mac_config_req(module_id_t Mod_id, eNB_flag_t eNB_flagP,uint8_t UE_id,ui
LOG_I(MAC, "[CONFIG] Number of PMCH in this MBSFN Area %d\n", pmch_InfoList->list.count);
for (i =0; i< pmch_InfoList->list.count; i++) {
eNB_mac_inst[Mod_id].pmch_Config[i] = &pmch_InfoList->list.array[i]->pmch_Config_r9;
eNB_mac_inst[Mod_id].common_channels[0].pmch_Config[i] = &pmch_InfoList->list.array[i]->pmch_Config_r9;
LOG_I(MAC, "[CONFIG] PMCH[%d]: This PMCH stop at subframe %ldth\n", i,
eNB_mac_inst[Mod_id].pmch_Config[i]->sf_AllocEnd_r9);
eNB_mac_inst[Mod_id].common_channels[0].pmch_Config[i]->sf_AllocEnd_r9);
LOG_I(MAC, "[CONFIG] PMCH[%d]: mch_Scheduling_Period = %ld\n", i,
eNB_mac_inst[Mod_id].pmch_Config[i]->mch_SchedulingPeriod_r9);
eNB_mac_inst[Mod_id].common_channels[0].pmch_Config[i]->mch_SchedulingPeriod_r9);
LOG_I(MAC, "[CONFIG] PMCH[%d]: dataMCS = %ld\n", i,
eNB_mac_inst[Mod_id].pmch_Config[i]->dataMCS_r9);
eNB_mac_inst[Mod_id].common_channels[0].pmch_Config[i]->dataMCS_r9);
// MBMS session info list in each MCH
eNB_mac_inst[Mod_id].mbms_SessionList[i] = &pmch_InfoList->list.array[i]->mbms_SessionInfoList_r9;
eNB_mac_inst[Mod_id].common_channels[0].mbms_SessionList[i] = &pmch_InfoList->list.array[i]->mbms_SessionInfoList_r9;
LOG_I(MAC, "PMCH[%d] Number of session (MTCH) is: %d\n",i, eNB_mac_inst[Mod_id].mbms_SessionList[i]->list.count);
}
}
......
......@@ -64,6 +64,7 @@
#include "MBSFN-AreaInfoList-r9.h"
#include "MBSFN-SubframeConfigList.h"
#include "PMCH-InfoList-r9.h"
#include "SCellToAddMod-r10.h"
#endif
//#ifdef PHY_EMUL
......@@ -620,14 +621,28 @@ typedef struct{
}SBMAP_CONF;
//end ALU's algo
typedef struct{
DLSCH_PDU DLSCH_pdu[MAX_NUM_CCs][2][NUMBER_OF_UE_MAX];
/// DCI template and MAC connection parameters for UEs
UE_TEMPLATE UE_template[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
/// DCI template and MAC connection for RA processes
int pCC_id[NUMBER_OF_UE_MAX];
int ordered_CCids[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
int numactiveCCs[NUMBER_OF_UE_MAX];
int ordered_ULCCids[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
int numactiveULCCs[NUMBER_OF_UE_MAX];
/// eNB to UE statistics
eNB_UE_STATS eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
UE_sched_ctrl UE_sched_ctrl[NUMBER_OF_UE_MAX];
int next[NUMBER_OF_UE_MAX];
int head;
int avail;
int num_UEs;
boolean_t active[NUMBER_OF_UE_MAX];
} UE_list_t;
typedef struct{
///
uint16_t Node_id;
/// frame counter
frame_t frame;
/// subframe counter
sub_frame_t subframe;
/// Outgoing DCI for PHY generated by eNB scheduler
DCI_PDU DCI_pdu;
/// Outgoing BCCH pdu for PHY
......@@ -636,11 +651,6 @@ typedef struct{
uint32_t BCCH_alloc_pdu;
/// Outgoing CCCH pdu for PHY
CCCH_PDU CCCH_pdu;
/// Outgoing DLSCH pdu for PHY
DLSCH_PDU DLSCH_pdu[NUMBER_OF_UE_MAX+1][2];
/// DCI template and MAC connection parameters for UEs
UE_TEMPLATE UE_template[NUMBER_OF_UE_MAX];
/// DCI template and MAC connection for RA processes
RA_TEMPLATE RA_template[NB_RA_PROC_MAX];
/// BCCH active flag
uint8_t bcch_active;
......@@ -674,16 +684,25 @@ typedef struct{
uint8_t num_active_cba_groups;
uint16_t cba_rnti[NUM_MAX_CBA_GROUP];
#endif
}COMMON_channels_t;
typedef struct{
///
uint16_t Node_id;
/// frame counter
frame_t frame;
/// subframe counter
sub_frame_t subframe;
/// Common cell resources
COMMON_channels_t common_channels[MAX_NUM_CCs];
UE_list_t UE_list;
///subband bitmap configuration
SBMAP_CONF sbmap_conf;
/// active flag for Other lcid
uint8_t lcid_active[NB_RB_MAX];
// uint8_t lcid_active[NB_RB_MAX];
// eNB stats
eNB_STATS eNB_stats;
/// eNB to UE statistics
eNB_UE_STATS eNB_UE_stats[NUMBER_OF_UE_MAX];
UE_sched_ctrl UE_sched_ctrl[NUMBER_OF_UE_MAX];
// MAC function execution peformance profiler
time_stats_t eNB_scheduler;
time_stats_t schedule_si;
......@@ -766,6 +785,10 @@ typedef struct{
struct RACH_ConfigDedicated *rach_ConfigDedicated;
/// pointer to RRC PHY configuration
struct PhysicalConfigDedicated *physicalConfigDedicated;
#ifdef Rel10
/// pointer to RRC PHY configuration SCEll
struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10;
#endif
/// pointer to TDD Configuration (NULL for FDD)
TDD_Config_t *tdd_Config;
/// Number of adjacent cells to measure
......@@ -912,6 +935,10 @@ int rrc_mac_config_req(module_id_t module_idP,
uint8_t eNB_index,
RadioResourceConfigCommonSIB_t *radioResourceConfigCommon,
struct PhysicalConfigDedicated *physicalConfigDedicated,
#ifdef Rel10
SCellToAddMod_r10_t *sCellToAddMod_r10,
//struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10,
#endif
MeasObjectToAddMod_t **measObj,
MAC_MainConfig_t *mac_MainConfig,
long logicalChannelIdentity,
......
......@@ -83,10 +83,10 @@
void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, frame_t frameP, sub_frame_t subframeP) {//, int calibration_flag) {
start_meas(&eNB_mac_inst[module_idP].eNB_scheduler);
unsigned char nprb=0;
unsigned int nCCE=0;
int mbsfn_status=0;
uint32_t RBalloc=0;
unsigned int nprb[MAX_NUM_CCs];
unsigned int nCCE[MAX_NUM_CCs];
int mbsfn_status[MAX_NUM_CCs];
uint32_t RBalloc[MAX_NUM_CCs];
#ifdef EXMIMO
int ret;
#endif
......@@ -96,12 +96,22 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
instance_t instance;
int result;
#endif
DCI_PDU *DCI_pdu[MAX_NUM_CCs];
int CC_id;
DCI_PDU *DCI_pdu= &eNB_mac_inst[module_idP].DCI_pdu;
LOG_D(MAC,"[eNB %d] Frame %d, Subframe %d, entering MAC scheduler\n",module_idP, frameP, subframeP);
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,1);
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
DCI_pdu[CC_id] = &eNB_mac_inst[module_idP].common_channels[CC_id].DCI_pdu;
nCCE[CC_id]=0;
nprb[CC_id]=0;
RBalloc[CC_id]=0;
mbsfn_status[CC_id]=0;
}
#if defined(ENABLE_ITTI)
do {
// Checks if a message has been sent to MAC sub-task
......@@ -154,16 +164,18 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
#endif
// clear DCI and BCCH contents before scheduling
DCI_pdu->Num_common_dci = 0;
DCI_pdu->Num_ue_spec_dci = 0;
eNB_mac_inst[module_idP].bcch_active = 0;
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
DCI_pdu[CC_id]->Num_common_dci = 0;
DCI_pdu[CC_id]->Num_ue_spec_dci = 0;
eNB_mac_inst[module_idP].common_channels[CC_id].bcch_active = 0;
#ifdef Rel10
eNB_mac_inst[module_idP].mcch_active =0;
eNB_mac_inst[module_idP].common_channels.mcch_active =0;
#endif
eNB_mac_inst[module_idP].frame = frameP;
eNB_mac_inst[module_idP].subframe = subframeP;
}
//if (subframeP%5 == 0)
#ifdef EXMIMO
......@@ -180,10 +192,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
#endif
#ifdef Rel10
if (eNB_mac_inst[module_idP].MBMS_flag >0) {
start_meas(&eNB_mac_inst[module_idP].schedule_mch);
mbsfn_status = schedule_MBMS(module_idP,frameP,subframeP);
stop_meas(&eNB_mac_inst[module_idP].schedule_mch);
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
if (eNB_mac_inst[module_idP].common_channels.MBMS_flag >0) {
start_meas(&eNB_mac_inst[module_idP].common_channels.schedule_mch);
mbsfn_status = schedule_MBMS(module_idP,CC_id,frameP,subframeP);
stop_meas(&eNB_mac_inst[module_idP][CC-id].schedule_mch);
}
}
#endif
......@@ -193,18 +207,18 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
// Schedule ULSCH for FDD or subframeP 4 (TDD config 0,3,6)
// Schedule Normal DLSCH
schedule_RA(module_idP,frameP,subframeP,2,&nprb,&nCCE);
schedule_RA(module_idP,frameP,subframeP,2,nprb,nCCE);
if (mac_xface->lte_frame_parms->frame_type == FDD) { //FDD
schedule_ulsch(module_idP,frameP,cooperation_flag,0,4,&nCCE);//,calibration_flag);
schedule_ulsch(module_idP,frameP,cooperation_flag,0,4,nCCE);//,calibration_flag);
}
else if ((mac_xface->lte_frame_parms->tdd_config == TDD) || //TDD
(mac_xface->lte_frame_parms->tdd_config == 3) ||
(mac_xface->lte_frame_parms->tdd_config == 6))
//schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4,&nCCE);//,calibration_flag);
//schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4,nCCE);//,calibration_flag);
// schedule_ue_spec(module_idP,subframeP,nprb,&nCCE,mbsfn_status);
// schedule_ue_spec(module_idP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status);
break;
......@@ -216,11 +230,11 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
switch (mac_xface->lte_frame_parms->tdd_config) {
case 0:
case 1:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7,&nCCE);
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7,nCCE);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
case 6:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8,&nCCE);
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8,nCCE);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
default:
......@@ -228,8 +242,8 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
}
}
else { //FDD
schedule_ulsch(module_idP,frameP,cooperation_flag,1,5,&nCCE);
// schedule_ue_spec(module_idP,subframeP,nprb,&nCCE,mbsfn_status);
schedule_ulsch(module_idP,frameP,cooperation_flag,1,5,nCCE);
// schedule_ue_spec(module_idP,subframeP,nprb,nCCE,mbsfn_status);
// fill_DLSCH_dci(module_idP,subframeP,RBalloc,0,mbsfn_status);
}
break;
......@@ -238,8 +252,8 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
// TDD, nothing
// FDD, normal UL/DLSCH
if (mac_xface->lte_frame_parms->frame_type == FDD) { //FDD
schedule_ulsch(module_idP,frameP,cooperation_flag,2,6,&nCCE);
// schedule_ue_spec(module_idP,subframeP,nprb,&nCCE,mbsfn_status);
schedule_ulsch(module_idP,frameP,cooperation_flag,2,6,nCCE);
// schedule_ue_spec(module_idP,subframeP,nprb,nCCE,mbsfn_status);
// fill_DLSCH_dci(module_idP,subframeP,RBalloc,0,mbsfn_status);
}
break;
......@@ -251,9 +265,9 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
if (mac_xface->lte_frame_parms->frame_type == TDD) {
switch (mac_xface->lte_frame_parms->tdd_config) {
case 2:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7,&nCCE);
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7,nCCE);
case 5:
schedule_ue_spec(module_idP,frameP,subframeP,nprb,&nCCE,mbsfn_status);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
default:
......@@ -261,7 +275,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
}
}
else { //FDD
// schedule_ulsch(module_idP,frameP,cooperation_flag,3,7,&nCCE);
// schedule_ulsch(module_idP,frameP,cooperation_flag,3,7,nCCE);
// schedule_ue_spec(module_idP,subframeP,0,0,mbsfn_status);
// fill_DLSCH_dci(module_idP,subframeP,RBalloc,0,mbsfn_status);
}
......@@ -274,12 +288,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
if (mac_xface->lte_frame_parms->frame_type == 1) { // TDD
switch (mac_xface->lte_frame_parms->tdd_config) {
case 1:
// schedule_RA(module_idP,frameP,subframeP,&nprb,&nCCE);
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8,&nCCE);
// schedule_RA(module_idP,frameP,subframeP,nprb,nCCE);
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8,nCCE);
case 2:
case 4:
case 5:
schedule_ue_spec(module_idP,frameP,subframeP,nprb,&nCCE,mbsfn_status);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status);
break;
default:
......@@ -288,9 +302,9 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
}
else {
if (mac_xface->lte_frame_parms->frame_type == FDD) { //FDD
schedule_RA(module_idP, frameP, subframeP, 0, &nprb, &nCCE);
// schedule_ulsch(module_idP, frameP, cooperation_flag, 4, 8, &nCCE);
//schedule_ue_spec(module_idP, frameP, subframeP, nprb, &nCCE, mbsfn_status);
schedule_RA(module_idP,frameP, subframeP, 0, nprb, nCCE);
// schedule_ulsch(module_idP, frameP, cooperation_flag, 4, 8, nCCE);
//schedule_ue_spec(module_idP, frameP, subframeP, nprb, nCCE, mbsfn_status);
fill_DLSCH_dci(module_idP, frameP, subframeP, RBalloc, 1, mbsfn_status);
}
......@@ -302,21 +316,21 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
// TDD Config 0,6 ULSCH for subframes 9,3 resp.
// TDD normal DLSCH
// FDD normal UL/DLSCH
schedule_SI(module_idP,frameP,&nprb,&nCCE);
//schedule_RA(module_idP,frameP,subframeP,5,&nprb,&nCCE);
schedule_SI(module_idP,frameP,nprb,nCCE);
//schedule_RA(module_idP,frameP,subframeP,5,nprb,nCCE);
if ((mac_xface->lte_frame_parms->frame_type == FDD) ) {
// schedule_RA(module_idP,frameP,subframeP,1,&nprb,&nCCE);
// schedule_ulsch(module_idP,frameP,cooperation_flag,5,9,&nCCE);
// schedule_RA(module_idP,frameP,subframeP,1,nprb,nCCE);
// schedule_ulsch(module_idP,frameP,cooperation_flag,5,9,nCCE);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
}
else if ((mac_xface->lte_frame_parms->tdd_config == 0) || // TDD Config 0
(mac_xface->lte_frame_parms->tdd_config == 6)) { // TDD Config 6
//schedule_ulsch(module_idP,cooperation_flag,subframeP,&nCCE);
//schedule_ulsch(module_idP,cooperation_flag,subframeP,nCCE);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
}
else {
//schedule_ue_spec(module_idP,subframeP,nprb,&nCCE,mbsfn_status);
//schedule_ue_spec(module_idP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
}
break;
......@@ -330,23 +344,23 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
case 0:
break;
case 1:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2,&nCCE);
// schedule_ue_spec(module_idP,frameP,subframeP,nprb,&nCCE,mbsfn_status);
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2,nCCE);
// schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
case 6:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,&nCCE);
// schedule_ue_spec(module_idP,frameP,subframeP,nprb,&nCCE,mbsfn_status);
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,nCCE);
// schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
case 5:
schedule_RA(module_idP,frameP,subframeP,2,&nprb,&nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,&nCCE,mbsfn_status);
schedule_RA(module_idP,frameP,subframeP,2,nprb,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status);
break;
case 3:
case 4:
schedule_ue_spec(module_idP,frameP,subframeP,nprb,&nCCE,mbsfn_status);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
......@@ -355,8 +369,8 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
}
}
else { //FDD
// schedule_ulsch(module_idP,frameP,cooperation_flag,6,0,&nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,&nCCE,mbsfn_status);
// schedule_ulsch(module_idP,frameP,cooperation_flag,6,0,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
}
break;
......@@ -368,12 +382,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
switch (mac_xface->lte_frame_parms->tdd_config) {
case 3:
case 4:
// schedule_RA(module_idP,frameP,subframeP,3,&nprb,&nCCE); // 3 = Msg3 subframeP, not
schedule_ue_spec(module_idP,frameP,subframeP,nprb,&nCCE,mbsfn_status);
// schedule_RA(module_idP,frameP,subframeP,3,nprb,nCCE); // 3 = Msg3 subframeP, not
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); //1,mbsfn_status);
break;
case 5:
schedule_ue_spec(module_idP,frameP,subframeP,nprb,&nCCE,mbsfn_status);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
default:
......@@ -381,8 +395,8 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
}
}
else { //FDD
// schedule_ulsch(module_idP,frameP,cooperation_flag,7,1,&nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,&nCCE,mbsfn_status);
// schedule_ulsch(module_idP,frameP,cooperation_flag,7,1,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
}
break;
......@@ -398,9 +412,9 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
case 4:
case 5:
// schedule_RA(module_idP,subframeP,&nprb,&nCCE);
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2,&nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,0,&nCCE,mbsfn_status);
// schedule_RA(module_idP,subframeP,nprb,nCCE);
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
default:
......@@ -408,8 +422,8 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
}
}
else { //FDD
// schedule_ulsch(module_idP,frameP,cooperation_flag,8,2,&nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,0,&nCCE,mbsfn_status);
// schedule_ulsch(module_idP,frameP,cooperation_flag,8,2,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
}
break;
......@@ -419,27 +433,27 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
if (mac_xface->lte_frame_parms->frame_type == TDD) {
switch (mac_xface->lte_frame_parms->tdd_config) {
case 1:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,&nCCE);
schedule_RA(module_idP,frameP,subframeP,7,&nprb,&nCCE); // 7 = Msg3 subframeP, not
schedule_ue_spec(module_idP,frameP,subframeP,0,&nCCE,mbsfn_status);
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,nCCE);
schedule_RA(module_idP,frameP,subframeP,7,nprb,nCCE); // 7 = Msg3 subframeP, not
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status);
break;
case 3:
case 4:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,&nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,0,&nCCE,mbsfn_status);
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
case 6:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4,&nCCE);
//schedule_RA(module_idP,frameP,subframeP,&nprb,&nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,0,&nCCE,mbsfn_status);
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4,nCCE);
//schedule_RA(module_idP,frameP,subframeP,nprb,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
case 2:
case 5:
//schedule_RA(module_idP,frameP,subframeP,&nprb,&nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,0,&nCCE,mbsfn_status);
//schedule_RA(module_idP,frameP,subframeP,nprb,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
break;
default:
......@@ -447,16 +461,17 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
}
}
else { //FDD
// schedule_ulsch(module_idP,frameP,cooperation_flag,9,3,&nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,0,&nCCE,mbsfn_status);
// schedule_ulsch(module_idP,frameP,cooperation_flag,9,3,nCCE);
schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
}
break;
}
DCI_pdu->nCCE = nCCE;
LOG_D(MAC,"frameP %d, subframeP %d nCCE %d\n",frameP,subframeP,nCCE);
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++)
DCI_pdu[CC_id]->nCCE = nCCE[CC_id];
LOG_D(MAC,"frameP %d, subframeP %d nCCE %d\n",frameP,subframeP,nCCE[0]);
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,0);
stop_meas(&eNB_mac_inst[module_idP].eNB_scheduler);
......
/*******************************************************************************
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,23 +70,31 @@
#define DEBUG_eNB_SCHEDULER 1
void schedule_SI(module_id_t module_idP,frame_t frameP, unsigned char *nprb,unsigned int *nCCE) {
void schedule_SI(module_id_t module_idP,frame_t frameP, unsigned int *nprbP,unsigned int *nCCEP) {
start_meas(&eNB_mac_inst[module_idP].schedule_si);
unsigned char bcch_sdu_length;
int mcs = -1;
void *BCCH_alloc_pdu=(void*)&eNB_mac_inst[module_idP].BCCH_alloc_pdu;
void *BCCH_alloc_pdu;
int CC_id;
eNB_MAC_INST *eNB = &eNB_mac_inst[module_idP];
start_meas(&eNB->schedule_si);
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
BCCH_alloc_pdu=(void*)&eNB->common_channels[CC_id].BCCH_alloc_pdu;
bcch_sdu_length = mac_rrc_data_req(module_idP,
frameP,
BCCH,1,
&eNB_mac_inst[module_idP].BCCH_pdu.payload[0],
&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, Received %d bytes \n",module_idP,frameP,bcch_sdu_length);
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)))
......@@ -108,8 +116,8 @@ void schedule_SI(module_id_t module_idP,frame_t frameP, unsigned char *nprb,unsi
else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(8,3)))
mcs=8;
if (mac_xface->lte_frame_parms->frame_type == TDD) {
switch (mac_xface->lte_frame_parms->N_RB_DL) {
if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) {
switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) {
case 6:
((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs;
break;
......@@ -126,7 +134,7 @@ void schedule_SI(module_id_t module_idP,frame_t frameP, unsigned char *nprb,unsi
}
}
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:
((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs;
break;
......@@ -146,12 +154,12 @@ void schedule_SI(module_id_t module_idP,frame_t frameP, unsigned char *nprb,unsi
#if defined(USER_MODE) && defined(OAI_EMU)
if (oai_emulation.info.opt_enabled) {
trace_pdu(1,
&eNB_mac_inst[module_idP].BCCH_pdu.payload[0],
&eNB->common_channels[CC_id].BCCH_pdu.payload[0],
bcch_sdu_length,
0xffff,
4,
0xffff,
eNB_mac_inst[module_idP].subframe,
eNB->subframe,
0,
0);
}
......@@ -159,7 +167,7 @@ void schedule_SI(module_id_t module_idP,frame_t frameP, unsigned char *nprb,unsi
module_idP, frameP, 0xffff, bcch_sdu_length);
#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",
frameP,
bcch_sdu_length,
......@@ -173,17 +181,18 @@ void schedule_SI(module_id_t module_idP,frame_t frameP, unsigned char *nprb,unsi
mcs,
mac_xface->get_TBS_DL(mcs,3));
}
eNB_mac_inst[module_idP].bcch_active=1;
*nprb=3;
*nCCE=4;
eNB->common_channels[CC_id].bcch_active=1;
nprbP[CC_id]=3;
nCCEP[CC_id]=4;
}
else {
eNB_mac_inst[module_idP].bcch_active=0;
*nprb=0;
*nCCE=0;
eNB->common_channels[CC_id].bcch_active=0;
nprbP[CC_id]=0;
nCCEP[CC_id]=0;
//LOG_D(MAC,"[eNB %d] Frame %d : BCCH not active \n",Mod_id,frame);
}
}
// this might be misleading when bcch is inactive
stop_meas(&eNB_mac_inst[module_idP].schedule_si);
stop_meas(&eNB->schedule_si);
return;
}
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){
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) {
if (eNB_mac_inst[module_idP].UE_template[ue_mod_id].rnti==rnti) {
return(ue_mod_id);
for (UE_id=UE_list->head;UE_id>=0;UE_id=UE_list->next[UE_id]){
if (UE_list->UE_template[UE_PCCID(mod_idP,UE_id)][UE_id].rnti==rntiP) {
return(UE_id);
}
}
return(module_id_t)(-1);
return(-1);
}
int UE_num_active_CC(UE_list_t *listP,int ue_idP) {
return(listP->numactiveCCs[ue_idP]);
}
int UE_PCCID(module_id_t mod_idP,int ue_idP) {
return(eNB_mac_inst[mod_idP].UE_list.pCC_id[ue_idP]);
}
rnti_t find_UE_RNTI(module_id_t module_idP, module_id_t ue_mod_idP) {
rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP) {
return (eNB_mac_inst[module_idP].UE_template[ue_mod_idP].rnti);
rnti_t rnti = eNB_mac_inst[mod_idP].UE_list.UE_template[UE_PCCID(mod_idP,ue_idP)][ue_idP].rnti;
if (rnti>0)
return (rnti);
LOG_E(MAC,"[eNB %d] Couldn't find RNTI for UE %d\n",mod_idP,ue_idP);
mac_xface->macphy_exit("");
return(0);
}
boolean_t is_UE_active(module_id_t module_idP, module_id_t ue_mod_idP ){
if (eNB_mac_inst[module_idP].UE_template[ue_mod_idP].rnti !=0 )
return TRUE;
else
return FALSE ;
boolean_t is_UE_active(module_id_t mod_idP, int ue_idP){
return(eNB_mac_inst[mod_idP].UE_list.active[ue_idP]);
}
uint8_t find_active_UEs(module_id_t module_idP){
/*
uint8_t find_active_UEs(module_id_t module_idP,int CC_id){
module_id_t ue_mod_id = 0;
rnti_t rnti = 0;
......@@ -137,43 +148,43 @@ uint8_t find_active_UEs(module_id_t module_idP){
for (ue_mod_id=0;ue_mod_id<NUMBER_OF_UE_MAX;ue_mod_id++) {
if (((rnti=eNB_mac_inst[module_idP].UE_template[ue_mod_id].rnti) !=0)&&(eNB_mac_inst[module_idP].UE_template[ue_mod_id].ul_active==TRUE)){
if (((rnti=eNB_mac_inst[module_idP][CC_id].UE_template[ue_mod_id].rnti) !=0)&&(eNB_mac_inst[module_idP][CC_id].UE_template[ue_mod_id].ul_active==TRUE)){
if (mac_xface->get_eNB_UE_stats(module_idP,rnti) != NULL){ // check at the phy enb_ue state for this rnti
nb_active_ue++;
}
else { // this ue is removed at the phy => remove it at the mac as well
mac_remove_ue(module_idP, ue_mod_id);
mac_remove_ue(module_idP, CC_id, ue_mod_id);
}
}
}
return(nb_active_ue);
}
*/
// get aggregatiob form phy for a give UE
unsigned char process_ue_cqi (module_id_t module_idP, module_id_t ue_mod_idP) {
unsigned char process_ue_cqi (module_id_t module_idP, int ue_idP) {
unsigned char aggregation=2;
// check the MCS and SNR and set the aggregation accordingly
return aggregation;
}
#ifdef CBA
uint8_t find_num_active_UEs_in_cbagroup(module_id_t module_idP, unsigned char group_id){
uint8_t find_num_active_UEs_in_cbagroup(module_id_t module_idP, int CC_id,unsigned char group_id){
module_id_t UE_id;
rnti_t rnti;
unsigned char nb_ue_in_pusch=0;
LTE_eNB_UE_stats* eNB_UE_stats;
for (UE_id=group_id;UE_id<NUMBER_OF_UE_MAX;UE_id+=eNB_mac_inst[module_idP].num_active_cba_groups) {
for (UE_id=group_id;UE_id<NUMBER_OF_UE_MAX;UE_id+=eNB_mac_inst[module_idP][CC_id].num_active_cba_groups) {
if (((rnti=eNB_mac_inst[module_idP].UE_template[UE_id].rnti) !=0) &&
(eNB_mac_inst[module_idP].UE_template[UE_id].ul_active==TRUE) &&
if (((rnti=eNB_mac_inst[module_idP][CC_id].UE_template[UE_id].rnti) !=0) &&
(eNB_mac_inst[module_idP][CC_id].UE_template[UE_id].ul_active==TRUE) &&
(mac_get_rrc_status(module_idP,1,UE_id) > RRC_CONNECTED)){
// && (UE_is_to_be_scheduled(module_idP,UE_id)))
// check at the phy enb_ue state for this rnti
if ((eNB_UE_stats= mac_xface->get_eNB_UE_stats(module_idP,rnti)) != NULL){
if ((eNB_UE_stats= mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti)) != NULL){
if ((eNB_UE_stats->mode == PUSCH) && (UE_is_to_be_scheduled(module_idP,UE_id) == 0)){
nb_ue_in_pusch++;
}
......@@ -183,64 +194,143 @@ uint8_t find_num_active_UEs_in_cbagroup(module_id_t module_idP, unsigned char gr
return(nb_ue_in_pusch);
}
#endif
int8_t add_new_ue(module_id_t enb_mod_idP, rnti_t rntiP) {
module_id_t ue_mod_id;
int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP) {
int UE_id;
int j;
for (ue_mod_id=0;ue_mod_id<NUMBER_OF_UE_MAX;ue_mod_id++) {
if (eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].rnti == 0) {
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].rnti = rntiP;
UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list;
LOG_D(MAC,"[eNB %d, CC_id %d] Adding UE with rnti %x (next avail %d, num_UEs %d)\n",mod_idP,cc_idP,rntiP,UE_list->avail,UE_list->num_UEs);
if (UE_list->avail>=0) {
UE_id = UE_list->avail;
UE_list->avail = UE_list->next[UE_list->avail];
UE_list->next[UE_id] = UE_list->head;
UE_list->head = UE_id;
UE_list->UE_template[cc_idP][UE_id].rnti = rntiP;
UE_list->numactiveCCs[UE_id] = 1;
UE_list->numactiveULCCs[UE_id] = 1;
UE_list->pCC_id[UE_id] = cc_idP;
UE_list->ordered_CCids[0][UE_id] = cc_idP;
UE_list->ordered_ULCCids[0][UE_id] = cc_idP;
UE_list->num_UEs++;
UE_list->active[UE_id] = TRUE;
for (j=0;j<8;j++) {
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].oldNDI[j] = 0;
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].oldNDI_UL[j] = 0;
}
eNB_ulsch_info[enb_mod_idP][ue_mod_id].status = S_UL_WAITING;
eNB_dlsch_info[enb_mod_idP][ue_mod_id].status = S_UL_WAITING;
LOG_D(MAC,"[eNB] Add UE_id %d : rnti %x\n",ue_mod_id,eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].rnti);
return((int8_t)ue_mod_id);
UE_list->UE_template[cc_idP][UE_id].oldNDI[j] = 0;
UE_list->UE_template[cc_idP][UE_id].oldNDI_UL[j] = 0;
}
eNB_ulsch_info[mod_idP][UE_id].status = S_UL_WAITING;
eNB_dlsch_info[mod_idP][UE_id].status = S_UL_WAITING;
LOG_D(MAC,"[eNB %d] Add UE_id %d on Primary CC_id %d: rnti %x\n",mod_idP,UE_id,cc_idP,rntiP);
return(UE_id);
}
return(-1);
}
int8_t mac_remove_ue(module_id_t enb_mod_idP, module_id_t ue_mod_idP) {
int mac_remove_ue(module_id_t mod_idP, int ue_idP) {
LOG_I(MAC,"Removing UE %d (rnti %x)\n",ue_mod_idP,eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].rnti);
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 from Primary CC_id %d (rnti %x)\n",ue_idP,pCC_id, UE_list->UE_template[pCC_id][ue_idP].rnti);
// clear all remaining pending transmissions
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].bsr_info[LCGID0] = 0;
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].bsr_info[LCGID1] = 0;
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].bsr_info[LCGID2] = 0;
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].bsr_info[LCGID3] = 0;
UE_list->UE_template[pCC_id][ue_idP].bsr_info[LCGID0] = 0;
UE_list->UE_template[pCC_id][ue_idP].bsr_info[LCGID1] = 0;
UE_list->UE_template[pCC_id][ue_idP].bsr_info[LCGID2] = 0;
UE_list->UE_template[pCC_id][ue_idP].bsr_info[LCGID3] = 0;
UE_list->UE_template[pCC_id][ue_idP].ul_SR = 0;
UE_list->UE_template[pCC_id][ue_idP].rnti = 0;
UE_list->UE_template[pCC_id][ue_idP].ul_active = FALSE;
eNB_ulsch_info[mod_idP][ue_idP].rnti = 0;
eNB_ulsch_info[mod_idP][ue_idP].status = S_UL_NONE;
eNB_dlsch_info[mod_idP][ue_idP].rnti = 0;
eNB_dlsch_info[mod_idP][ue_idP].status = S_DL_NONE;
rrc_eNB_free_UE_index(mod_idP,ue_idP);
prev = UE_list->head;
for (i=UE_list->head;i>=0;i=UE_list->next[i]) {
if (i == ue_idP) {
// link prev to next in Active list
if (prev==UE_list->head)
UE_list->head = UE_list->next[i];
else
UE_list->next[prev] = UE_list->next[i];
// add UE id (i)to available
UE_list->next[i] = UE_list->avail;
UE_list->avail = i;
UE_list->active[i] = FALSE;
return(0);
}
prev=i;
}
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].ul_SR = 0;
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].rnti = 0;
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].ul_active = FALSE;
eNB_ulsch_info[enb_mod_idP][ue_mod_idP].rnti = 0;
eNB_ulsch_info[enb_mod_idP][ue_mod_idP].status = S_UL_NONE;
eNB_dlsch_info[enb_mod_idP][ue_mod_idP].rnti = 0;
eNB_dlsch_info[enb_mod_idP][ue_mod_idP].status = S_DL_NONE;
UE_list->num_UEs--;
rrc_eNB_free_UE_index(enb_mod_idP,ue_mod_idP);
return(-1);
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 swap_UEs(UE_list_t *listP,int nodeiP, int nodejP) {
int prev_i,prev_j,next_i;
prev_i = prev(listP,nodeiP);
prev_j = prev(listP,nodejP);
next_i = listP->next[nodeiP];
listP->next[nodeiP] = listP->next[nodejP];
listP->next[nodejP] = next_i;
if (nodeiP==listP->head) {
listP->head=nodejP;
}
else {
listP->next[prev_i] = nodejP;
}
if (nodejP==listP->head) {
listP->head=nodeiP;
}
else {
listP->next[prev_j] = nodeiP;
}
}
void SR_indication(module_id_t enb_mod_idP, frame_t frameP, rnti_t rntiP, sub_frame_t subframeP) {
void SR_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, rnti_t rntiP, sub_frame_t subframeP) {
module_id_t ue_mod_id = find_UE_id(enb_mod_idP, rntiP);
int UE_id = find_UE_id(mod_idP, rntiP);
UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list;
if (ue_mod_id != UE_INDEX_INVALID ) {
LOG_D(MAC,"[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d \n",enb_mod_idP,rntiP,frameP,subframeP, ue_mod_id);
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].ul_SR = 1;
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].ul_active = TRUE;
if (UE_id != UE_INDEX_INVALID ) {
LOG_D(MAC,"[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d on CC_id %d\n",mod_idP,rntiP,frameP,subframeP, UE_id,cc_idP);
UE_list->UE_template[cc_idP][UE_id].ul_SR = 1;
UE_list->UE_template[cc_idP][UE_id].ul_active = TRUE;
} else {
// AssertFatal(0, "find_UE_id(%u,rnti %d) not found", enb_mod_idP, rntiP);
// AssertError(0, 0, "Frame %d: find_UE_id(%u,rnti %d) not found\n", frameP, enb_mod_idP, rntiP);
LOG_D(MAC,"[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d (unknown UEid) \n",enb_mod_idP,rntiP,frameP,subframeP, ue_mod_id);
LOG_D(MAC,"[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d (unknown UEid) \n",mod_idP,rntiP,frameP,subframeP, UE_id);
}
}
......@@ -397,17 +487,18 @@ void add_ue_spec_dci(DCI_PDU *DCI_pdu,void *pdu,rnti_t rnti,unsigned char dci_si
// This has to be updated to include BSR information
uint8_t UE_is_to_be_scheduled(module_id_t module_idP,uint8_t UE_id) {
uint8_t UE_is_to_be_scheduled(module_id_t module_idP,int CC_id,uint8_t UE_id) {
UE_TEMPLATE *UE_template = &eNB_mac_inst[module_idP].UE_list.UE_template[CC_id][UE_id];
// LOG_D(MAC,"[eNB %d][PUSCH] Frame %d subframeP %d Scheduling UE %d\n",module_idP,rnti,frameP,subframeP,
// UE_id);
if ((eNB_mac_inst[module_idP].UE_template[UE_id].bsr_info[LCGID0]>0) ||
(eNB_mac_inst[module_idP].UE_template[UE_id].bsr_info[LCGID1]>0) ||
(eNB_mac_inst[module_idP].UE_template[UE_id].bsr_info[LCGID2]>0) ||
(eNB_mac_inst[module_idP].UE_template[UE_id].bsr_info[LCGID3]>0) ||
(eNB_mac_inst[module_idP].UE_template[UE_id].ul_SR>0)) // uplink scheduling request
if ((UE_template->bsr_info[LCGID0]>0) ||
(UE_template->bsr_info[LCGID1]>0) ||
(UE_template->bsr_info[LCGID2]>0) ||
(UE_template->bsr_info[LCGID3]>0) ||
(UE_template->ul_SR>0)) // uplink scheduling request
return(1);
else
return(0);
......@@ -416,7 +507,7 @@ uint8_t UE_is_to_be_scheduled(module_id_t module_idP,uint8_t UE_id) {
uint32_t allocate_prbs(module_id_t ue_mod_idP,unsigned char nb_rb, uint32_t *rballoc) {
uint32_t allocate_prbs(int UE_id,unsigned char nb_rb, uint32_t *rballoc) {
int i;
uint32_t rballoc_dci=0;
......@@ -487,9 +578,9 @@ uint32_t allocate_prbs_sub(int nb_rb, uint8_t *rballoc) {
void update_ul_dci(module_id_t module_idP,rnti_t rnti,uint8_t dai) {
void update_ul_dci(module_id_t module_idP,int CC_id,rnti_t rnti,uint8_t dai) {
DCI_PDU *DCI_pdu = &eNB_mac_inst[module_idP].DCI_pdu;
DCI_PDU *DCI_pdu = &eNB_mac_inst[module_idP].common_channels[CC_id].DCI_pdu;
int i;
DCI0_5MHz_TDD_1_6_t *ULSCH_dci = NULL;;
......
......@@ -73,6 +73,197 @@
// This table holds the allowable PRB sizes for ULSCH transmissions
uint8_t rb_table[33] = {1,2,3,4,5,6,8,9,10,12,15,16,18,20,24,25,27,30,32,36,40,45,48,50,54,60,72,75,80,81,90,96,100};
void rx_sdu(module_id_t enb_mod_idP,int CC_id,frame_t frameP,rnti_t rntiP,uint8_t *sdu, uint16_t sdu_len) {
unsigned char rx_ces[MAX_NUM_CE],num_ce,num_sdu,i,*payload_ptr;
unsigned char rx_lcids[NB_RB_MAX];
unsigned short rx_lengths[NB_RB_MAX];
int UE_id = find_UE_id(enb_mod_idP,rntiP);
int ii,j;
eNB_MAC_INST *eNB = &eNB_mac_inst[enb_mod_idP];
UE_list_t *UE_list= &eNB->UE_list;
start_meas(&eNB->rx_ulsch_sdu);
if ((UE_id > NUMBER_OF_UE_MAX) || (UE_id == -1) )
for(ii=0; ii<NB_RB_MAX; ii++) rx_lengths[ii] = 0;
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,1);
LOG_D(MAC,"[eNB %d] Received ULSCH sdu from PHY (rnti %x, UE_id %d), parsing header\n",enb_mod_idP,rntiP,UE_id);
payload_ptr = parse_ulsch_header(sdu,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,sdu_len);
// control element
for (i=0;i<num_ce;i++) {
switch (rx_ces[i]) { // implement and process BSR + CRNTI +
case POWER_HEADROOM:
if (UE_id != UE_INDEX_INVALID ){
UE_list->UE_template[CC_id][UE_id].phr_info = (payload_ptr[0] & 0x3f);// - PHR_MAPPING_OFFSET;
LOG_D(MAC, "[eNB] MAC CE_LCID %d : Received PHR PH = %d (db)\n", rx_ces[i], UE_list->UE_template[CC_id][UE_id].phr_info);
}
payload_ptr+=sizeof(POWER_HEADROOM_CMD);
break;
case CRNTI:
LOG_D(MAC, "[eNB] MAC CE_LCID %d : Received CRNTI %d \n", rx_ces[i], payload_ptr[0]);
payload_ptr+=1;
break;
case TRUNCATED_BSR:
case SHORT_BSR: {
if (UE_id != UE_INDEX_INVALID ){
uint8_t lcgid;
lcgid = (payload_ptr[0] >> 6);
LOG_D(MAC, "[eNB] MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n",
rx_ces[i], lcgid, payload_ptr[0] & 0x3f);
UE_list->UE_template[CC_id][UE_id].bsr_info[lcgid] = (payload_ptr[0] & 0x3f);
}
payload_ptr += 1;//sizeof(SHORT_BSR); // fixme
} break;
case LONG_BSR:
if (UE_id != UE_INDEX_INVALID ){
UE_list->UE_template[CC_id][UE_id].bsr_info[LCGID0] = ((payload_ptr[0] & 0xFC) >> 2);
UE_list->UE_template[CC_id][UE_id].bsr_info[LCGID1] =
((payload_ptr[0] & 0x03) << 4) | ((payload_ptr[1] & 0xF0) >> 4);
UE_list->UE_template[CC_id][UE_id].bsr_info[LCGID2] =
((payload_ptr[1] & 0x0F) << 2) | ((payload_ptr[2] & 0xC0) >> 6);
UE_list->UE_template[CC_id][UE_id].bsr_info[LCGID3] = (payload_ptr[2] & 0x3F);
LOG_D(MAC, "[eNB] MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
"%u LCGID2 = %u LCGID3 = %u\n",
rx_ces[i],
UE_list->UE_template[CC_id][UE_id].bsr_info[LCGID0],
UE_list->UE_template[CC_id][UE_id].bsr_info[LCGID1],
UE_list->UE_template[CC_id][UE_id].bsr_info[LCGID2],
UE_list->UE_template[CC_id][UE_id].bsr_info[LCGID3]);
}
payload_ptr += 3;////sizeof(LONG_BSR);
break;
default:
LOG_E(MAC, "[eNB] Received unknown MAC header (0x%02x)\n", rx_ces[i]);
break;
}
}
for (i=0;i<num_sdu;i++) {
LOG_D(MAC,"SDU Number %d MAC Subheader SDU_LCID %d, length %d\n",i,rx_lcids[i],rx_lengths[i]);
switch (rx_lcids[i]) {
case CCCH :
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, Received CCCH: %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n",
enb_mod_idP,frameP,
payload_ptr[0],payload_ptr[1],payload_ptr[2],payload_ptr[3],payload_ptr[4], payload_ptr[5], rntiP);
for (ii=0;ii<NB_RA_PROC_MAX;ii++) {
LOG_D(MAC,"[RAPROC] Checking proc %d : rnti (%x, %x), active %d\n",ii,
eNB->common_channels[CC_id].RA_template[ii].rnti, rntiP,
eNB->common_channels[CC_id].RA_template[ii].RA_active);
if ((eNB->common_channels[CC_id].RA_template[ii].rnti==rntiP) &&
(eNB->common_channels[CC_id].RA_template[ii].RA_active==TRUE)) {
//payload_ptr = parse_ulsch_header(msg3,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,msg3_len);
if (UE_id < 0) {
memcpy(&eNB->common_channels[CC_id].RA_template[ii].cont_res_id[0],payload_ptr,6);
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d CCCH: Received RRCConnectionRequest: length %d, offset %d\n",
enb_mod_idP,frameP,rx_lengths[ii],payload_ptr-sdu);
if ((UE_id=add_new_ue(enb_mod_idP,CC_id,eNB->common_channels[CC_id].RA_template[ii].rnti)) == -1 )
mac_xface->macphy_exit("[MAC][eNB] Max user count reached\n");
else
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d Added user with rnti %x => UE %d\n",
enb_mod_idP,frameP,eNB->common_channels[CC_id].RA_template[ii].rnti,UE_id);
} else {
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d CCCH: Received RRCConnectionReestablishment from UE %d: length %d, offset %d\n",
enb_mod_idP,frameP,UE_id,rx_lengths[ii],payload_ptr-sdu);
}
if (Is_rrc_registered == 1)
mac_rrc_data_ind(enb_mod_idP,frameP,CCCH,(uint8_t *)payload_ptr,rx_lengths[ii],1,enb_mod_idP,0);
if (num_ce >0) { // handle msg3 which is not RRCConnectionRequest
// process_ra_message(msg3,num_ce,rx_lcids,rx_ces);
}
eNB->common_channels[CC_id].RA_template[ii].generate_Msg4 = 1;
eNB->common_channels[CC_id].RA_template[ii].wait_ack_Msg4 = 0;
} // if process is active
} // loop on RA processes
break;
case DCCH :
case DCCH1 :
// if(eNB_mac_inst[module_idP][CC_id].Dcch_lchan[UE_id].Active==1){
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sdu));
for (j=0;j<32;j++)
LOG_T(MAC,"%x ",payload_ptr[j]);
LOG_T(MAC,"\n");
#endif
// This check is just to make sure we didn't get a bogus SDU length, to be removed ...
if (rx_lengths[i]<CCCH_PAYLOAD_SIZE_MAX) {
LOG_D(MAC,"[eNB %d] Frame %d : ULSCH -> UL-DCCH, received %d bytes form UE %d on LCID %d(%d) \n",
enb_mod_idP,frameP, rx_lengths[i], UE_id, rx_lcids[i], rx_lcids[i]);
mac_rlc_data_ind(enb_mod_idP,UE_id, frameP,ENB_FLAG_YES,MBMS_FLAG_NO,
rx_lcids[i],
(char *)payload_ptr,
rx_lengths[i],
1,
NULL);//(unsigned int*)crc_status);
UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_rx[rx_lcids[i]]+=1;
UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_rx[rx_lcids[i]]+=rx_lengths[i];
}
// }
break;
case DTCH: // default DRB
// if(eNB_mac_inst[module_idP][CC_id].Dcch_lchan[UE_id].Active==1){
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sdu));
for (j=0;j<32;j++)
LOG_T(MAC,"%x ",payload_ptr[j]);
LOG_T(MAC,"\n");
#endif
LOG_D(MAC,"[eNB %d] Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d (%d)\n",
enb_mod_idP,frameP, rx_lengths[i], UE_id,rx_lcids[i],rx_lcids[i]);
if ((rx_lengths[i] <SCH_PAYLOAD_SIZE_MAX) && (rx_lengths[i] > 0) ) { // MAX SIZE OF transport block
mac_rlc_data_ind(enb_mod_idP,UE_id, frameP,ENB_FLAG_YES,MBMS_FLAG_NO,
DTCH,
(char *)payload_ptr,
rx_lengths[i],
1,
NULL);//(unsigned int*)crc_status);
UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_rx[rx_lcids[i]]+=1;
UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_rx[rx_lcids[i]]+=rx_lengths[i];
}
// }
break;
default : //if (rx_lcids[i] >= DTCH) {
UE_list->eNB_UE_stats[CC_id][UE_id].num_errors_rx+=1;
LOG_E(MAC,"[eNB %d] received unsupported or unknown LCID %d from UE %d ", rx_lcids[i], UE_id);
break;
}
payload_ptr+=rx_lengths[i];
}
UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes_rx+=sdu_len;
UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus_rx+=1;
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,0);
stop_meas(&eNB->rx_ulsch_sdu);
}
uint32_t bytes_to_bsr_index(int32_t nbytes) {
uint32_t i=0;
......@@ -88,45 +279,47 @@ uint32_t bytes_to_bsr_index(int32_t nbytes) {
}
void add_ue_ulsch_info(module_id_t module_idP, module_id_t ue_mod_idP, sub_frame_t subframeP, UE_ULSCH_STATUS status){
void add_ue_ulsch_info(module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframeP, UE_ULSCH_STATUS status){
eNB_ulsch_info[module_idP][ue_mod_idP].rnti = find_UE_RNTI(module_idP,ue_mod_idP);
eNB_ulsch_info[module_idP][ue_mod_idP].subframe = subframeP;
eNB_ulsch_info[module_idP][ue_mod_idP].status = status;
eNB_ulsch_info[module_idP][UE_id].rnti = UE_RNTI(module_idP,UE_id);
eNB_ulsch_info[module_idP][UE_id].subframe = subframeP;
eNB_ulsch_info[module_idP][UE_id].status = status;
eNB_ulsch_info[module_idP][ue_mod_idP].serving_num++;
eNB_ulsch_info[module_idP][UE_id].serving_num++;
}
module_id_t schedule_next_ulue(module_id_t module_idP, module_id_t ue_mod_idP, sub_frame_t subframeP){
// This seems not to be used anymore
/*
int schedule_next_ulue(module_id_t module_idP, int UE_id, sub_frame_t subframeP){
module_id_t next_ue;
int next_ue;
// first phase: scheduling for ACK
switch (subframeP) {
// scheduling for subframeP 2: for scheduled user during subframeP 5 and 6
case 8:
if ((eNB_dlsch_info[module_idP][ue_mod_idP].status == S_DL_SCHEDULED) &&
(eNB_dlsch_info[module_idP][ue_mod_idP].subframe == 5 || eNB_dlsch_info[module_idP][ue_mod_idP].subframe == 6)){
if ((eNB_dlsch_info[module_idP][UE_id].status == S_DL_SCHEDULED) &&
(eNB_dlsch_info[module_idP][UE_id].subframe == 5 || eNB_dlsch_info[module_idP][UE_id].subframe == 6)){
// set the downlink status
eNB_dlsch_info[module_idP][ue_mod_idP].status = S_DL_BUFFERED;
return ue_mod_idP;
eNB_dlsch_info[module_idP][UE_id].status = S_DL_BUFFERED;
return UE_id;
}
break;
// scheduling for subframeP 3: for scheduled user during subframeP 7 and 8
case 9:
if ((eNB_dlsch_info[module_idP][ue_mod_idP].status == S_DL_SCHEDULED) &&
(eNB_dlsch_info[module_idP][ue_mod_idP].subframe == 7 || eNB_dlsch_info[module_idP][ue_mod_idP].subframe == 8)){
eNB_dlsch_info[module_idP][ue_mod_idP].status = S_DL_BUFFERED;
return ue_mod_idP;
if ((eNB_dlsch_info[module_idP][UE_id].status == S_DL_SCHEDULED) &&
(eNB_dlsch_info[module_idP][UE_id].subframe == 7 || eNB_dlsch_info[module_idP][UE_id].subframe == 8)){
eNB_dlsch_info[module_idP][UE_id].status = S_DL_BUFFERED;
return UE_id;
}
break;
// scheduling UL subframeP 4: for scheduled user during subframeP 9 and 0
case 0 :
if ((eNB_dlsch_info[module_idP][ue_mod_idP].status == S_DL_SCHEDULED) &&
(eNB_dlsch_info[module_idP][ue_mod_idP].subframe == 9 || eNB_dlsch_info[module_idP][ue_mod_idP].subframe == 0)){
eNB_dlsch_info[module_idP][ue_mod_idP].status = S_DL_BUFFERED;
return ue_mod_idP;
if ((eNB_dlsch_info[module_idP][UE_id].status == S_DL_SCHEDULED) &&
(eNB_dlsch_info[module_idP][UE_id].subframe == 9 || eNB_dlsch_info[module_idP][UE_id].subframe == 0)){
eNB_dlsch_info[module_idP][UE_id].status = S_DL_BUFFERED;
return UE_id;
}
break;
default:
......@@ -150,7 +343,7 @@ module_id_t schedule_next_ulue(module_id_t module_idP, module_id_t ue_mod_idP, s
return next_ue;
}
*/
......@@ -227,13 +420,19 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header,
void schedule_ulsch(module_id_t module_idP, frame_t frameP,unsigned char cooperation_flag,sub_frame_t subframeP, unsigned char sched_subframe,unsigned int *nCCE) {//,int calibration_flag) {
start_meas(&eNB_mac_inst[module_idP].schedule_ulsch);
uint8_t granted_UEs;
unsigned int nCCE_available;
uint16_t first_rb=1,i;
granted_UEs = find_ulgranted_UEs(module_idP);
nCCE_available = mac_xface->get_nCCE_max(module_idP) - *nCCE;
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
......@@ -249,21 +448,23 @@ void schedule_ulsch(module_id_t module_idP, frame_t frameP,unsigned char coopera
// 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++;
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, granted_UEs, nCCE, &nCCE_available, &first_rb);
schedule_ulsch_rnti(module_idP, cooperation_flag, frameP, subframeP, sched_subframe, nCCE, nCCE_available, first_rb);
#ifdef CBA
if ((eNB_mac_inst[module_idP].num_active_cba_groups > 0) && (*nCCE == 0))
schedule_ulsch_cba_rnti(module_idP, cooperation_flag, frameP, subframeP, sched_subframe, granted_UEs, nCCE, &nCCE_available, &first_rb);
#endif
stop_meas(&eNB_mac_inst[module_idP].schedule_ulsch);
stop_meas(&eNB->schedule_ulsch);
}
......@@ -274,70 +475,80 @@ void schedule_ulsch_rnti(module_id_t module_idP,
frame_t frameP,
sub_frame_t subframeP,
unsigned char sched_subframe,
uint8_t granted_UEs,
unsigned int *nCCE,
unsigned int *nCCE_available,
uint16_t *first_rb){
module_id_t ue_mod_id = -1;
module_id_t next_ue = -1;
int UE_id;
unsigned char aggregation = 2;
rnti_t rnti = -1;
uint8_t round = 0;
uint8_t harq_pid = 0;
void *ULSCH_dci = NULL;
LTE_eNB_UE_stats *eNB_UE_stats = NULL;
DCI_PDU *DCI_pdu = &eNB_mac_inst[module_idP].DCI_pdu;
DCI_PDU *DCI_pdu;
uint8_t status = 0;
uint8_t rb_table_index = -1;
uint16_t TBS,i;
uint32_t buffer_occupancy;
uint32_t tmp_bsr;
uint32_t cqi_req,cshift,ndi,mcs,rballoc;
int rvidx_tab[4] = {0,3,1,2};
for (ue_mod_id=0;ue_mod_id<granted_UEs && (*nCCE_available > (1<<aggregation));ue_mod_id++) {
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};
// msg("[MAC][eNB] subframeP %d: checking UE_id %d\n",subframeP,UE_id);
next_ue = ue_mod_id; // find next ue to schedule
// msg("[MAC][eNB] subframeP %d: next ue %d\n",subframeP,next_ue);
rnti = find_UE_RNTI(module_idP,next_ue); // radio network temp id is obtained
// msg("[MAC][eNB] subframeP %d: rnti %x\n",subframeP,rnti);
// loop over all active UEs
for (UE_id=UE_list->head;(UE_id>=0) && (*nCCE_available > (1<<aggregation));UE_id=UE_list->next[UE_id]) {
rnti = UE_RNTI(module_idP,UE_id); // radio network temp id is obtained
if (rnti==0) // if so, go to next UE
continue;
eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,rnti);
// 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];
DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu;
UE_template = &UE_list->UE_template[CC_id][UE_id];
eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti);
if (eNB_UE_stats==NULL)
mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n");
LOG_I(MAC,"[eNB %d] Scheduler Frame %d, subframeP %d, nCCE %d: Checking ULSCH next UE_id %d mode id %d (rnti %x,mode %s), format 0\n",
module_idP,frameP,subframeP,*nCCE,next_ue,module_idP, rnti,mode_string[eNB_UE_stats->mode]);
module_idP,frameP,subframeP,*nCCE,UE_id,module_idP, rnti,mode_string[eNB_UE_stats->mode]);
if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel
int8_t ret;
// Get candidate harq_pid from PHY
ret = mac_xface->get_ue_active_harq_pid(module_idP,rnti,subframeP,&harq_pid,&round,1);
LOG_I(MAC,"Got harq_pid %d, round %d, next_ue %d\n",harq_pid,round,next_ue);
ret = mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,subframeP,&harq_pid,&round,1);
LOG_I(MAC,"Got harq_pid %d, round %d, UE_id %d\n",harq_pid,round,UE_id);
/* [SR] 01/07/13: Don't schedule UE if we cannot get harq pid */
#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
#else
if (round==0)
#endif
{
LOG_D(MAC,"[eNB %d][PUSCH %x] Frame %d subframeP %d Scheduling UE %d (SR %d)\n",
module_idP,rnti,frameP,subframeP,ue_mod_id,
eNB_mac_inst[module_idP].UE_template[ue_mod_id].ul_SR);
module_idP,rnti,frameP,subframeP,UE_id,
UE_template->ul_SR);
// reset the scheduling request
eNB_mac_inst[module_idP].UE_template[ue_mod_id].ul_SR = 0;
UE_template->ul_SR = 0;
aggregation = process_ue_cqi(module_idP,next_ue); // =2 by default!!
aggregation = process_ue_cqi(module_idP,UE_id); // =2 by default!!
// msg("[MAC][eNB] subframeP %d: aggregation %d\n",subframeP,aggregation);
status = mac_get_rrc_status(module_idP,1,next_ue);
status = mac_get_rrc_status(module_idP,1,UE_id);
if (status < RRC_CONNECTED)
cqi_req = 0;
......@@ -345,47 +556,48 @@ void schedule_ulsch_rnti(module_id_t module_idP,
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!
ndi = UE_template->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;
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) && (next_ue == 1)) { // Allocation on same set of RBs
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,
((next_ue-1)*4),//openair_daq_vars.ue_ul_nb_rb),
((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 = ((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))?
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[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)
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_mod_id,
UE_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],
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) &&
......@@ -406,7 +618,7 @@ void schedule_ulsch_rnti(module_id_t module_idP,
//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,
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);
......@@ -416,67 +628,67 @@ void schedule_ulsch_rnti(module_id_t module_idP,
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
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 (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;
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 {
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));
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 {
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));
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 {
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);
UE_template->bsr_info[LCGID1] = bytes_to_bsr_index((int32_t)BSR_TABLE[UE_template->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);
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
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;
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,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]),
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,
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
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(next_ue == 1)// For Distriibuted Alamouti, cyclic shift applied to 2nd UE
if(UE_id == 1)// For Distriibuted Alamouti, cyclic shift applied to 2nd UE
cshift = 1;
else
cshift = 0;
......@@ -487,7 +699,7 @@ void schedule_ulsch_rnti(module_id_t module_idP,
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];
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;
......@@ -497,7 +709,7 @@ void schedule_ulsch_rnti(module_id_t module_idP,
((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)->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,
......@@ -511,7 +723,7 @@ void schedule_ulsch_rnti(module_id_t module_idP,
break;
default:
case 25:
ULSCH_dci = eNB_mac_inst[module_idP].UE_template[next_ue].ULSCH_DCI[harq_pid];
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;
......@@ -521,7 +733,7 @@ void schedule_ulsch_rnti(module_id_t module_idP,
((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)->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,
......@@ -534,7 +746,7 @@ void schedule_ulsch_rnti(module_id_t module_idP,
0);
break;
case 50:
ULSCH_dci = eNB_mac_inst[module_idP].UE_template[next_ue].ULSCH_DCI[harq_pid];
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;
......@@ -544,7 +756,7 @@ void schedule_ulsch_rnti(module_id_t module_idP,
((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)->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,
......@@ -557,7 +769,7 @@ void schedule_ulsch_rnti(module_id_t module_idP,
0);
break;
case 100:
ULSCH_dci = eNB_mac_inst[module_idP].UE_template[next_ue].ULSCH_DCI[harq_pid];
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;
......@@ -567,7 +779,7 @@ void schedule_ulsch_rnti(module_id_t module_idP,
((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)->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,
......@@ -586,7 +798,7 @@ void schedule_ulsch_rnti(module_id_t module_idP,
case 25:
default:
ULSCH_dci = eNB_mac_inst[module_idP].UE_template[next_ue].ULSCH_DCI[harq_pid];
ULSCH_dci = UE_template->ULSCH_DCI[harq_pid];
((DCI0_5MHz_FDD_t *)ULSCH_dci)->type = 0;
((DCI0_5MHz_FDD_t *)ULSCH_dci)->hopping = 0;
......@@ -608,7 +820,7 @@ void schedule_ulsch_rnti(module_id_t module_idP,
0);
break;
case 6:
ULSCH_dci = eNB_mac_inst[module_idP].UE_template[next_ue].ULSCH_DCI[harq_pid];
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;
......@@ -630,7 +842,7 @@ void schedule_ulsch_rnti(module_id_t module_idP,
0);
break;
case 50:
ULSCH_dci = eNB_mac_inst[module_idP].UE_template[next_ue].ULSCH_DCI[harq_pid];
ULSCH_dci = UE_template->ULSCH_DCI[harq_pid];
((DCI0_10MHz_FDD_t *)ULSCH_dci)->type = 0;
((DCI0_10MHz_FDD_t *)ULSCH_dci)->hopping = 0;
......@@ -652,7 +864,7 @@ void schedule_ulsch_rnti(module_id_t module_idP,
0);
break;
case 100:
ULSCH_dci = eNB_mac_inst[module_idP].UE_template[next_ue].ULSCH_DCI[harq_pid];
ULSCH_dci = UE_template->ULSCH_DCI[harq_pid];
((DCI0_20MHz_FDD_t *)ULSCH_dci)->type = 0;
((DCI0_20MHz_FDD_t *)ULSCH_dci)->hopping = 0;
......@@ -681,51 +893,28 @@ void schedule_ulsch_rnti(module_id_t module_idP,
// &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,
CC_id,
UE_id,
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);
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
}
uint8_t find_ulgranted_UEs(module_id_t module_idP){
// all active users should be granted
return(find_active_UEs(module_idP));
}
unsigned char *get_dlsch_sdu(module_id_t module_idP, frame_t frameP, rnti_t rntiP, uint8_t TBindex) {
module_id_t ue_mod_id;
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;
}
}
#ifdef CBA
void schedule_ulsch_cba_rnti(module_id_t module_idP, unsigned char cooperation_flag, frame_t frameP, sub_frame_t subframeP, unsigned char sched_subframe, uint8_t granted_UEs, unsigned int *nCCE, unsigned int *nCCE_available, uint16_t *first_rb){
DCI0_5MHz_TDD_1_6_t *ULSCH_dci_tdd16;
DCI0_5MHz_FDD_t *ULSCH_dci_fdd;
DCI_PDU *DCI_pdu= &eNB_mac_inst[module_idP].DCI_pdu;
DCI_PDU *DCI_pdu;
uint8_t rb_table_index=0, aggregation=2;
uint32_t rballoc;
......@@ -735,18 +924,27 @@ void schedule_ulsch_cba_rnti(module_id_t module_idP, unsigned char cooperation_f
uint8_t remaining_rbs= available_rbs;
uint8_t allocated_rbs;
// We compute the weight of each group and initialize some variables
for (cba_group=0;cba_group<eNB_mac_inst[module_idP].num_active_cba_groups;cba_group++) {
for (cba_group=0;cba_group<eNB_mac_inst[module_idP][CC_id].num_active_cba_groups;cba_group++) {
// UEs in PUSCH with traffic
weight[cba_group] = find_num_active_UEs_in_cbagroup(module_idP, cba_group);
required_rbs[cba_group] = 0;
num_cba_resources[cba_group]=0;
}
//LOG_D(MAC, "[eNB ] CBA granted ues are %d\n",granted_UEs );
for (cba_group=0;cba_group<eNB_mac_inst[module_idP].num_active_cba_groups && (*nCCE_available > (1<<aggregation));cba_group++) {
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].cba_rnti[cba_group] != 0){
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);
......@@ -769,7 +967,7 @@ void schedule_ulsch_cba_rnti(module_id_t module_idP, unsigned char cooperation_f
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)
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",
......@@ -782,7 +980,7 @@ void schedule_ulsch_cba_rnti(module_id_t module_idP, unsigned char cooperation_f
}
}
// phase 2
for (cba_group=0;cba_group<eNB_mac_inst[module_idP].num_active_cba_groups;cba_group++) {
for (cba_group=0;cba_group<eNB_mac_inst[module_idP][CC_id].num_active_cba_groups;cba_group++) {
for (cba_resources=0; cba_resources < num_cba_resources[cba_group]; cba_resources++){
rb_table_index =0;
// check if there was an allocation for this group in the 1st phase
......@@ -804,13 +1002,13 @@ void schedule_ulsch_cba_rnti(module_id_t module_idP, unsigned char cooperation_f
*first_rb+=rb_table[rb_table_index];
LOG_D(MAC,"[eNB %d] Frame %d, subframeP %d: CBA %d rnti %x, total/required/allocated/remaining rbs (%d/%d/%d/%d), rballoc %d, nCCE (%d/%d)\n",
module_idP, frameP, subframeP, cba_group,eNB_mac_inst[module_idP].cba_rnti[cba_group],
module_idP, frameP, subframeP, cba_group,eNB_mac_inst[module_idP][CC_id].cba_rnti[cba_group],
available_rbs, required_rbs[cba_group], allocated_rbs, remaining_rbs,rballoc,
*nCCE_available,*nCCE);
nCCE_available[CC_id],nCCE[CC_id]);
if (mac_xface->lte_frame_parms->frame_type == TDD) {
ULSCH_dci_tdd16 = (DCI0_5MHz_TDD_1_6_t *)eNB_mac_inst[module_idP].UE_template[cba_group].ULSCH_DCI[0];
ULSCH_dci_tdd16 = (DCI0_5MHz_TDD_1_6_t *)UE_list->UE_template[CC_id][cba_group].ULSCH_DCI[0];
ULSCH_dci_tdd16->type = 0;
ULSCH_dci_tdd16->hopping = 0;
......@@ -819,13 +1017,13 @@ void schedule_ulsch_cba_rnti(module_id_t module_idP, unsigned char cooperation_f
ULSCH_dci_tdd16->ndi = 1;
ULSCH_dci_tdd16->TPC = 1;
ULSCH_dci_tdd16->cshift = cba_group;
ULSCH_dci_tdd16->dai = eNB_mac_inst[module_idP].UE_template[cba_group].DAI_ul[sched_subframe];
ULSCH_dci_tdd16->dai = UE_list->UE_template[CC_id][cba_group].DAI_ul[sched_subframe];
ULSCH_dci_tdd16->cqi_req = 1;
//add_ue_spec_dci
add_common_dci(DCI_pdu,
ULSCH_dci_tdd16,
eNB_mac_inst[module_idP].cba_rnti[cba_group],
eNB_mac_inst[module_idP][CC_id].cba_rnti[cba_group],
sizeof(DCI0_5MHz_TDD_1_6_t),
aggregation,
sizeof_DCI0_5MHz_TDD_1_6_t,
......@@ -833,7 +1031,7 @@ void schedule_ulsch_cba_rnti(module_id_t module_idP, unsigned char cooperation_f
0);
}
else {
ULSCH_dci_fdd = (DCI0_5MHz_FDD_t *)eNB_mac_inst[module_idP].UE_template[cba_group].ULSCH_DCI[0];
ULSCH_dci_fdd = (DCI0_5MHz_FDD_t *)UE_list->UE_template[CC_id][cba_group].ULSCH_DCI[0];
ULSCH_dci_fdd->type = 0;
ULSCH_dci_fdd->hopping = 0;
......@@ -847,17 +1045,19 @@ void schedule_ulsch_cba_rnti(module_id_t module_idP, unsigned char cooperation_f
//add_ue_spec_dci
add_common_dci(DCI_pdu,
ULSCH_dci_fdd,
eNB_mac_inst[module_idP].cba_rnti[cba_group],
eNB_mac_inst[module_idP][CC_id].cba_rnti[cba_group],
sizeof(DCI0_5MHz_FDD_t),
aggregation,
sizeof_DCI0_5MHz_FDD_t,
format0,
0);
}
*nCCE = (*nCCE) + (1<<aggregation) * num_cba_resources[cba_group];
*nCCE_available = mac_xface->get_nCCE_max(module_idP) - *nCCE;
nCCE[CC_id] = nCCE[CC_id] + (1<<aggregation) * num_cba_resources[cba_group];
nCCE_available[CC_id] = mac_xface->get_nCCE_max(module_idP,CC_id) - nCCE[CC_id];
// break;// for the moment only schedule one
}
}
}
}
}
#endif
......@@ -41,21 +41,33 @@
#include "UTIL/LOG/log.h"
#include "proto.h"
int8_t get_Po_NOMINAL_PUSCH(module_id_t module_idP) {
int8_t get_Po_NOMINAL_PUSCH(module_id_t module_idP,int CC_id) {
RACH_ConfigCommon_t *rach_ConfigCommon = NULL;
if (CC_id>0) {
LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n");
mac_xface->macphy_exit("MAC FATAL CC_id>0");
return;
}
if (UE_mac_inst[module_idP].radioResourceConfigCommon)
rach_ConfigCommon = &UE_mac_inst[module_idP].radioResourceConfigCommon->rach_ConfigCommon;
else {
LOG_E(MAC,"[UE %d] FATAL radioResourceConfigCommon is NULL !!!\n",module_idP);
LOG_E(MAC,"[UE %d] CCid %d FATAL radioResourceConfigCommon is NULL !!!\n",module_idP,CC_id);
mac_xface->macphy_exit("FATAL radioResourceConfigCommon is NULL");
}
return(-120 + (rach_ConfigCommon->powerRampingParameters.preambleInitialReceivedTargetPower<<1) +
get_DELTA_PREAMBLE(module_idP));
get_DELTA_PREAMBLE(module_idP,CC_id));
}
int8_t get_deltaP_rampup(module_id_t module_idP) {
int8_t get_deltaP_rampup(module_id_t module_idP,int CC_id) {
if (CC_id>0) {
LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n");
mac_xface->macphy_exit("MAC FATAL CC_id>0");
return;
}
LOG_D(MAC,"[PUSCH]%d dB\n",UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER<<1);
return((int8_t)(UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER<<1));
......
......@@ -115,6 +115,9 @@ int mac_top_init(int eMBMS_active, uint8_t cba_group_active, uint8_t HO_active){
RA_TEMPLATE *RA_template;
UE_TEMPLATE *UE_template;
int size_bytes1,size_bytes2,size_bits1,size_bits2;
int CC_id;
int list_el;
UE_list_t *UE_list;
LOG_I(MAC,"[MAIN] Init function start:Nb_UE_INST=%d\n",NB_UE_INST);
if (NB_UE_INST>0) {
......@@ -137,16 +140,28 @@ int mac_top_init(int eMBMS_active, uint8_t cba_group_active, uint8_t HO_active){
if (NB_eNB_INST>0) {
eNB_mac_inst = (eNB_MAC_INST*)malloc16(NB_eNB_INST*sizeof(eNB_MAC_INST));
if (eNB_mac_inst == NULL){
LOG_D(MAC,"[MAIN] can't ALLOCATE %d Bytes for %d eNB_MAC_INST with size %d \n",NB_eNB_INST*sizeof(eNB_MAC_INST),NB_eNB_INST,sizeof(eNB_MAC_INST));
LOG_D(MAC,"[MAIN] can't ALLOCATE %d Bytes for %d eNB_MAC_INST with size %d \n",NB_eNB_INST*sizeof(eNB_MAC_INST*),NB_eNB_INST,sizeof(eNB_MAC_INST));
mac_xface->macphy_exit("[MAC][MAIN] not enough memory for eNB \n");
}
LOG_D(MAC,"[MAIN] ALLOCATE %d Bytes for %d eNB_MAC_INST @ %p\n",NB_eNB_INST*sizeof(eNB_MAC_INST),NB_eNB_INST,eNB_mac_inst);
else{
LOG_D(MAC,"[MAIN] ALLOCATE %d Bytes for %d eNB_MAC_INST @ %p\n",sizeof(eNB_MAC_INST),NB_eNB_INST,eNB_mac_inst);
bzero(eNB_mac_inst,NB_eNB_INST*sizeof(eNB_MAC_INST));
}
}
else
eNB_mac_inst = NULL;
// Initialize Linked-List for Active UEs
for(Mod_id=0;Mod_id<NB_eNB_INST;Mod_id++){
UE_list = &eNB_mac_inst[Mod_id].UE_list;
UE_list->num_UEs=0;
UE_list->head=-1;
UE_list->avail=0;
for (list_el=0;list_el<NUMBER_OF_UE_MAX-1;list_el++) {
UE_list->next[list_el]=list_el+1;
}
UE_list->next[list_el]=-1;
#ifdef PHY_EMUL
Mac_rlc_xface->Is_cluster_head[Mod_id]=2;//0: MR, 1: CH, 2: not CH neither MR
......@@ -181,11 +196,12 @@ int mac_top_init(int eMBMS_active, uint8_t cba_group_active, uint8_t HO_active){
// Set up DCIs for TDD 5MHz Config 1..6
for (i=0;i<NB_eNB_INST;i++) {
for (i=0;i<NB_eNB_INST;i++)
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
LOG_D(MAC,"[MAIN][eNB %d] initializing RA_template\n",i);
LOG_D(MAC, "[MSC_NEW][FRAME 00000][MAC_eNB][MOD %02d][]\n", i);
RA_template = (RA_TEMPLATE *)&eNB_mac_inst[i].RA_template[0];
RA_template = (RA_TEMPLATE *)&eNB_mac_inst[i].common_channels[CC_id].RA_template[0];
for (j=0;j<NB_RA_PROC_MAX;j++) {
if (mac_xface->lte_frame_parms->frame_type == TDD) {
switch (mac_xface->lte_frame_parms->N_RB_DL) {
......@@ -268,11 +284,11 @@ int mac_top_init(int eMBMS_active, uint8_t cba_group_active, uint8_t HO_active){
}
memset (&eNB_mac_inst[i].eNB_stats,0,sizeof(eNB_STATS));
UE_template = (UE_TEMPLATE *)&eNB_mac_inst[i].UE_template[0];
UE_template = (UE_TEMPLATE *)&eNB_mac_inst[i].UE_list.UE_template[CC_id][0];
for (j=0;j<NUMBER_OF_UE_MAX;j++) {
UE_template[j].rnti=0;
// initiallize the eNB to UE statistics
memset (&eNB_mac_inst[i].eNB_UE_stats[j],0,sizeof(eNB_UE_STATS));
memset (&eNB_mac_inst[i].UE_list.eNB_UE_stats[CC_id][j],0,sizeof(eNB_UE_STATS));
}
}
......@@ -284,15 +300,16 @@ int mac_top_init(int eMBMS_active, uint8_t cba_group_active, uint8_t HO_active){
srand (time(NULL));
for(j=0;j<NB_eNB_INST;j++){
eNB_mac_inst[j].sbmap_conf.first_subframe=0;
eNB_mac_inst[j].sbmap_conf.periodicity=10;
eNB_mac_inst[j].sbmap_conf.sb_size=SB_size;
eNB_mac_inst[j].sbmap_conf.nb_active_sb=1;
for(j=0;j<NB_eNB_INST;j++)
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++){
eNB_mac_inst[j][CC_id].sbmap_conf.first_subframe=0;
eNB_mac_inst[j][CC_id].sbmap_conf.periodicity=10;
eNB_mac_inst[j][CC_id].sbmap_conf.sb_size=SB_size;
eNB_mac_inst[j][CC_id].sbmap_conf.nb_active_sb=1;
for(i=0;i<NUMBER_OF_SUBBANDS;i++)
eNB_mac_inst[j].sbmap_conf.sbmap[i]=1;
eNB_mac_inst[j][CC_id].sbmap_conf.sbmap[i]=1;
eNB_mac_inst[j].sbmap_conf.sbmap[rand()%NUMBER_OF_SUBBANDS]=0;
eNB_mac_inst[j][CC_id].sbmap_conf.sbmap[rand()%NUMBER_OF_SUBBANDS]=0;
}
#endif
......
......@@ -50,10 +50,6 @@
#include "UTIL/OPT/opt.h"
#include "OCG.h"
#include "OCG_extern.h"
#include "ARCH/CBMIMO1/DEVICE_DRIVER/extern.h"
#include "ARCH/CBMIMO1/DEVICE_DRIVER/defs.h"
#include "ARCH/CBMIMO1/DEVICE_DRIVER/from_grlib_softregs.h"
#include "RRC/LITE/extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
......@@ -69,7 +65,7 @@
#ifndef USER_MODE
#define msg debug_msg
#endif
*/
*/
extern inline unsigned int taus(void);
......@@ -80,64 +76,60 @@ void store_dlsch_buffer (module_id_t Mod_id,
frame_t frameP,
sub_frame_t subframeP){
module_id_t next_ue;
int UE_id,i;
rnti_t rnti;
uint16_t i=0;
mac_rlc_status_resp_t rlc_status;
unsigned char UE_id,granted_UEs;
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;
eNB_mac_inst[Mod_id].UE_template[UE_id].dl_pdus_total = 0;
UE_template = &UE_list->UE_template[UE_PCCID(Mod_id,UE_id)][UE_id];
// clear logical channel interface variables
UE_template->dl_buffer_total = 0;
UE_template->dl_pdus_total = 0;
for(i=0;i< MAX_NUM_LCID; i++) {
eNB_mac_inst[Mod_id].UE_template[UE_id].dl_buffer_info[i]=0;
eNB_mac_inst[Mod_id].UE_template[UE_id].dl_pdus_in_buffer[i]=0;
eNB_mac_inst[Mod_id].UE_template[UE_id].dl_buffer_head_sdu_creation_time[i]=0;
eNB_mac_inst[Mod_id].UE_template[UE_id].dl_buffer_head_sdu_remaining_size_to_send[i]=0;
}
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 = find_UE_RNTI(Mod_id,next_ue);
if (rnti == 0)
continue;
rnti = UE_RNTI(Mod_id,UE_id);
for(i=0;i< MAX_NUM_LCID; i++){ // loop over all the logical channels
rlc_status = mac_rlc_status_ind(Mod_id,next_ue, frameP,ENB_FLAG_YES,MBMS_FLAG_NO,i,0 );
eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_info[i] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel
eNB_mac_inst[Mod_id].UE_template[next_ue].dl_pdus_in_buffer[i] = rlc_status.pdus_in_buffer;
eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_creation_time[i] = rlc_status.head_sdu_creation_time ;
eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_remaining_size_to_send[i] = rlc_status.head_sdu_remaining_size_to_send;
eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_is_segmented[i] = rlc_status.head_sdu_is_segmented;
eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_total = eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_total + eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_info[i];//storing the total dlsch buffer
eNB_mac_inst[Mod_id].UE_template[next_ue].dl_pdus_total += eNB_mac_inst[Mod_id].UE_template[next_ue].dl_pdus_in_buffer[i];
rlc_status = mac_rlc_status_ind(Mod_id,UE_id, frameP,ENB_FLAG_YES,MBMS_FLAG_NO,i,0 );
UE_template->dl_buffer_info[i] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel
UE_template->dl_pdus_in_buffer[i] = rlc_status.pdus_in_buffer;
UE_template->dl_buffer_head_sdu_creation_time[i] = rlc_status.head_sdu_creation_time ;
UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = rlc_status.head_sdu_remaining_size_to_send;
UE_template->dl_buffer_head_sdu_is_segmented[i] = rlc_status.head_sdu_is_segmented;
UE_template->dl_buffer_total = UE_template->dl_buffer_total + UE_template->dl_buffer_info[i];//storing the total dlsch buffer
UE_template->dl_pdus_total += UE_template->dl_pdus_in_buffer[i];
#ifdef DEBUG_eNB_SCHEDULER
/* note for dl_buffer_head_sdu_remaining_size_to_send[i] :
* 0 if head SDU has not been segmented (yet), else remaining size not already segmented and sent
*/
if (eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_info[i]>0)
LOG_D(MAC,"[eNB %d] Frame %d Subframe %d : RLC status for UE %d in LCID%d: total of %d pdus and %d size, head sdu queuing time %d, remaining size %d, is segmeneted %d \n",
Mod_id, frameP, subframeP, next_ue,
i, eNB_mac_inst[Mod_id].UE_template[next_ue].dl_pdus_in_buffer[i],eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_info[i],
eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_creation_time[i],
eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_remaining_size_to_send[i],
eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_is_segmented[i]
if (UE_template->dl_buffer_info[i]>0)
LOG_D(MAC,"[eNB %d] Frame %d Subframe %d : RLC status for UE %d in LCID%d: total of %d pdus and size %d, head sdu queuing time %d, remaining size %d, is segmeneted %d \n",
Mod_id, frameP, subframeP, UE_id,
i, UE_template->dl_pdus_in_buffer[i],UE_template->dl_buffer_info[i],
UE_template->dl_buffer_head_sdu_creation_time[i],
UE_template->dl_buffer_head_sdu_remaining_size_to_send[i],
UE_template->dl_buffer_head_sdu_is_segmented[i]
);
#endif
}
#ifdef DEBUG_eNB_SCHEDULER
if ( eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_total>0)
if ( UE_template->dl_buffer_total>0)
LOG_D(MAC,"[eNB %d] Frame %d Subframe %d : RLC status for UE %d : total DL buffer size %d and total number of pdu %d \n",
Mod_id, frameP, subframeP, next_ue,
eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_total,
eNB_mac_inst[Mod_id].UE_template[next_ue].dl_pdus_total
Mod_id, frameP, subframeP, UE_id,
UE_template->dl_buffer_total,
UE_template->dl_pdus_total
);
#endif
}
......@@ -148,294 +140,345 @@ void store_dlsch_buffer (module_id_t Mod_id,
void assign_rbs_required (module_id_t Mod_id,
frame_t frameP,
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;
uint16_t TBS = 0;
LTE_eNB_UE_stats *eNB_UE_stats = NULL;
module_id_t ue_inst;
unsigned char granted_UEs;
LTE_eNB_UE_stats *eNB_UE_stats[MAX_NUM_CCs];
int UE_id,n,i,j,CC_id,pCCid,tmp;
UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
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]){
pCCid = UE_PCCID(Mod_id,UE_id);
for (ue_inst=0;ue_inst<granted_UEs;ue_inst++) {
//update CQI information across component carriers
for (n=0;n<UE_list->numactiveCCs[UE_id];n++) {
next_ue = ue_inst;
rnti = find_UE_RNTI(Mod_id,next_ue);
if (rnti == 0)
continue;
CC_id = UE_list->ordered_CCids[n][UE_id];
eNB_UE_stats = mac_xface->get_eNB_UE_stats(Mod_id,rnti);
//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:
eNB_UE_stats->dlsch_mcs1 = 0;
eNB_UE_stats[CC_id]->dlsch_mcs1 = 0;
break;
case 1:
eNB_UE_stats->dlsch_mcs1 = 0;
eNB_UE_stats[CC_id]->dlsch_mcs1 = 0;
break;
case 2:
eNB_UE_stats->dlsch_mcs1 = 0;
eNB_UE_stats[CC_id]->dlsch_mcs1 = 0;
break;
case 3:
eNB_UE_stats->dlsch_mcs1 = 2;
eNB_UE_stats[CC_id]->dlsch_mcs1 = 2;
break;
case 4:
eNB_UE_stats->dlsch_mcs1 = 4;
eNB_UE_stats[CC_id]->dlsch_mcs1 = 4;
break;
case 5:
eNB_UE_stats->dlsch_mcs1 = 6;
eNB_UE_stats[CC_id]->dlsch_mcs1 = 6;
break;
case 6:
eNB_UE_stats->dlsch_mcs1 = 8;
eNB_UE_stats[CC_id]->dlsch_mcs1 = 8;
break;
case 7:
eNB_UE_stats->dlsch_mcs1 = 11;
eNB_UE_stats[CC_id]->dlsch_mcs1 = 11;
break;
case 8:
eNB_UE_stats->dlsch_mcs1 = 13;
eNB_UE_stats[CC_id]->dlsch_mcs1 = 13;
break;
case 9:
eNB_UE_stats->dlsch_mcs1 = 16;
eNB_UE_stats[CC_id]->dlsch_mcs1 = 16;
break;
case 10:
eNB_UE_stats->dlsch_mcs1 = 18;
eNB_UE_stats[CC_id]->dlsch_mcs1 = 18;
break;
case 11:
eNB_UE_stats->dlsch_mcs1 = 20;
eNB_UE_stats[CC_id]->dlsch_mcs1 = 20;
break;
case 12:
eNB_UE_stats->dlsch_mcs1 = 22;
eNB_UE_stats[CC_id]->dlsch_mcs1 = 22;
break;
case 13:
eNB_UE_stats->dlsch_mcs1 = 22;//25
eNB_UE_stats[CC_id]->dlsch_mcs1 = 25;
break;
case 14:
eNB_UE_stats->dlsch_mcs1 = 22;//27
eNB_UE_stats[CC_id]->dlsch_mcs1 = 27;
break;
case 15:
eNB_UE_stats->dlsch_mcs1 = 22;//28
eNB_UE_stats[CC_id]->dlsch_mcs1 = 28;
break;
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);
}
}
// provide the list of CCs sorted according to MCS
for (i=0;i<UE_list->numactiveCCs[UE_id];i++) {
for (j=i+1;j<UE_list->numactiveCCs[UE_id];j++) {
if (eNB_UE_stats[UE_list->ordered_CCids[i][UE_id]]->dlsch_mcs1 >
eNB_UE_stats[UE_list->ordered_CCids[j][UE_id]]->dlsch_mcs1) {
tmp = UE_list->ordered_CCids[i][UE_id];
UE_list->ordered_CCids[i][UE_id] = UE_list->ordered_CCids[j][UE_id];
UE_list->ordered_CCids[j][UE_id] = tmp;
}
}
}
if ((mac_get_rrc_status(Mod_id,1,next_ue) < RRC_RECONFIGURED)){
nb_rbs_required[next_ue] = mac_xface->lte_frame_parms->N_RB_DL;
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_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_total> 0) {
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];
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[CC_id]->dlsch_mcs1,nb_rbs_required[CC_id][UE_id]);
TBS = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_rbs_required[next_ue]);
while (TBS < eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_total) {
nb_rbs_required[next_ue] += 2;
if (nb_rbs_required[next_ue]>mac_xface->lte_frame_parms->N_RB_DL) {
TBS = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,mac_xface->lte_frame_parms->N_RB_DL);
nb_rbs_required[next_ue] = mac_xface->lte_frame_parms->N_RB_DL;// calculating required number of RBs for each UE
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->dlsch_mcs1,nb_rbs_required[next_ue]);
TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1,nb_rbs_required[CC_id][UE_id]);
}
}
}
}
}
// 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){
// This function scans all CC_ids for a particular UE to find the maximum round index of its HARQ processes
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;
int maxround(module_id_t Mod_id,uint16_t rnti,sub_frame_t subframe) {
uint8_t round,round_max=0,harq_pid;
int CC_id;
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++){
mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,subframe,&harq_pid,&round,0);
if (round > round_max)
round_max = round;
}
granted_UEs = find_dlgranted_UEs(Mod_id);
}
// This function scans all CC_ids for a particular UE to find the maximum DL CQI
int maxcqi(module_id_t Mod_id,uint16_t rnti) {
LTE_eNB_UE_stats *eNB_UE_stats = NULL;
int CC_id;
int CQI = 0;
for (ue_inst=0;ue_inst<granted_UEs;ue_inst++) {
UE_id_sorted[i] = ue_inst;
i++;
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++){
eNB_UE_stats = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti);
if (eNB_UE_stats->DL_cqi[0] > CQI)
CQI = eNB_UE_stats->DL_cqi[0];
}
for(i=0; i < granted_UEs;i++){
return(CQI);
}
next_ue1 = UE_id_sorted[i];
rnti1 = find_UE_RNTI(Mod_id,next_ue1);
if(rnti1 == 0)
continue;
// This fuction sorts the UE in order their dlsch buffer and CQI
void sort_UEs (module_id_t Mod_id,
sub_frame_t subframe) {
eNB_UE_stats1 = mac_xface->get_eNB_UE_stats(Mod_id,rnti1);
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;
mac_xface->get_ue_active_harq_pid(Mod_id,rnti1,subframe,&harq_pid1,&round1,0);
for (i=UE_list->head;i>=0;i=UE_list->next[i]) {
rnti1 = UE_RNTI(Mod_id,i);
if(rnti1 == 0)
continue;
for(ii=i+1;ii<granted_UEs;ii++){
UE_id1 = i;
pCC_id1 = UE_PCCID(Mod_id,UE_id1);
cqi1 = maxcqi(Mod_id,rnti1); //
round1 = maxround(Mod_id,rnti1,subframe);
next_ue2 = UE_id_sorted[ii];
rnti2 = find_UE_RNTI(Mod_id,next_ue2);
for(ii=UE_list->next[i];ii>=0;ii=UE_list->next[ii]){
UE_id2 = ii;
rnti2 = UE_RNTI(Mod_id,UE_id2);
if(rnti2 == 0)
continue;
eNB_UE_stats2 = mac_xface->get_eNB_UE_stats(Mod_id,rnti2);
mac_xface->get_ue_active_harq_pid(Mod_id,rnti2,subframe,&harq_pid2,&round2,0);
cqi2 = maxcqi(Mod_id,rnti2);
round2 = maxround(Mod_id,rnti2,subframe); //mac_xface->get_ue_active_harq_pid(Mod_id,rnti2,subframe,&harq_pid2,&round2,0);
pCC_id2 = UE_PCCID(Mod_id,UE_id2);
if(round2 > round1){
UE_id_sorted[i] = next_ue2;
UE_id_sorted[ii] = next_ue1;
if(round2 > round1){ // Check first if one of the UEs has an active HARQ process which needs service and swap order
swap_UEs(UE_list,UE_id1,UE_id2);
}
else if (round2 == round1){
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]){
UE_id_sorted[i] = next_ue2;
UE_id_sorted[ii] = next_ue1;
break;
// 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((j == MAX_NUM_LCID-1))
{
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].UE_sched_ctrl[next_ue1].priority[3]<eNB_mac_inst[Mod_id].UE_sched_ctrl[next_ue2].priority[3])
/*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] = next_ue2;
UE_id_sorted[ii] = next_ue1;
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].UE_sched_ctrl[next_ue1].priority[3]==eNB_mac_inst[Mod_id].UE_sched_ctrl[next_ue2].priority[3]){*/
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]){*/
if(eNB_UE_stats1->DL_cqi[0] < eNB_UE_stats2->DL_cqi[0]){
UE_id_sorted[i] = next_ue2;
UE_id_sorted[ii] = next_ue1;
}
//}
}
}
// }
}
}
}
}
// This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done
void dlsch_scheduler_pre_processor (module_id_t Mod_id,
frame_t frameP,
sub_frame_t subframeP,
uint8_t *dl_pow_off,
uint16_t *pre_nb_available_rbs,
int N_RBGS,
unsigned char rballoc_sub_UE[NUMBER_OF_UE_MAX][N_RBGS_MAX]){
unsigned char next_ue,next_ue1,next_ue2,rballoc_sub[mac_xface->lte_frame_parms->N_RBGS],harq_pid=0,harq_pid1=0,harq_pid2=0,round=0,round1=0,round2=0,total_ue_count=0;
unsigned char MIMO_mode_indicator[mac_xface->lte_frame_parms->N_RBGS];
module_id_t UE_id, i;
module_id_t UE_id_sorted[NUMBER_OF_UE_MAX];
module_id_t granted_UEs;
uint8_t dl_pow_off[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
uint16_t pre_nb_available_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
int N_RBGS[MAX_NUM_CCs],
unsigned char rballoc_sub_UE[MAX_NUM_CCs][NUMBER_OF_UE_MAX][N_RBGS_MAX],
int *mbsfn_flag){
unsigned char rballoc_sub[MAX_NUM_CCs][13],harq_pid=0,harq_pid1=0,harq_pid2=0,round=0,round1=0,round2=0,total_ue_count[MAX_NUM_CCs];
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][13];
int UE_id, UE_id2, i;
uint16_t ii,j;
uint16_t nb_rbs_required[NUMBER_OF_UE_MAX];
uint16_t nb_rbs_required_remaining[NUMBER_OF_UE_MAX];
uint16_t nb_rbs_required_remaining_1[NUMBER_OF_UE_MAX];
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
uint16_t nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
uint16_t i1,i2,i3,r1=0;
uint16_t average_rbs_per_user=0;
uint16_t average_rbs_per_user[MAX_NUM_CCs];
rnti_t rnti,rnti1,rnti2;
LTE_eNB_UE_stats *eNB_UE_stats1 = NULL;
LTE_eNB_UE_stats *eNB_UE_stats2 = NULL;
uint16_t min_rb_unit;
int min_rb_unit[MAX_NUM_CCs];
int CC_id;
UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
switch (mac_xface->lte_frame_parms->N_RB_DL) {
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
if (mbsfn_flag[CC_id]>0) // If this CC is allocated for MBSFN skip it here
continue;
switch (PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL) {
case 6:
min_rb_unit=1;
min_rb_unit[CC_id]=1;
break;
case 25:
min_rb_unit=2;
min_rb_unit[CC_id]=2;
break;
case 50:
min_rb_unit=3;
min_rb_unit[CC_id]=3;
break;
case 100:
min_rb_unit=4;
min_rb_unit[CC_id]=4;
break;
default:
min_rb_unit=2;
min_rb_unit[CC_id]=2;
break;
}
granted_UEs = find_dlgranted_UEs(Mod_id);
// Initialize scheduling information for all active UEs
for (i=UE_list->head;i>=0;i=UE_list->next[i]) {
UE_id = i;
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++)
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[j] = 2;
rballoc_sub[j] = 0;
rballoc_sub_UE[i][j] = 0;
MIMO_mode_indicator[CC_id][j] = 2;
rballoc_sub[CC_id][j] = 0;
rballoc_sub_UE[CC_id][UE_id][j] = 0;
}
}
}
//printf("SUCCESS %d",mac_xface->lte_frame_parms->N_RBGS);
//exit(-1);
// Store the DLSCH buffer for each logical channel
store_dlsch_buffer (Mod_id,frameP,subframeP);
// Calculate the number of RBs required by each UE on the basis of logical channel's buffer
assign_rbs_required (Mod_id,frameP,subframeP,nb_rbs_required);
assign_rbs_required (Mod_id,frameP,subframeP,nb_rbs_required,min_rb_unit);
// Sorts the user on the basis of dlsch logical channel buffer and CQI
sort_UEs (Mod_id,subframeP,UE_id_sorted);
//printf ("Frame:%d,SUCCESS %d[%d] %d[%d]\n",frameP,UE_id_sorted[0],nb_rbs_required[UE_id_sorted[0]],UE_id_sorted[1],nb_rbs_required[UE_id_sorted[1]]);
sort_UEs (Mod_id,subframeP);
for (i=0;i<granted_UEs;i++){
rnti = find_UE_RNTI(Mod_id,i);
// loop over all active UEs
for (i=UE_list->head;i>=0;i=UE_list->next[i]) {
UE_id = i;
rnti = UE_RNTI(Mod_id,UE_id);
if(rnti == 0)
continue;
mac_xface->get_ue_active_harq_pid(Mod_id,rnti,subframeP,&harq_pid,&round,0);
for (ii=0;ii<UE_num_active_CC(UE_list,UE_id);ii++) {
CC_id = UE_list->ordered_CCids[ii][UE_id];
total_ue_count[CC_id]=0;
average_rbs_per_user[CC_id]=0;
mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,subframeP,&harq_pid,&round,0);
if(round>0)
nb_rbs_required[i] = eNB_mac_inst[Mod_id].UE_template[i].nb_rb[harq_pid];
//nb_rbs_required_remaining[i] = nb_rbs_required[i];
if(nb_rbs_required[i] > 0)
total_ue_count = total_ue_count + 1;
nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
//nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id];
if (nb_rbs_required[CC_id][UE_id] > 0) {
total_ue_count[CC_id] = total_ue_count[CC_id] + 1;
}
// hypotetical assignement
/*
* If schedule is enabled and if the priority of the UEs is modified
......@@ -445,17 +488,24 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id,
* average rbs per user and the level of priority or multiply the average rbs
* per user by a coefficient which represents the degree of priority.
*/
if((total_ue_count > 0) && ( min_rb_unit * total_ue_count <= mac_xface->lte_frame_parms->N_RB_DL ) )
average_rbs_per_user = (uint16_t) ceil(mac_xface->lte_frame_parms->N_RB_DL/total_ue_count);
if((total_ue_count[CC_id] > 0) && ( min_rb_unit[CC_id] * total_ue_count[CC_id] <= PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL ) )
average_rbs_per_user[CC_id] = (uint16_t) ceil(PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL/total_ue_count[CC_id]);
else
average_rbs_per_user = min_rb_unit;
average_rbs_per_user[CC_id] = min_rb_unit[CC_id];
}
}
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++) {
CC_id = UE_list->ordered_CCids[ii][UE_id];
// control channel
if (mac_get_rrc_status(Mod_id,1,i) < RRC_RECONFIGURED)
nb_rbs_required_remaining_1[i] = nb_rbs_required[i];
nb_rbs_required_remaining_1[CC_id][i] = nb_rbs_required[CC_id][i];
else
nb_rbs_required_remaining_1[i] = cmin(average_rbs_per_user,nb_rbs_required[i]);
nb_rbs_required_remaining_1[CC_id][i] = cmin(average_rbs_per_user[CC_id],nb_rbs_required[CC_id][i]);
}
}
......@@ -464,275 +514,290 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id,
// 2nd round: remaining RBs are allocated to high priority UEs
for(r1=0;r1<2;r1++){
for(i=0; i<granted_UEs;i++)
{
for(i=UE_list->head; i>=0;i=UE_list->next[i]) {
for (ii=0;ii<UE_num_active_CC(UE_list,UE_id);ii++) {
CC_id = UE_list->ordered_CCids[ii][UE_id];
if(r1 == 0)
nb_rbs_required_remaining[i] = nb_rbs_required_remaining_1[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
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[CC_id][i]-nb_rbs_required_remaining_1[CC_id][i]+nb_rbs_required_remaining[CC_id][i];
}
}
// retransmission in control channels
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++) {
CC_id = UE_list->ordered_CCids[ii][UE_id];
next_ue = UE_id_sorted[i];
rnti = find_UE_RNTI(Mod_id,next_ue);
rnti = UE_RNTI(Mod_id,UE_id);
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)) {
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++){
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,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 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;
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[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;
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];
}
}
}
}
}
}
// retransmission in data channels
for (i = 0 ;i<granted_UEs; i++){
next_ue = UE_id_sorted[i];
rnti = find_UE_RNTI(Mod_id,next_ue);
for(i=UE_list->head; i>=0;i=UE_list->next[i]) {
UE_id = i;
for (ii=0;ii<UE_num_active_CC(UE_list,UE_id);ii++) {
CC_id = UE_list->ordered_CCids[ii][UE_id];
rnti = UE_RNTI(Mod_id,UE_id);
if(rnti == 0)
continue;
mac_xface->get_ue_active_harq_pid(Mod_id,rnti,subframeP,&harq_pid,&round,0);
if ((mac_get_rrc_status(Mod_id,1,next_ue) >= RRC_RECONFIGURED) && (round > 0)) {
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)||
(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;
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[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;
nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id];
pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + min_rb_unit[CC_id];
}
}
}
}
}
}
// control channel in the 1st transmission
for (i = 0 ;i<granted_UEs; i++){
next_ue = UE_id_sorted[i];
rnti = find_UE_RNTI(Mod_id,next_ue);
for(i=UE_list->head; i>=0;i=UE_list->next[i]) {
UE_id = i;
for (ii=0;ii<UE_num_active_CC(UE_list,UE_id);ii++) {
CC_id = UE_list->ordered_CCids[ii][UE_id];
rnti = UE_RNTI(Mod_id,UE_id);
if(rnti == 0)
continue;
mac_xface->get_ue_active_harq_pid(Mod_id,rnti,subframeP,&harq_pid,&round,0);
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;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[CC_id][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)||
(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;
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[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;
nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id];
pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + min_rb_unit[CC_id];
}
}
}
}
}
}
// data chanel TM5
for (i = 0 ;i<granted_UEs; i++){
for(i=UE_list->head; i>=0;i=UE_list->next[i]) {
UE_id = i;
for (ii=0;ii<UE_num_active_CC(UE_list,UE_id);ii++) {
CC_id = UE_list->ordered_CCids[ii][UE_id];
next_ue1 = UE_id_sorted[i];
rnti1 = find_UE_RNTI(Mod_id,next_ue1);
rnti1 = UE_RNTI(Mod_id,UE_id);
if(rnti1 == 0)
continue;
eNB_UE_stats1 = mac_xface->get_eNB_UE_stats(Mod_id,rnti1);
eNB_UE_stats1 = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti1);
mac_xface->get_ue_active_harq_pid(Mod_id,rnti1,subframeP,&harq_pid1,&round1,0);
mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti1,subframeP,&harq_pid1,&round1,0);
if ((mac_get_rrc_status(Mod_id,1,next_ue1) >= RRC_RECONFIGURED) && (round1==0) && (mac_xface->get_transmission_mode(Mod_id,rnti1)==5) && (dl_pow_off[next_ue1] != 1)) {
if ((mac_get_rrc_status(Mod_id,1,UE_id) >= RRC_RECONFIGURED) && (round1==0) && (mac_xface->get_transmission_mode(Mod_id,CC_id,rnti1)==5) && (dl_pow_off[CC_id][UE_id] != 1)) {
for(j=0;j<N_RBGS;j+=2){
for(j=0;j<N_RBGS[CC_id];j+=2){
if((((j == (N_RBGS-1))&& (rballoc_sub[j] == 0) && (rballoc_sub_UE[next_ue1][j] == 0)) || ((j < (N_RBGS-1)) && (rballoc_sub[j+1] == 0) && (rballoc_sub_UE[next_ue1][j+1] == 0))) && (nb_rbs_required_remaining[next_ue1]>0)){
if((((j == (N_RBGS[CC_id]-1))&& (rballoc_sub[CC_id][j] == 0) && (rballoc_sub_UE[CC_id][UE_id][j] == 0)) || ((j < (N_RBGS[CC_id]-1)) && (rballoc_sub[CC_id][j+1] == 0) && (rballoc_sub_UE[CC_id][UE_id][j+1] == 0))) && (nb_rbs_required_remaining[CC_id][UE_id]>0)){
for (ii = i+1;ii < granted_UEs;ii++) {
for (ii = UE_list->next[i+1];ii >=0;ii=UE_list->next[ii]) {
next_ue2 = UE_id_sorted[ii];
rnti2 = find_UE_RNTI(Mod_id,next_ue2);
UE_id2 = ii;
rnti2 = UE_RNTI(Mod_id,UE_id2);
if(rnti2 == 0)
continue;
eNB_UE_stats2 = mac_xface->get_eNB_UE_stats(Mod_id,rnti2);
mac_xface->get_ue_active_harq_pid(Mod_id,rnti2,subframeP,&harq_pid2,&round2,0);
eNB_UE_stats2 = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti2);
mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,subframeP,&harq_pid2,&round2,0);
if ((mac_get_rrc_status(Mod_id,1,next_ue2) >= RRC_RECONFIGURED) && (round2==0) && (mac_xface->get_transmission_mode(Mod_id,rnti2)==5) && (dl_pow_off[next_ue2] != 1)) {
if ((mac_get_rrc_status(Mod_id,1,UE_id2) >= RRC_RECONFIGURED) && (round2==0) && (mac_xface->get_transmission_mode(Mod_id,CC_id,rnti2)==5) && (dl_pow_off[CC_id][UE_id2] != 1)) {
if((((j == (N_RBGS-1)) && (rballoc_sub_UE[next_ue2][j] == 0)) || ((j < (N_RBGS-1)) && (rballoc_sub_UE[next_ue2][j+1] == 0))) && (nb_rbs_required_remaining[next_ue2]>0)){
if((((j == (N_RBGS[CC_id]-1)) && (rballoc_sub_UE[CC_id][UE_id2][j] == 0)) || ((j < (N_RBGS[CC_id]-1)) && (rballoc_sub_UE[CC_id][UE_id2][j+1] == 0))) && (nb_rbs_required_remaining[CC_id][UE_id2]>0)){
if((((eNB_UE_stats2->DL_pmi_single^eNB_UE_stats1->DL_pmi_single)<<(14-j))&0xc000)== 0x4000){ //MU-MIMO only for 25 RBs configuration
rballoc_sub[j] = 1;
rballoc_sub_UE[next_ue1][j] = 1;
rballoc_sub_UE[next_ue2][j] = 1;
MIMO_mode_indicator[j] = 0;
rballoc_sub[CC_id][j] = 1;
rballoc_sub_UE[CC_id][UE_id][j] = 1;
rballoc_sub_UE[CC_id][UE_id2][j] = 1;
MIMO_mode_indicator[CC_id][j] = 0;
if (j< N_RBGS-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;
if (j< N_RBGS[CC_id]-1) {
rballoc_sub[CC_id][j+1] = 1;
rballoc_sub_UE[CC_id][UE_id][j+1] = 1;
rballoc_sub_UE[CC_id][UE_id2][j+1] = 1;
MIMO_mode_indicator[CC_id][j+1] = 0;
}
dl_pow_off[next_ue1] = 0;
dl_pow_off[next_ue2] = 0;
dl_pow_off[CC_id][UE_id] = 0;
dl_pow_off[CC_id][UE_id2] = 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;
if ((j == N_RBGS[CC_id]-1) &&
((PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL == 25) ||
(PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL == 50))){
nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id]+1;
pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + min_rb_unit[CC_id]-1;
nb_rbs_required_remaining[CC_id][UE_id2] = nb_rbs_required_remaining[CC_id][UE_id2] - min_rb_unit[CC_id]+1;
pre_nb_available_rbs[CC_id][UE_id2] = pre_nb_available_rbs[CC_id][UE_id2] + min_rb_unit[CC_id]-1;
}
else {
nb_rbs_required_remaining[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;
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 = 0;i<granted_UEs; i++){
next_ue = UE_id_sorted[i];
rnti = find_UE_RNTI(Mod_id,next_ue);
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,rnti,subframeP,&harq_pid,&round,0);
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;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[CC_id][UE_id]>0)){
switch (mac_xface->get_transmission_mode(Mod_id,rnti)) {
switch (mac_xface->get_transmission_mode(Mod_id,CC_id,rnti)) {
case 1:
case 2:
case 4:
case 6:
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((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;
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[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;
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[next_ue] != 0){
if (dl_pow_off[CC_id][UE_id] != 0){
dl_pow_off[next_ue] = 1;
dl_pow_off[CC_id][UE_id] = 1;
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((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;
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[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;
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;
......@@ -744,45 +809,52 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id,
}
}
}
}
// This has to be revisited!!!!
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
i1=0;
i2=0;
i3=0;
for (j=0;j<N_RBGS;j++){
if(MIMO_mode_indicator[j] == 2)
for (j=0;j<N_RBGS[CC_id];j++){
if(MIMO_mode_indicator[CC_id][j] == 2)
i1 = i1+1;
else if(MIMO_mode_indicator[j] == 1)
else if(MIMO_mode_indicator[CC_id][j] == 1)
i2 = i2+1;
else if(MIMO_mode_indicator[j] == 0)
else if(MIMO_mode_indicator[CC_id][j] == 0)
i3 = i3+1;
}
if((i1 < N_RBGS) && (i2>0) && (i3==0))
PHY_vars_eNB_g[Mod_id]->check_for_SUMIMO_transmissions = PHY_vars_eNB_g[Mod_id]->check_for_SUMIMO_transmissions + 1;
if((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 && i1==0 && i2==0)
PHY_vars_eNB_g[Mod_id]->FULL_MUMIMO_transmissions = PHY_vars_eNB_g[Mod_id]->FULL_MUMIMO_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) && (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;
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(UE_id=0;UE_id<granted_UEs;UE_id++){
for(i=UE_list->head; i>=0;i=UE_list->next[i]) {
for (ii=0;ii<UE_num_active_CC(UE_list,UE_id);ii++) {
CC_id = UE_list->ordered_CCids[ii][UE_id];
UE_id = i;
//PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id];
LOG_D(MAC,"******************Scheduling Information for UE%d ************************\n",UE_id);
LOG_D(MAC,"dl power offset UE%d = %d \n",UE_id,dl_pow_off[UE_id]);
LOG_D(MAC,"dl power offset UE%d = %d \n",UE_id,dl_pow_off[CC_id][UE_id]);
LOG_D(MAC,"***********RB Alloc for every subband for UE%d ***********\n",UE_id);
for(j=0;j<N_RBGS;j++){
//PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[i] = rballoc_sub_UE[UE_id][i];
LOG_D(MAC,"RB Alloc for UE%d and Subband%d = %d\n",UE_id,j,rballoc_sub_UE[UE_id][j]);
for(j=0;j<N_RBGS[CC_id];j++){
//PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[i] = rballoc_sub_UE[CC_id][UE_id][i];
LOG_D(MAC,"RB Alloc for UE%d and Subband%d = %d\n",UE_id,j,rballoc_sub_UE[CC_id][UE_id][j]);
}
//PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id];
LOG_D(MAC,"Total RBs allocated for UE%d = %d\n",UE_id,pre_nb_available_rbs[CC_id][UE_id]);
}
//PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[UE_id];
LOG_D(MAC,"Total RBs allocated for UE%d = %d\n",UE_id,pre_nb_available_rbs[UE_id]);
}
}
......@@ -51,7 +51,7 @@ for the message.
@param nprb Pointer to current PRB count
@param nCCE Pointer to current nCCE count
*/
void schedule_RA(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,uint8_t Msg3_subframe,uint8_t *nprb,unsigned int *nCCE);
void schedule_RA(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,uint8_t Msg3_subframe,unsigned int *nprb,unsigned int *nCCE);
/** \brief First stage of SI Scheduling. Gets a SI SDU from RRC if available and computes the MCS required to transport it as a function of the SDU length. It assumes a length less than or equal to 64 bytes (MCS 6, 3 PRBs).
@param Mod_id Instance ID of eNB
......@@ -61,7 +61,7 @@ void schedule_RA(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,uint
@param nprb Pointer to current PRB count
@param nCCE Pointer to current nCCE count
*/
void schedule_SI(module_id_t module_idP,frame_t frameP,uint8_t *nprb,unsigned int *nCCE);
void schedule_SI(module_id_t module_idP,frame_t frameP,unsigned int *nprb,unsigned int *nCCE);
/** \brief MBMS scheduling: Checking the position for MBSFN subframes. Create MSI, transfer MCCH from RRC to MAC, transfer MTCHs from RLC to MAC. Multiplexing MSI,MCCH&MTCHs. Return 1 if there are MBSFN data being allocated, otherwise return 0;
@param Mod_id Instance ID of eNB
......@@ -101,7 +101,7 @@ void schedule_ulsch(module_id_t module_idP,frame_t frameP,unsigned char cooperat
@param sched_subframe Subframe number where PUSCH is transmitted (for DAI lookup)
@param nCCE Pointer to current nCCE count
*/
void schedule_ulsch_rnti(module_id_t module_idP, unsigned char cooperation_flag, frame_t frameP, sub_frame_t subframe, unsigned char sched_subframe, uint8_t granted_UEs, unsigned int *nCCE, unsigned int *nCCE_available, uint16_t *first_rb);
void schedule_ulsch_rnti(module_id_t module_idP, unsigned char cooperation_flag, frame_t frameP, sub_frame_t subframe, unsigned char sched_subframe, unsigned int *nCCE, unsigned int *nCCE_available, uint16_t *first_rb);
/** \brief ULSCH Scheduling for CBA RNTI TDD config (config 1-6).
@param Mod_id Instance ID of eNB
......@@ -120,7 +120,7 @@ void schedule_ulsch_cba_rnti(module_id_t module_idP, unsigned char cooperation_f
@param RA_scheduled RA was scheduled in this subframe
@param mbsfn_flag Indicates that this subframe is for MCH/MCCH
*/
void fill_DLSCH_dci(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,uint32_t rballoc,uint8_t RA_scheduled,int mbsfn_flag);
void fill_DLSCH_dci(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,uint32_t *rballoc,uint8_t RA_scheduled,int *mbsfn_flag);
/** \brief UE specific DLSCH scheduling. Retrieves next ue to be schduled from round-robin scheduler and gets the appropriate harq_pid for the subframe from PHY. If the process is active and requires a retransmission, it schedules the retransmission with the same PRB count and MCS as the first transmission. Otherwise it consults RLC for DCCH/DTCH SDUs (status with maximum number of available PRBS), builds the MAC header (timing advance sent by default) and copies
@param Mod_id Instance ID of eNB
......@@ -130,25 +130,25 @@ void fill_DLSCH_dci(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,u
@param nCCE_used Number of CCE used by SI/RA
@param mbsfn_flag Indicates that MCH/MCCH is in this subframe
*/
void schedule_ue_spec(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,uint16_t nb_rb_used0,unsigned int *nCCE_used,int mbsfn_flag);
void schedule_ue_spec(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,unsigned int *nb_rb_used0,unsigned int *nCCE_used,int *mbsfn_flag);
/** \brief Function for UE/PHY to compute PUSCH transmit power in power-control procedure.
@param Mod_id Module id of UE
@returns Po_NOMINAL_PUSCH (PREAMBLE_RECEIVED_TARGET_POWER+DELTA_PREAMBLE
*/
int8_t get_Po_NOMINAL_PUSCH(module_id_t module_idP);
int8_t get_Po_NOMINAL_PUSCH(module_id_t module_idP,int CC_id);
/** \brief Function to compute DELTA_PREAMBLE from 36.321 (for RA power ramping procedure and Msg3 PUSCH power control policy)
@param Mod_id Module id of UE
@returns DELTA_PREAMBLE
*/
int8_t get_DELTA_PREAMBLE(module_id_t module_idP);
int8_t get_DELTA_PREAMBLE(module_id_t module_idP,int CC_id);
/** \brief Function for compute deltaP_rampup from 36.321 (for RA power ramping procedure and Msg3 PUSCH power control policy)
@param Mod_id Module id of UE
@returns deltaP_rampup
*/
int8_t get_deltaP_rampup(module_id_t module_idP);
int8_t get_deltaP_rampup(module_id_t module_idP,int CC_id);
//main.c
......@@ -186,10 +186,11 @@ void mac_UE_out_of_sync_ind(module_id_t module_idP,frame_t frameP, uint16_t eNB_
void dlsch_scheduler_pre_processor (module_id_t module_idP,
frame_t frameP,
sub_frame_t subframe,
uint8_t *dl_pow_off,
uint16_t *pre_nb_available_rbs,
int N_RBGS,
unsigned char rballoc_sub_UE[NUMBER_OF_UE_MAX][N_RBGS_MAX]);
uint8_t dl_pow_off[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
uint16_t pre_nb_available_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
int N_RBGS[MAX_NUM_CCs],
unsigned char rballoc_sub_UE[MAX_NUM_CCs][NUMBER_OF_UE_MAX][N_RBGS_MAX],
int *mbsfn_flag);
/* \brief Function to trigger the eNB scheduling procedure. It is called by PHY at the beginning of each subframe, \f$n$\f
and generates all DLSCH allocations for subframe \f$n\f$ and ULSCH allocations for subframe \f$n+k$\f. The resultant DCI_PDU is
......@@ -205,17 +206,18 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, uint8_t cooperation_flag,
/* \brief Function to retrieve result of scheduling (DCI) in current subframe. Can be called an arbitrary numeber of times after eNB_dlsch_ulsch_scheduler
in a given subframe.
@param Mod_id Instance ID of eNB
@param CC_id Component Carrier Index
@param subframe Index of current subframe
@returns Pointer to generated DCI for subframe
*/
DCI_PDU *get_dci_sdu(module_id_t module_idP,frame_t frameP,sub_frame_t subframe);
DCI_PDU *get_dci_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subframe);
/* \brief Function to indicate a received preamble on PRACH. It initiates the RA procedure.
@param Mod_id Instance ID of eNB
@param preamble_index index of the received RA request
@param timing_offset Offset in samples of the received PRACH w.r.t. eNB timing. This is used to
*/
void initiate_ra_proc(module_id_t module_idP,frame_t frameP, uint16_t preamble_index,int16_t timing_offset,uint8_t sect_id,sub_frame_t subframe,uint8_t f_id);
void initiate_ra_proc(module_id_t module_idP,int CC_id,frame_t frameP, uint16_t preamble_index,int16_t timing_offset,uint8_t sect_id,sub_frame_t subframe,uint8_t f_id);
/* \brief Function in eNB to fill RAR pdu when requested by PHY. This provides a single RAR SDU for the moment and returns the t-CRNTI.
@param Mod_id Instance ID of eNB
......@@ -224,6 +226,7 @@ void initiate_ra_proc(module_id_t module_idP,frame_t frameP, uint16_t preamble_i
@returns t_CRNTI
*/
uint16_t fill_rar(module_id_t module_idP,
int CC_id,
frame_t frameP,
uint8_t *dlsch_buffer,
uint16_t N_RB_UL,
......@@ -234,29 +237,29 @@ uint16_t fill_rar(module_id_t module_idP,
@param rnti RNTI of UE transmitting l3msg
@param l3msg Pointer to received l3msg
*/
void terminate_ra_proc(module_id_t module_idP,frame_t frameP, rnti_t rnti, uint8_t *l3msg, uint16_t l3msg_len);
void terminate_ra_proc(module_id_t module_idP,int CC_id,frame_t frameP, rnti_t rnti, uint8_t *l3msg, uint16_t l3msg_len);
/* \brief Function to indicate a failed RA response. It removes all temporary variables related to the initial connection of a UE
@param Mod_id Instance ID of eNB
@param preamble_index index of the received RA request.
*/
void cancel_ra_proc(module_id_t module_idP,frame_t frameP, uint16_t preamble_index);
void cancel_ra_proc(module_id_t module_idP,int CC_id,frame_t frameP, uint16_t preamble_index);
/* \brief Function to indicate a received SDU on ULSCH.
@param Mod_id Instance ID of eNB
@param rnti RNTI of UE transmitting the SR
@param sdu Pointer to received SDU
*/
void rx_sdu(module_id_t module_idP, frame_t frameP, rnti_t rnti, uint8_t *sdu, uint16_t sdu_len);
void rx_sdu(module_id_t module_idP, int CC_id,frame_t frameP, rnti_t rnti, uint8_t *sdu, uint16_t sdu_len);
/* \brief Function to indicate a scheduled schduling request (SR) was received by eNB.
@param Mod_id Instance ID of eNB
@param rnti RNTI of UE transmitting the SR
@param subframe Index of subframe where SR was received
*/
void SR_indication(module_id_t module_idP,frame_t frameP,rnti_t rnti, sub_frame_t subframe);
void SR_indication(module_id_t module_idP,int CC_id,frame_t frameP,rnti_t rnti, sub_frame_t subframe);
uint8_t *get_dlsch_sdu(module_id_t module_idP,frame_t frameP,rnti_t rnti,uint8_t TBindex);
uint8_t *get_dlsch_sdu(module_id_t module_idP,int CC_id,frame_t frameP,rnti_t rnti,uint8_t TBindex);
/* \brief Function to retrieve MCH transport block and MCS used for MCH in this MBSFN subframe. Returns null if no MCH is to be transmitted
@param Mod_id Instance ID of eNB
......@@ -265,7 +268,7 @@ uint8_t *get_dlsch_sdu(module_id_t module_idP,frame_t frameP,rnti_t rnti,uint8_t
@param mcs Pointer to mcs used by PHY (to be filled by MAC)
@returns Pointer to MCH transport block and mcs for subframe
*/
MCH_PDU *get_mch_sdu(uint8_t Mod_id,uint32_t frame,uint32_t subframe);
MCH_PDU *get_mch_sdu(uint8_t Mod_id,uint32_t frame,sub_frame_t subframe);
//added for ALU icic purpose
......@@ -277,33 +280,32 @@ void UpdateSBnumber(module_id_t module_idP);
void ue_mac_reset (module_id_t module_idP,uint8_t eNB_index);
void ue_init_mac (module_id_t module_idP);
void init_ue_sched_info(void);
void add_ue_ulsch_info (module_id_t module_idP, module_id_t ue_mod_idP, sub_frame_t subframe,UE_ULSCH_STATUS status);
void add_ue_dlsch_info (module_id_t module_idP, module_id_t ue_mod_idP, sub_frame_t subframe,UE_DLSCH_STATUS status);
module_id_t find_UE_id (module_id_t module_idP, rnti_t rnti) ;
rnti_t find_UE_RNTI (module_id_t module_idP, module_id_t ue_mod_idP);
void add_ue_ulsch_info (module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframe,UE_ULSCH_STATUS status);
void add_ue_dlsch_info (module_id_t module_idP, int CC_id,int UE_id, sub_frame_t subframe,UE_DLSCH_STATUS status);
int find_UE_id (module_id_t module_idP, rnti_t rnti) ;
rnti_t UE_RNTI (module_id_t module_idP, int UE_id);
int UE_PCCID (module_id_t module_idP, int UE_id);
uint8_t find_active_UEs (module_id_t module_idP);
boolean_t is_UE_active (module_id_t module_idP, module_id_t ue_mod_idP );
uint8_t find_ulgranted_UEs(module_id_t module_idP);
uint8_t find_dlgranted_UEs(module_id_t module_idP);
uint8_t process_ue_cqi (module_id_t module_idP, module_id_t ue_mod_idP);
boolean_t is_UE_active (module_id_t module_idP, int UE_id);
uint8_t process_ue_cqi (module_id_t module_idP, int UE_id);
int8_t find_active_UEs_with_traffic(module_id_t module_idP);
uint8_t find_num_active_UEs_in_cbagroup(module_id_t module_idP, unsigned char group_id);
uint8_t UE_is_to_be_scheduled(module_id_t module_idP,uint8_t UE_id);
uint8_t UE_is_to_be_scheduled(module_id_t module_idP,int CC_id,uint8_t UE_id);
/** \brief Round-robin scheduler for ULSCH traffic.
@param Mod_id Instance ID for eNB
@param subframe Subframe number on which to act
@returns UE index that is to be scheduled if needed/room
*/
module_id_t schedule_next_ulue(module_id_t module_idP, module_id_t ue_mod_idP,sub_frame_t subframe);
module_id_t schedule_next_ulue(module_id_t module_idP, int UE_id,sub_frame_t subframe);
/** \brief Round-robin scheduler for DLSCH traffic.
@param Mod_id Instance ID for eNB
@param subframe Subframe number on which to act
@returns UE index that is to be scheduled if needed/room
*/
module_id_t schedule_next_dlue(module_id_t module_idP, sub_frame_t subframe);
int schedule_next_dlue(module_id_t module_idP, sub_frame_t subframe);
/* \brief Allocates a set of PRBS for a particular UE. This is a simple function for the moment, later it should process frequency-domain CQI information and/or PMI information. Currently it just returns the first PRBS that are available in the subframe based on the number requested.
@param UE_id Index of UE on which to act
......@@ -311,7 +313,7 @@ module_id_t schedule_next_dlue(module_id_t module_idP, sub_frame_t subframe);
@param rballoc Pointer to bit-map of current PRB allocation given to previous users/control channels. This is updated for subsequent calls to the routine.
@returns an rballoc bitmap for resource type 0 allocation (DCI).
*/
uint32_t allocate_prbs(module_id_t ue_mod_idP,uint8_t nb_rb, uint32_t *rballoc);
uint32_t allocate_prbs(int UE_id,uint8_t nb_rb, uint32_t *rballoc);
/* \fn uint32_t req_new_ulsch(module_id_t module_idP)
\brief check for a new transmission in any drb
......@@ -322,22 +324,23 @@ uint32_t req_new_ulsch(module_id_t module_idP);
/* \brief Get SR payload (0,1) from UE MAC
@param Mod_id Instance id of UE in machine
@param CC_id Component Carrier index
@param eNB_id Index of eNB that UE is attached to
@param rnti C_RNTI of UE
@param subframe subframe number
@returns 0 for no SR, 1 for SR
*/
uint32_t ue_get_SR(module_id_t module_idP, frame_t frameP, uint8_t eNB_id,rnti_t rnti,sub_frame_t subframe);
uint32_t ue_get_SR(module_id_t module_idP, int CC_id,frame_t frameP, uint8_t eNB_id,rnti_t rnti,sub_frame_t subframe);
uint8_t get_ue_weight(module_id_t module_idP, module_id_t ue_mod_idP);
uint8_t get_ue_weight(module_id_t module_idP, int UE_id);
// UE functions
void mac_out_of_sync_ind(module_id_t module_idP, frame_t frameP, uint16_t CH_index);
void ue_decode_si(module_id_t module_idP, frame_t frame, uint8_t CH_index, void *pdu, uint16_t len);
void ue_decode_si(module_id_t module_idP, int CC_id,frame_t frame, uint8_t CH_index, void *pdu, uint16_t len);
void ue_send_sdu(module_id_t module_idP, frame_t frame, uint8_t *sdu,uint16_t sdu_len,uint8_t CH_index);
void ue_send_sdu(module_id_t module_idP, int CC_id,frame_t frame, uint8_t *sdu,uint16_t sdu_len,uint8_t CH_index);
#ifdef Rel10
......@@ -370,14 +373,15 @@ int ue_query_mch(uint8_t Mod_id,uint32_t frame,sub_frame_t subframe, uint8_t eNB
@param subframe subframe number
@returns 0 for no SR, 1 for SR
*/
void ue_get_sdu(module_id_t module_idP, frame_t frameP, sub_frame_t subframe, uint8_t eNB_index,uint8_t *ulsch_buffer,uint16_t buflen,uint8_t *access_mode);
void ue_get_sdu(module_id_t module_idP, int CC_id,frame_t frameP, sub_frame_t subframe, uint8_t eNB_index,uint8_t *ulsch_buffer,uint16_t buflen,uint8_t *access_mode);
/* \brief Function called by PHY to retrieve information to be transmitted using the RA procedure. If the UE is not in PUSCH mode for a particular eNB index, this is assumed to be an Msg3 and MAC attempts to retrieves the CCCH message from RRC. If the UE is in PUSCH mode for a particular eNB index and PUCCH format 0 (Scheduling Request) is not activated, the MAC may use this resource for random-access to transmit a BSR along with the C-RNTI control element (see 5.1.4 from 36.321)
@param Mod_id Index of UE instance
@param Mod_id Component Carrier Index
@param New_Msg3 Flag to indicate this call is for a new Msg3
@param subframe Index of subframe for PRACH transmission (0 ... 9)
@returns A pointer to a PRACH_RESOURCES_t */
PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,frame_t frameP,uint8_t new_Msg3,sub_frame_t subframe);
PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP,uint8_t new_Msg3,sub_frame_t subframe);
/* \brief Function called by PHY to process the received RAR. It checks that the preamble matches what was sent by the eNB and provides the timing advance and t-CRNTI.
@param Mod_id Index of UE instance
......@@ -387,7 +391,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,frame_t frameP,uint8_t new
random-access procedure
@returns timing advance or 0xffff if preamble doesn't match
*/
uint16_t ue_process_rar(module_id_t module_idP, frame_t frameP,uint8_t *dlsch_buffer,uint16_t *t_crnti,uint8_t preamble_index);
uint16_t ue_process_rar(module_id_t module_idP, int CC_id,frame_t frameP,uint8_t *dlsch_buffer,uint16_t *t_crnti,uint8_t preamble_index);
/* \brief Generate header for UL-SCH. This function parses the desired control elements and sdus and generates the header as described
......@@ -440,8 +444,8 @@ uint8_t *parse_ulsch_header(uint8_t *mac_header,
int l2_init(LTE_DL_FRAME_PARMS *frame_parms,int eMBMS_active, uint8_t cba_group_active, uint8_t HO_active);
int mac_init(void);
int8_t add_new_ue(module_id_t module_idP, rnti_t rnti);
int8_t mac_remove_ue(module_id_t enb_mod_idP, module_id_t ue_mod_idP);
int add_new_ue(module_id_t Mod_id, int CC_id, rnti_t rnti);
int mac_remove_ue(module_id_t Mod_id, int UE_id);
/*! \fn UE_L2_state_t ue_scheduler(module_id_t module_idP,frame_t frameP, sub_frame_t subframe, lte_subframe_t direction,uint8_t eNB_index)
\brief UE scheduler where all the ue background tasks are done. This function performs the following: 1) Trigger PDCP every 5ms 2) Call RRC for link status return to PHY3) Perform SR/BSR procedures for scheduling feedback 4) Perform PHR procedures.
......@@ -470,7 +474,7 @@ int use_cba_access(module_id_t module_idP,frame_t frameP,sub_frame_t subframe, u
*/
int get_bsr_lcgid (module_id_t module_idP);
/*! \fn uint8_t get_bsr_len (module_id_t module_idP, uint16_t bufflen);
/*! \fn uint8_t get_bsr_len (module_id_t module_idP,uint16_t bufflen);
\brief determine whether the bsr is short or long assuming that the MAC pdu is built
\param[in] Mod_id instance of the UE
\param[in] bufflen size of phy transport block
......@@ -554,25 +558,27 @@ int get_sf_prohibitPHR_Timer(uint8_t prohibitPHR_Timer);
*/
int get_db_dl_PathlossChange(uint8_t dl_PathlossChange);
/*! \fn uint8_t get_phr_mapping (module_id_t module_idP, uint8_t eNB_index)
/*! \fn uint8_t get_phr_mapping (module_id_t module_idP, int CC_id,uint8_t eNB_index)
\brief get phr mapping as described in 36.313
\param[in] Mod_id index of eNB
\param[in] CC_id Component Carrier Index
\return phr mapping
*/
uint8_t get_phr_mapping (module_id_t module_idP, uint8_t eNB_index);
uint8_t get_phr_mapping (module_id_t module_idP, int CC_id, uint8_t eNB_index);
/*! \fn void update_phr (module_id_t module_idP)
\brief update/reset the phr timers
\param[in] Mod_id index of eNB
\param[in] CC_id Component carrier index
\return void
*/
void update_phr (module_id_t module_idP);
void update_phr (module_id_t module_idP,int CC_id);
/*! \brief Function to indicate Msg3 transmission/retransmission which initiates/reset Contention Resolution Timer
\param[in] Mod_id Instance index of UE
\param[in] eNB_id Index of eNB
*/
void Msg3_tx(module_id_t module_idP,frame_t frameP,uint8_t eNB_id);
void Msg3_tx(module_id_t module_idP,int CC_id,frame_t frameP,uint8_t eNB_id);
/*! \brief Function to indicate the transmission of msg1/rach
......@@ -580,7 +586,7 @@ void Msg3_tx(module_id_t module_idP,frame_t frameP,uint8_t eNB_id);
\param[in] eNB_id Index of eNB
*/
void Msg1_tx(module_id_t module_idP,frame_t frameP, uint8_t eNB_id);
void Msg1_tx(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_id);
void dl_phy_sync_success(module_id_t module_idP,
frame_t frameP,
......@@ -603,5 +609,5 @@ void add_common_dci(DCI_PDU *DCI_pdu,
uint32_t allocate_prbs_sub(int nb_rb, uint8_t *rballoc);
void update_ul_dci(module_id_t module_idP,rnti_t rnti,uint8_t dai);
void update_ul_dci(module_id_t module_idP,int CC_id,rnti_t rnti,uint8_t dai);
#endif
......@@ -57,7 +57,13 @@
extern inline unsigned int taus(void);
int8_t get_DELTA_PREAMBLE(module_id_t module_idP) {
int8_t get_DELTA_PREAMBLE(module_id_t module_idP,int CC_id) {
if (CC_id>0) {
LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n");
mac_xface->macphy_exit("MAC FATAL CC_id>0");
return;
}
uint8_t prachConfigIndex = UE_mac_inst[module_idP].radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_ConfigIndex;
uint8_t preambleformat;
......@@ -96,8 +102,9 @@ 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,
int CC_id,
uint8_t eNB_index,
uint8_t t_id,
uint8_t first_Msg3,
......@@ -109,6 +116,12 @@ void get_prach_resources(module_id_t module_idP,
uint8_t noGroupB = 0;
uint8_t f_id = 0,num_prach=0;
if (CC_id>0) {
LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n");
mac_xface->macphy_exit("MAC FATAL CC_id>0");
return;
}
if (UE_mac_inst[module_idP].radioResourceConfigCommon)
rach_ConfigCommon = &UE_mac_inst[module_idP].radioResourceConfigCommon->rach_ConfigCommon;
else {
......@@ -156,7 +169,7 @@ void get_prach_resources(module_id_t module_idP,
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0;
UE_mac_inst[module_idP].RA_usedGroupA = 0;
}
UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER = get_Po_NOMINAL_PUSCH(module_idP);
UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER = get_Po_NOMINAL_PUSCH(module_idP,CC_id);
}
else { // Msg3 is being retransmitted
if (UE_mac_inst[module_idP].RA_usedGroupA == 1) {
......@@ -187,7 +200,13 @@ void get_prach_resources(module_id_t module_idP,
UE_mac_inst[module_idP].RA_prach_resources.ra_RNTI = 1 + t_id + 10*f_id;
}
void Msg1_tx(module_id_t module_idP,frame_t frameP, uint8_t eNB_id) {
void Msg1_tx(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_id) {
if (CC_id>0) {
LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n");
mac_xface->macphy_exit("MAC FATAL CC_id>0");
return;
}
// start contention resolution timer
UE_mac_inst[module_idP].RA_attempt_number++;
......@@ -202,7 +221,13 @@ void Msg1_tx(module_id_t module_idP,frame_t frameP, uint8_t eNB_id) {
}
void Msg3_tx(module_id_t module_idP,frame_t frameP, uint8_t eNB_id) {
void Msg3_tx(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_id) {
if (CC_id>0) {
LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n");
mac_xface->macphy_exit("MAC FATAL CC_id>0");
return;
}
// start contention resolution timer
LOG_I(MAC,"[UE %d][RAPROC] Frame %d : Msg3_tx: Setting contention resolution timer\n",module_idP,frameP);
......@@ -220,11 +245,11 @@ void Msg3_tx(module_id_t module_idP,frame_t frameP, uint8_t eNB_id) {
}
PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,frame_t frameP, uint8_t eNB_indexP,sub_frame_t subframeP){
PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_indexP,sub_frame_t subframeP){
uint8_t Size=0;
UE_MODE_t UE_mode = mac_xface->get_ue_mode(module_idP,eNB_indexP);
UE_MODE_t UE_mode = mac_xface->get_ue_mode(module_idP,0,eNB_indexP);
uint8_t lcid = CCCH;
uint16_t Size16;
struct RACH_ConfigCommon *rach_ConfigCommon = (struct RACH_ConfigCommon *)NULL;
......@@ -234,6 +259,12 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,frame_t frameP, uint8_t eN
uint16_t sdu_lengths[8];
uint8_t ulsch_buff[MAX_ULSCH_PAYLOAD_BYTES];
if (CC_id>0) {
LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n");
mac_xface->macphy_exit("MAC FATAL CC_id>0");
return;
}
if (UE_mode == PRACH) {
if (UE_mac_inst[module_idP].radioResourceConfigCommon)
rach_ConfigCommon = &UE_mac_inst[module_idP].radioResourceConfigCommon->rach_ConfigCommon;
......@@ -243,6 +274,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,frame_t frameP, uint8_t eN
if (Is_rrc_registered == 1) {
if (UE_mac_inst[module_idP].RA_active == 0) {
printf("RA not active\n");
// check if RRC is ready to initiate the RA procedure
Size = mac_rrc_data_req(module_idP,
frameP,
......@@ -279,7 +311,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,frame_t frameP, uint8_t eN
UE_mac_inst[module_idP].RA_backoff_frame = frameP;
UE_mac_inst[module_idP].RA_backoff_subframe = subframeP;
// Fill in preamble and PRACH resource
get_prach_resources(module_idP,eNB_indexP,subframeP,1,NULL);
get_prach_resources(module_idP,CC_id,eNB_indexP,subframeP,1,NULL);
generate_ulsch_header((uint8_t*)&UE_mac_inst[module_idP].CCCH_pdu.payload[0], // mac header
1, // num sdus
......@@ -335,7 +367,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,frame_t frameP, uint8_t eN
UE_mac_inst[module_idP].RA_backoff_frame = frameP;
UE_mac_inst[module_idP].RA_backoff_subframe = subframeP;
// Fill in preamble and PRACH resource
get_prach_resources(module_idP,eNB_indexP,subframeP,1,NULL);
get_prach_resources(module_idP,CC_id,eNB_indexP,subframeP,1,NULL);
generate_ulsch_header((uint8_t*)ulsch_buff, // mac header
1, // num sdus
0, // short pading
......@@ -385,13 +417,13 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,frame_t frameP, uint8_t eN
LOG_D(MAC,"[UE %d] Frame %d: Maximum number of RACH attempts (%d)\n",module_idP,frameP,rach_ConfigCommon->ra_SupervisionInfo.preambleTransMax);
// send message to RRC
UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER=1;
UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER = get_Po_NOMINAL_PUSCH(module_idP);
UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER = get_Po_NOMINAL_PUSCH(module_idP,CC_id);
}
UE_mac_inst[module_idP].RA_window_cnt = 2+ rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize;
UE_mac_inst[module_idP].RA_backoff_cnt = 0;
// Fill in preamble and PRACH resource
get_prach_resources(module_idP,eNB_indexP,subframeP,0,NULL);
get_prach_resources(module_idP,CC_id,eNB_indexP,subframeP,0,NULL);
return(&UE_mac_inst[module_idP].RA_prach_resources);
}
}
......@@ -403,648 +435,3 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,frame_t frameP, uint8_t eN
}
return(NULL);
}
void cancel_ra_proc(module_id_t module_idP, frame_t frameP, rnti_t rnti) {
unsigned char i;
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d Cancelling RA procedure for UE rnti %x\n",module_idP,frameP,rnti);
for (i=0;i<NB_RA_PROC_MAX;i++) {
if (rnti == eNB_mac_inst[module_idP].RA_template[i].rnti) {
eNB_mac_inst[module_idP].RA_template[i].RA_active=FALSE;
eNB_mac_inst[module_idP].RA_template[i].generate_rar=0;
eNB_mac_inst[module_idP].RA_template[i].generate_Msg4=0;
eNB_mac_inst[module_idP].RA_template[i].wait_ack_Msg4=0;
eNB_mac_inst[module_idP].RA_template[i].timing_offset=0;
eNB_mac_inst[module_idP].RA_template[i].RRC_timer=20;
eNB_mac_inst[module_idP].RA_template[i].rnti = 0;
}
}
}
void terminate_ra_proc(module_id_t module_idP,frame_t frameP,rnti_t rnti,unsigned char *msg3, uint16_t msg3_len) {
unsigned char rx_ces[MAX_NUM_CE],num_ce,num_sdu,i,*payload_ptr;
unsigned char rx_lcids[NB_RB_MAX];
uint16_t rx_lengths[NB_RB_MAX];
int8_t UE_id;
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, Received msg3 %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n",
module_idP,frameP,
msg3[3],msg3[4],msg3[5],msg3[6],msg3[7], msg3[8], rnti);
for (i=0;i<NB_RA_PROC_MAX;i++) {
LOG_D(MAC,"[RAPROC] Checking proc %d : rnti (%x, %x), active %d\n",i,
eNB_mac_inst[module_idP].RA_template[i].rnti, rnti,
eNB_mac_inst[module_idP].RA_template[i].RA_active);
if ((eNB_mac_inst[module_idP].RA_template[i].rnti==rnti) &&
(eNB_mac_inst[module_idP].RA_template[i].RA_active==TRUE)) {
payload_ptr = parse_ulsch_header(msg3,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,msg3_len);
LOG_D(MAC,"[eNB %d][RAPROC] Frame %d Received CCCH: length %d, offset %d\n",
module_idP,frameP,rx_lengths[0],payload_ptr-msg3);
if (/*(num_ce == 0) &&*/ (num_sdu==1) && (rx_lcids[0] == CCCH)) { // This is an RRCConnectionRequest/Restablishment
memcpy(&eNB_mac_inst[module_idP].RA_template[i].cont_res_id[0],payload_ptr,6);
LOG_D(MAC,"[eNB %d][RAPROC] Frame %d Received CCCH: length %d, offset %d\n",
module_idP,frameP,rx_lengths[0],payload_ptr-msg3);
UE_id=add_new_ue(module_idP,eNB_mac_inst[module_idP].RA_template[i].rnti);
if (UE_id==-1) {
mac_xface->macphy_exit("[MAC][eNB] Max user count reached\n");
}
else {
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d Added user with rnti %x => UE %d\n",
module_idP,frameP,eNB_mac_inst[module_idP].RA_template[i].rnti,UE_id);
}
if (Is_rrc_registered == 1)
mac_rrc_data_ind(module_idP,frameP,CCCH,(uint8_t *)payload_ptr,rx_lengths[0],1,module_idP,0);
// add_user. This is needed to have the rnti for configuring UE (PHY). The UE is removed if RRC
// doesn't provide a CCCH SDU
}
else if (num_ce >0) { // handle msg3 which is not RRCConnectionRequest
// process_ra_message(msg3,num_ce,rx_lcids,rx_ces);
}
eNB_mac_inst[module_idP].RA_template[i].generate_Msg4 = 1;
eNB_mac_inst[module_idP].RA_template[i].wait_ack_Msg4 = 0;
return;
} // if process is active
} // loop on RA processes
}
void rx_sdu(module_id_t enb_mod_idP,frame_t frameP,rnti_t rntiP,uint8_t *sdu, uint16_t sdu_len) {
unsigned char rx_ces[MAX_NUM_CE],num_ce,num_sdu,i,*payload_ptr;
unsigned char rx_lcids[NB_RB_MAX];
unsigned short rx_lengths[NB_RB_MAX];
module_id_t ue_mod_id = find_UE_id(enb_mod_idP,rntiP);
int ii,j;
start_meas(&eNB_mac_inst[enb_mod_idP].rx_ulsch_sdu);
if ((ue_mod_id > NUMBER_OF_UE_MAX) || (ue_mod_id == -1) || (ue_mod_id == 255) )
for(ii=0; ii<NB_RB_MAX; ii++) rx_lengths[ii] = 0;
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,1);
LOG_D(MAC,"[eNB %d] Received ULSCH sdu from PHY (rnti %x, UE_id %d), parsing header\n",enb_mod_idP,rntiP,ue_mod_id);
payload_ptr = parse_ulsch_header(sdu,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,sdu_len);
// control element
for (i=0;i<num_ce;i++) {
switch (rx_ces[i]) { // implement and process BSR + CRNTI +
case POWER_HEADROOM:
if (ue_mod_id != UE_INDEX_INVALID ){
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].phr_info = (payload_ptr[0] & 0x3f);// - PHR_MAPPING_OFFSET;
LOG_D(MAC, "[eNB] MAC CE_LCID %d : Received PHR PH = %d (db)\n", rx_ces[i], eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].phr_info);
}
payload_ptr+=sizeof(POWER_HEADROOM_CMD);
break;
case CRNTI:
LOG_D(MAC, "[eNB] MAC CE_LCID %d : Received CRNTI %d \n", rx_ces[i], payload_ptr[0]);
payload_ptr+=1;
break;
case TRUNCATED_BSR:
case SHORT_BSR: {
if (ue_mod_id != UE_INDEX_INVALID ){
uint8_t lcgid;
lcgid = (payload_ptr[0] >> 6);
LOG_D(MAC, "[eNB] MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n",
rx_ces[i], lcgid, payload_ptr[0] & 0x3f);
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].bsr_info[lcgid] = (payload_ptr[0] & 0x3f);
}
payload_ptr += 1;//sizeof(SHORT_BSR); // fixme
} break;
case LONG_BSR:
if (ue_mod_id != UE_INDEX_INVALID ){
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].bsr_info[LCGID0] = ((payload_ptr[0] & 0xFC) >> 2);
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].bsr_info[LCGID1] =
((payload_ptr[0] & 0x03) << 4) | ((payload_ptr[1] & 0xF0) >> 4);
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].bsr_info[LCGID2] =
((payload_ptr[1] & 0x0F) << 2) | ((payload_ptr[2] & 0xC0) >> 6);
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].bsr_info[LCGID3] = (payload_ptr[2] & 0x3F);
LOG_D(MAC, "[eNB] MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
"%u LCGID2 = %u LCGID3 = %u\n",
rx_ces[i],
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].bsr_info[LCGID0],
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].bsr_info[LCGID1],
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].bsr_info[LCGID2],
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].bsr_info[LCGID3]);
}
payload_ptr += 3;////sizeof(LONG_BSR);
break;
default:
LOG_E(MAC, "[eNB] Received unknown MAC header (0x%02x)\n", rx_ces[i]);
break;
}
}
for (i=0;i<num_sdu;i++) {
LOG_D(MAC,"SDU Number %d MAC Subheader SDU_LCID %d, length %d\n",i,rx_lcids[i],rx_lengths[i]);
switch (rx_lcids[i]) {
case CCCH :
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, Received CCCH: %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n",
enb_mod_idP,frameP,
payload_ptr[0],payload_ptr[1],payload_ptr[2],payload_ptr[3],payload_ptr[4], payload_ptr[5], rntiP);
for (ii=0;ii<NB_RA_PROC_MAX;ii++) {
LOG_D(MAC,"[RAPROC] Checking proc %d : rnti (%x, %x), active %d\n",ii,
eNB_mac_inst[enb_mod_idP].RA_template[ii].rnti, rntiP,
eNB_mac_inst[enb_mod_idP].RA_template[ii].RA_active);
if ((eNB_mac_inst[enb_mod_idP].RA_template[ii].rnti==rntiP) &&
(eNB_mac_inst[enb_mod_idP].RA_template[ii].RA_active==TRUE)) {
//payload_ptr = parse_ulsch_header(msg3,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,msg3_len);
if (ue_mod_id == UE_INDEX_INVALID) {
memcpy(&eNB_mac_inst[enb_mod_idP].RA_template[ii].cont_res_id[0],payload_ptr,6);
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d CCCH: Received RRCConnectionRequest: length %d, offset %d\n",
enb_mod_idP,frameP,rx_lengths[ii],payload_ptr-sdu);
if ((ue_mod_id=add_new_ue(enb_mod_idP,eNB_mac_inst[enb_mod_idP].RA_template[ii].rnti)) == -1 )
mac_xface->macphy_exit("[MAC][eNB] Max user count reached\n");
else
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d Added user with rnti %x => UE %d\n",
enb_mod_idP,frameP,eNB_mac_inst[enb_mod_idP].RA_template[ii].rnti,ue_mod_id);
} else {
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d CCCH: Received RRCConnectionReestablishment from UE %d: length %d, offset %d\n",
enb_mod_idP,frameP,ue_mod_id,rx_lengths[ii],payload_ptr-sdu);
}
if (Is_rrc_registered == 1)
mac_rrc_data_ind(enb_mod_idP,frameP,CCCH,(uint8_t *)payload_ptr,rx_lengths[ii],1,enb_mod_idP,0);
if (num_ce >0) { // handle msg3 which is not RRCConnectionRequest
// process_ra_message(msg3,num_ce,rx_lcids,rx_ces);
}
eNB_mac_inst[enb_mod_idP].RA_template[ii].generate_Msg4 = 1;
eNB_mac_inst[enb_mod_idP].RA_template[ii].wait_ack_Msg4 = 0;
} // if process is active
} // loop on RA processes
break;
case DCCH :
case DCCH1 :
// if(eNB_mac_inst[module_idP].Dcch_lchan[UE_id].Active==1){
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sdu));
for (j=0;j<32;j++)
LOG_T(MAC,"%x ",payload_ptr[j]);
LOG_T(MAC,"\n");
#endif
// This check is just to make sure we didn't get a bogus SDU length, to be removed ...
if (rx_lengths[i]<CCCH_PAYLOAD_SIZE_MAX) {
LOG_D(MAC,"[eNB %d] Frame %d : ULSCH -> UL-DCCH, received %d bytes form UE %d on LCID %d(%d) \n",
enb_mod_idP,frameP, rx_lengths[i], ue_mod_id, rx_lcids[i], rx_lcids[i]);
mac_rlc_data_ind(enb_mod_idP,ue_mod_id, frameP,ENB_FLAG_YES,MBMS_FLAG_NO,
rx_lcids[i],
(char *)payload_ptr,
rx_lengths[i],
1,
NULL);//(unsigned int*)crc_status);
eNB_mac_inst[enb_mod_idP].eNB_UE_stats[ue_mod_id].num_pdu_rx[rx_lcids[i]]+=1;
eNB_mac_inst[enb_mod_idP].eNB_UE_stats[ue_mod_id].num_bytes_rx[rx_lcids[i]]+=rx_lengths[i];
}
// }
break;
case DTCH: // default DRB
// if(eNB_mac_inst[module_idP].Dcch_lchan[UE_id].Active==1){
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sdu));
for (j=0;j<32;j++)
LOG_T(MAC,"%x ",payload_ptr[j]);
LOG_T(MAC,"\n");
#endif
LOG_D(MAC,"[eNB %d] Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d (%d)\n",
enb_mod_idP,frameP, rx_lengths[i], ue_mod_id,rx_lcids[i],rx_lcids[i]);
if ((rx_lengths[i] <SCH_PAYLOAD_SIZE_MAX) && (rx_lengths[i] > 0) ) { // MAX SIZE OF transport block
mac_rlc_data_ind(enb_mod_idP,ue_mod_id, frameP,ENB_FLAG_YES,MBMS_FLAG_NO,
DTCH,
(char *)payload_ptr,
rx_lengths[i],
1,
NULL);//(unsigned int*)crc_status);
eNB_mac_inst[enb_mod_idP].eNB_UE_stats[ue_mod_id].num_pdu_rx[rx_lcids[i]]+=1;
eNB_mac_inst[enb_mod_idP].eNB_UE_stats[ue_mod_id].num_bytes_rx[rx_lcids[i]]+=rx_lengths[i];
}
// }
break;
default : //if (rx_lcids[i] >= DTCH) {
eNB_mac_inst[enb_mod_idP].eNB_UE_stats[ue_mod_id].num_errors_rx+=1;
LOG_E(MAC,"[eNB %d] received unsupported or unknown LCID %d from UE %d ", rx_lcids[i], ue_mod_id);
break;
}
payload_ptr+=rx_lengths[i];
}
eNB_mac_inst[enb_mod_idP].eNB_UE_stats[ue_mod_id].total_pdu_bytes_rx+=sdu_len;
eNB_mac_inst[enb_mod_idP].eNB_UE_stats[ue_mod_id].total_num_pdus_rx+=1;
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,0);
stop_meas(&eNB_mac_inst[enb_mod_idP].rx_ulsch_sdu);
}
// First stage of Random-Access Scheduling
void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP,unsigned char Msg3_subframe,unsigned char *nprb,unsigned int *nCCE) {
start_meas(&eNB_mac_inst[module_idP].schedule_ra);
RA_TEMPLATE *RA_template = (RA_TEMPLATE *)&eNB_mac_inst[module_idP].RA_template[0];
unsigned char i;//,harq_pid,round;
uint16_t rrc_sdu_length;
unsigned char lcid,offset;
module_id_t UE_id= UE_INDEX_INVALID;
unsigned short TBsize = -1;
unsigned short msg4_padding,msg4_post_padding,msg4_header;
for (i=0;i<NB_RA_PROC_MAX;i++) {
if (RA_template[i].RA_active == TRUE) {
LOG_I(MAC,"[eNB %d][RAPROC] RA %d is active (generate RAR %d, generate_Msg4 %d, wait_ack_Msg4 %d, rnti %x)\n",
module_idP,i,RA_template[i].generate_rar,RA_template[i].generate_Msg4,RA_template[i].wait_ack_Msg4, RA_template[i].rnti);
if (RA_template[i].generate_rar == 1) {
*nprb= (*nprb) + 3;
*nCCE = (*nCCE) + 4;
RA_template[i].Msg3_subframe=Msg3_subframe;
}
else if (RA_template[i].generate_Msg4 == 1) {
// check for Msg4 Message
UE_id = find_UE_id(module_idP,RA_template[i].rnti);
if (Is_rrc_registered == 1) {
// Get RRCConnectionSetup for Piggyback
rrc_sdu_length = mac_rrc_data_req(module_idP,
frameP,
CCCH,1,
&eNB_mac_inst[module_idP].CCCH_pdu.payload[0],
1,
module_idP,
0); // not used in this case
if (rrc_sdu_length == -1)
mac_xface->macphy_exit("[MAC][eNB Scheduler] CCCH not allocated\n");
else {
//msg("[MAC][eNB %d] Frame %d, subframeP %d: got %d bytes from RRC\n",module_idP,frameP, subframeP,rrc_sdu_length);
}
}
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d: UE_id %d, Is_rrc_registered %d, rrc_sdu_length %d\n",
module_idP,frameP, subframeP,UE_id, Is_rrc_registered,rrc_sdu_length);
if (rrc_sdu_length>0) {
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RA proc %d, RNTI %x)\n",
module_idP,frameP, subframeP,i,RA_template[i].rnti);
//msg("[MAC][eNB %d][RAPROC] Frame %d, subframeP %d: Received %d bytes for Msg4: \n",module_idP,frameP,subframeP,rrc_sdu_length);
// for (j=0;j<rrc_sdu_length;j++)
// msg("%x ",(unsigned char)eNB_mac_inst[module_idP].CCCH_pdu.payload[j]);
// msg("\n");
// msg("[MAC][eNB] Frame %d, subframeP %d: Generated DLSCH (Msg4) DCI, format 1A, for UE %d\n",frameP, subframeP,UE_id);
// Schedule Reflection of Connection request
// Compute MCS for 3 PRB
msg4_header = 1+6+1; // CR header, CR CE, SDU header
if (mac_xface->lte_frame_parms->frame_type == TDD) {
switch (mac_xface->lte_frame_parms->N_RB_DL) {
case 6:
((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1;
if ((rrc_sdu_length+msg4_header) <= 22) {
((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4;
TBsize = 22;
}
else if ((rrc_sdu_length+msg4_header) <= 28) {
((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5;
TBsize = 28;
}
else if ((rrc_sdu_length+msg4_header) <= 32) {
((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6;
TBsize = 32;
}
else if ((rrc_sdu_length+msg4_header) <= 41) {
((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7;
TBsize = 41;
}
else if ((rrc_sdu_length+msg4_header) <= 49) {
((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8;
TBsize = 49;
}
else if ((rrc_sdu_length+msg4_header) <= 57) {
((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9;
TBsize = 57;
}
break;
case 25:
((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1;
if ((rrc_sdu_length+msg4_header) <= 22) {
((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4;
TBsize = 22;
}
else if ((rrc_sdu_length+msg4_header) <= 28) {
((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5;
TBsize = 28;
}
else if ((rrc_sdu_length+msg4_header) <= 32) {
((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6;
TBsize = 32;
}
else if ((rrc_sdu_length+msg4_header) <= 41) {
((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7;
TBsize = 41;
}
else if ((rrc_sdu_length+msg4_header) <= 49) {
((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8;
TBsize = 49;
}
else if ((rrc_sdu_length+msg4_header) <= 57) {
((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9;
TBsize = 57;
}
break;
case 50:
((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1;
if ((rrc_sdu_length+msg4_header) <= 22) {
((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4;
TBsize = 22;
}
else if ((rrc_sdu_length+msg4_header) <= 28) {
((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5;
TBsize = 28;
}
else if ((rrc_sdu_length+msg4_header) <= 32) {
((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6;
TBsize = 32;
}
else if ((rrc_sdu_length+msg4_header) <= 41) {
((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7;
TBsize = 41;
}
else if ((rrc_sdu_length+msg4_header) <= 49) {
((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8;
TBsize = 49;
}
else if ((rrc_sdu_length+msg4_header) <= 57) {
((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9;
TBsize = 57;
}
break;
case 100:
((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1;
if ((rrc_sdu_length+msg4_header) <= 22) {
((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4;
TBsize = 22;
}
else if ((rrc_sdu_length+msg4_header) <= 28) {
((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5;
TBsize = 28;
}
else if ((rrc_sdu_length+msg4_header) <= 32) {
((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6;
TBsize = 32;
}
else if ((rrc_sdu_length+msg4_header) <= 41) {
((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7;
TBsize = 41;
}
else if ((rrc_sdu_length+msg4_header) <= 49) {
((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8;
TBsize = 49;
}
else if ((rrc_sdu_length+msg4_header) <= 57) {
((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9;
TBsize = 57;
}
break;
}
}
else { // FDD DCI
switch (mac_xface->lte_frame_parms->N_RB_DL) {
case 6:
((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1;
if ((rrc_sdu_length+msg4_header) <= 22) {
((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4;
TBsize = 22;
}
else if ((rrc_sdu_length+msg4_header) <= 28) {
((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5;
TBsize = 28;
}
else if ((rrc_sdu_length+msg4_header) <= 32) {
((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6;
TBsize = 32;
}
else if ((rrc_sdu_length+msg4_header) <= 41) {
((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7;
TBsize = 41;
}
else if ((rrc_sdu_length+msg4_header) <= 49) {
((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8;
TBsize = 49;
}
else if ((rrc_sdu_length+msg4_header) <= 57) {
((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9;
TBsize = 57;
}
break;
case 25:
((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1;
if ((rrc_sdu_length+msg4_header) <= 22) {
((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4;
TBsize = 22;
}
else if ((rrc_sdu_length+msg4_header) <= 28) {
((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5;
TBsize = 28;
}
else if ((rrc_sdu_length+msg4_header) <= 32) {
((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6;
TBsize = 32;
}
else if ((rrc_sdu_length+msg4_header) <= 41) {
((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7;
TBsize = 41;
}
else if ((rrc_sdu_length+msg4_header) <= 49) {
((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8;
TBsize = 49;
}
else if ((rrc_sdu_length+msg4_header) <= 57) {
((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9;
TBsize = 57;
}
break;
case 50:
((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1;
if ((rrc_sdu_length+msg4_header) <= 22) {
((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4;
TBsize = 22;
}
else if ((rrc_sdu_length+msg4_header) <= 28) {
((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5;
TBsize = 28;
}
else if ((rrc_sdu_length+msg4_header) <= 32) {
((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6;
TBsize = 32;
}
else if ((rrc_sdu_length+msg4_header) <= 41) {
((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7;
TBsize = 41;
}
else if ((rrc_sdu_length+msg4_header) <= 49) {
((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8;
TBsize = 49;
}
else if ((rrc_sdu_length+msg4_header) <= 57) {
((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9;
TBsize = 57;
}
break;
case 100:
((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1;
if ((rrc_sdu_length+msg4_header) <= 22) {
((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4;
TBsize = 22;
}
else if ((rrc_sdu_length+msg4_header) <= 28) {
((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5;
TBsize = 28;
}
else if ((rrc_sdu_length+msg4_header) <= 32) {
((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6;
TBsize = 32;
}
else if ((rrc_sdu_length+msg4_header) <= 41) {
((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7;
TBsize = 41;
}
else if ((rrc_sdu_length+msg4_header) <= 49) {
((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8;
TBsize = 49;
}
else if ((rrc_sdu_length+msg4_header) <= 57) {
((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9;
TBsize = 57;
}
break;
}
}
RA_template[i].generate_Msg4=0;
RA_template[i].generate_Msg4_dci=1;
RA_template[i].wait_ack_Msg4=1;
RA_template[i].RA_active = FALSE;
lcid=0;
if ((TBsize - rrc_sdu_length - msg4_header) <= 2) {
msg4_padding = TBsize - rrc_sdu_length - msg4_header;
msg4_post_padding = 0;
}
else {
msg4_padding = 0;
msg4_post_padding = TBsize - rrc_sdu_length - msg4_header -1;
}
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d subframeP %d Msg4 : TBS %d, sdu_len %d, msg4_header %d, msg4_padding %d, msg4_post_padding %d\n",
module_idP,frameP,subframeP,TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding);
offset = generate_dlsch_header((unsigned char*)eNB_mac_inst[module_idP].DLSCH_pdu[(unsigned char)UE_id][0].payload[0],
1, //num_sdus
&rrc_sdu_length, //
&lcid, // sdu_lcid
255, // no drx
0, // no timing advance
RA_template[i].cont_res_id, // contention res id
msg4_padding, // no padding
msg4_post_padding);
memcpy((void*)&eNB_mac_inst[module_idP].DLSCH_pdu[(unsigned char)UE_id][0].payload[0][(unsigned char)offset],
&eNB_mac_inst[module_idP].CCCH_pdu.payload[0],
rrc_sdu_length);
#if defined(USER_MODE) && defined(OAI_EMU)
if (oai_emulation.info.opt_enabled){
trace_pdu(1, (uint8_t *)eNB_mac_inst[module_idP].DLSCH_pdu[(unsigned char)UE_id][0].payload[0],
rrc_sdu_length, UE_id, 3, find_UE_RNTI(module_idP, UE_id),
eNB_mac_inst[module_idP].subframe,0,0);
LOG_D(OPT,"[eNB %d][DLSCH] Frame %d trace pdu for rnti %x with size %d\n",
module_idP, frameP, find_UE_RNTI(module_idP,UE_id), rrc_sdu_length);
}
#endif
*nprb= (*nprb) + 3;
*nCCE = (*nCCE) + 4;
}
//try here
}
/*
else if (eNB_mac_inst[module_idP].RA_template[i].wait_ack_Msg4==1) {
// check HARQ status and retransmit if necessary
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d: Checking if Msg4 was acknowledged :\n",module_idP,frameP,subframeP);
// Get candidate harq_pid from PHY
mac_xface->get_ue_active_harq_pid(module_idP,eNB_mac_inst[module_idP].RA_template[i].rnti,subframeP,&harq_pid,&round,0);
if (round>0) {
*nprb= (*nprb) + 3;
*nCCE = (*nCCE) + 4;
}
}
*/
}
}
stop_meas(&eNB_mac_inst[module_idP].schedule_ra);
}
void initiate_ra_proc(module_id_t module_idP, frame_t frameP, uint16_t preamble_index,int16_t timing_offset,uint8_t sect_id,sub_frame_t subframeP,uint8_t f_id) {
uint8_t i;
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d Initiating RA procedure for preamble index %d\n",module_idP,frameP,preamble_index);
for (i=0;i<NB_RA_PROC_MAX;i++) {
if (eNB_mac_inst[module_idP].RA_template[i].RA_active==FALSE) {
eNB_mac_inst[module_idP].RA_template[i].RA_active=TRUE;
eNB_mac_inst[module_idP].RA_template[i].generate_rar=1;
eNB_mac_inst[module_idP].RA_template[i].generate_Msg4=0;
eNB_mac_inst[module_idP].RA_template[i].wait_ack_Msg4=0;
eNB_mac_inst[module_idP].RA_template[i].timing_offset=timing_offset;
// Put in random rnti (to be replaced with proper procedure!!)
eNB_mac_inst[module_idP].RA_template[i].rnti = taus();
eNB_mac_inst[module_idP].RA_template[i].RA_rnti = 1+subframeP+(10*f_id);
eNB_mac_inst[module_idP].RA_template[i].preamble_index = preamble_index;
LOG_D(MAC,"[eNB %d][RAPROC] Frame %d Activating RAR generation for process %d, rnti %x, RA_active %d\n",
module_idP,frameP,i,eNB_mac_inst[module_idP].RA_template[i].rnti,
eNB_mac_inst[module_idP].RA_template[i].RA_active);
return;
}
}
}
......@@ -57,6 +57,7 @@ extern unsigned short RIV2first_rb_LUT25[512];
extern inline unsigned int taus(void);
unsigned short fill_rar(module_id_t module_idP,
int CC_id,
frame_t frameP,
uint8_t *dlsch_buffer,
uint16_t N_RB_UL,
......@@ -70,9 +71,9 @@ unsigned short fill_rar(module_id_t module_idP,
uint8_t mcs,TPC,ULdelay,cqireq;
for (i=0;i<NB_RA_PROC_MAX;i++) {
if (eNB_mac_inst[module_idP].RA_template[i].generate_rar == 1) {
if (eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[i].generate_rar == 1) {
ra_idx=i;
eNB_mac_inst[module_idP].RA_template[i].generate_rar = 0;
eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[i].generate_rar = 0;
break;
}
}
......@@ -80,24 +81,24 @@ unsigned short fill_rar(module_id_t module_idP,
// subheader fixed
rarh->E = 0; // First and last RAR
rarh->T = 1; // 0 for E/T/R/R/BI subheader, 1 for E/T/RAPID subheader
rarh->RAPID = eNB_mac_inst[module_idP].RA_template[ra_idx].preamble_index; // Respond to Preamble 0 only for the moment
rarh->RAPID = eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].preamble_index; // Respond to Preamble 0 only for the moment
/*
rar->R = 0;
rar->Timing_Advance_Command = eNB_mac_inst[module_idP].RA_template[ra_idx].timing_offset/4;
rar->Timing_Advance_Command = eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset/4;
rar->hopping_flag = 0;
rar->rb_alloc = mac_xface->computeRIV(N_RB_UL,12,2); // 2 RB
rar->mcs = 2; // mcs 2
rar->TPC = 4; // 2 dB power adjustment
rar->UL_delay = 0;
rar->cqi_req = 1;
rar->t_crnti = eNB_mac_inst[module_idP].RA_template[ra_idx].rnti;
rar->t_crnti = eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].rnti;
*/
rar[4] = (uint8_t)(eNB_mac_inst[module_idP].RA_template[ra_idx].rnti>>8);
rar[5] = (uint8_t)(eNB_mac_inst[module_idP].RA_template[ra_idx].rnti&0xff);
eNB_mac_inst[module_idP].RA_template[ra_idx].timing_offset = 0;
//eNB_mac_inst[module_idP].RA_template[ra_idx].timing_offset /= 16;
rar[0] = (uint8_t)(eNB_mac_inst[module_idP].RA_template[ra_idx].timing_offset>>(2+4)); // 7 MSBs of timing advance + divide by 4
rar[1] = (uint8_t)(eNB_mac_inst[module_idP].RA_template[ra_idx].timing_offset<<(4-2))&0xf0; // 4 LSBs of timing advance + divide by 4
rar[4] = (uint8_t)(eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].rnti>>8);
rar[5] = (uint8_t)(eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].rnti&0xff);
eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset = 0;
//eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset /= 16;
rar[0] = (uint8_t)(eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset>>(2+4)); // 7 MSBs of timing advance + divide by 4
rar[1] = (uint8_t)(eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset<<(4-2))&0xf0; // 4 LSBs of timing advance + divide by 4
rballoc = mac_xface->computeRIV(N_RB_UL,1,1); // first PRB only for UL Grant
rar[1] |= (rballoc>>7)&7; // Hopping = 0 (bit 3), 3 MSBs of rballoc
rar[2] = ((uint8_t)(rballoc&0xff))<<1; // 7 LSBs of rballoc
......@@ -111,28 +112,33 @@ unsigned short fill_rar(module_id_t module_idP,
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d Generating RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for ra_idx %d, CRNTI %x,preamble %d/%d,TIMING OFFSET %d\n",module_idP,frameP,
*(uint8_t*)rarh,rar[0],rar[1],rar[2],rar[3],rar[4],rar[5],
ra_idx,
eNB_mac_inst[module_idP].RA_template[ra_idx].rnti,
rarh->RAPID,eNB_mac_inst[module_idP].RA_template[0].preamble_index,
eNB_mac_inst[module_idP].RA_template[ra_idx].timing_offset);
eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].rnti,
rarh->RAPID,eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[0].preamble_index,
eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset);
#if defined(USER_MODE) && defined(OAI_EMU)
if (oai_emulation.info.opt_enabled){
trace_pdu(1, dlsch_buffer, input_buffer_length, module_idP, 2, 1,
eNB_mac_inst[module_idP].subframe, 0, 0);
LOG_I(OPT,"[eNB %d][RAPROC] RAR Frame %d trace pdu for rnti %x and rapid %d size %d\n",
module_idP, frameP, eNB_mac_inst[module_idP].RA_template[ra_idx].rnti,
module_idP, frameP, eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].rnti,
rarh->RAPID, input_buffer_length);
}
#endif
return(eNB_mac_inst[module_idP].RA_template[ra_idx].rnti);
return(eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].rnti);
}
uint16_t ue_process_rar(module_id_t module_idP, frame_t frameP, uint8_t *dlsch_buffer,rnti_t *t_crnti,uint8_t preamble_index) {
uint16_t ue_process_rar(module_id_t module_idP, int CC_id,frame_t frameP, uint8_t *dlsch_buffer,rnti_t *t_crnti,uint8_t preamble_index) {
RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *)dlsch_buffer;
// RAR_PDU *rar = (RAR_PDU *)(dlsch_buffer+1);
uint8_t *rar = (uint8_t *)(dlsch_buffer+1);
if (CC_id>0) {
LOG_W(MAC,"Should not have received RAR on secondary CCs! \n");
return(0xffff);
}
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n",module_idP,frameP,
*(uint8_t*)rarh,rar[0],rar[1],rar[2],rar[3],rar[4],rar[5],
rarh->RAPID,preamble_index);
......
......@@ -95,10 +95,8 @@ extern inline unsigned int taus(void);
void ue_init_mac(module_id_t module_idP){
int i;
// default values as deined in 36.331 sec 9.2.2
LOG_I(MAC,"[UE%d] Applying default macMainConfig\n",module_idP);
//UE_mac_inst[module_idP].scheduling_info.macConfig=NULL;
UE_mac_inst[module_idP].scheduling_info.retxBSR_Timer= MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf2560;
UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer=MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity;
......@@ -131,6 +129,7 @@ void ue_init_mac(module_id_t module_idP){
}
}
unsigned char *parse_header(unsigned char *mac_header,
unsigned char *num_ce,
unsigned char *num_sdu,
......@@ -203,7 +202,7 @@ unsigned char *parse_header(unsigned char *mac_header,
return(mac_header_ptr);
}
uint32_t ue_get_SR(module_id_t module_idP,frame_t frameP,uint8_t eNB_id,uint16_t rnti, sub_frame_t subframe) {
uint32_t ue_get_SR(module_id_t module_idP,int CC_id,frame_t frameP,uint8_t eNB_id,uint16_t rnti, sub_frame_t subframe) {
// no UL-SCH resources available for this tti && UE has a valid PUCCH resources for SR configuration for this tti
// int MGL=6;// measurement gap length in ms
......@@ -213,6 +212,12 @@ uint32_t ue_get_SR(module_id_t module_idP,frame_t frameP,uint8_t eNB_id,uint16_t
DevCheck(module_idP < NB_UE_INST, module_idP, NB_UE_INST, 0);
if (CC_id>0) {
LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n");
mac_xface->macphy_exit("MAC FATAL CC_id>0");
return;
}
// determin the measurement gap
LOG_D(MAC,"[UE %d][SR %x] Frame %d subframe %d PHY asks for SR (SR_COUNTER/dsr_TransMax %d/%d), SR_pending %d\n",
module_idP,rnti,frameP,subframe,
......@@ -269,7 +274,7 @@ uint32_t ue_get_SR(module_id_t module_idP,frame_t frameP,uint8_t eNB_id,uint16_t
}
}
void ue_send_sdu(module_id_t module_idP,frame_t frameP,uint8_t *sdu,uint16_t sdu_len,uint8_t eNB_index) {
void ue_send_sdu(module_id_t module_idP,int CC_id,frame_t frameP,uint8_t *sdu,uint16_t sdu_len,uint8_t eNB_index) {
unsigned char rx_ces[MAX_NUM_CE],num_ce,num_sdu,i,*payload_ptr;
unsigned char rx_lcids[NB_RB_MAX];
......@@ -319,14 +324,14 @@ void ue_send_sdu(module_id_t module_idP,frame_t frameP,uint8_t *sdu,uint16_t sdu
for (i=0;i<6;i++)
if (tx_sdu[i] != payload_ptr[i]) {
LOG_E(MAC,"[UE %d][RAPROC] Contention detected, RA failed\n",module_idP);
mac_xface->ra_failed(module_idP,eNB_index);
mac_xface->ra_failed(module_idP,CC_id,eNB_index);
UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0;
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT);
return;
}
LOG_I(MAC,"[UE %d][RAPROC] Frame %d : Clearing contention resolution timer\n");
UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0;
mac_xface->ra_succeeded(module_idP,eNB_index);
mac_xface->ra_succeeded(module_idP,CC_id,eNB_index);
}
payload_ptr+=6;
break;
......@@ -418,7 +423,7 @@ void ue_send_sdu(module_id_t module_idP,frame_t frameP,uint8_t *sdu,uint16_t sdu
stop_meas(&UE_mac_inst[module_idP].rx_dlsch_sdu);
}
void ue_decode_si(module_id_t module_idP,frame_t frameP, uint8_t eNB_index, void *pdu,uint16_t len) {
void ue_decode_si(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_index, void *pdu,uint16_t len) {
start_meas(&UE_mac_inst[module_idP].rx_si);
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_IN);
......@@ -1030,7 +1035,7 @@ unsigned char generate_ulsch_header(uint8_t *mac_header,
}
void ue_get_sdu(module_id_t module_idP,frame_t frameP,sub_frame_t subframe, uint8_t eNB_index,uint8_t *ulsch_buffer,uint16_t buflen, uint8_t *access_mode) {
void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subframe, uint8_t eNB_index,uint8_t *ulsch_buffer,uint16_t buflen, uint8_t *access_mode) {
mac_rlc_status_resp_t rlc_status;
uint8_t dcch_header_len=0,dcch1_header_len=0,dtch_header_len=0;
......@@ -1053,6 +1058,12 @@ void ue_get_sdu(module_id_t module_idP,frame_t frameP,sub_frame_t subframe, uint
int j; // used for padding
// Compute header length
if (CC_id>0) {
LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n");
mac_xface->macphy_exit("MAC FATAL CC_id>0");
return;
}
start_meas(&UE_mac_inst[module_idP].tx_ulsch_sdu);
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GET_SDU, VCD_FUNCTION_IN);
......@@ -1217,11 +1228,11 @@ void ue_get_sdu(module_id_t module_idP,frame_t frameP,sub_frame_t subframe, uint
// build PHR and update the timers
if (phr_ce_len == sizeof(POWER_HEADROOM_CMD)){
phr_p->PH = get_phr_mapping(module_idP,eNB_index);
phr_p->PH = get_phr_mapping(module_idP,CC_id,eNB_index);
phr_p->R = 0;
LOG_D(MAC,"[UE %d] Frame %d report PHR with mapping (%d->%d) for LCID %d\n",
module_idP,frameP, mac_xface->get_PHR(module_idP,eNB_index), phr_p->PH,POWER_HEADROOM);
update_phr(module_idP);
module_idP,frameP, mac_xface->get_PHR(module_idP,CC_id,eNB_index), phr_p->PH,POWER_HEADROOM);
update_phr(module_idP,CC_id);
}else
phr_p=NULL;
......@@ -1416,7 +1427,7 @@ UE_L2_STATE_t ue_scheduler(module_id_t module_idP,frame_t frameP, sub_frame_t su
UE_mac_inst[module_idP].RA_active = 0;
// Signal PHY to quit RA procedure
LOG_E(MAC,"Module id %u Contention resolution timer expired, RA failed\n", module_idP);
mac_xface->ra_failed(module_idP,eNB_indexP);
mac_xface->ra_failed(module_idP,0,eNB_indexP);
}
}
......@@ -1573,6 +1584,7 @@ uint8_t get_bsr_len (module_id_t module_idP, uint16_t buflen) {
uint8_t bsr_len=0, num_lcgid=0;
int pdu = 0;
for (lcgid=0; lcgid < MAX_NUM_LCGID; lcgid++ ) {
if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid] > 0 )
pdu += (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid] + bsr_len + 2); //2 = sizeof(SCH_SUBHEADER_SHORT)
......@@ -1597,6 +1609,8 @@ boolean_t update_bsr(module_id_t module_idP, frame_t frameP, uint8_t lcid, uint
mac_rlc_status_resp_t rlc_status;
boolean_t sr_pending = FALSE;
if ((lcg_id < 0) || (lcg_id > MAX_NUM_LCGID) )
return sr_pending;
// fixme: need a better way to reset
......@@ -1754,23 +1768,34 @@ int get_ms_bucketsizeduration(uint8_t bucketsizeduration){
}
}
void update_phr(module_id_t module_idP){
void update_phr(module_id_t module_idP,int CC_id){
if (CC_id>0) {
LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n");
mac_xface->macphy_exit("MAC FATAL CC_id>0");
return;
}
UE_mac_inst[module_idP].PHR_reporting_active =0;
UE_mac_inst[module_idP].scheduling_info.periodicPHR_SF = get_sf_perioidicPHR_Timer(UE_mac_inst[module_idP].scheduling_info.periodicPHR_Timer);
UE_mac_inst[module_idP].scheduling_info.prohibitPHR_SF = get_sf_prohibitPHR_Timer(UE_mac_inst[module_idP].scheduling_info.prohibitPHR_Timer);
// LOG_D(MAC,"phr %d %d\n ",UE_mac_inst[module_idP].scheduling_info.periodicPHR_SF, UE_mac_inst[module_idP].scheduling_info.prohibitPHR_SF);
}
uint8_t get_phr_mapping (module_id_t module_idP, uint8_t eNB_index){
uint8_t get_phr_mapping (module_id_t module_idP, int CC_id, uint8_t eNB_index){
if (CC_id>0) {
LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n");
mac_xface->macphy_exit("MAC FATAL CC_id>0");
return;
}
//power headroom reporting range is from -23 ...+40 dB, as described in 36313
//note: mac_xface->get_Po_NOMINAL_PUSCH(module_idP) is float
if (mac_xface->get_PHR(module_idP,eNB_index) < -23)
if (mac_xface->get_PHR(module_idP,CC_id,eNB_index) < -23)
return 0;
else if (mac_xface->get_PHR(module_idP,eNB_index) >= 40)
else if (mac_xface->get_PHR(module_idP,CC_id,eNB_index) >= 40)
return 63;
else // -23 to 40
return (uint8_t) mac_xface->get_PHR(module_idP,eNB_index) + PHR_MAPPING_OFFSET;
return (uint8_t) mac_xface->get_PHR(module_idP,CC_id,eNB_index) + PHR_MAPPING_OFFSET;
}
int get_sf_perioidicPHR_Timer(uint8_t perioidicPHR_Timer){
......
......@@ -61,6 +61,11 @@ UE_MAC_INST *UE_mac_inst; //[NB_MODULE_MAX];
eNB_MAC_INST *eNB_mac_inst; //[NB_MODULE_MAX];
MAC_RLC_XFACE *Mac_rlc_xface;
/// Primary component carrier index of eNB
int pCC_id[NUMBER_OF_eNB_MAX];
eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8
eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8
......
......@@ -89,6 +89,7 @@ MAC_OBJS += $(MAC_DIR)/eNB_scheduler_ulsch.o
MAC_OBJS += $(MAC_DIR)/eNB_scheduler_mch.o
MAC_OBJS += $(MAC_DIR)/eNB_scheduler_bch.o
MAC_OBJS += $(MAC_DIR)/eNB_scheduler_primitives.o
MAC_OBJS += $(MAC_DIR)/eNB_scheduler_RA.o
MAC_OBJS += $(MAC_DIR)/pre_processor.o
MAC_OBJS += $(MAC_DIR)/config.o
......
......@@ -68,74 +68,81 @@ static mapping rrc_status_names[] = {
int dump_eNB_l2_stats(char *buffer, int length){
uint8_t eNB_id,UE_id,number_of_cards;
int eNB_id,UE_id,number_of_cards;
int len= length;
int CC_id=0;
int i;
#ifdef EXMIMO
number_of_cards=1;
#else
number_of_cards=NB_eNB_INST;
#endif
eNB_MAC_INST *eNB;
UE_list_t *UE_list;
for (eNB_id=0;eNB_id<number_of_cards;eNB_id++) {
/* reset the values */
eNB_mac_inst[eNB_id].eNB_stats.dlsch_bitrate= 0;
eNB = &eNB_mac_inst[eNB_id];
UE_list = &eNB->UE_list;
eNB->eNB_stats.dlsch_bitrate= 0;
len += sprintf(&buffer[len],"eNB %d Frame %d: Active UEs %d, Available PRBs %d, nCCE %d \n",
eNB_id, eNB_mac_inst[eNB_id].frame,
eNB_mac_inst[eNB_id].eNB_stats.num_dlactive_UEs,
eNB_mac_inst[eNB_id].eNB_stats.available_prbs,
eNB_mac_inst[eNB_id].eNB_stats.available_ncces);
eNB_id, eNB->frame,
eNB->eNB_stats.num_dlactive_UEs,
eNB->eNB_stats.available_prbs,
eNB->eNB_stats.available_ncces);
eNB_mac_inst[eNB_id].eNB_stats.dlsch_bitrate=((eNB_mac_inst[eNB_id].eNB_stats.dlsch_bytes_tx*8)/((eNB_mac_inst[eNB_id].frame + 1)*10));
eNB_mac_inst[eNB_id].eNB_stats.total_dlsch_pdus_tx+=eNB_mac_inst[eNB_id].eNB_stats.dlsch_pdus_tx;
eNB_mac_inst[eNB_id].eNB_stats.total_dlsch_bytes_tx+=eNB_mac_inst[eNB_id].eNB_stats.dlsch_bytes_tx;
eNB_mac_inst[eNB_id].eNB_stats.total_dlsch_bitrate=((eNB_mac_inst[eNB_id].eNB_stats.total_dlsch_bytes_tx*8)/((eNB_mac_inst[eNB_id].frame + 1)*10));
eNB->eNB_stats.dlsch_bitrate=((eNB->eNB_stats.dlsch_bytes_tx*8)/((eNB->frame + 1)*10));
eNB->eNB_stats.total_dlsch_pdus_tx+=eNB->eNB_stats.dlsch_pdus_tx;
eNB->eNB_stats.total_dlsch_bytes_tx+=eNB->eNB_stats.dlsch_bytes_tx;
eNB->eNB_stats.total_dlsch_bitrate=((eNB->eNB_stats.total_dlsch_bytes_tx*8)/((eNB->frame + 1)*10));
len += sprintf(&buffer[len],"DLSCH bitrate (TTI %u, avg %u) kbps, Transmitted bytes (TTI %u, total %u), Transmitted PDU (TTI %u, total %u) \n",
eNB_mac_inst[eNB_id].eNB_stats.dlsch_bitrate,
eNB_mac_inst[eNB_id].eNB_stats.total_dlsch_bitrate,
eNB_mac_inst[eNB_id].eNB_stats.dlsch_bytes_tx,
eNB_mac_inst[eNB_id].eNB_stats.total_dlsch_bytes_tx,
eNB_mac_inst[eNB_id].eNB_stats.dlsch_pdus_tx,
eNB_mac_inst[eNB_id].eNB_stats.total_dlsch_pdus_tx);
eNB->eNB_stats.dlsch_bitrate,
eNB->eNB_stats.total_dlsch_bitrate,
eNB->eNB_stats.dlsch_bytes_tx,
eNB->eNB_stats.total_dlsch_bytes_tx,
eNB->eNB_stats.dlsch_pdus_tx,
eNB->eNB_stats.total_dlsch_pdus_tx);
len += sprintf(&buffer[len],"\n");
for (UE_id=0;UE_id<NUMBER_OF_UE_MAX;UE_id++) {
if (eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].crnti > 0 ) {
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].dlsch_bitrate=((eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].TBS*8)/((eNB_mac_inst[eNB_id].frame + 1)*10));
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_dlsch_bitrate= ((eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_pdu_bytes*8)/((eNB_mac_inst[eNB_id].frame + 1)*10));
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_overhead_bytes+= eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].overhead_bytes;
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].avg_overhead_bytes=((eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_overhead_bytes*8)/((eNB_mac_inst[eNB_id].frame + 1)*10));
for (UE_id=UE_list->head;UE_id>0;UE_id=UE_list->next[UE_id]) {
for (i=0;i<UE_list->numactiveCCs[UE_id];i++) {
CC_id=UE_list->ordered_CCids[i][UE_id];
UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_bitrate=((UE_list->eNB_UE_stats[CC_id][UE_id].TBS*8)/((eNB->frame + 1)*10));
UE_list->eNB_UE_stats[CC_id][UE_id].total_dlsch_bitrate= ((UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes*8)/((eNB->frame + 1)*10));
UE_list->eNB_UE_stats[CC_id][UE_id].total_overhead_bytes+= UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes;
UE_list->eNB_UE_stats[CC_id][UE_id].avg_overhead_bytes=((UE_list->eNB_UE_stats[CC_id][UE_id].total_overhead_bytes*8)/((eNB->frame + 1)*10));
len += sprintf(&buffer[len],"UE %d %s, RNTI %x : CQI %d, MCS(%d->%d), RB(tx %d, retx %d, total %d), ncce (tx %d, retx %d) \n ",
UE_id,
map_int_to_str(rrc_status_names, eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].rrc_status),
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].crnti,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].dl_cqi,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].dlsch_mcs1,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].dlsch_mcs2,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].rbs_used,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].rbs_used_retx,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_rbs_used,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].ncce_used,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].ncce_used_retx
map_int_to_str(rrc_status_names, UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status),
UE_list->eNB_UE_stats[CC_id][UE_id].crnti,
UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi,
UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1,
UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2,
UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used,
UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx,
UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used,
UE_list->eNB_UE_stats[CC_id][UE_id].ncce_used,
UE_list->eNB_UE_stats[CC_id][UE_id].ncce_used_retx
);
len += sprintf(&buffer[len],
"[MAC] DLSCH bitrate (TTI %d, avg %d), Transmitted bytes "
"(TTI %d, total %"PRIu64"), Total Transmitted PDU %d, Overhead "
"(TTI %"PRIu64", total %"PRIu64", avg %"PRIu64,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].dlsch_bitrate,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_dlsch_bitrate,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].TBS,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_pdu_bytes,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_num_pdus,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].overhead_bytes,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].total_overhead_bytes,
eNB_mac_inst[eNB_id].eNB_UE_stats[UE_id].avg_overhead_bytes
UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_bitrate,
UE_list->eNB_UE_stats[CC_id][UE_id].total_dlsch_bitrate,
UE_list->eNB_UE_stats[CC_id][UE_id].TBS,
UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes,
UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus,
UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes,
UE_list->eNB_UE_stats[CC_id][UE_id].total_overhead_bytes,
UE_list->eNB_UE_stats[CC_id][UE_id].avg_overhead_bytes
);
}
......
......@@ -70,43 +70,43 @@ typedef struct
// eNB functions
/// Invoke dlsch/ulsch scheduling procedure for new subframe
void (*eNB_dlsch_ulsch_scheduler)(module_id_t Mod_id, uint8_t cooperation_flag, frame_t frameP, sub_frame_t subframeP);//, int calibration_flag);
void (*eNB_dlsch_ulsch_scheduler)(module_id_t Mod_id,uint8_t cooperation_flag, frame_t frameP, sub_frame_t subframeP);//, int calibration_flag);
/// Fill random access response sdu, passing timing advance
uint16_t (*fill_rar)(module_id_t Mod_id,frame_t frameP,uint8_t *dlsch_buffer,uint16_t N_RB_UL, uint8_t input_buffer_length);
uint16_t (*fill_rar)(module_id_t Mod_id,int CC_id,frame_t frameP,uint8_t *dlsch_buffer,uint16_t N_RB_UL, uint8_t input_buffer_length);
/// Terminate the RA procedure upon reception of l3msg on ulsch
void (*terminate_ra_proc)(module_id_t Mod_id,frame_t frameP,uint16_t UE_id, uint8_t *l3msg, uint16_t l3msg_len);
void (*terminate_ra_proc)(module_id_t Mod_id,int CC_id,frame_t frameP,uint16_t UE_id, uint8_t *l3msg, uint16_t l3msg_len);
/// Initiate the RA procedure upon reception (hypothetical) of a valid preamble
void (*initiate_ra_proc)(module_id_t Mod_id,frame_t frameP,uint16_t preamble,int16_t timing_offset,uint8_t sect_id,uint8_t subframe,uint8_t f_id);
void (*initiate_ra_proc)(module_id_t Mod_id,int CC_id,frame_t frameP,uint16_t preamble,int16_t timing_offset,uint8_t sect_id,sub_frame_t subframe,uint8_t f_id);
/// cancel an ongoing RA procedure
void (*cancel_ra_proc)(module_id_t Mod_id,frame_t frameP,uint16_t preamble);
void (*cancel_ra_proc)(module_id_t Mod_id,int CC_id,frame_t frameP,uint16_t preamble);
/// Get DCI for current subframe from MAC
DCI_PDU* (*get_dci_sdu)(module_id_t Mod_id,frame_t frameP,sub_frame_t subframe);
DCI_PDU* (*get_dci_sdu)(module_id_t Mod_id,int CC_id,frame_t frameP,sub_frame_t subframe);
/// Get DLSCH sdu for particular RNTI and Transport block index
uint8_t* (*get_dlsch_sdu)(module_id_t Mod_id,frame_t frameP,rnti_t rnti,uint8_t TB_index);
uint8_t* (*get_dlsch_sdu)(module_id_t Mod_id,int CC_id,frame_t frameP,rnti_t rnti,uint8_t TB_index);
/// Send ULSCH sdu to MAC for given rnti
void (*rx_sdu)(module_id_t Mod_id,frame_t frameP,rnti_t rnti, uint8_t *sdu,uint16_t sdu_len);
void (*rx_sdu)(module_id_t Mod_id,int CC_id,frame_t frameP,rnti_t rnti, uint8_t *sdu,uint16_t sdu_len);
/// Indicate failure to synch to external source
void (*mrbch_phy_sync_failure) (module_id_t Mod_id,frame_t frameP, uint8_t free_eNB_index);
/// Indicate Scheduling Request from UE
void (*SR_indication)(module_id_t Mod_id,frame_t frameP,rnti_t rnti,sub_frame_t subframe);
void (*SR_indication)(module_id_t Mod_id,int CC_id,frame_t frameP,rnti_t rnti,sub_frame_t subframe);
/// Configure Common PHY parameters from SIB1
void (*phy_config_sib1_eNB)(module_id_t Mod_id,
void (*phy_config_sib1_eNB)(module_id_t Mod_id,int CC_id,
TDD_Config_t *tdd_config,
uint8_t SIwindowsize,
uint16_t SIperiod);
/// Configure Common PHY parameters from SIB2
void (*phy_config_sib2_eNB)(module_id_t Mod_id,
void (*phy_config_sib2_eNB)(module_id_t Mod_id, int CC_id,
RadioResourceConfigCommonSIB_t *radioResourceConfigCommon,
ARFCN_ValueEUTRA_t *ul_CArrierFreq,
long *ul_Bandwidth,
......@@ -115,12 +115,12 @@ typedef struct
#ifdef Rel10
/// Configure Common PHY parameters from SIB13
void (*phy_config_sib13_eNB)(module_id_t Mod_id,int mbsfn_Area_idx,
void (*phy_config_sib13_eNB)(module_id_t Mod_id,int CC_id, int mbsfn_Area_idx,
long mbsfn_AreaId_r9);
#endif
/// PHY-Config-Dedicated eNB
void (*phy_config_dedicated_eNB)(module_id_t Mod_id,rnti_t rnti,
void (*phy_config_dedicated_eNB)(module_id_t Mod_id,int CC_id,rnti_t rnti,
struct PhysicalConfigDedicated *physicalConfigDedicated);
#ifdef Rel10
......@@ -139,10 +139,10 @@ typedef struct
void (*out_of_sync_ind)(module_id_t Mod_id,frame_t frameP,uint16_t eNB_index);
/// Send a received SI sdu
void (*ue_decode_si)(module_id_t Mod_id,frame_t frameP, uint8_t CH_index, void *pdu, uint16_t len);
void (*ue_decode_si)(module_id_t Mod_id,int CC_id,frame_t frameP, uint8_t CH_index, void *pdu, uint16_t len);
/// Send a received DLSCH sdu to MAC
void (*ue_send_sdu)(module_id_t Mod_id,frame_t frameP,uint8_t *sdu,uint16_t sdu_len,uint8_t CH_index);
void (*ue_send_sdu)(module_id_t Mod_id,int CC_id,frame_t frameP,uint8_t *sdu,uint16_t sdu_len,uint8_t CH_index);
#ifdef Rel10
/// Send a received MCH sdu to MAC
......@@ -150,20 +150,20 @@ typedef struct
/// Function to check if UE PHY needs to decode MCH for MAC
/// get the sync area id, and teturn MCS value if need to decode, otherwise -1
int (*ue_query_mch)(module_id_t Mod_id,frame_t frameP,sub_frame_t subframe,uint8_t eNB_index,uint8_t *sync_area, uint8_t *mcch_active);
int (*ue_query_mch)(module_id_t Mod_id,int CC_id,frame_t frameP,sub_frame_t subframe,uint8_t eNB_index,uint8_t *sync_area, uint8_t *mcch_active);
#endif
/// Retrieve ULSCH sdu from MAC
void (*ue_get_sdu)(module_id_t Mod_id,frame_t frameP,sub_frame_t subframe, uint8_t CH_index,uint8_t *ulsch_buffer,uint16_t buflen,uint8_t *access_mode);
void (*ue_get_sdu)(module_id_t Mod_id,int CC_id,frame_t frameP,sub_frame_t subframe, uint8_t CH_index,uint8_t *ulsch_buffer,uint16_t buflen,uint8_t *access_mode);
/// Retrieve RRCConnectionReq from MAC
PRACH_RESOURCES_t* (*ue_get_rach)(module_id_t Mod_id,frame_t frameP,uint8_t Msg3_flag,sub_frame_t subframe);
PRACH_RESOURCES_t* (*ue_get_rach)(module_id_t Mod_id,int CC_id,frame_t frameP,uint8_t Msg3_flag,sub_frame_t subframe);
/// Process Random-Access Response
uint16_t (*ue_process_rar)(module_id_t Mod_id,frame_t frameP,uint8_t *dlsch_buffer,uint16_t *t_crnti,uint8_t preamble_index);
uint16_t (*ue_process_rar)(module_id_t Mod_id,int CC_id,frame_t frameP,uint8_t *dlsch_buffer,uint16_t *t_crnti,uint8_t preamble_index);
/// Get SR payload (0,1) from UE MAC
uint32_t (*ue_get_SR)(module_id_t Mod_id,frame_t frameP,uint8_t eNB_id,rnti_t rnti,sub_frame_t subframe);
uint32_t (*ue_get_SR)(module_id_t Mod_id,int CC_id,frame_t frameP,uint8_t eNB_id,rnti_t rnti,sub_frame_t subframe);
/// Indicate synchronization with valid PBCH
void (*dl_phy_sync_success) (module_id_t Mod_id,frame_t frameP, uint8_t CH_index,uint8_t first_sync);
......@@ -172,17 +172,17 @@ typedef struct
UE_L2_STATE_t (*ue_scheduler)(module_id_t Mod_id, frame_t frameP,sub_frame_t subframe, lte_subframe_t direction,uint8_t eNB_id);
/// PHY-Config-Dedicated UE
void (*phy_config_dedicated_ue)(module_id_t Mod_id,uint8_t CH_index,
void (*phy_config_dedicated_ue)(module_id_t Mod_id,int CC_id,uint8_t CH_index,
struct PhysicalConfigDedicated *physicalConfigDedicated);
/// Configure Common PHY parameters from SIB1
void (*phy_config_sib1_ue)(module_id_t Mod_id,uint8_t CH_index,
void (*phy_config_sib1_ue)(module_id_t Mod_id,int CC_id,uint8_t CH_index,
TDD_Config_t *tdd_config,
uint8_t SIwindowsize,
uint16_t SIperiod);
/// Configure Common PHY parameters from SIB2
void (*phy_config_sib2_ue)(module_id_t Mod_id,uint8_t CH_index,
void (*phy_config_sib2_ue)(module_id_t Mod_id,int CC_id,uint8_t CH_index,
RadioResourceConfigCommonSIB_t *radioResourceConfigCommon,
ARFCN_ValueEUTRA_t *ul_CArrierFreq,
long *ul_Bandwidth,
......@@ -200,19 +200,19 @@ typedef struct
uint8_t ho_failed);
/// Function to indicate failure of contention resolution or RA procedure
void (*ra_failed)(module_id_t Mod_id,uint8_t eNB_index);
void (*ra_failed)(module_id_t Mod_id,int CC_id,uint8_t eNB_index);
/// Function to indicate success of contention resolution or RA procedure
void (*ra_succeeded)(module_id_t Mod_id,uint8_t eNB_index);
void (*ra_succeeded)(module_id_t Mod_id,int CC_id, uint8_t eNB_index);
/// Function to indicate the transmission of msg1/rach to MAC
void (*Msg1_transmitted)(module_id_t Mod_id,frame_t frameP,uint8_t eNB_id);
void (*Msg1_transmitted)(module_id_t Mod_id,int CC_id,frame_t frameP,uint8_t eNB_id);
/// Function to indicate Msg3 transmission/retransmission which initiates/reset Contention Resolution Timer
void (*Msg3_transmitted)(module_id_t Mod_id,frame_t frameP,uint8_t eNB_id);
void (*Msg3_transmitted)(module_id_t Mod_id,int CC_id,frame_t frameP,uint8_t eNB_id);
/// Function to pass inter-cell measurement parameters to PHY (cell Ids)
void (*phy_config_meas_ue)(module_id_t Mod_id,uint8_t eNB_index,uint8_t n_adj_cells,uint32_t *adj_cell_id);
void (*phy_config_meas_ue)(module_id_t Mod_id,int CC_id,uint8_t eNB_index,uint8_t n_adj_cells,uint32_t *adj_cell_id);
// PHY Helper Functions
......@@ -226,22 +226,22 @@ typedef struct
uint16_t (*get_TBS_UL)(uint8_t mcs, uint16_t nb_rb);
/// Function to retrieve the HARQ round index for a particular UL/DLSCH and harq_pid
int (*get_ue_active_harq_pid)(module_id_t Mod_id, rnti_t rnti, uint8_t subframe, uint8_t *harq_pid, uint8_t *round, uint8_t ul_flag);
int (*get_ue_active_harq_pid)(module_id_t Mod_id, int CC_id,rnti_t rnti, uint8_t subframe, uint8_t *harq_pid, uint8_t *round, uint8_t ul_flag);
/// Function to retrieve number of CCE
uint16_t (*get_nCCE_max)(module_id_t Mod_id);
uint16_t (*get_nCCE_max)(module_id_t Mod_id,int CC_id);
/// Function to retrieve number of PRB in an rb_alloc
uint32_t (*get_nb_rb)(uint8_t ra_header, uint32_t rb_alloc, int n_rb_dl);
/// Function to retrieve transmission mode for UE
uint8_t (*get_transmission_mode)(module_id_t Mod_id,rnti_t rnti);
uint8_t (*get_transmission_mode)(module_id_t Mod_id,int CC_id,rnti_t rnti);
/// Function to retrieve rb_alloc bitmap from dci rballoc field and VRB type
uint32_t (*get_rballoc)(uint8_t vrb_type, uint16_t rb_alloc_dci);
/// Function for UE MAC to retrieve current PHY connectivity mode (PRACH,RA_RESPONSE,PUSCH)
UE_MODE_t (*get_ue_mode)(module_id_t Mod_id,uint8_t eNB_index);
UE_MODE_t (*get_ue_mode)(module_id_t Mod_id,int CC_id,uint8_t eNB_index);
/// Function for UE MAC to retrieve measured Path Loss
int16_t (*get_PL)(module_id_t Mod_id,uint8_t eNB_index);
......@@ -278,17 +278,17 @@ typedef struct
// MAC Helper functions
/// Function for UE/PHY to compute PUSCH transmit power in power-control procedure (Po_NOMINAL_PUSCH parameter)
int8_t (*get_Po_NOMINAL_PUSCH)(module_id_t Mod_id);
int8_t (*get_Po_NOMINAL_PUSCH)(module_id_t Mod_id,int CC_id);
/// Function for UE/PHY to compute PUSCH transmit power in power-control procedure (deltaP_rampup parameter)
int8_t (*get_deltaP_rampup)(module_id_t Mod_id);
int8_t (*get_deltaP_rampup)(module_id_t Mod_id,int CC_id);
/// Function for UE/PHY to compute PHR
int8_t (*get_PHR)(module_id_t Mod_id, uint8_t eNB_index);
int8_t (*get_PHR)(module_id_t Mod_id, int CC_id,uint8_t eNB_index);
void (*process_timing_advance)(module_id_t Mod_id,int16_t timing_advance);
LTE_eNB_UE_stats* (*get_eNB_UE_stats)(module_id_t Mod_id, rnti_t rnti);
LTE_eNB_UE_stats* (*get_eNB_UE_stats)(module_id_t Mod_id, int CC_id, rnti_t rnti);
unsigned char is_cluster_head;
unsigned char is_primary_cluster_head;
......
......@@ -2455,8 +2455,8 @@ void rrc_eNB_generate_RRCConnectionSetup(
eNB_rrc_inst[enb_mod_idP].Srb0.Tx_buffer.payload_size =
do_RRCConnectionSetup(enb_mod_idP,
(uint8_t *) eNB_rrc_inst[enb_mod_idP].Srb0.Tx_buffer.Payload,
mac_xface->get_transmission_mode(enb_mod_idP,
find_UE_RNTI
mac_xface->get_transmission_mode(enb_mod_idP,0, //CC_id 0!!!!
UE_RNTI
(enb_mod_idP,
ue_mod_idP)),
ue_mod_idP,
......
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