Commit d01aa2d0 authored by Raymond Knopp's avatar Raymond Knopp

changing of notation for Random-Access procedure to match documentation....

changing of notation for Random-Access procedure to match documentation. Function remains the same. Indentation (-kr) run on all files in LAYER2/MAC
parent d915c208
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
extern RAN_CONTEXT_t RC; extern RAN_CONTEXT_t RC;
/* sec 5.9, 36.321: MAC Reset Procedure */ /* sec 5.9, 36.321: MAC Reset Procedure */
void ue_mac_reset(module_id_t module_idP,uint8_t eNB_index) void ue_mac_reset(module_id_t module_idP, uint8_t eNB_index)
{ {
//Resetting Bj //Resetting Bj
...@@ -73,12 +73,12 @@ void ue_mac_reset(module_id_t module_idP,uint8_t eNB_index) ...@@ -73,12 +73,12 @@ void ue_mac_reset(module_id_t module_idP,uint8_t eNB_index)
//timeAlignmentTimer expires //timeAlignmentTimer expires
// PHY changes for UE MAC reset // PHY changes for UE MAC reset
phy_reset_ue(module_idP,0,eNB_index); phy_reset_ue(module_idP, 0, eNB_index);
// notify RRC to relase PUCCH/SRS // notify RRC to relase PUCCH/SRS
// cancel all pending SRs // cancel all pending SRs
UE_mac_inst[module_idP].scheduling_info.SR_pending=0; UE_mac_inst[module_idP].scheduling_info.SR_pending = 0;
UE_mac_inst[module_idP].scheduling_info.SR_COUNTER=0; UE_mac_inst[module_idP].scheduling_info.SR_COUNTER = 0;
//Set BSR Trigger Bmp and remove timer flags //Set BSR Trigger Bmp and remove timer flags
UE_mac_inst[module_idP].BSR_reporting_active = BSR_TRIGGER_NONE; UE_mac_inst[module_idP].BSR_reporting_active = BSR_TRIGGER_NONE;
...@@ -115,15 +115,15 @@ typedef struct band_info_s { ...@@ -115,15 +115,15 @@ typedef struct band_info_s {
static const eutra_bandentry_t eutra_bandtable[] = { static const eutra_bandentry_t eutra_bandtable[] = {
{ 1, 19200, 19800, 21100, 21700, 0}, {1, 19200, 19800, 21100, 21700, 0},
{ 2, 18500, 19100, 19300, 19900, 6000}, {2, 18500, 19100, 19300, 19900, 6000},
{ 3, 17100, 17850, 18050, 18800, 12000}, {3, 17100, 17850, 18050, 18800, 12000},
{ 4, 17100, 17550, 21100, 21550, 19500}, {4, 17100, 17550, 21100, 21550, 19500},
{ 5, 8240, 8490, 8690, 8940, 24000}, {5, 8240, 8490, 8690, 8940, 24000},
{ 6, 8300, 8400, 8750, 8850, 26500}, {6, 8300, 8400, 8750, 8850, 26500},
{ 7, 25000, 25700, 26200, 26900, 27500}, {7, 25000, 25700, 26200, 26900, 27500},
{ 8, 8800, 9150 , 9250, 9600, 34500}, {8, 8800, 9150, 9250, 9600, 34500},
{ 9, 17499, 17849, 18449, 18799, 38000}, {9, 17499, 17849, 18449, 18799, 38000},
{10, 17100, 17700, 21100, 21700, 41500}, {10, 17100, 17700, 21100, 21700, 41500},
{11, 14279, 14529, 14759, 15009, 47500}, {11, 14279, 14529, 14759, 15009, 47500},
{12, 6980, 7160, 7280, 7460, 50100}, {12, 6980, 7160, 7280, 7460, 50100},
...@@ -138,13 +138,13 @@ static const eutra_bandentry_t eutra_bandtable[] = { ...@@ -138,13 +138,13 @@ static const eutra_bandentry_t eutra_bandtable[] = {
{23, 20000, 20200, 21800, 22000, 75000}, {23, 20000, 20200, 21800, 22000, 75000},
{24, 16126, 16605, 15250, 15590, 77000}, {24, 16126, 16605, 15250, 15590, 77000},
{25, 18500, 19150, 19300, 19950, 80400}, {25, 18500, 19150, 19300, 19950, 80400},
{26, 8140 , 8490, 8590, 8940, 86900}, {26, 8140, 8490, 8590, 8940, 86900},
{27, 8070 , 8240, 8520, 8690, 90400}, {27, 8070, 8240, 8520, 8690, 90400},
{28, 7030 , 7580, 7580, 8130, 92100}, {28, 7030, 7580, 7580, 8130, 92100},
{29, 0 , 0 , 7170, 7280, 96600}, {29, 0, 0, 7170, 7280, 96600},
{30, 23050, 23250, 23500, 23600, 97700}, {30, 23050, 23250, 23500, 23600, 97700},
{31, 45250, 34900, 46250, 35900, 98700}, {31, 45250, 34900, 46250, 35900, 98700},
{32, 0 , 0 , 14520, 14960, 99200}, {32, 0, 0, 14520, 14960, 99200},
{33, 19000, 19200, 19000, 19200, 36000}, {33, 19000, 19200, 19000, 19200, 36000},
{34, 20100, 20250, 20100, 20250, 36200}, {34, 20100, 20250, 20100, 20250, 36200},
{35, 18500, 19100, 18500, 19100, 36350}, {35, 18500, 19100, 18500, 19100, 36350},
...@@ -156,66 +156,77 @@ static const eutra_bandentry_t eutra_bandtable[] = { ...@@ -156,66 +156,77 @@ static const eutra_bandentry_t eutra_bandtable[] = {
{41, 24960, 26900, 24960, 26900, 39650}, {41, 24960, 26900, 24960, 26900, 39650},
{42, 34000, 36000, 34000, 36000, 41590}, {42, 34000, 36000, 34000, 36000, 41590},
{43, 36000, 38000, 36000, 38000, 43590}, {43, 36000, 38000, 36000, 38000, 43590},
{44, 7030 , 8030, 7030, 8030, 45590}, {44, 7030, 8030, 7030, 8030, 45590},
{45, 14470, 14670, 14470, 14670, 46590}, {45, 14470, 14670, 14470, 14670, 46590},
{46, 51500, 59250, 51500, 59250, 46790}, {46, 51500, 59250, 51500, 59250, 46790},
{65, 19200, 20100, 21100, 22000, 65536}, {65, 19200, 20100, 21100, 22000, 65536},
{66, 17100, 18000, 21100, 22000, 66436}, {66, 17100, 18000, 21100, 22000, 66436},
{67, 0 , 0 , 7380, 7580, 67336}, {67, 0, 0, 7380, 7580, 67336},
{68, 6980 , 7280 , 7530, 7830, 67536}}; {68, 6980, 7280, 7530, 7830, 67536}
};
uint32_t to_earfcn(int eutra_bandP,uint32_t dl_CarrierFreq,uint32_t bw) { uint32_t to_earfcn(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw)
{
uint32_t dl_CarrierFreq_by_100k = dl_CarrierFreq/100000; uint32_t dl_CarrierFreq_by_100k = dl_CarrierFreq / 100000;
int bw_by_100 = bw/100; int bw_by_100 = bw / 100;
int i; int i;
AssertFatal(eutra_bandP < 69,"eutra_band %d > 68\n",eutra_bandP); AssertFatal(eutra_bandP < 69, "eutra_band %d > 68\n", eutra_bandP);
for (i=0;i<69 && eutra_bandtable[i].band!=eutra_bandP;i++); for (i = 0; i < 69 && eutra_bandtable[i].band != eutra_bandP; i++);
AssertFatal(dl_CarrierFreq_by_100k>=eutra_bandtable[i].dl_min, AssertFatal(dl_CarrierFreq_by_100k >= eutra_bandtable[i].dl_min,
"Band %d, bw %u : DL carrier frequency %u Hz < %u\n", "Band %d, bw %u : DL carrier frequency %u Hz < %u\n",
eutra_bandP,bw,dl_CarrierFreq,eutra_bandtable[i].dl_min); eutra_bandP, bw, dl_CarrierFreq,
AssertFatal(dl_CarrierFreq_by_100k<=(eutra_bandtable[i].dl_max-bw_by_100), eutra_bandtable[i].dl_min);
AssertFatal(dl_CarrierFreq_by_100k <=
(eutra_bandtable[i].dl_max - bw_by_100),
"Band %d, bw %u: DL carrier frequency %u Hz > %d\n", "Band %d, bw %u: DL carrier frequency %u Hz > %d\n",
eutra_bandP,bw,dl_CarrierFreq,eutra_bandtable[i].dl_max-bw_by_100); eutra_bandP, bw, dl_CarrierFreq,
eutra_bandtable[i].dl_max - bw_by_100);
return(dl_CarrierFreq_by_100k - eutra_bandtable[i].dl_min + (eutra_bandtable[i].N_OFFs_DL/10)); return (dl_CarrierFreq_by_100k - eutra_bandtable[i].dl_min +
(eutra_bandtable[i].N_OFFs_DL / 10));
} }
uint32_t from_earfcn(int eutra_bandP,uint32_t dl_earfcn) { uint32_t from_earfcn(int eutra_bandP, uint32_t dl_earfcn)
{
int i; int i;
AssertFatal(eutra_bandP < 69,"eutra_band %d > 68\n",eutra_bandP); AssertFatal(eutra_bandP < 69, "eutra_band %d > 68\n", eutra_bandP);
for (i=0;i<69 && eutra_bandtable[i].band!=eutra_bandP;i++); for (i = 0; i < 69 && eutra_bandtable[i].band != eutra_bandP; i++);
return(eutra_bandtable[i].dl_min + (dl_earfcn-(eutra_bandtable[i].N_OFFs_DL/10)))*100000; return (eutra_bandtable[i].dl_min +
(dl_earfcn - (eutra_bandtable[i].N_OFFs_DL / 10))) * 100000;
} }
int32_t get_uldl_offset(int eutra_bandP) { int32_t get_uldl_offset(int eutra_bandP)
{
int i; int i;
for (i=0;i<69 && eutra_bandtable[i].band!=eutra_bandP;i++); for (i = 0; i < 69 && eutra_bandtable[i].band != eutra_bandP; i++);
return(eutra_bandtable[i].dl_min - eutra_bandtable[i].ul_min); return (eutra_bandtable[i].dl_min - eutra_bandtable[i].ul_min);
} }
uint32_t bw_table[6] = {6*180,15*180,25*180,50*180,75*180,100*180}; uint32_t bw_table[6] =
{ 6 * 180, 15 * 180, 25 * 180, 50 * 180, 75 * 180, 100 * 180 };
void config_mib(int Mod_idP, void
config_mib(int Mod_idP,
int CC_idP, int CC_idP,
int eutra_bandP, int eutra_bandP,
int dl_BandwidthP, int dl_BandwidthP,
PHICH_Config_t *phich_configP, PHICH_Config_t * phich_configP,
int Nid_cellP, int Nid_cellP,
int NcpP, int NcpP,
int p_eNBP, int p_eNBP,
uint32_t dl_CarrierFreqP, uint32_t dl_CarrierFreqP,
uint32_t ul_CarrierFreqP, uint32_t ul_CarrierFreqP, uint32_t pbch_repetitionP)
uint32_t pbch_repetitionP) { {
nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP];
...@@ -223,14 +234,16 @@ void config_mib(int Mod_idP, ...@@ -223,14 +234,16 @@ void config_mib(int Mod_idP,
cfg->subframe_config.dl_cyclic_prefix_type.value = NcpP; cfg->subframe_config.dl_cyclic_prefix_type.value = NcpP;
cfg->subframe_config.ul_cyclic_prefix_type.value = NcpP; cfg->subframe_config.ul_cyclic_prefix_type.value = NcpP;
LOG_I(MAC,"Ncp %d,p_eNB %d\n",NcpP,p_eNBP); LOG_I(MAC, "Ncp %d,p_eNB %d\n", NcpP, p_eNBP);
cfg->rf_config.dl_channel_bandwidth.value = dl_BandwidthP; cfg->rf_config.dl_channel_bandwidth.value = dl_BandwidthP;
cfg->rf_config.ul_channel_bandwidth.value = dl_BandwidthP; cfg->rf_config.ul_channel_bandwidth.value = dl_BandwidthP;
cfg->rf_config.tx_antenna_ports.value = p_eNBP; cfg->rf_config.tx_antenna_ports.value = p_eNBP;
cfg->rf_config.rx_antenna_ports.value = 2; cfg->rf_config.rx_antenna_ports.value = 2;
cfg->nfapi_config.earfcn.value = to_earfcn(eutra_bandP,dl_CarrierFreqP,bw_table[dl_BandwidthP]/100); cfg->nfapi_config.earfcn.value =
to_earfcn(eutra_bandP, dl_CarrierFreqP,
bw_table[dl_BandwidthP] / 100);
cfg->nfapi_config.rf_bands.number_rf_bands = 1; cfg->nfapi_config.rf_bands.number_rf_bands = 1;
cfg->nfapi_config.rf_bands.rf_band[0] = eutra_bandP; cfg->nfapi_config.rf_bands.rf_band[0] = eutra_bandP;
cfg->phich_config.phich_resource.value = phich_configP->phich_Resource; cfg->phich_config.phich_resource.value = phich_configP->phich_Resource;
...@@ -246,18 +259,18 @@ void config_mib(int Mod_idP, ...@@ -246,18 +259,18 @@ void config_mib(int Mod_idP,
#endif #endif
} }
void config_sib1(int Mod_idP, void config_sib1(int Mod_idP, int CC_idP, TDD_Config_t * tdd_ConfigP)
int CC_idP, {
TDD_Config_t *tdd_ConfigP) {
nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP];
if (tdd_ConfigP) { //TDD if (tdd_ConfigP) { //TDD
cfg->subframe_config.duplex_mode.value = 0; cfg->subframe_config.duplex_mode.value = 0;
cfg->tdd_frame_structure_config.subframe_assignment.value = tdd_ConfigP->subframeAssignment; cfg->tdd_frame_structure_config.subframe_assignment.value =
cfg->tdd_frame_structure_config.special_subframe_patterns.value = tdd_ConfigP->specialSubframePatterns; tdd_ConfigP->subframeAssignment;
} cfg->tdd_frame_structure_config.special_subframe_patterns.value =
else { // FDD tdd_ConfigP->specialSubframePatterns;
} else { // FDD
cfg->subframe_config.duplex_mode.value = 1; cfg->subframe_config.duplex_mode.value = 1;
// Note no half-duplex here // Note no half-duplex here
} }
...@@ -265,148 +278,253 @@ void config_sib1(int Mod_idP, ...@@ -265,148 +278,253 @@ void config_sib1(int Mod_idP,
} }
int power_off_dB[6] = {78,118,140,170,188,200}; int power_off_dB[6] = { 78, 118, 140, 170, 188, 200 };
void config_sib2(int Mod_idP, void
config_sib2(int Mod_idP,
int CC_idP, int CC_idP,
RadioResourceConfigCommonSIB_t *radioResourceConfigCommonP, RadioResourceConfigCommonSIB_t * radioResourceConfigCommonP,
#ifdef Rel14 #ifdef Rel14
RadioResourceConfigCommonSIB_t *radioResourceConfigCommon_BRP, RadioResourceConfigCommonSIB_t * radioResourceConfigCommon_BRP,
#endif #endif
ARFCN_ValueEUTRA_t *ul_CArrierFreqP, ARFCN_ValueEUTRA_t * ul_CArrierFreqP,
long *ul_BandwidthP, long *ul_BandwidthP,
AdditionalSpectrumEmission_t *additionalSpectrumEmissionP, AdditionalSpectrumEmission_t *
struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigListP) { additionalSpectrumEmissionP,
struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigListP)
{
nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP];
cfg->subframe_config.pb.value = radioResourceConfigCommonP->pdsch_ConfigCommon.p_b; cfg->subframe_config.pb.value =
cfg->rf_config.reference_signal_power.value = radioResourceConfigCommonP->pdsch_ConfigCommon.referenceSignalPower; radioResourceConfigCommonP->pdsch_ConfigCommon.p_b;
cfg->nfapi_config.max_transmit_power.value = cfg->rf_config.reference_signal_power.value + power_off_dB[cfg->rf_config.dl_channel_bandwidth.value]; cfg->rf_config.reference_signal_power.value =
radioResourceConfigCommonP->pdsch_ConfigCommon.
cfg->prach_config.configuration_index.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.prach_ConfigIndex; referenceSignalPower;
cfg->prach_config.root_sequence_index.value = radioResourceConfigCommonP->prach_Config.rootSequenceIndex; cfg->nfapi_config.max_transmit_power.value =
cfg->prach_config.zero_correlation_zone_configuration.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig; cfg->rf_config.reference_signal_power.value +
cfg->prach_config.high_speed_flag.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.highSpeedFlag; power_off_dB[cfg->rf_config.dl_channel_bandwidth.value];
cfg->prach_config.frequency_offset.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.prach_FreqOffset;
cfg->prach_config.configuration_index.value =
cfg->pusch_config.hopping_mode.value = radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode; radioResourceConfigCommonP->prach_Config.
cfg->pusch_config.number_of_subbands.value = radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic.n_SB; prach_ConfigInfo.prach_ConfigIndex;
cfg->pusch_config.hopping_offset.value = radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset; cfg->prach_config.root_sequence_index.value =
radioResourceConfigCommonP->prach_Config.rootSequenceIndex;
cfg->prach_config.zero_correlation_zone_configuration.value =
radioResourceConfigCommonP->prach_Config.
cfg->pucch_config.delta_pucch_shift.value = radioResourceConfigCommonP->pucch_ConfigCommon.deltaPUCCH_Shift; prach_ConfigInfo.zeroCorrelationZoneConfig;
cfg->pucch_config.n_cqi_rb.value = radioResourceConfigCommonP->pucch_ConfigCommon.nRB_CQI; cfg->prach_config.high_speed_flag.value =
cfg->pucch_config.n_an_cs.value = radioResourceConfigCommonP->pucch_ConfigCommon.nCS_AN; radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.
cfg->pucch_config.n1_pucch_an.value = radioResourceConfigCommonP->pucch_ConfigCommon.n1PUCCH_AN; highSpeedFlag;
cfg->prach_config.frequency_offset.value =
if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled == true) radioResourceConfigCommonP->prach_Config.
prach_ConfigInfo.prach_FreqOffset;
cfg->pusch_config.hopping_mode.value =
radioResourceConfigCommonP->pusch_ConfigCommon.
pusch_ConfigBasic.hoppingMode;
cfg->pusch_config.number_of_subbands.value =
radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic.
n_SB;
cfg->pusch_config.hopping_offset.value =
radioResourceConfigCommonP->pusch_ConfigCommon.
pusch_ConfigBasic.pusch_HoppingOffset;
cfg->pucch_config.delta_pucch_shift.value =
radioResourceConfigCommonP->pucch_ConfigCommon.deltaPUCCH_Shift;
cfg->pucch_config.n_cqi_rb.value =
radioResourceConfigCommonP->pucch_ConfigCommon.nRB_CQI;
cfg->pucch_config.n_an_cs.value =
radioResourceConfigCommonP->pucch_ConfigCommon.nCS_AN;
cfg->pucch_config.n1_pucch_an.value =
radioResourceConfigCommonP->pucch_ConfigCommon.n1PUCCH_AN;
if (radioResourceConfigCommonP->
pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled ==
true)
cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 1; cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 1;
else if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled == true) else if (radioResourceConfigCommonP->
pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.
sequenceHoppingEnabled == true)
cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 2; cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 2;
else // No hopping else // No hopping
cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 0; cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 0;
cfg->uplink_reference_signal_config.group_assignment.value = radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH; cfg->uplink_reference_signal_config.group_assignment.value =
cfg->uplink_reference_signal_config.cyclic_shift_1_for_drms.value = radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift; radioResourceConfigCommonP->
pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH;
cfg->uplink_reference_signal_config.cyclic_shift_1_for_drms.value =
radioResourceConfigCommonP->
pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift;
// how to enable/disable SRS? // how to enable/disable SRS?
if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.present==SoundingRS_UL_ConfigCommon_PR_setup) { if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.present ==
cfg->srs_config.bandwidth_configuration.value = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig; SoundingRS_UL_ConfigCommon_PR_setup) {
cfg->srs_config.srs_subframe_configuration.value = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig; cfg->srs_config.bandwidth_configuration.value =
cfg->srs_config.srs_acknack_srs_simultaneous_transmission.value = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.
choice.setup.srs_BandwidthConfig;
if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts) cfg->srs_config.srs_subframe_configuration.value =
radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.
choice.setup.srs_SubframeConfig;
cfg->srs_config.srs_acknack_srs_simultaneous_transmission.value =
radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.
choice.setup.ackNackSRS_SimultaneousTransmission;
if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.
choice.setup.srs_MaxUpPts)
cfg->srs_config.max_up_pts.value = 1; cfg->srs_config.max_up_pts.value = 1;
else else
cfg->srs_config.max_up_pts.value = 0; cfg->srs_config.max_up_pts.value = 0;
} }
#ifdef Rel14 #ifdef Rel14
if (RC.mac[Mod_idP]->common_channels[CC_idP].mib->message.schedulingInfoSIB1_BR_r13>0) { if (RC.mac[Mod_idP]->common_channels[CC_idP].mib->
AssertFatal(radioResourceConfigCommon_BRP!=NULL,"radioResource rou is missing\n"); message.schedulingInfoSIB1_BR_r13 > 0) {
AssertFatal(radioResourceConfigCommon_BRP->ext4!=NULL,"ext4 is missing\n"); AssertFatal(radioResourceConfigCommon_BRP != NULL,
cfg->emtc_config.prach_catm_root_sequence_index.value = radioResourceConfigCommon_BRP->prach_Config.rootSequenceIndex; "radioResource rou is missing\n");
cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.value = radioResourceConfigCommon_BRP->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig; AssertFatal(radioResourceConfigCommon_BRP->ext4 != NULL,
cfg->emtc_config.prach_catm_high_speed_flag.value = radioResourceConfigCommon_BRP->prach_Config.prach_ConfigInfo.highSpeedFlag; "ext4 is missing\n");
cfg->emtc_config.prach_catm_root_sequence_index.value =
struct PRACH_ConfigSIB_v1310 *ext4_prach=radioResourceConfigCommon_BRP->ext4->prach_ConfigCommon_v1310; radioResourceConfigCommon_BRP->prach_Config.rootSequenceIndex;
cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.
PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; value =
radioResourceConfigCommon_BRP->prach_Config.
prach_ConfigInfo.zeroCorrelationZoneConfig;
cfg->emtc_config.prach_catm_high_speed_flag.value =
radioResourceConfigCommon_BRP->prach_Config.
prach_ConfigInfo.highSpeedFlag;
struct PRACH_ConfigSIB_v1310 *ext4_prach =
radioResourceConfigCommon_BRP->ext4->prach_ConfigCommon_v1310;
PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 =
&ext4_prach->prach_ParametersListCE_r13;
PRACH_ParametersCE_r13_t *p; PRACH_ParametersCE_r13_t *p;
cfg->emtc_config.prach_ce_level_0_enable.value=0; cfg->emtc_config.prach_ce_level_0_enable.value = 0;
cfg->emtc_config.prach_ce_level_1_enable.value=0; cfg->emtc_config.prach_ce_level_1_enable.value = 0;
cfg->emtc_config.prach_ce_level_2_enable.value=0; cfg->emtc_config.prach_ce_level_2_enable.value = 0;
cfg->emtc_config.prach_ce_level_3_enable.value=0; cfg->emtc_config.prach_ce_level_3_enable.value = 0;
switch (prach_ParametersListCE_r13->list.count) { switch (prach_ParametersListCE_r13->list.count) {
case 4: case 4:
p=prach_ParametersListCE_r13->list.array[3]; p = prach_ParametersListCE_r13->list.array[3];
cfg->emtc_config.prach_ce_level_3_enable.value = 1; cfg->emtc_config.prach_ce_level_3_enable.value = 1;
cfg->emtc_config.prach_ce_level_3_configuration_index.value = p->prach_ConfigIndex_r13; cfg->emtc_config.prach_ce_level_3_configuration_index.value =
cfg->emtc_config.prach_ce_level_3_frequency_offset.value = p->prach_FreqOffset_r13; p->prach_ConfigIndex_r13;
cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.value = p->numRepetitionPerPreambleAttempt_r13; cfg->emtc_config.prach_ce_level_3_frequency_offset.value =
p->prach_FreqOffset_r13;
cfg->
emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.
value = p->numRepetitionPerPreambleAttempt_r13;
if (p->prach_StartingSubframe_r13) if (p->prach_StartingSubframe_r13)
cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.value = *p->prach_StartingSubframe_r13; cfg->
cfg->emtc_config.prach_ce_level_3_hopping_enable.value = p->prach_HoppingConfig_r13; emtc_config.prach_ce_level_3_starting_subframe_periodicity.
cfg->emtc_config.prach_ce_level_3_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value-6; value = *p->prach_StartingSubframe_r13;
cfg->emtc_config.prach_ce_level_3_hopping_enable.value =
p->prach_HoppingConfig_r13;
cfg->emtc_config.prach_ce_level_3_hopping_offset.value =
cfg->rf_config.ul_channel_bandwidth.value - 6;
case 3: case 3:
p=prach_ParametersListCE_r13->list.array[2]; p = prach_ParametersListCE_r13->list.array[2];
cfg->emtc_config.prach_ce_level_2_enable.value = 1; cfg->emtc_config.prach_ce_level_2_enable.value = 1;
cfg->emtc_config.prach_ce_level_2_configuration_index.value = p->prach_ConfigIndex_r13; cfg->emtc_config.prach_ce_level_2_configuration_index.value =
cfg->emtc_config.prach_ce_level_2_frequency_offset.value = p->prach_FreqOffset_r13; p->prach_ConfigIndex_r13;
cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.value = p->numRepetitionPerPreambleAttempt_r13; cfg->emtc_config.prach_ce_level_2_frequency_offset.value =
p->prach_FreqOffset_r13;
cfg->
emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.
value = p->numRepetitionPerPreambleAttempt_r13;
if (p->prach_StartingSubframe_r13) if (p->prach_StartingSubframe_r13)
cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.value = *p->prach_StartingSubframe_r13; cfg->
cfg->emtc_config.prach_ce_level_2_hopping_enable.value = p->prach_HoppingConfig_r13; emtc_config.prach_ce_level_2_starting_subframe_periodicity.
cfg->emtc_config.prach_ce_level_2_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value-6; value = *p->prach_StartingSubframe_r13;
cfg->emtc_config.prach_ce_level_2_hopping_enable.value =
p->prach_HoppingConfig_r13;
cfg->emtc_config.prach_ce_level_2_hopping_offset.value =
cfg->rf_config.ul_channel_bandwidth.value - 6;
case 2: case 2:
p=prach_ParametersListCE_r13->list.array[1]; p = prach_ParametersListCE_r13->list.array[1];
cfg->emtc_config.prach_ce_level_1_enable.value = 1; cfg->emtc_config.prach_ce_level_1_enable.value = 1;
cfg->emtc_config.prach_ce_level_1_configuration_index.value = p->prach_ConfigIndex_r13; cfg->emtc_config.prach_ce_level_1_configuration_index.value =
cfg->emtc_config.prach_ce_level_1_frequency_offset.value = p->prach_FreqOffset_r13; p->prach_ConfigIndex_r13;
cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.value = p->numRepetitionPerPreambleAttempt_r13; cfg->emtc_config.prach_ce_level_1_frequency_offset.value =
p->prach_FreqOffset_r13;
cfg->
emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.
value = p->numRepetitionPerPreambleAttempt_r13;
if (p->prach_StartingSubframe_r13) if (p->prach_StartingSubframe_r13)
cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.value = *p->prach_StartingSubframe_r13; cfg->
cfg->emtc_config.prach_ce_level_1_hopping_enable.value = p->prach_HoppingConfig_r13; emtc_config.prach_ce_level_1_starting_subframe_periodicity.
cfg->emtc_config.prach_ce_level_1_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value-6; value = *p->prach_StartingSubframe_r13;
cfg->emtc_config.prach_ce_level_1_hopping_enable.value =
p->prach_HoppingConfig_r13;
cfg->emtc_config.prach_ce_level_1_hopping_offset.value =
cfg->rf_config.ul_channel_bandwidth.value - 6;
case 1: case 1:
p=prach_ParametersListCE_r13->list.array[0]; p = prach_ParametersListCE_r13->list.array[0];
cfg->emtc_config.prach_ce_level_0_enable.value = 1; cfg->emtc_config.prach_ce_level_0_enable.value = 1;
cfg->emtc_config.prach_ce_level_0_configuration_index.value = p->prach_ConfigIndex_r13; cfg->emtc_config.prach_ce_level_0_configuration_index.value =
cfg->emtc_config.prach_ce_level_0_frequency_offset.value = p->prach_FreqOffset_r13; p->prach_ConfigIndex_r13;
cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.value = p->numRepetitionPerPreambleAttempt_r13; cfg->emtc_config.prach_ce_level_0_frequency_offset.value =
p->prach_FreqOffset_r13;
cfg->
emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.
value = p->numRepetitionPerPreambleAttempt_r13;
if (p->prach_StartingSubframe_r13) if (p->prach_StartingSubframe_r13)
cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.value = *p->prach_StartingSubframe_r13; cfg->
cfg->emtc_config.prach_ce_level_0_hopping_enable.value = p->prach_HoppingConfig_r13; emtc_config.prach_ce_level_0_starting_subframe_periodicity.
cfg->emtc_config.prach_ce_level_0_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value-6; value = *p->prach_StartingSubframe_r13;
cfg->emtc_config.prach_ce_level_0_hopping_enable.value =
p->prach_HoppingConfig_r13;
cfg->emtc_config.prach_ce_level_0_hopping_offset.value =
cfg->rf_config.ul_channel_bandwidth.value - 6;
} }
struct FreqHoppingParameters_r13 *ext4_freqHoppingParameters = radioResourceConfigCommonP->ext4->freqHoppingParameters_r13; struct FreqHoppingParameters_r13 *ext4_freqHoppingParameters =
if ((ext4_freqHoppingParameters) && radioResourceConfigCommonP->ext4->freqHoppingParameters_r13;
(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13)){ if ((ext4_freqHoppingParameters)
switch(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->present) { &&
(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13))
{
switch
(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->
present) {
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_NOTHING: /* No components present */ case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_NOTHING: /* No components present */
break; break;
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_FDD_r13: case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_FDD_r13:
cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_FDD_r13; cfg->emtc_config.
pucch_interval_ulhoppingconfigcommonmodea.value =
ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->
choice.interval_FDD_r13;
break; break;
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_TDD_r13: case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_TDD_r13:
cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_TDD_r13; cfg->emtc_config.
pucch_interval_ulhoppingconfigcommonmodea.value =
ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->
choice.interval_TDD_r13;
break; break;
} }
} }
if ((ext4_freqHoppingParameters) && if ((ext4_freqHoppingParameters) &&
(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13)){ (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13))
switch(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->present) { {
switch
(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->
present) {
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_NOTHING: /* No components present */ case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_NOTHING: /* No components present */
break; break;
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_FDD_r13: case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_FDD_r13:
cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_FDD_r13; cfg->emtc_config.
pucch_interval_ulhoppingconfigcommonmodeb.value =
ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->
choice.interval_FDD_r13;
break; break;
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_TDD_r13: case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_TDD_r13:
cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_TDD_r13; cfg->emtc_config.
pucch_interval_ulhoppingconfigcommonmodeb.value =
ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->
choice.interval_TDD_r13;
break; break;
} }
} }
...@@ -415,74 +533,86 @@ void config_sib2(int Mod_idP, ...@@ -415,74 +533,86 @@ void config_sib2(int Mod_idP,
} }
void config_dedicated(int Mod_idP, void
config_dedicated(int Mod_idP,
int CC_idP, int CC_idP,
uint16_t rnti, uint16_t rnti,
struct PhysicalConfigDedicated *physicalConfigDedicated) { struct PhysicalConfigDedicated *physicalConfigDedicated)
{
} }
void config_dedicated_scell(int Mod_idP, void
config_dedicated_scell(int Mod_idP,
uint16_t rnti, uint16_t rnti,
SCellToAddMod_r10_t *sCellToAddMod_r10) { SCellToAddMod_r10_t * sCellToAddMod_r10)
{
} }
int rrc_mac_config_req_eNB(module_id_t Mod_idP, int
rrc_mac_config_req_eNB(module_id_t Mod_idP,
int CC_idP, int CC_idP,
int physCellId, int physCellId,
int p_eNB, int p_eNB,
int Ncp, int Ncp, int eutra_band, uint32_t dl_CarrierFreq,
int eutra_band,
uint32_t dl_CarrierFreq,
#ifdef Rel14 #ifdef Rel14
int pbch_repetition, int pbch_repetition,
#endif #endif
rnti_t rntiP, rnti_t rntiP,
BCCH_BCH_Message_t *mib, BCCH_BCH_Message_t * mib,
RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, RadioResourceConfigCommonSIB_t *
radioResourceConfigCommon,
#ifdef Rel14 #ifdef Rel14
RadioResourceConfigCommonSIB_t *radioResourceConfigCommon_BR, RadioResourceConfigCommonSIB_t *
radioResourceConfigCommon_BR,
#endif #endif
struct PhysicalConfigDedicated *physicalConfigDedicated, struct PhysicalConfigDedicated
*physicalConfigDedicated,
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
SCellToAddMod_r10_t *sCellToAddMod_r10, SCellToAddMod_r10_t * sCellToAddMod_r10,
//struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10,
#endif #endif
MeasObjectToAddMod_t **measObj, MeasObjectToAddMod_t ** measObj,
MAC_MainConfig_t *mac_MainConfig, MAC_MainConfig_t * mac_MainConfig,
long logicalChannelIdentity, long logicalChannelIdentity,
LogicalChannelConfig_t *logicalChannelConfig, LogicalChannelConfig_t * logicalChannelConfig,
MeasGapConfig_t *measGapConfig, MeasGapConfig_t * measGapConfig,
TDD_Config_t *tdd_Config, TDD_Config_t * tdd_Config,
MobilityControlInfo_t *mobilityControlInfo, MobilityControlInfo_t * mobilityControlInfo,
SchedulingInfoList_t *schedulingInfoList, SchedulingInfoList_t * schedulingInfoList,
uint32_t ul_CarrierFreq, uint32_t ul_CarrierFreq,
long *ul_Bandwidth, long *ul_Bandwidth,
AdditionalSpectrumEmission_t *additionalSpectrumEmission, AdditionalSpectrumEmission_t *
struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList additionalSpectrumEmission,
struct MBSFN_SubframeConfigList
*mbsfn_SubframeConfigList
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
,uint8_t MBMS_Flag, , uint8_t MBMS_Flag,
MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList, MBSFN_AreaInfoList_r9_t * mbsfn_AreaInfoList,
PMCH_InfoList_r9_t *pmch_InfoList PMCH_InfoList_r9_t * pmch_InfoList
#endif #endif
#ifdef Rel14 #ifdef Rel14
, ,
SystemInformationBlockType1_v1310_IEs_t *sib1_v13ext SystemInformationBlockType1_v1310_IEs_t *
sib1_v13ext
#endif #endif
) { )
{
int i; int i;
int UE_id = -1; int UE_id = -1;
eNB_MAC_INST *eNB = RC.mac[Mod_idP]; eNB_MAC_INST *eNB = RC.mac[Mod_idP];
UE_list_t *UE_list= &eNB->UE_list; UE_list_t *UE_list = &eNB->UE_list;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN);
if (mib!=NULL) { if (mib != NULL) {
if (RC.mac == NULL) l2_init_eNB(); if (RC.mac == NULL)
l2_init_eNB();
mac_top_init_eNB(); mac_top_init_eNB();
...@@ -491,88 +621,124 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, ...@@ -491,88 +621,124 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
RC.mac[Mod_idP]->common_channels[CC_idP].p_eNB = p_eNB; RC.mac[Mod_idP]->common_channels[CC_idP].p_eNB = p_eNB;
RC.mac[Mod_idP]->common_channels[CC_idP].Ncp = Ncp; RC.mac[Mod_idP]->common_channels[CC_idP].Ncp = Ncp;
RC.mac[Mod_idP]->common_channels[CC_idP].eutra_band = eutra_band; RC.mac[Mod_idP]->common_channels[CC_idP].eutra_band = eutra_band;
RC.mac[Mod_idP]->common_channels[CC_idP].dl_CarrierFreq = dl_CarrierFreq; RC.mac[Mod_idP]->common_channels[CC_idP].dl_CarrierFreq =
dl_CarrierFreq;
LOG_I(MAC, LOG_I(MAC,
"Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d,Nid_cell %d,p %d,DL freq %u,phich_config.resource %d, phich_config.duration %d)\n", "Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d,Nid_cell %d,p %d,DL freq %u,phich_config.resource %d, phich_config.duration %d)\n",
Mod_idP, Mod_idP,
CC_idP, CC_idP,
eutra_band, eutra_band,
to_prb((int)mib->message.dl_Bandwidth), to_prb((int) mib->message.dl_Bandwidth),
physCellId, physCellId,
p_eNB, p_eNB,
dl_CarrierFreq, dl_CarrierFreq,
(int)mib->message.phich_Config.phich_Resource, (int) mib->message.phich_Config.phich_Resource,
(int)mib->message.phich_Config.phich_Duration); (int) mib->message.phich_Config.phich_Duration);
config_mib(Mod_idP,CC_idP, config_mib(Mod_idP, CC_idP,
eutra_band, eutra_band,
mib->message.dl_Bandwidth, mib->message.dl_Bandwidth,
&mib->message.phich_Config, &mib->message.phich_Config,
physCellId, physCellId, Ncp, p_eNB, dl_CarrierFreq, ul_CarrierFreq
Ncp,
p_eNB,
dl_CarrierFreq,
ul_CarrierFreq
#ifdef Rel14 #ifdef Rel14
,pbch_repetition , pbch_repetition
#endif #endif
); );
mac_init_cell_params(Mod_idP,CC_idP); mac_init_cell_params(Mod_idP, CC_idP);
} }
if (schedulingInfoList!=NULL) { if (schedulingInfoList != NULL) {
RC.mac[Mod_idP]->common_channels[CC_idP].tdd_Config = tdd_Config; RC.mac[Mod_idP]->common_channels[CC_idP].tdd_Config = tdd_Config;
RC.mac[Mod_idP]->common_channels[CC_idP].schedulingInfoList = schedulingInfoList; RC.mac[Mod_idP]->common_channels[CC_idP].schedulingInfoList =
config_sib1(Mod_idP,CC_idP,tdd_Config); schedulingInfoList;
config_sib1(Mod_idP, CC_idP, tdd_Config);
} }
#ifdef Rel14 #ifdef Rel14
if (sib1_v13ext != NULL) { if (sib1_v13ext != NULL) {
RC.mac[Mod_idP]->common_channels[CC_idP].sib1_v13ext = sib1_v13ext; RC.mac[Mod_idP]->common_channels[CC_idP].sib1_v13ext = sib1_v13ext;
} }
#endif #endif
if (radioResourceConfigCommon!=NULL) { if (radioResourceConfigCommon != NULL) {
LOG_I(MAC,"[CONFIG]SIB2/3 Contents (partial)\n"); LOG_I(MAC, "[CONFIG]SIB2/3 Contents (partial)\n");
LOG_I(MAC,"[CONFIG]pusch_config_common.n_SB = %ld\n",radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.n_SB); LOG_I(MAC, "[CONFIG]pusch_config_common.n_SB = %ld\n",
LOG_I(MAC,"[CONFIG]pusch_config_common.hoppingMode = %ld\n",radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode); radioResourceConfigCommon->
LOG_I(MAC,"[CONFIG]pusch_config_common.pusch_HoppingOffset = %ld\n", radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset); pusch_ConfigCommon.pusch_ConfigBasic.n_SB);
LOG_I(MAC,"[CONFIG]pusch_config_common.enable64QAM = %d\n",radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM); LOG_I(MAC, "[CONFIG]pusch_config_common.hoppingMode = %ld\n",
LOG_I(MAC,"[CONFIG]pusch_config_common.groupHoppingEnabled = %d\n",radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled); radioResourceConfigCommon->
LOG_I(MAC,"[CONFIG]pusch_config_common.groupAssignmentPUSCH = %ld\n",radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH); pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode);
LOG_I(MAC,"[CONFIG]pusch_config_common.sequenceHoppingEnabled = %d\n",radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled); LOG_I(MAC,
LOG_I(MAC,"[CONFIG]pusch_config_common.cyclicShift = %ld\n",radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift); "[CONFIG]pusch_config_common.pusch_HoppingOffset = %ld\n",
radioResourceConfigCommon->
AssertFatal(radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx > 0, pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset);
LOG_I(MAC, "[CONFIG]pusch_config_common.enable64QAM = %d\n",
radioResourceConfigCommon->
pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM);
LOG_I(MAC,
"[CONFIG]pusch_config_common.groupHoppingEnabled = %d\n",
radioResourceConfigCommon->
pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.
groupHoppingEnabled);
LOG_I(MAC,
"[CONFIG]pusch_config_common.groupAssignmentPUSCH = %ld\n",
radioResourceConfigCommon->
pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.
groupAssignmentPUSCH);
LOG_I(MAC,
"[CONFIG]pusch_config_common.sequenceHoppingEnabled = %d\n",
radioResourceConfigCommon->
pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.
sequenceHoppingEnabled);
LOG_I(MAC, "[CONFIG]pusch_config_common.cyclicShift = %ld\n",
radioResourceConfigCommon->
pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift);
AssertFatal(radioResourceConfigCommon->
rach_ConfigCommon.maxHARQ_Msg3Tx > 0,
"radioResourceconfigCommon %d == 0\n", "radioResourceconfigCommon %d == 0\n",
(int)radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx); (int) radioResourceConfigCommon->
rach_ConfigCommon.maxHARQ_Msg3Tx);
RC.mac[Mod_idP]->common_channels[CC_idP].radioResourceConfigCommon = radioResourceConfigCommon;
if (ul_CarrierFreq>0) RC.mac[Mod_idP]->common_channels[CC_idP].ul_CarrierFreq = ul_CarrierFreq; RC.mac[Mod_idP]->common_channels[CC_idP].
if (ul_Bandwidth) RC.mac[Mod_idP]->common_channels[CC_idP].ul_Bandwidth = *ul_Bandwidth; radioResourceConfigCommon = radioResourceConfigCommon;
else RC.mac[Mod_idP]->common_channels[CC_idP].ul_Bandwidth = RC.mac[Mod_idP]->common_channels[CC_idP].mib->message.dl_Bandwidth; if (ul_CarrierFreq > 0)
RC.mac[Mod_idP]->common_channels[CC_idP].ul_CarrierFreq =
ul_CarrierFreq;
if (ul_Bandwidth)
RC.mac[Mod_idP]->common_channels[CC_idP].ul_Bandwidth =
*ul_Bandwidth;
else
RC.mac[Mod_idP]->common_channels[CC_idP].ul_Bandwidth =
RC.mac[Mod_idP]->common_channels[CC_idP].mib->message.
dl_Bandwidth;
config_sib2(Mod_idP, CC_idP, config_sib2(Mod_idP, CC_idP, radioResourceConfigCommon,
radioResourceConfigCommon,
#ifdef Rel14 #ifdef Rel14
radioResourceConfigCommon_BR, radioResourceConfigCommon_BR,
#endif #endif
NULL, ul_Bandwidth, additionalSpectrumEmission, mbsfn_SubframeConfigList); NULL, ul_Bandwidth, additionalSpectrumEmission,
mbsfn_SubframeConfigList);
} }
// SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters->logicalChannelGroup // SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters->logicalChannelGroup
if (logicalChannelConfig!= NULL) { // check for eMTC specific things if (logicalChannelConfig != NULL) { // check for eMTC specific things
UE_id = find_UE_id(Mod_idP, rntiP); UE_id = find_UE_id(Mod_idP, rntiP);
if (UE_id == -1) { if (UE_id == -1) {
LOG_E(MAC,"%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, __LINE__, __FUNCTION__); LOG_E(MAC, "%s:%d:%s: ERROR, UE_id == -1\n", __FILE__,
__LINE__, __FUNCTION__);
} else { } else {
if (logicalChannelConfig) if (logicalChannelConfig)
UE_list->UE_template[CC_idP][UE_id].lcgidmap[logicalChannelIdentity] = *logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup; UE_list->
UE_template[CC_idP][UE_id].lcgidmap
[logicalChannelIdentity] =
*logicalChannelConfig->
ul_SpecificParameters->logicalChannelGroup;
else else
UE_list->UE_template[CC_idP][UE_id].lcgidmap[logicalChannelIdentity] = 0; UE_list->
UE_template[CC_idP][UE_id].lcgidmap
[logicalChannelIdentity] = 0;
} }
} }
...@@ -581,56 +747,70 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, ...@@ -581,56 +747,70 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
UE_id = find_UE_id(Mod_idP, rntiP); UE_id = find_UE_id(Mod_idP, rntiP);
if (UE_id == -1) if (UE_id == -1)
LOG_E(MAC,"%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, __LINE__, __FUNCTION__); LOG_E(MAC, "%s:%d:%s: ERROR, UE_id == -1\n", __FILE__,
__LINE__, __FUNCTION__);
else else
UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated=physicalConfigDedicated; UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated =
physicalConfigDedicated;
} }
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
if (sCellToAddMod_r10 != NULL) { if (sCellToAddMod_r10 != NULL) {
UE_id = find_UE_id(Mod_idP, rntiP); UE_id = find_UE_id(Mod_idP, rntiP);
if (UE_id == -1) if (UE_id == -1)
LOG_E(MAC,"%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, __LINE__, __FUNCTION__); LOG_E(MAC, "%s:%d:%s: ERROR, UE_id == -1\n", __FILE__,
__LINE__, __FUNCTION__);
else else
config_dedicated_scell(Mod_idP,rntiP,sCellToAddMod_r10); config_dedicated_scell(Mod_idP, rntiP, sCellToAddMod_r10);
} }
#endif #endif
if (mbsfn_SubframeConfigList != NULL) { if (mbsfn_SubframeConfigList != NULL) {
LOG_I(MAC,"[eNB %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n", Mod_idP, mbsfn_SubframeConfigList->list.count); LOG_I(MAC,
RC.mac[Mod_idP]->common_channels[0].num_sf_allocation_pattern= mbsfn_SubframeConfigList->list.count; "[eNB %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n",
Mod_idP, mbsfn_SubframeConfigList->list.count);
for (i=0; i<mbsfn_SubframeConfigList->list.count; i++) { RC.mac[Mod_idP]->common_channels[0].num_sf_allocation_pattern =
RC.mac[Mod_idP]->common_channels[0].mbsfn_SubframeConfig[i] = mbsfn_SubframeConfigList->list.array[i]; mbsfn_SubframeConfigList->list.count;
LOG_I(MAC, "[eNB %d][CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", Mod_idP, i,
RC.mac[Mod_idP]->common_channels[0].mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]); for (i = 0; i < mbsfn_SubframeConfigList->list.count; i++) {
RC.mac[Mod_idP]->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_idP, i,
RC.mac[Mod_idP]->
common_channels[0].mbsfn_SubframeConfig[i]->
subframeAllocation.choice.oneFrame.buf[0]);
} }
#ifdef Rel10 #ifdef Rel10
RC.mac[Mod_idP]->common_channels[0].MBMS_flag = MBMS_Flag; RC.mac[Mod_idP]->common_channels[0].MBMS_flag = MBMS_Flag;
#endif #endif
} }
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
if (mbsfn_AreaInfoList != NULL) { if (mbsfn_AreaInfoList != NULL) {
// One eNB could be part of multiple mbsfn syc area, this could change over time so reset each time // One eNB could be part of multiple mbsfn syc area, this could change over time so reset each time
LOG_I(MAC,"[eNB %d][CONFIG] Received %d MBSFN Area Info\n", Mod_idP, mbsfn_AreaInfoList->list.count); LOG_I(MAC, "[eNB %d][CONFIG] Received %d MBSFN Area Info\n",
RC.mac[Mod_idP]->common_channels[0].num_active_mbsfn_area = mbsfn_AreaInfoList->list.count; Mod_idP, mbsfn_AreaInfoList->list.count);
RC.mac[Mod_idP]->common_channels[0].num_active_mbsfn_area =
for (i =0; i< mbsfn_AreaInfoList->list.count; i++) { mbsfn_AreaInfoList->list.count;
RC.mac[Mod_idP]->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_idP,i, for (i = 0; i < mbsfn_AreaInfoList->list.count; i++) {
RC.mac[Mod_idP]->common_channels[0].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9); RC.mac[Mod_idP]->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_idP, i,
RC.mac[Mod_idP]->common_channels[0].
mbsfn_AreaInfo[i]->mcch_Config_r9.
mcch_RepetitionPeriod_r9);
// config_sib13(Mod_idP,0,i,RC.mac[Mod_idP]->common_channels[0].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9); // config_sib13(Mod_idP,0,i,RC.mac[Mod_idP]->common_channels[0].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9);
} }
} }
...@@ -639,81 +819,98 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, ...@@ -639,81 +819,98 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
// LOG_I(MAC,"DUY: lcid when entering rrc_mac config_req is %02d\n",(pmch_InfoList->list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9)); // LOG_I(MAC,"DUY: lcid when entering rrc_mac config_req is %02d\n",(pmch_InfoList->list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9));
LOG_I(MAC, "[CONFIG] Number of PMCH in this MBSFN Area %d\n", pmch_InfoList->list.count); LOG_I(MAC, "[CONFIG] Number of PMCH in this MBSFN Area %d\n",
pmch_InfoList->list.count);
for (i =0; i< pmch_InfoList->list.count; i++) { for (i = 0; i < pmch_InfoList->list.count; i++) {
RC.mac[Mod_idP]->common_channels[0].pmch_Config[i] = &pmch_InfoList->list.array[i]->pmch_Config_r9; RC.mac[Mod_idP]->common_channels[0].pmch_Config[i] =
&pmch_InfoList->list.array[i]->pmch_Config_r9;
LOG_I(MAC, "[CONFIG] PMCH[%d]: This PMCH stop (sf_AllocEnd_r9) at subframe %ldth\n", i, LOG_I(MAC,
RC.mac[Mod_idP]->common_channels[0].pmch_Config[i]->sf_AllocEnd_r9); "[CONFIG] PMCH[%d]: This PMCH stop (sf_AllocEnd_r9) at subframe %ldth\n",
LOG_I(MAC, "[CONFIG] PMCH[%d]: mch_Scheduling_Period = %ld\n", i, i,
RC.mac[Mod_idP]->common_channels[0].pmch_Config[i]->mch_SchedulingPeriod_r9); RC.mac[Mod_idP]->common_channels[0].
pmch_Config[i]->sf_AllocEnd_r9);
LOG_I(MAC, "[CONFIG] PMCH[%d]: mch_Scheduling_Period = %ld\n",
i,
RC.mac[Mod_idP]->common_channels[0].
pmch_Config[i]->mch_SchedulingPeriod_r9);
LOG_I(MAC, "[CONFIG] PMCH[%d]: dataMCS = %ld\n", i, LOG_I(MAC, "[CONFIG] PMCH[%d]: dataMCS = %ld\n", i,
RC.mac[Mod_idP]->common_channels[0].pmch_Config[i]->dataMCS_r9); RC.mac[Mod_idP]->common_channels[0].
pmch_Config[i]->dataMCS_r9);
// MBMS session info list in each MCH // MBMS session info list in each MCH
RC.mac[Mod_idP]->common_channels[0].mbms_SessionList[i] = &pmch_InfoList->list.array[i]->mbms_SessionInfoList_r9; RC.mac[Mod_idP]->common_channels[0].mbms_SessionList[i] =
LOG_I(MAC, "PMCH[%d] Number of session (MTCH) is: %d\n",i, RC.mac[Mod_idP]->common_channels[0].mbms_SessionList[i]->list.count); &pmch_InfoList->list.array[i]->mbms_SessionInfoList_r9;
LOG_I(MAC, "PMCH[%d] Number of session (MTCH) is: %d\n", i,
RC.mac[Mod_idP]->common_channels[0].
mbms_SessionList[i]->list.count);
} }
} }
#endif #endif
if (radioResourceConfigCommon!=NULL) { if (radioResourceConfigCommon != NULL) {
AssertFatal(RC.mac[Mod_idP]->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n"); AssertFatal(RC.mac[Mod_idP]->if_inst->PHY_config_req != NULL,
"if_inst->phy_config_request is null\n");
PHY_Config_t phycfg; PHY_Config_t phycfg;
phycfg.Mod_id = Mod_idP; phycfg.Mod_id = Mod_idP;
phycfg.CC_id = CC_idP; phycfg.CC_id = CC_idP;
phycfg.cfg = &RC.mac[Mod_idP]->config[CC_idP]; phycfg.cfg = &RC.mac[Mod_idP]->config[CC_idP];
if (RC.mac[Mod_idP]->if_inst->PHY_config_req) RC.mac[Mod_idP]->if_inst->PHY_config_req(&phycfg); if (RC.mac[Mod_idP]->if_inst->PHY_config_req)
RC.mac[Mod_idP]->if_inst->PHY_config_req(&phycfg);
} }
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT);
return(0); return (0);
} }
int int
rrc_mac_config_req_ue( rrc_mac_config_req_ue(module_id_t Mod_idP,
module_id_t Mod_idP,
int CC_idP, int CC_idP,
uint8_t eNB_index, uint8_t eNB_index,
RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, RadioResourceConfigCommonSIB_t *
struct PhysicalConfigDedicated *physicalConfigDedicated, radioResourceConfigCommon,
struct PhysicalConfigDedicated
*physicalConfigDedicated,
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
SCellToAddMod_r10_t *sCellToAddMod_r10, SCellToAddMod_r10_t * sCellToAddMod_r10,
//struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10,
#endif #endif
MeasObjectToAddMod_t **measObj, MeasObjectToAddMod_t ** measObj,
MAC_MainConfig_t *mac_MainConfig, MAC_MainConfig_t * mac_MainConfig,
long logicalChannelIdentity, long logicalChannelIdentity,
LogicalChannelConfig_t *logicalChannelConfig, LogicalChannelConfig_t * logicalChannelConfig,
MeasGapConfig_t *measGapConfig, MeasGapConfig_t * measGapConfig,
TDD_Config_t *tdd_Config, TDD_Config_t * tdd_Config,
MobilityControlInfo_t *mobilityControlInfo, MobilityControlInfo_t * mobilityControlInfo,
uint8_t *SIwindowsize, uint8_t * SIwindowsize,
uint16_t *SIperiod, uint16_t * SIperiod,
ARFCN_ValueEUTRA_t *ul_CarrierFreq, ARFCN_ValueEUTRA_t * ul_CarrierFreq,
long *ul_Bandwidth, long *ul_Bandwidth,
AdditionalSpectrumEmission_t *additionalSpectrumEmission, AdditionalSpectrumEmission_t *
struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList additionalSpectrumEmission,
struct MBSFN_SubframeConfigList
*mbsfn_SubframeConfigList
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
,uint8_t MBMS_Flag, , uint8_t MBMS_Flag,
MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList, MBSFN_AreaInfoList_r9_t * mbsfn_AreaInfoList,
PMCH_InfoList_r9_t *pmch_InfoList PMCH_InfoList_r9_t * pmch_InfoList
#endif #endif
#ifdef CBA #ifdef CBA
,uint8_t num_active_cba_groups, , uint8_t num_active_cba_groups, uint16_t cba_rnti
uint16_t cba_rnti
#endif #endif
) )
{ {
int i; int i;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN);
LOG_I(MAC,"[CONFIG][UE %d] Configuring MAC/PHY from eNB %d\n",Mod_idP,eNB_index); LOG_I(MAC, "[CONFIG][UE %d] Configuring MAC/PHY from eNB %d\n",
Mod_idP, eNB_index);
if (tdd_Config != NULL) { if (tdd_Config != NULL) {
UE_mac_inst[Mod_idP].tdd_Config = tdd_Config; UE_mac_inst[Mod_idP].tdd_Config = tdd_Config;
...@@ -721,48 +918,68 @@ rrc_mac_config_req_ue( ...@@ -721,48 +918,68 @@ rrc_mac_config_req_ue(
if (tdd_Config && SIwindowsize && SIperiod) { if (tdd_Config && SIwindowsize && SIperiod) {
phy_config_sib1_ue(Mod_idP,0,eNB_index,tdd_Config,*SIwindowsize,*SIperiod); phy_config_sib1_ue(Mod_idP, 0, eNB_index, tdd_Config,
*SIwindowsize, *SIperiod);
} }
if (radioResourceConfigCommon!=NULL) { if (radioResourceConfigCommon != NULL) {
UE_mac_inst[Mod_idP].radioResourceConfigCommon = radioResourceConfigCommon; UE_mac_inst[Mod_idP].radioResourceConfigCommon =
phy_config_sib2_ue(Mod_idP,0,eNB_index,radioResourceConfigCommon,ul_CarrierFreq,ul_Bandwidth,additionalSpectrumEmission,mbsfn_SubframeConfigList); radioResourceConfigCommon;
phy_config_sib2_ue(Mod_idP, 0, eNB_index,
radioResourceConfigCommon, ul_CarrierFreq,
ul_Bandwidth, additionalSpectrumEmission,
mbsfn_SubframeConfigList);
} }
// SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters->logicalChannelGroup // SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters->logicalChannelGroup
if (logicalChannelConfig!= NULL) { if (logicalChannelConfig != NULL) {
LOG_I(MAC,"[CONFIG][UE %d] Applying RRC logicalChannelConfig from eNB%d\n",Mod_idP,eNB_index); LOG_I(MAC,
UE_mac_inst[Mod_idP].logicalChannelConfig[logicalChannelIdentity]=logicalChannelConfig; "[CONFIG][UE %d] Applying RRC logicalChannelConfig from eNB%d\n",
UE_mac_inst[Mod_idP].scheduling_info.Bj[logicalChannelIdentity]=0; // initilize the bucket for this lcid Mod_idP, eNB_index);
UE_mac_inst[Mod_idP].logicalChannelConfig[logicalChannelIdentity] =
logicalChannelConfig;
UE_mac_inst[Mod_idP].scheduling_info.Bj[logicalChannelIdentity] = 0; // initilize the bucket for this lcid
AssertFatal(logicalChannelConfig->ul_SpecificParameters!=NULL, AssertFatal(logicalChannelConfig->ul_SpecificParameters != NULL,
"[UE %d] LCID %ld NULL ul_SpecificParameters\n", "[UE %d] LCID %ld NULL ul_SpecificParameters\n",
Mod_idP,logicalChannelIdentity); Mod_idP, logicalChannelIdentity);
UE_mac_inst[Mod_idP].scheduling_info.bucket_size[logicalChannelIdentity]=logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate * UE_mac_inst[Mod_idP].scheduling_info.bucket_size[logicalChannelIdentity] = logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate * logicalChannelConfig->ul_SpecificParameters->bucketSizeDuration; // set the max bucket size
logicalChannelConfig->ul_SpecificParameters->bucketSizeDuration; // set the max bucket size if (logicalChannelConfig->ul_SpecificParameters->
if (logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup != NULL) { logicalChannelGroup != NULL) {
UE_mac_inst[Mod_idP].scheduling_info.LCGID[logicalChannelIdentity]=*logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup; UE_mac_inst[Mod_idP].scheduling_info.
LOG_D(MAC,"[CONFIG][UE %d] LCID %ld is attached to the LCGID %ld\n",Mod_idP,logicalChannelIdentity,*logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup); LCGID[logicalChannelIdentity] =
} *logicalChannelConfig->ul_SpecificParameters->
else { logicalChannelGroup;
UE_mac_inst[Mod_idP].scheduling_info.LCGID[logicalChannelIdentity] = MAX_NUM_LCGID; LOG_D(MAC,
"[CONFIG][UE %d] LCID %ld is attached to the LCGID %ld\n",
Mod_idP, logicalChannelIdentity,
*logicalChannelConfig->
ul_SpecificParameters->logicalChannelGroup);
} else {
UE_mac_inst[Mod_idP].scheduling_info.
LCGID[logicalChannelIdentity] = MAX_NUM_LCGID;
} }
UE_mac_inst[Mod_idP].scheduling_info.LCID_buffer_remain[logicalChannelIdentity] = 0; UE_mac_inst[Mod_idP].
scheduling_info.LCID_buffer_remain[logicalChannelIdentity] = 0;
} }
if (mac_MainConfig != NULL) { if (mac_MainConfig != NULL) {
LOG_I(MAC,"[CONFIG][UE%d] Applying RRC macMainConfig from eNB%d\n",Mod_idP,eNB_index); LOG_I(MAC,
UE_mac_inst[Mod_idP].macConfig=mac_MainConfig; "[CONFIG][UE%d] Applying RRC macMainConfig from eNB%d\n",
UE_mac_inst[Mod_idP].measGapConfig=measGapConfig; Mod_idP, eNB_index);
UE_mac_inst[Mod_idP].macConfig = mac_MainConfig;
UE_mac_inst[Mod_idP].measGapConfig = measGapConfig;
if (mac_MainConfig->ul_SCH_Config) { if (mac_MainConfig->ul_SCH_Config) {
if (mac_MainConfig->ul_SCH_Config->periodicBSR_Timer) { if (mac_MainConfig->ul_SCH_Config->periodicBSR_Timer) {
UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_Timer = (uint16_t) *mac_MainConfig->ul_SCH_Config->periodicBSR_Timer; UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_Timer =
(uint16_t) *
mac_MainConfig->ul_SCH_Config->periodicBSR_Timer;
} else { } else {
UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_Timer = UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_Timer =
#ifndef Rel14 #ifndef Rel14
(uint16_t) MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity (uint16_t)
MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity
#else #else
(uint16_t) PeriodicBSR_Timer_r12_infinity; (uint16_t) PeriodicBSR_Timer_r12_infinity;
#endif #endif
...@@ -770,82 +987,126 @@ rrc_mac_config_req_ue( ...@@ -770,82 +987,126 @@ rrc_mac_config_req_ue(
} }
if (mac_MainConfig->ul_SCH_Config->maxHARQ_Tx) { if (mac_MainConfig->ul_SCH_Config->maxHARQ_Tx) {
UE_mac_inst[Mod_idP].scheduling_info.maxHARQ_Tx = (uint16_t) *mac_MainConfig->ul_SCH_Config->maxHARQ_Tx; UE_mac_inst[Mod_idP].scheduling_info.maxHARQ_Tx =
(uint16_t) * mac_MainConfig->ul_SCH_Config->maxHARQ_Tx;
} else { } else {
UE_mac_inst[Mod_idP].scheduling_info.maxHARQ_Tx = (uint16_t) MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; UE_mac_inst[Mod_idP].scheduling_info.maxHARQ_Tx =
(uint16_t)
MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5;
} }
phy_config_harq_ue(Mod_idP,0,eNB_index,UE_mac_inst[Mod_idP].scheduling_info.maxHARQ_Tx); phy_config_harq_ue(Mod_idP, 0, eNB_index,
UE_mac_inst[Mod_idP].
scheduling_info.maxHARQ_Tx);
if (mac_MainConfig->ul_SCH_Config->retxBSR_Timer) { if (mac_MainConfig->ul_SCH_Config->retxBSR_Timer) {
UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer = (uint16_t) mac_MainConfig->ul_SCH_Config->retxBSR_Timer; UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer =
(uint16_t) mac_MainConfig->ul_SCH_Config->
retxBSR_Timer;
} else { } else {
#ifndef Rel14 #ifndef Rel14
UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer = (uint16_t)MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf2560; UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer =
(uint16_t)
MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf2560;
#else #else
UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer = (uint16_t)RetxBSR_Timer_r12_sf2560; UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer =
(uint16_t) RetxBSR_Timer_r12_sf2560;
#endif #endif
} }
} }
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
if (mac_MainConfig->ext1 && mac_MainConfig->ext1->sr_ProhibitTimer_r9) { if (mac_MainConfig->ext1
UE_mac_inst[Mod_idP].scheduling_info.sr_ProhibitTimer = (uint16_t) *mac_MainConfig->ext1->sr_ProhibitTimer_r9; && mac_MainConfig->ext1->sr_ProhibitTimer_r9) {
UE_mac_inst[Mod_idP].scheduling_info.sr_ProhibitTimer =
(uint16_t) * mac_MainConfig->ext1->sr_ProhibitTimer_r9;
} else { } else {
UE_mac_inst[Mod_idP].scheduling_info.sr_ProhibitTimer = 0; UE_mac_inst[Mod_idP].scheduling_info.sr_ProhibitTimer = 0;
} }
if (mac_MainConfig->ext2 && mac_MainConfig->ext2->mac_MainConfig_v1020) { if (mac_MainConfig->ext2
if (mac_MainConfig->ext2->mac_MainConfig_v1020->extendedBSR_Sizes_r10) { && mac_MainConfig->ext2->mac_MainConfig_v1020) {
UE_mac_inst[Mod_idP].scheduling_info.extendedBSR_Sizes_r10 = (uint16_t) *mac_MainConfig->ext2->mac_MainConfig_v1020->extendedBSR_Sizes_r10; if (mac_MainConfig->ext2->
mac_MainConfig_v1020->extendedBSR_Sizes_r10) {
UE_mac_inst[Mod_idP].scheduling_info.
extendedBSR_Sizes_r10 =
(uint16_t) *
mac_MainConfig->ext2->
mac_MainConfig_v1020->extendedBSR_Sizes_r10;
} else { } else {
UE_mac_inst[Mod_idP].scheduling_info.extendedBSR_Sizes_r10 = (uint16_t)0; UE_mac_inst[Mod_idP].scheduling_info.
extendedBSR_Sizes_r10 = (uint16_t) 0;
} }
if (mac_MainConfig->ext2->mac_MainConfig_v1020->extendedPHR_r10) { if (mac_MainConfig->ext2->mac_MainConfig_v1020->
UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 = (uint16_t) *mac_MainConfig->ext2->mac_MainConfig_v1020->extendedPHR_r10; extendedPHR_r10) {
UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 =
(uint16_t) *
mac_MainConfig->ext2->mac_MainConfig_v1020->
extendedPHR_r10;
} else { } else {
UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 = (uint16_t)0; UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 =
(uint16_t) 0;
} }
} else { } else {
UE_mac_inst[Mod_idP].scheduling_info.extendedBSR_Sizes_r10 = (uint16_t)0; UE_mac_inst[Mod_idP].scheduling_info.extendedBSR_Sizes_r10 =
UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 = (uint16_t)0; (uint16_t) 0;
UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 =
(uint16_t) 0;
} }
#endif #endif
UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING; UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_SF =
UE_mac_inst[Mod_idP].scheduling_info.retxBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING; MAC_UE_BSR_TIMER_NOT_RUNNING;
UE_mac_inst[Mod_idP].scheduling_info.retxBSR_SF =
MAC_UE_BSR_TIMER_NOT_RUNNING;
UE_mac_inst[Mod_idP].BSR_reporting_active = BSR_TRIGGER_NONE; UE_mac_inst[Mod_idP].BSR_reporting_active = BSR_TRIGGER_NONE;
LOG_D(MAC,"[UE %d]: periodic BSR %d (SF), retx BSR %d (SF)\n", LOG_D(MAC, "[UE %d]: periodic BSR %d (SF), retx BSR %d (SF)\n",
Mod_idP, Mod_idP,
UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_SF, UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_SF,
UE_mac_inst[Mod_idP].scheduling_info.retxBSR_SF); UE_mac_inst[Mod_idP].scheduling_info.retxBSR_SF);
UE_mac_inst[Mod_idP].scheduling_info.drx_config = mac_MainConfig->drx_Config; UE_mac_inst[Mod_idP].scheduling_info.drx_config =
UE_mac_inst[Mod_idP].scheduling_info.phr_config = mac_MainConfig->phr_Config; mac_MainConfig->drx_Config;
UE_mac_inst[Mod_idP].scheduling_info.phr_config =
mac_MainConfig->phr_Config;
if (mac_MainConfig->phr_Config) { if (mac_MainConfig->phr_Config) {
UE_mac_inst[Mod_idP].PHR_state = mac_MainConfig->phr_Config->present; UE_mac_inst[Mod_idP].PHR_state =
mac_MainConfig->phr_Config->present;
UE_mac_inst[Mod_idP].PHR_reconfigured = 1; UE_mac_inst[Mod_idP].PHR_reconfigured = 1;
UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_Timer = mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer; UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_Timer =
UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_Timer = mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer; mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer;
UE_mac_inst[Mod_idP].scheduling_info.PathlossChange = mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange; UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_Timer =
mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer;
UE_mac_inst[Mod_idP].scheduling_info.PathlossChange =
mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange;
} else { } else {
UE_mac_inst[Mod_idP].PHR_reconfigured = 0; UE_mac_inst[Mod_idP].PHR_reconfigured = 0;
UE_mac_inst[Mod_idP].PHR_state = MAC_MainConfig__phr_Config_PR_setup; UE_mac_inst[Mod_idP].PHR_state =
UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_Timer = MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; MAC_MainConfig__phr_Config_PR_setup;
UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_Timer = MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_Timer =
UE_mac_inst[Mod_idP].scheduling_info.PathlossChange = MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20;
UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_Timer =
MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20;
UE_mac_inst[Mod_idP].scheduling_info.PathlossChange =
MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1;
} }
UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_SF = get_sf_perioidicPHR_Timer(UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_Timer); UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_SF =
UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_SF = get_sf_prohibitPHR_Timer(UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_Timer); get_sf_perioidicPHR_Timer(UE_mac_inst[Mod_idP].
UE_mac_inst[Mod_idP].scheduling_info.PathlossChange_db = get_db_dl_PathlossChange(UE_mac_inst[Mod_idP].scheduling_info.PathlossChange); scheduling_info.periodicPHR_Timer);
UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_SF =
get_sf_prohibitPHR_Timer(UE_mac_inst[Mod_idP].
scheduling_info.prohibitPHR_Timer);
UE_mac_inst[Mod_idP].scheduling_info.PathlossChange_db =
get_db_dl_PathlossChange(UE_mac_inst[Mod_idP].
scheduling_info.PathlossChange);
UE_mac_inst[Mod_idP].PHR_reporting_active = 0; UE_mac_inst[Mod_idP].PHR_reporting_active = 0;
LOG_D(MAC,"[UE %d] config PHR (%d): periodic %d (SF) prohibit %d (SF) pathlosschange %d (db) \n", LOG_D(MAC,
"[UE %d] config PHR (%d): periodic %d (SF) prohibit %d (SF) pathlosschange %d (db) \n",
Mod_idP, Mod_idP,
(mac_MainConfig->phr_Config)?mac_MainConfig->phr_Config->present:-1, (mac_MainConfig->phr_Config) ? mac_MainConfig->
phr_Config->present : -1,
UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_SF, UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_SF,
UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_SF, UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_SF,
UE_mac_inst[Mod_idP].scheduling_info.PathlossChange_db); UE_mac_inst[Mod_idP].scheduling_info.PathlossChange_db);
...@@ -853,143 +1114,199 @@ rrc_mac_config_req_ue( ...@@ -853,143 +1114,199 @@ rrc_mac_config_req_ue(
if (physicalConfigDedicated != NULL) { if (physicalConfigDedicated != NULL) {
phy_config_dedicated_ue(Mod_idP,0,eNB_index,physicalConfigDedicated); phy_config_dedicated_ue(Mod_idP, 0, eNB_index,
UE_mac_inst[Mod_idP].physicalConfigDedicated=physicalConfigDedicated; // for SR proc physicalConfigDedicated);
UE_mac_inst[Mod_idP].physicalConfigDedicated = physicalConfigDedicated; // for SR proc
} }
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
if (sCellToAddMod_r10 != NULL) { if (sCellToAddMod_r10 != NULL) {
phy_config_dedicated_scell_ue(Mod_idP,eNB_index,sCellToAddMod_r10,1); phy_config_dedicated_scell_ue(Mod_idP, eNB_index,
sCellToAddMod_r10, 1);
UE_mac_inst[Mod_idP].physicalConfigDedicatedSCell_r10 = sCellToAddMod_r10->radioResourceConfigDedicatedSCell_r10->physicalConfigDedicatedSCell_r10; // using SCell index 0 UE_mac_inst[Mod_idP].physicalConfigDedicatedSCell_r10 = sCellToAddMod_r10->radioResourceConfigDedicatedSCell_r10->physicalConfigDedicatedSCell_r10; // using SCell index 0
} }
#endif #endif
if (measObj!= NULL) { if (measObj != NULL) {
if (measObj[0]!= NULL) { if (measObj[0] != NULL) {
UE_mac_inst[Mod_idP].n_adj_cells = measObj[0]->measObject.choice.measObjectEUTRA.cellsToAddModList->list.count; UE_mac_inst[Mod_idP].n_adj_cells =
LOG_I(MAC,"Number of adjacent cells %d\n",UE_mac_inst[Mod_idP].n_adj_cells); measObj[0]->measObject.choice.
measObjectEUTRA.cellsToAddModList->list.count;
for (i=0; i<UE_mac_inst[Mod_idP].n_adj_cells; i++) { LOG_I(MAC, "Number of adjacent cells %d\n",
UE_mac_inst[Mod_idP].adj_cell_id[i] = measObj[0]->measObject.choice.measObjectEUTRA.cellsToAddModList->list.array[i]->physCellId; UE_mac_inst[Mod_idP].n_adj_cells);
LOG_I(MAC,"Cell %d : Nid_cell %d\n",i,UE_mac_inst[Mod_idP].adj_cell_id[i]);
for (i = 0; i < UE_mac_inst[Mod_idP].n_adj_cells; i++) {
UE_mac_inst[Mod_idP].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_idP].adj_cell_id[i]);
} }
phy_config_meas_ue(Mod_idP,0,eNB_index,UE_mac_inst[Mod_idP].n_adj_cells,UE_mac_inst[Mod_idP].adj_cell_id); phy_config_meas_ue(Mod_idP, 0, eNB_index,
UE_mac_inst[Mod_idP].n_adj_cells,
UE_mac_inst[Mod_idP].adj_cell_id);
} }
} }
if(mobilityControlInfo != NULL) { if (mobilityControlInfo != NULL) {
LOG_D(MAC,"[UE%d] MAC Reset procedure triggered by RRC eNB %d \n",Mod_idP,eNB_index); LOG_D(MAC, "[UE%d] MAC Reset procedure triggered by RRC eNB %d \n",
ue_mac_reset(Mod_idP,eNB_index); Mod_idP, eNB_index);
ue_mac_reset(Mod_idP, eNB_index);
if(mobilityControlInfo->radioResourceConfigCommon.rach_ConfigCommon) { if (mobilityControlInfo->radioResourceConfigCommon.
memcpy((void *)&UE_mac_inst[Mod_idP].radioResourceConfigCommon->rach_ConfigCommon, rach_ConfigCommon) {
(void *)mobilityControlInfo->radioResourceConfigCommon.rach_ConfigCommon, memcpy((void *)
&UE_mac_inst[Mod_idP].radioResourceConfigCommon->
rach_ConfigCommon,
(void *) mobilityControlInfo->
radioResourceConfigCommon.rach_ConfigCommon,
sizeof(RACH_ConfigCommon_t)); sizeof(RACH_ConfigCommon_t));
} }
memcpy((void *)&UE_mac_inst[Mod_idP].radioResourceConfigCommon->prach_Config.prach_ConfigInfo, memcpy((void *) &UE_mac_inst[Mod_idP].
(void *)mobilityControlInfo->radioResourceConfigCommon.prach_Config.prach_ConfigInfo, radioResourceConfigCommon->prach_Config.prach_ConfigInfo,
(void *) mobilityControlInfo->
radioResourceConfigCommon.prach_Config.prach_ConfigInfo,
sizeof(PRACH_ConfigInfo_t)); sizeof(PRACH_ConfigInfo_t));
UE_mac_inst[Mod_idP].radioResourceConfigCommon->prach_Config.rootSequenceIndex = mobilityControlInfo->radioResourceConfigCommon.prach_Config.rootSequenceIndex; UE_mac_inst[Mod_idP].radioResourceConfigCommon->
prach_Config.rootSequenceIndex =
if(mobilityControlInfo->radioResourceConfigCommon.pdsch_ConfigCommon) { mobilityControlInfo->radioResourceConfigCommon.
memcpy((void *)&UE_mac_inst[Mod_idP].radioResourceConfigCommon->pdsch_ConfigCommon, prach_Config.rootSequenceIndex;
(void *)mobilityControlInfo->radioResourceConfigCommon.pdsch_ConfigCommon,
if (mobilityControlInfo->radioResourceConfigCommon.
pdsch_ConfigCommon) {
memcpy((void *)
&UE_mac_inst[Mod_idP].radioResourceConfigCommon->
pdsch_ConfigCommon,
(void *) mobilityControlInfo->
radioResourceConfigCommon.pdsch_ConfigCommon,
sizeof(PDSCH_ConfigCommon_t)); sizeof(PDSCH_ConfigCommon_t));
} }
// not a pointer: mobilityControlInfo->radioResourceConfigCommon.pusch_ConfigCommon // not a pointer: mobilityControlInfo->radioResourceConfigCommon.pusch_ConfigCommon
memcpy((void *)&UE_mac_inst[Mod_idP].radioResourceConfigCommon->pusch_ConfigCommon, memcpy((void *) &UE_mac_inst[Mod_idP].
(void *)&mobilityControlInfo->radioResourceConfigCommon.pusch_ConfigCommon, radioResourceConfigCommon->pusch_ConfigCommon,
(void *) &mobilityControlInfo->
radioResourceConfigCommon.pusch_ConfigCommon,
sizeof(PUSCH_ConfigCommon_t)); sizeof(PUSCH_ConfigCommon_t));
if(mobilityControlInfo->radioResourceConfigCommon.phich_Config) { if (mobilityControlInfo->radioResourceConfigCommon.phich_Config) {
/* memcpy((void *)&UE_mac_inst[Mod_idP].radioResourceConfigCommon->phich_Config, /* memcpy((void *)&UE_mac_inst[Mod_idP].radioResourceConfigCommon->phich_Config,
(void *)mobilityControlInfo->radioResourceConfigCommon.phich_Config, (void *)mobilityControlInfo->radioResourceConfigCommon.phich_Config,
sizeof(PHICH_Config_t)); */ sizeof(PHICH_Config_t)); */
} }
if(mobilityControlInfo->radioResourceConfigCommon.pucch_ConfigCommon) { if (mobilityControlInfo->radioResourceConfigCommon.
memcpy((void *)&UE_mac_inst[Mod_idP].radioResourceConfigCommon->pucch_ConfigCommon, pucch_ConfigCommon) {
(void *)mobilityControlInfo->radioResourceConfigCommon.pucch_ConfigCommon, memcpy((void *)
&UE_mac_inst[Mod_idP].radioResourceConfigCommon->
pucch_ConfigCommon,
(void *) mobilityControlInfo->
radioResourceConfigCommon.pucch_ConfigCommon,
sizeof(PUCCH_ConfigCommon_t)); sizeof(PUCCH_ConfigCommon_t));
} }
if(mobilityControlInfo->radioResourceConfigCommon.soundingRS_UL_ConfigCommon) { if (mobilityControlInfo->
memcpy((void *)&UE_mac_inst[Mod_idP].radioResourceConfigCommon->soundingRS_UL_ConfigCommon, radioResourceConfigCommon.soundingRS_UL_ConfigCommon) {
(void *)mobilityControlInfo->radioResourceConfigCommon.soundingRS_UL_ConfigCommon, memcpy((void *)
&UE_mac_inst[Mod_idP].radioResourceConfigCommon->
soundingRS_UL_ConfigCommon,
(void *) mobilityControlInfo->
radioResourceConfigCommon.soundingRS_UL_ConfigCommon,
sizeof(SoundingRS_UL_ConfigCommon_t)); sizeof(SoundingRS_UL_ConfigCommon_t));
} }
if(mobilityControlInfo->radioResourceConfigCommon.uplinkPowerControlCommon) { if (mobilityControlInfo->
memcpy((void *)&UE_mac_inst[Mod_idP].radioResourceConfigCommon->uplinkPowerControlCommon, radioResourceConfigCommon.uplinkPowerControlCommon) {
(void *)mobilityControlInfo->radioResourceConfigCommon.uplinkPowerControlCommon, memcpy((void *)
&UE_mac_inst[Mod_idP].radioResourceConfigCommon->
uplinkPowerControlCommon,
(void *) mobilityControlInfo->
radioResourceConfigCommon.uplinkPowerControlCommon,
sizeof(UplinkPowerControlCommon_t)); sizeof(UplinkPowerControlCommon_t));
} }
//configure antennaInfoCommon somewhere here.. //configure antennaInfoCommon somewhere here..
if(mobilityControlInfo->radioResourceConfigCommon.p_Max) { if (mobilityControlInfo->radioResourceConfigCommon.p_Max) {
//to be configured //to be configured
} }
if(mobilityControlInfo->radioResourceConfigCommon.tdd_Config) { if (mobilityControlInfo->radioResourceConfigCommon.tdd_Config) {
UE_mac_inst[Mod_idP].tdd_Config = mobilityControlInfo->radioResourceConfigCommon.tdd_Config; UE_mac_inst[Mod_idP].tdd_Config =
mobilityControlInfo->radioResourceConfigCommon.tdd_Config;
} }
if(mobilityControlInfo->radioResourceConfigCommon.ul_CyclicPrefixLength) { if (mobilityControlInfo->
memcpy((void *)&UE_mac_inst[Mod_idP].radioResourceConfigCommon->ul_CyclicPrefixLength, radioResourceConfigCommon.ul_CyclicPrefixLength) {
(void *)mobilityControlInfo->radioResourceConfigCommon.ul_CyclicPrefixLength, memcpy((void *)
&UE_mac_inst[Mod_idP].radioResourceConfigCommon->
ul_CyclicPrefixLength,
(void *) mobilityControlInfo->
radioResourceConfigCommon.ul_CyclicPrefixLength,
sizeof(UL_CyclicPrefixLength_t)); sizeof(UL_CyclicPrefixLength_t));
} }
// store the previous rnti in case of failure, and set thenew rnti // store the previous rnti in case of failure, and set thenew rnti
UE_mac_inst[Mod_idP].crnti_before_ho = UE_mac_inst[Mod_idP].crnti; UE_mac_inst[Mod_idP].crnti_before_ho = UE_mac_inst[Mod_idP].crnti;
UE_mac_inst[Mod_idP].crnti = ((mobilityControlInfo->newUE_Identity.buf[0])|(mobilityControlInfo->newUE_Identity.buf[1]<<8)); UE_mac_inst[Mod_idP].crnti =
LOG_I(MAC,"[UE %d] Received new identity %x from %d\n", Mod_idP, UE_mac_inst[Mod_idP].crnti, eNB_index); ((mobilityControlInfo->
UE_mac_inst[Mod_idP].rach_ConfigDedicated = malloc(sizeof(*mobilityControlInfo->rach_ConfigDedicated)); newUE_Identity.buf[0]) | (mobilityControlInfo->
newUE_Identity.buf[1] << 8));
LOG_I(MAC, "[UE %d] Received new identity %x from %d\n", Mod_idP,
UE_mac_inst[Mod_idP].crnti, eNB_index);
UE_mac_inst[Mod_idP].rach_ConfigDedicated =
malloc(sizeof(*mobilityControlInfo->rach_ConfigDedicated));
if (mobilityControlInfo->rach_ConfigDedicated) { if (mobilityControlInfo->rach_ConfigDedicated) {
memcpy((void*)UE_mac_inst[Mod_idP].rach_ConfigDedicated, memcpy((void *) UE_mac_inst[Mod_idP].rach_ConfigDedicated,
(void*)mobilityControlInfo->rach_ConfigDedicated, (void *) mobilityControlInfo->rach_ConfigDedicated,
sizeof(*mobilityControlInfo->rach_ConfigDedicated)); sizeof(*mobilityControlInfo->rach_ConfigDedicated));
} }
phy_config_afterHO_ue(Mod_idP,0,eNB_index,mobilityControlInfo,0); phy_config_afterHO_ue(Mod_idP, 0, eNB_index, mobilityControlInfo,
0);
} }
if (mbsfn_SubframeConfigList != NULL) { if (mbsfn_SubframeConfigList != NULL) {
LOG_I(MAC,"[UE %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n", Mod_idP, mbsfn_SubframeConfigList->list.count); LOG_I(MAC,
UE_mac_inst[Mod_idP].num_sf_allocation_pattern= mbsfn_SubframeConfigList->list.count; "[UE %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n",
Mod_idP, mbsfn_SubframeConfigList->list.count);
UE_mac_inst[Mod_idP].num_sf_allocation_pattern =
mbsfn_SubframeConfigList->list.count;
for (i=0; i<mbsfn_SubframeConfigList->list.count; i++) { for (i = 0; i < mbsfn_SubframeConfigList->list.count; i++) {
LOG_I(MAC, "[UE %d] Configuring MBSFN_SubframeConfig %d from received SIB2 \n", Mod_idP, i); LOG_I(MAC,
UE_mac_inst[Mod_idP].mbsfn_SubframeConfig[i] = mbsfn_SubframeConfigList->list.array[i]; "[UE %d] Configuring MBSFN_SubframeConfig %d from received SIB2 \n",
Mod_idP, i);
UE_mac_inst[Mod_idP].mbsfn_SubframeConfig[i] =
mbsfn_SubframeConfigList->list.array[i];
// LOG_I("[UE %d] MBSFN_SubframeConfig[%d] pattern is %ld\n", Mod_idP, // LOG_I("[UE %d] MBSFN_SubframeConfig[%d] pattern is %ld\n", Mod_idP,
// UE_mac_inst[Mod_idP].mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]); // UE_mac_inst[Mod_idP].mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]);
} }
} }
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
if (mbsfn_AreaInfoList != NULL) { if (mbsfn_AreaInfoList != NULL) {
LOG_I(MAC,"[UE %d][CONFIG] Received %d MBSFN Area Info\n", Mod_idP, mbsfn_AreaInfoList->list.count); LOG_I(MAC, "[UE %d][CONFIG] Received %d MBSFN Area Info\n",
UE_mac_inst[Mod_idP].num_active_mbsfn_area = mbsfn_AreaInfoList->list.count; Mod_idP, mbsfn_AreaInfoList->list.count);
UE_mac_inst[Mod_idP].num_active_mbsfn_area =
for (i =0; i< mbsfn_AreaInfoList->list.count; i++) { mbsfn_AreaInfoList->list.count;
UE_mac_inst[Mod_idP].mbsfn_AreaInfo[i] = mbsfn_AreaInfoList->list.array[i];
LOG_I(MAC,"[UE %d] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n",Mod_idP, i, for (i = 0; i < mbsfn_AreaInfoList->list.count; i++) {
UE_mac_inst[Mod_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9); UE_mac_inst[Mod_idP].mbsfn_AreaInfo[i] =
phy_config_sib13_ue(Mod_idP,0,eNB_index,i,UE_mac_inst[Mod_idP].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9); mbsfn_AreaInfoList->list.array[i];
LOG_I(MAC,
"[UE %d] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n",
Mod_idP, i,
UE_mac_inst[Mod_idP].mbsfn_AreaInfo[i]->
mcch_Config_r9.mcch_RepetitionPeriod_r9);
phy_config_sib13_ue(Mod_idP, 0, eNB_index, i,
UE_mac_inst[Mod_idP].
mbsfn_AreaInfo[i]->mbsfn_AreaId_r9);
} }
} }
...@@ -997,30 +1314,37 @@ rrc_mac_config_req_ue( ...@@ -997,30 +1314,37 @@ rrc_mac_config_req_ue(
// LOG_I(MAC,"DUY: lcid when entering rrc_mac config_req is %02d\n",(pmch_InfoList->list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9)); // LOG_I(MAC,"DUY: lcid when entering rrc_mac config_req is %02d\n",(pmch_InfoList->list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9));
LOG_I(MAC, "[UE %d] Configuring PMCH_config from MCCH MESSAGE \n",Mod_idP); LOG_I(MAC, "[UE %d] Configuring PMCH_config from MCCH MESSAGE \n",
Mod_idP);
for (i =0; i< pmch_InfoList->list.count; i++) { for (i = 0; i < pmch_InfoList->list.count; i++) {
UE_mac_inst[Mod_idP].pmch_Config[i] = &pmch_InfoList->list.array[i]->pmch_Config_r9; UE_mac_inst[Mod_idP].pmch_Config[i] =
LOG_I(MAC, "[UE %d] PMCH[%d]: MCH_Scheduling_Period = %ld\n", Mod_idP, i, &pmch_InfoList->list.array[i]->pmch_Config_r9;
UE_mac_inst[Mod_idP].pmch_Config[i]->mch_SchedulingPeriod_r9); LOG_I(MAC, "[UE %d] PMCH[%d]: MCH_Scheduling_Period = %ld\n",
Mod_idP, i,
UE_mac_inst[Mod_idP].
pmch_Config[i]->mch_SchedulingPeriod_r9);
} }
UE_mac_inst[Mod_idP].mcch_status = 1; UE_mac_inst[Mod_idP].mcch_status = 1;
} }
#endif #endif
#ifdef CBA #ifdef CBA
if (cba_rnti) { if (cba_rnti) {
UE_mac_inst[Mod_idP].cba_rnti[num_active_cba_groups-1] = cba_rnti; UE_mac_inst[Mod_idP].cba_rnti[num_active_cba_groups - 1] =
LOG_D(MAC,"[UE %d] configure CBA group %d RNTI %x for eNB %d (total active cba group %d)\n", cba_rnti;
Mod_idP,Mod_idP%num_active_cba_groups, cba_rnti,eNB_index,num_active_cba_groups); LOG_D(MAC,
phy_config_cba_rnti(Mod_idP,CC_idP,eNB_flagP,eNB_index,cba_rnti,num_active_cba_groups-1, num_active_cba_groups); "[UE %d] configure CBA group %d RNTI %x for eNB %d (total active cba group %d)\n",
Mod_idP, Mod_idP % num_active_cba_groups, cba_rnti,
eNB_index, num_active_cba_groups);
phy_config_cba_rnti(Mod_idP, CC_idP, eNB_flagP, eNB_index,
cba_rnti, num_active_cba_groups - 1,
num_active_cba_groups);
} }
#endif #endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT);
return(0); return (0);
} }
...@@ -90,12 +90,12 @@ ...@@ -90,12 +90,12 @@
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
// Mask for identifying subframe for MBMS // Mask for identifying subframe for MBMS
#define MBSFN_TDD_SF3 0x80// for TDD #define MBSFN_TDD_SF3 0x80 // for TDD
#define MBSFN_TDD_SF4 0x40 #define MBSFN_TDD_SF4 0x40
#define MBSFN_TDD_SF7 0x20 #define MBSFN_TDD_SF7 0x20
#define MBSFN_TDD_SF8 0x10 #define MBSFN_TDD_SF8 0x10
#define MBSFN_TDD_SF9 0x08 #define MBSFN_TDD_SF9 0x08
#define MBSFN_FDD_SF1 0x80// for FDD #define MBSFN_FDD_SF1 0x80 // for FDD
#define MBSFN_FDD_SF2 0x40 #define MBSFN_FDD_SF2 0x40
#define MBSFN_FDD_SF3 0x20 #define MBSFN_FDD_SF3 0x20
#define MBSFN_FDD_SF6 0x10 #define MBSFN_FDD_SF6 0x10
...@@ -172,7 +172,7 @@ typedef struct { ...@@ -172,7 +172,7 @@ typedef struct {
uint8_t RAPID:6; uint8_t RAPID:6;
uint8_t T:1; uint8_t T:1;
uint8_t E:1; uint8_t E:1;
} __attribute__((__packed__))RA_HEADER_RAPID; } __attribute__ ((__packed__)) RA_HEADER_RAPID;
/*!\brief MAC header of Random Access Response for backoff indicator (BI)*/ /*!\brief MAC header of Random Access Response for backoff indicator (BI)*/
typedef struct { typedef struct {
...@@ -180,7 +180,7 @@ typedef struct { ...@@ -180,7 +180,7 @@ typedef struct {
uint8_t R:2; uint8_t R:2;
uint8_t T:1; uint8_t T:1;
uint8_t E:1; uint8_t E:1;
} __attribute__((__packed__))RA_HEADER_BI; } __attribute__ ((__packed__)) RA_HEADER_BI;
/* /*
typedef struct { typedef struct {
uint64_t padding:16; uint64_t padding:16;
...@@ -217,7 +217,7 @@ typedef struct { ...@@ -217,7 +217,7 @@ typedef struct {
uint8_t R:2; // octet 1 MSB uint8_t R:2; // octet 1 MSB
uint8_t L:7; // octet 2 LSB uint8_t L:7; // octet 2 LSB
uint8_t F:1; // octet 2 MSB uint8_t F:1; // octet 2 MSB
} __attribute__((__packed__))SCH_SUBHEADER_SHORT; } __attribute__ ((__packed__)) SCH_SUBHEADER_SHORT;
/*!\brief MAC subheader long with 15bit Length field */ /*!\brief MAC subheader long with 15bit Length field */
typedef struct { typedef struct {
uint8_t LCID:5; // octet 1 LSB uint8_t LCID:5; // octet 1 LSB
...@@ -227,19 +227,19 @@ typedef struct { ...@@ -227,19 +227,19 @@ typedef struct {
uint8_t F:1; // octet 2 MSB uint8_t F:1; // octet 2 MSB
uint8_t L_LSB:8; uint8_t L_LSB:8;
uint8_t padding; uint8_t padding;
} __attribute__((__packed__))SCH_SUBHEADER_LONG; } __attribute__ ((__packed__)) SCH_SUBHEADER_LONG;
/*!\brief MAC subheader short without length field */ /*!\brief MAC subheader short without length field */
typedef struct { typedef struct {
uint8_t LCID:5; uint8_t LCID:5;
uint8_t E:1; uint8_t E:1;
uint8_t R:2; uint8_t R:2;
} __attribute__((__packed__))SCH_SUBHEADER_FIXED; } __attribute__ ((__packed__)) SCH_SUBHEADER_FIXED;
/*!\brief mac control element: short buffer status report for a specific logical channel group ID*/ /*!\brief mac control element: short buffer status report for a specific logical channel group ID*/
typedef struct { typedef struct {
uint8_t Buffer_size:6; // octet 1 LSB uint8_t Buffer_size:6; // octet 1 LSB
uint8_t LCGID:2; // octet 1 MSB uint8_t LCGID:2; // octet 1 MSB
} __attribute__((__packed__))BSR_SHORT; } __attribute__ ((__packed__)) BSR_SHORT;
typedef BSR_SHORT BSR_TRUNCATED; typedef BSR_SHORT BSR_TRUNCATED;
/*!\brief mac control element: long buffer status report for all logical channel group ID*/ /*!\brief mac control element: long buffer status report for all logical channel group ID*/
...@@ -248,63 +248,63 @@ typedef struct { ...@@ -248,63 +248,63 @@ typedef struct {
uint8_t Buffer_size2:6; uint8_t Buffer_size2:6;
uint8_t Buffer_size1:6; uint8_t Buffer_size1:6;
uint8_t Buffer_size0:6; uint8_t Buffer_size0:6;
} __attribute__((__packed__))BSR_LONG; } __attribute__ ((__packed__)) BSR_LONG;
#define BSR_LONG_SIZE (sizeof(BSR_LONG)) #define BSR_LONG_SIZE (sizeof(BSR_LONG))
/*!\brief mac control element: timing advance */ /*!\brief mac control element: timing advance */
typedef struct { typedef struct {
uint8_t TA:6; uint8_t TA:6;
uint8_t R:2; uint8_t R:2;
} __attribute__((__packed__))TIMING_ADVANCE_CMD; } __attribute__ ((__packed__)) TIMING_ADVANCE_CMD;
/*!\brief mac control element: power headroom report */ /*!\brief mac control element: power headroom report */
typedef struct { typedef struct {
uint8_t PH:6; uint8_t PH:6;
uint8_t R:2; uint8_t R:2;
} __attribute__((__packed__))POWER_HEADROOM_CMD; } __attribute__ ((__packed__)) POWER_HEADROOM_CMD;
/*! \brief MIB payload */ /*! \brief MIB payload */
typedef struct { typedef struct {
uint8_t payload[3] ; uint8_t payload[3];
} __attribute__((__packed__))MIB_PDU; } __attribute__ ((__packed__)) MIB_PDU;
/*! \brief CCCH payload */ /*! \brief CCCH payload */
typedef struct { typedef struct {
uint8_t payload[CCCH_PAYLOAD_SIZE_MAX] ; uint8_t payload[CCCH_PAYLOAD_SIZE_MAX];
} __attribute__((__packed__))CCCH_PDU; } __attribute__ ((__packed__)) CCCH_PDU;
/*! \brief BCCH payload */ /*! \brief BCCH payload */
typedef struct { typedef struct {
uint8_t payload[BCCH_PAYLOAD_SIZE_MAX] ; uint8_t payload[BCCH_PAYLOAD_SIZE_MAX];
} __attribute__((__packed__))BCCH_PDU; } __attribute__ ((__packed__)) BCCH_PDU;
/*! \brief RAR payload */ /*! \brief RAR payload */
typedef struct { typedef struct {
uint8_t payload[RAR_PAYLOAD_SIZE_MAX]; uint8_t payload[RAR_PAYLOAD_SIZE_MAX];
} __attribute__ ((__packed__)) RAR_PDU; } __attribute__ ((__packed__)) RAR_PDU;
/*! \brief BCCH payload */ /*! \brief BCCH payload */
typedef struct { typedef struct {
uint8_t payload[PCCH_PAYLOAD_SIZE_MAX] ; uint8_t payload[PCCH_PAYLOAD_SIZE_MAX];
} __attribute__((__packed__))PCCH_PDU; } __attribute__ ((__packed__)) PCCH_PDU;
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
/*! \brief MCCH payload */ /*! \brief MCCH payload */
typedef struct { typedef struct {
uint8_t payload[MCCH_PAYLOAD_SIZE_MAX] ; uint8_t payload[MCCH_PAYLOAD_SIZE_MAX];
} __attribute__((__packed__))MCCH_PDU; } __attribute__ ((__packed__)) MCCH_PDU;
/*!< \brief MAC control element for activation and deactivation of component carriers */ /*!< \brief MAC control element for activation and deactivation of component carriers */
typedef struct { typedef struct {
uint8_t C7:1;/*!< \brief Component carrier 7 */ uint8_t C7:1; /*!< \brief Component carrier 7 */
uint8_t C6:1;/*!< \brief Component carrier 6 */ uint8_t C6:1; /*!< \brief Component carrier 6 */
uint8_t C5:1;/*!< \brief Component carrier 5 */ uint8_t C5:1; /*!< \brief Component carrier 5 */
uint8_t C4:1;/*!< \brief Component carrier 4 */ uint8_t C4:1; /*!< \brief Component carrier 4 */
uint8_t C3:1;/*!< \brief Component carrier 3 */ uint8_t C3:1; /*!< \brief Component carrier 3 */
uint8_t C2:1;/*!< \brief Component carrier 2 */ uint8_t C2:1; /*!< \brief Component carrier 2 */
uint8_t C1:1;/*!< \brief Component carrier 1 */ uint8_t C1:1; /*!< \brief Component carrier 1 */
uint8_t R:1;/*!< \brief Reserved */ uint8_t R:1; /*!< \brief Reserved */
} __attribute__((__packed__))CC_ELEMENT; } __attribute__ ((__packed__)) CC_ELEMENT;
/*! \brief MAC control element: MCH Scheduling Information */ /*! \brief MAC control element: MCH Scheduling Information */
typedef struct { typedef struct {
uint8_t stop_sf_MSB:3; // octet 1 LSB uint8_t stop_sf_MSB:3; // octet 1 LSB
uint8_t lcid:5; // octet 2 MSB uint8_t lcid:5; // octet 2 MSB
uint8_t stop_sf_LSB:8; uint8_t stop_sf_LSB:8;
} __attribute__((__packed__))MSI_ELEMENT; } __attribute__ ((__packed__)) MSI_ELEMENT;
#endif #endif
/*! \brief Values of CCCH LCID for DLSCH */ /*! \brief Values of CCCH LCID for DLSCH */
#define CCCH_LCHANID 0 #define CCCH_LCHANID 0
...@@ -396,9 +396,18 @@ typedef struct { ...@@ -396,9 +396,18 @@ typedef struct {
#include "PHY/impl_defs_top.h" #include "PHY/impl_defs_top.h"
/*!\brief RA process state*/
typedef enum {
IDLE = 0,
MSG2,
WAITMSG3,
MSG4,
WAITMSG4ACK
} RA_state;
/*!\brief UE ULSCH scheduling states*/ /*!\brief UE ULSCH scheduling states*/
typedef enum { typedef enum {
S_UL_NONE =0, S_UL_NONE = 0,
S_UL_WAITING, S_UL_WAITING,
S_UL_SCHEDULED, S_UL_SCHEDULED,
S_UL_BUFFERED, S_UL_BUFFERED,
...@@ -407,7 +416,7 @@ typedef enum { ...@@ -407,7 +416,7 @@ typedef enum {
/*!\brief UE DLSCH scheduling states*/ /*!\brief UE DLSCH scheduling states*/
typedef enum { typedef enum {
S_DL_NONE =0, S_DL_NONE = 0,
S_DL_WAITING, S_DL_WAITING,
S_DL_SCHEDULED, S_DL_SCHEDULED,
S_DL_BUFFERED, S_DL_BUFFERED,
...@@ -416,7 +425,7 @@ typedef enum { ...@@ -416,7 +425,7 @@ typedef enum {
/*!\brief scheduling policy for the contention-based access */ /*!\brief scheduling policy for the contention-based access */
typedef enum { typedef enum {
CBA_ES=0, /// equal share of RB among groups w CBA_ES = 0, /// equal share of RB among groups w
CBA_ES_S, /// equal share of RB among groups with small allocation CBA_ES_S, /// equal share of RB among groups with small allocation
CBA_PF, /// proportional fair (kind of) CBA_PF, /// proportional fair (kind of)
CBA_PF_S, /// proportional fair (kind of) with small RB allocation CBA_PF_S, /// proportional fair (kind of) with small RB allocation
...@@ -846,25 +855,7 @@ typedef struct { ...@@ -846,25 +855,7 @@ typedef struct {
/*! \brief eNB template for the Random access information */ /*! \brief eNB template for the Random access information */
typedef struct { typedef struct {
/// Flag to indicate this process is active /// Flag to indicate this process is active
boolean_t RA_active; RA_state state;
/// Size of DCI for RA-Response (bytes)
uint8_t RA_dci_size_bytes1;
/// Size of DCI for RA-Response (bits)
uint8_t RA_dci_size_bits1;
/// Actual DCI to transmit for RA-Response
uint8_t RA_alloc_pdu1[(MAX_DCI_SIZE_BITS>>3)+1];
/// DCI format for RA-Response (should be 1A)
uint8_t RA_dci_fmt1;
/// Size of DCI for Msg4/ContRes (bytes)
uint8_t RA_dci_size_bytes2;
/// Size of DCI for Msg4/ContRes (bits)
uint8_t RA_dci_size_bits2;
/// Actual DCI to transmit for Msg4/ContRes
uint8_t RA_alloc_pdu2[(MAX_DCI_SIZE_BITS>>3)+1];
/// DCI format for Msg4/ContRes (should be 1A)
uint8_t RA_dci_fmt2;
/// Flag to indicate the eNB should generate RAR. This is triggered by detection of PRACH
uint8_t generate_rar;
/// Subframe where preamble was received /// Subframe where preamble was received
uint8_t preamble_subframe; uint8_t preamble_subframe;
/// Subframe where Msg2 is to be sent /// Subframe where Msg2 is to be sent
...@@ -879,10 +870,6 @@ typedef struct { ...@@ -879,10 +870,6 @@ typedef struct {
sub_frame_t Msg4_subframe; sub_frame_t Msg4_subframe;
/// Frame where Msg4 is to be sent /// Frame where Msg4 is to be sent
frame_t Msg4_frame; frame_t Msg4_frame;
/// Flag to indicate the eNB should generate Msg4 upon reception of SDU from RRC. This is triggered by first ULSCH reception at eNB for new user.
uint8_t generate_Msg4;
/// Flag to indicate that eNB is waiting for ACK that UE has received Msg3.
uint8_t wait_ack_Msg4;
/// harq_pid used for Msg4 transmission /// harq_pid used for Msg4 transmission
uint8_t harq_pid; uint8_t harq_pid;
/// UE RNTI allocated during RAR /// UE RNTI allocated during RAR
...@@ -922,7 +909,7 @@ typedef struct { ...@@ -922,7 +909,7 @@ typedef struct {
uint8_t msg2_narrowband; uint8_t msg2_narrowband;
uint8_t msg34_narrowband; uint8_t msg34_narrowband;
#endif #endif
} RA_TEMPLATE; } RA_t;
/*! \brief subband bitmap confguration (for ALU icic algo purpose), in test phase */ /*! \brief subband bitmap confguration (for ALU icic algo purpose), in test phase */
...@@ -936,7 +923,8 @@ typedef struct { ...@@ -936,7 +923,8 @@ typedef struct {
/*! \brief UE list used by eNB to order UEs/CC for scheduling*/ /*! \brief UE list used by eNB to order UEs/CC for scheduling*/
typedef struct { typedef struct {
/// Dedicated information for UEs /// Dedicated information for UEs
struct PhysicalConfigDedicated *physicalConfigDedicated[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; struct PhysicalConfigDedicated
*physicalConfigDedicated[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
/// DLSCH pdu /// DLSCH pdu
DLSCH_PDU DLSCH_pdu[MAX_NUM_CCs][2][NUMBER_OF_UE_MAX]; DLSCH_PDU DLSCH_pdu[MAX_NUM_CCs][2][NUMBER_OF_UE_MAX];
/// DCI template and MAC connection parameters for UEs /// DCI template and MAC connection parameters for UEs
...@@ -993,7 +981,7 @@ typedef struct { ...@@ -993,7 +981,7 @@ typedef struct {
/// Outgoing RAR pdu for PHY /// Outgoing RAR pdu for PHY
RAR_PDU RAR_pdu; RAR_PDU RAR_pdu;
/// Template for RA computations /// Template for RA computations
RA_TEMPLATE RA_template[NB_RA_PROC_MAX]; RA_t ra[NB_RA_PROC_MAX];
/// VRB map for common channels /// VRB map for common channels
uint8_t vrb_map[100]; uint8_t vrb_map[100];
/// VRB map for common channels and retransmissions by PHICH /// VRB map for common channels and retransmissions by PHICH
...@@ -1055,23 +1043,28 @@ typedef struct eNB_MAC_INST_s { ...@@ -1055,23 +1043,28 @@ typedef struct eNB_MAC_INST_s {
/// NFAPI Config Request Structure /// NFAPI Config Request Structure
nfapi_config_request_t config[MAX_NUM_CCs]; nfapi_config_request_t config[MAX_NUM_CCs];
/// Preallocated DL pdu list /// Preallocated DL pdu list
nfapi_dl_config_request_pdu_t dl_config_pdu_list[MAX_NUM_CCs][MAX_NUM_DL_PDU]; nfapi_dl_config_request_pdu_t
dl_config_pdu_list[MAX_NUM_CCs][MAX_NUM_DL_PDU];
/// NFAPI DL Config Request Structure /// NFAPI DL Config Request Structure
nfapi_dl_config_request_t DL_req[MAX_NUM_CCs]; nfapi_dl_config_request_t DL_req[MAX_NUM_CCs];
/// Preallocated UL pdu list /// Preallocated UL pdu list
nfapi_ul_config_request_pdu_t ul_config_pdu_list[MAX_NUM_CCs][MAX_NUM_UL_PDU]; nfapi_ul_config_request_pdu_t
ul_config_pdu_list[MAX_NUM_CCs][MAX_NUM_UL_PDU];
/// Preallocated UL pdu list for ULSCH (n+k delay) /// Preallocated UL pdu list for ULSCH (n+k delay)
nfapi_ul_config_request_pdu_t ul_config_pdu_list_tmp[MAX_NUM_CCs][10][MAX_NUM_UL_PDU]; nfapi_ul_config_request_pdu_t
ul_config_pdu_list_tmp[MAX_NUM_CCs][10][MAX_NUM_UL_PDU];
/// NFAPI UL Config Request Structure, send to L1 4 subframes before processing takes place /// NFAPI UL Config Request Structure, send to L1 4 subframes before processing takes place
nfapi_ul_config_request_t UL_req[MAX_NUM_CCs]; nfapi_ul_config_request_t UL_req[MAX_NUM_CCs];
/// NFAPI "Temporary" UL Config Request Structure, holds future UL_config requests /// NFAPI "Temporary" UL Config Request Structure, holds future UL_config requests
nfapi_ul_config_request_t UL_req_tmp[MAX_NUM_CCs][10]; nfapi_ul_config_request_t UL_req_tmp[MAX_NUM_CCs][10];
/// Preallocated HI_DCI0 pdu list /// Preallocated HI_DCI0 pdu list
nfapi_hi_dci0_request_pdu_t hi_dci0_pdu_list[MAX_NUM_CCs][MAX_NUM_HI_DCI0_PDU]; nfapi_hi_dci0_request_pdu_t
hi_dci0_pdu_list[MAX_NUM_CCs][MAX_NUM_HI_DCI0_PDU];
/// NFAPI HI/DCI0 Config Request Structure /// NFAPI HI/DCI0 Config Request Structure
nfapi_hi_dci0_request_t HI_DCI0_req[MAX_NUM_CCs]; nfapi_hi_dci0_request_t HI_DCI0_req[MAX_NUM_CCs];
/// Prealocated TX pdu list /// Prealocated TX pdu list
nfapi_tx_request_pdu_t tx_request_pdu[MAX_NUM_CCs][MAX_NUM_TX_REQUEST_PDU]; nfapi_tx_request_pdu_t
tx_request_pdu[MAX_NUM_CCs][MAX_NUM_TX_REQUEST_PDU];
/// NFAPI DL PDU structure /// NFAPI DL PDU structure
nfapi_tx_request_t TX_req[MAX_NUM_CCs]; nfapi_tx_request_t TX_req[MAX_NUM_CCs];
/// UL handle /// UL handle
...@@ -1122,7 +1115,7 @@ typedef enum { ...@@ -1122,7 +1115,7 @@ typedef enum {
/*!\brief UE layer 2 status */ /*!\brief UE layer 2 status */
typedef enum { typedef enum {
CONNECTION_OK=0, CONNECTION_OK = 0,
CONNECTION_LOST, CONNECTION_LOST,
PHY_RESYNCH, PHY_RESYNCH,
PHY_HO_PRACH PHY_HO_PRACH
...@@ -1214,7 +1207,8 @@ typedef struct { ...@@ -1214,7 +1207,8 @@ typedef struct {
struct PhysicalConfigDedicated *physicalConfigDedicated; struct PhysicalConfigDedicated *physicalConfigDedicated;
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
/// pointer to RRC PHY configuration SCEll /// pointer to RRC PHY configuration SCEll
struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10; struct PhysicalConfigDedicatedSCell_r10
*physicalConfigDedicatedSCell_r10;
#endif #endif
/// pointer to TDD Configuration (NULL for FDD) /// pointer to TDD Configuration (NULL for FDD)
TDD_Config_t *tdd_Config; TDD_Config_t *tdd_Config;
...@@ -1298,7 +1292,7 @@ typedef struct { ...@@ -1298,7 +1292,7 @@ typedef struct {
/// MCCH status /// MCCH status
uint8_t mcch_status; uint8_t mcch_status;
/// MSI status /// MSI status
uint8_t msi_status;// could be an array if there are >1 MCH in one MBSFN area uint8_t msi_status; // could be an array if there are >1 MCH in one MBSFN area
#endif #endif
//#ifdef CBA //#ifdef CBA
/// CBA RNTI for each group /// CBA RNTI for each group
...@@ -1311,7 +1305,7 @@ typedef struct { ...@@ -1311,7 +1305,7 @@ typedef struct {
/// UE ULSCH tx processing time inlcuding RLC interface (rlc_data_req) and mac header generation /// UE ULSCH tx processing time inlcuding RLC interface (rlc_data_req) and mac header generation
time_stats_t tx_ulsch_sdu; time_stats_t tx_ulsch_sdu;
/// UE DLSCH rx processing time inlcuding RLC interface (mac_rrc_data_ind or mac_rlc_status_ind+mac_rlc_data_ind) and mac header parser /// UE DLSCH rx processing time inlcuding RLC interface (mac_rrc_data_ind or mac_rlc_status_ind+mac_rlc_data_ind) and mac header parser
time_stats_t rx_dlsch_sdu ; time_stats_t rx_dlsch_sdu;
/// UE query for MCH subframe processing time /// UE query for MCH subframe processing time
time_stats_t ue_query_mch; time_stats_t ue_query_mch;
/// UE MCH rx processing time /// UE MCH rx processing time
...@@ -1330,6 +1324,3 @@ typedef struct { ...@@ -1330,6 +1324,3 @@ typedef struct {
#include "proto.h" #include "proto.h"
/*@}*/ /*@}*/
#endif /*__LAYER2_MAC_DEFS_H__ */ #endif /*__LAYER2_MAC_DEFS_H__ */
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
#endif #endif
#if defined(ENABLE_ITTI) #if defined(ENABLE_ITTI)
# include "intertask_interface.h" #include "intertask_interface.h"
#endif #endif
#define ENABLE_MAC_PAYLOAD_DEBUG #define ENABLE_MAC_PAYLOAD_DEBUG
...@@ -68,15 +68,16 @@ ...@@ -68,15 +68,16 @@
extern RAN_CONTEXT_t RC; extern RAN_CONTEXT_t RC;
uint16_t pdcch_order_table[6] = {31,31,511,2047,2047,8191}; uint16_t pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 };
void schedule_SRS(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) void
schedule_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
{ {
eNB_MAC_INST *eNB = RC.mac[module_idP]; eNB_MAC_INST *eNB = RC.mac[module_idP];
UE_list_t *UE_list = &eNB->UE_list; UE_list_t *UE_list = &eNB->UE_list;
nfapi_ul_config_request_body_t *ul_req; nfapi_ul_config_request_body_t *ul_req;
int CC_id,UE_id; int CC_id, UE_id;
COMMON_channels_t *cc = RC.mac[module_idP]->common_channels; COMMON_channels_t *cc = RC.mac[module_idP]->common_channels;
SoundingRS_UL_ConfigCommon_t *soundingRS_UL_ConfigCommon; SoundingRS_UL_ConfigCommon_t *soundingRS_UL_ConfigCommon;
struct SoundingRS_UL_ConfigDedicated *soundingRS_UL_ConfigDedicated; struct SoundingRS_UL_ConfigDedicated *soundingRS_UL_ConfigDedicated;
...@@ -85,60 +86,116 @@ void schedule_SRS(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) ...@@ -85,60 +86,116 @@ void schedule_SRS(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
uint8_t srs_SubframeConfig; uint8_t srs_SubframeConfig;
// table for TSFC (Period) and deltaSFC (offset) // table for TSFC (Period) and deltaSFC (offset)
const uint16_t deltaTSFCTabType1[15][2] = { {1,1},{1,2},{2,2},{1,5},{2,5},{4,5},{8,5},{3,5},{12,5},{1,10},{2,10},{4,10},{8,10},{351,10},{383,10} }; // Table 5.5.3.3-2 3GPP 36.211 FDD const uint16_t deltaTSFCTabType1[15][2] = { {1, 1}, {1, 2}, {2, 2}, {1, 5}, {2, 5}, {4, 5}, {8, 5}, {3, 5}, {12, 5}, {1, 10}, {2, 10}, {4, 10}, {8, 10}, {351, 10}, {383, 10} }; // Table 5.5.3.3-2 3GPP 36.211 FDD
const uint16_t deltaTSFCTabType2[14][2] = { {2,5},{6,5},{10,5},{18,5},{14,5},{22,5},{26,5},{30,5},{70,10},{74,10},{194,10},{326,10},{586,10},{210,10} }; // Table 5.5.3.3-2 3GPP 36.211 TDD const uint16_t deltaTSFCTabType2[14][2] = { {2, 5}, {6, 5}, {10, 5}, {18, 5}, {14, 5}, {22, 5}, {26, 5}, {30, 5}, {70, 10}, {74, 10}, {194, 10}, {326, 10}, {586, 10}, {210, 10} }; // Table 5.5.3.3-2 3GPP 36.211 TDD
uint16_t srsPeriodicity,srsOffset; uint16_t srsPeriodicity, srsOffset;
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
soundingRS_UL_ConfigCommon = &cc[CC_id].radioResourceConfigCommon->soundingRS_UL_ConfigCommon; soundingRS_UL_ConfigCommon =
&cc[CC_id].radioResourceConfigCommon->
soundingRS_UL_ConfigCommon;
// check if SRS is enabled in this frame/subframe // check if SRS is enabled in this frame/subframe
if (soundingRS_UL_ConfigCommon) { if (soundingRS_UL_ConfigCommon) {
srs_SubframeConfig = soundingRS_UL_ConfigCommon->choice.setup.srs_SubframeConfig; srs_SubframeConfig =
soundingRS_UL_ConfigCommon->choice.setup.
srs_SubframeConfig;
if (cc[CC_id].tdd_Config == NULL) { // FDD if (cc[CC_id].tdd_Config == NULL) { // FDD
deltaTSFC = deltaTSFCTabType1[srs_SubframeConfig][0]; deltaTSFC = deltaTSFCTabType1[srs_SubframeConfig][0];
TSFC = deltaTSFCTabType1[srs_SubframeConfig][1]; TSFC = deltaTSFCTabType1[srs_SubframeConfig][1];
} } else { // TDD
else { // TDD
deltaTSFC = deltaTSFCTabType2[srs_SubframeConfig][0]; deltaTSFC = deltaTSFCTabType2[srs_SubframeConfig][0];
TSFC = deltaTSFCTabType2[srs_SubframeConfig][1]; TSFC = deltaTSFCTabType2[srs_SubframeConfig][1];
} }
// Sounding reference signal subframes are the subframes satisfying ns/2 mod TSFC (- deltaTSFC // Sounding reference signal subframes are the subframes satisfying ns/2 mod TSFC (- deltaTSFC
uint16_t tmp = (subframeP % TSFC); uint16_t tmp = (subframeP % TSFC);
if((1<<tmp) & deltaTSFC) { if ((1 << tmp) & deltaTSFC) {
// This is an SRS subframe, loop over UEs // This is an SRS subframe, loop over UEs
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) { for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
if (RC.mac[module_idP]->UE_list.active[UE_id]!=TRUE) continue; if (RC.mac[module_idP]->UE_list.active[UE_id] != TRUE)
ul_req = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body; continue;
ul_req =
&RC.mac[module_idP]->UL_req[CC_id].
ul_config_request_body;
// drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet
if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED) continue; if (mac_eNB_get_rrc_status
(module_idP,
AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",UE_id); UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED)
continue;
if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL) { AssertFatal(UE_list->UE_template[CC_id]
if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) { [UE_id].physicalConfigDedicated != NULL,
get_srs_pos(&cc[CC_id], soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex, &srsPeriodicity, &srsOffset); "physicalConfigDedicated is null for UE %d\n",
if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset) { UE_id);
if ((soundingRS_UL_ConfigDedicated =
UE_list->UE_template[CC_id]
[UE_id].
physicalConfigDedicated->soundingRS_UL_ConfigDedicated)
!= NULL) {
if (soundingRS_UL_ConfigDedicated->present ==
SoundingRS_UL_ConfigDedicated_PR_setup) {
get_srs_pos(&cc[CC_id],
soundingRS_UL_ConfigDedicated->choice.
setup.srs_ConfigIndex,
&srsPeriodicity, &srsOffset);
if (((10 * frameP +
subframeP) % srsPeriodicity) ==
srsOffset) {
// Prorgram SRS // Prorgram SRS
ul_req->srs_present = 1; ul_req->srs_present = 1;
nfapi_ul_config_request_pdu_t* ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; nfapi_ul_config_request_pdu_t
memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t)); * ul_config_pdu =
ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_SRS_PDU_TYPE; &ul_req->
ul_config_pdu->pdu_size = 2+(uint8_t)(2+sizeof(nfapi_ul_config_srs_pdu)); ul_config_pdu_list
ul_config_pdu->srs_pdu.srs_pdu_rel8.size = (uint8_t)sizeof(nfapi_ul_config_srs_pdu);; [ul_req->number_of_pdus];
ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; memset((void *) ul_config_pdu, 0,
ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth; sizeof
ul_config_pdu->srs_pdu.srs_pdu_rel8.frequency_domain_position = soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition; (nfapi_ul_config_request_pdu_t));
ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_hopping_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth;; ul_config_pdu->pdu_type =
ul_config_pdu->srs_pdu.srs_pdu_rel8.transmission_comb = soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb; NFAPI_UL_CONFIG_SRS_PDU_TYPE;
ul_config_pdu->srs_pdu.srs_pdu_rel8.i_srs = soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex; ul_config_pdu->pdu_size =
ul_config_pdu->srs_pdu.srs_pdu_rel8.sounding_reference_cyclic_shift = soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift; 2 + (uint8_t) (2 +
sizeof
(nfapi_ul_config_srs_pdu));
ul_config_pdu->srs_pdu.srs_pdu_rel8.size =
(uint8_t)
sizeof(nfapi_ul_config_srs_pdu);;
ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti =
UE_list->UE_template[CC_id][UE_id].
rnti;
ul_config_pdu->srs_pdu.
srs_pdu_rel8.srs_bandwidth =
soundingRS_UL_ConfigDedicated->
choice.setup.srs_Bandwidth;
ul_config_pdu->srs_pdu.
srs_pdu_rel8.frequency_domain_position
=
soundingRS_UL_ConfigDedicated->
choice.setup.freqDomainPosition;
ul_config_pdu->srs_pdu.
srs_pdu_rel8.srs_hopping_bandwidth =
soundingRS_UL_ConfigDedicated->
choice.setup.srs_HoppingBandwidth;;
ul_config_pdu->srs_pdu.
srs_pdu_rel8.transmission_comb =
soundingRS_UL_ConfigDedicated->
choice.setup.transmissionComb;
ul_config_pdu->srs_pdu.srs_pdu_rel8.i_srs =
soundingRS_UL_ConfigDedicated->
choice.setup.srs_ConfigIndex;
ul_config_pdu->srs_pdu.
srs_pdu_rel8.sounding_reference_cyclic_shift
=
soundingRS_UL_ConfigDedicated->
choice.setup.cyclicShift;
// ul_config_pdu->srs_pdu.srs_pdu_rel10.antenna_port = ;// // ul_config_pdu->srs_pdu.srs_pdu_rel10.antenna_port = ;//
// ul_config_pdu->srs_pdu.srs_pdu_rel13.number_of_combs = ;// // ul_config_pdu->srs_pdu.srs_pdu_rel13.number_of_combs = ;//
RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP<<4)+subframeP; RC.mac[module_idP]->UL_req[CC_id].sfn_sf =
(frameP << 4) + subframeP;
ul_req->number_of_pdus++; ul_req->number_of_pdus++;
} // if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset) } // if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset)
} // if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) } // if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup)
...@@ -146,73 +203,121 @@ void schedule_SRS(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) ...@@ -146,73 +203,121 @@ void schedule_SRS(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
} // for (UE_id ... } // for (UE_id ...
} // if((1<<tmp) & deltaTSFC) } // if((1<<tmp) & deltaTSFC)
}// SRS config } // SRS config
} }
} }
void schedule_CSI(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) void
schedule_CSI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
{ {
eNB_MAC_INST *eNB = RC.mac[module_idP]; eNB_MAC_INST *eNB = RC.mac[module_idP];
UE_list_t *UE_list = &eNB->UE_list; UE_list_t *UE_list = &eNB->UE_list;
COMMON_channels_t *cc; COMMON_channels_t *cc;
nfapi_ul_config_request_body_t *ul_req; nfapi_ul_config_request_body_t *ul_req;
int CC_id,UE_id; int CC_id, UE_id;
struct CQI_ReportPeriodic *cqi_ReportPeriodic; struct CQI_ReportPeriodic *cqi_ReportPeriodic;
uint16_t Npd,N_OFFSET_CQI; uint16_t Npd, N_OFFSET_CQI;
int H; int H;
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
cc = &eNB->common_channels[CC_id]; cc = &eNB->common_channels[CC_id];
for (UE_id=0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
if (UE_list->active[UE_id] != TRUE) continue; if (UE_list->active[UE_id] != TRUE)
continue;
ul_req = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body; ul_req =
&RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body;
// drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet
if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED) continue; if (mac_eNB_get_rrc_status
(module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED)
AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",UE_id); continue;
if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig) { AssertFatal(UE_list->
if ((cqi_ReportPeriodic = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic)!=NULL && UE_template[CC_id][UE_id].physicalConfigDedicated
(cqi_ReportPeriodic->present!=CQI_ReportPeriodic_PR_release)) { != NULL,
"physicalConfigDedicated is null for UE %d\n",
UE_id);
if (UE_list->
UE_template[CC_id][UE_id].physicalConfigDedicated->
cqi_ReportConfig) {
if ((cqi_ReportPeriodic =
UE_list->
UE_template[CC_id][UE_id].physicalConfigDedicated->
cqi_ReportConfig->cqi_ReportPeriodic) != NULL
&& (cqi_ReportPeriodic->present !=
CQI_ReportPeriodic_PR_release)) {
//Rel8 Periodic CQI/PMI/RI reporting //Rel8 Periodic CQI/PMI/RI reporting
get_csi_params(cc,cqi_ReportPeriodic,&Npd,&N_OFFSET_CQI,&H); get_csi_params(cc, cqi_ReportPeriodic, &Npd,
&N_OFFSET_CQI, &H);
if ((((frameP*10)+subframeP)%Npd) == N_OFFSET_CQI) { // CQI opportunity if ((((frameP * 10) + subframeP) % Npd) == N_OFFSET_CQI) { // CQI opportunity
UE_list->UE_sched_ctrl[UE_id].feedback_cnt[CC_id]=(((frameP*10)+subframeP)/Npd)%H; UE_list->UE_sched_ctrl[UE_id].feedback_cnt[CC_id] =
(((frameP * 10) + subframeP) / Npd) % H;
// Program CQI // Program CQI
nfapi_ul_config_request_pdu_t* ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; nfapi_ul_config_request_pdu_t *ul_config_pdu =
memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t)); &ul_req->ul_config_pdu_list[ul_req->
ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE; number_of_pdus];
ul_config_pdu->pdu_size = 2+(uint8_t)(2+sizeof(nfapi_ul_config_uci_cqi_pdu)); memset((void *) ul_config_pdu, 0,
ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; sizeof(nfapi_ul_config_request_pdu_t));
ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.pucch_index = cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; ul_config_pdu->pdu_type =
ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.dl_cqi_pmi_size = get_rel8_dl_cqi_pmi_size(&UE_list->UE_sched_ctrl[UE_id], NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE;
CC_id, ul_config_pdu->pdu_size =
cc, 2 + (uint8_t) (2 +
get_tmode(module_idP,CC_id,UE_id), sizeof
(nfapi_ul_config_uci_cqi_pdu));
ul_config_pdu->uci_cqi_pdu.
ue_information.ue_information_rel8.rnti =
UE_list->UE_template[CC_id][UE_id].rnti;
ul_config_pdu->uci_cqi_pdu.
cqi_information.cqi_information_rel8.
pucch_index =
cqi_ReportPeriodic->choice.
setup.cqi_PUCCH_ResourceIndex;
ul_config_pdu->uci_cqi_pdu.
cqi_information.cqi_information_rel8.
dl_cqi_pmi_size =
get_rel8_dl_cqi_pmi_size
(&UE_list->UE_sched_ctrl[UE_id], CC_id, cc,
get_tmode(module_idP, CC_id, UE_id),
cqi_ReportPeriodic); cqi_ReportPeriodic);
ul_req->number_of_pdus++; ul_req->number_of_pdus++;
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
// PUT rel10-13 UCI options here // PUT rel10-13 UCI options here
#endif #endif
} } else
else if ((cqi_ReportPeriodic->choice.setup.ri_ConfigIndex) && if ((cqi_ReportPeriodic->choice.setup.
((((frameP*10)+subframeP)%((H*Npd)<<(*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex/161)))== ri_ConfigIndex)
N_OFFSET_CQI + (*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex%161))) { // RI opportunity && ((((frameP * 10) + subframeP) % ((H * Npd) << (*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex / 161))) == N_OFFSET_CQI + (*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex % 161))) { // RI opportunity
// Program RI // Program RI
nfapi_ul_config_request_pdu_t* ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; nfapi_ul_config_request_pdu_t *ul_config_pdu =
memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t)); &ul_req->ul_config_pdu_list[ul_req->
ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE; number_of_pdus];
ul_config_pdu->pdu_size = 2+(uint8_t)(2+sizeof(nfapi_ul_config_uci_cqi_pdu)); memset((void *) ul_config_pdu, 0,
ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; sizeof(nfapi_ul_config_request_pdu_t));
ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.pucch_index = cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; ul_config_pdu->pdu_type =
ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.dl_cqi_pmi_size = (cc->p_eNB==2)?1:2; NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE;
RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP<<4)+subframeP; ul_config_pdu->pdu_size =
2 + (uint8_t) (2 +
sizeof
(nfapi_ul_config_uci_cqi_pdu));
ul_config_pdu->uci_cqi_pdu.
ue_information.ue_information_rel8.rnti =
UE_list->UE_template[CC_id][UE_id].rnti;
ul_config_pdu->uci_cqi_pdu.
cqi_information.cqi_information_rel8.
pucch_index =
cqi_ReportPeriodic->choice.
setup.cqi_PUCCH_ResourceIndex;
ul_config_pdu->uci_cqi_pdu.
cqi_information.cqi_information_rel8.
dl_cqi_pmi_size = (cc->p_eNB == 2) ? 1 : 2;
RC.mac[module_idP]->UL_req[CC_id].sfn_sf =
(frameP << 4) + subframeP;
ul_req->number_of_pdus++; ul_req->number_of_pdus++;
} }
...@@ -222,7 +327,8 @@ void schedule_CSI(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) ...@@ -222,7 +327,8 @@ void schedule_CSI(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
} // for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { } // for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
} }
void schedule_SR(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) void
schedule_SR(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
{ {
eNB_MAC_INST *eNB = RC.mac[module_idP]; eNB_MAC_INST *eNB = RC.mac[module_idP];
UE_list_t *UE_list = &eNB->UE_list; UE_list_t *UE_list = &eNB->UE_list;
...@@ -236,34 +342,51 @@ void schedule_SR(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) ...@@ -236,34 +342,51 @@ void schedule_SR(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
int i; int i;
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP; RC.mac[module_idP]->UL_req[CC_id].sfn_sf =
(frameP << 4) + subframeP;
for (UE_id = 0; UE_id<NUMBER_OF_UE_MAX; UE_id++) { for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
if (RC.mac[module_idP]->UE_list.active[UE_id]!=TRUE) continue; if (RC.mac[module_idP]->UE_list.active[UE_id] != TRUE)
continue;
ul_req = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body; ul_req =
&RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body;
AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",UE_id); AssertFatal(UE_list->
UE_template[CC_id][UE_id].physicalConfigDedicated
!= NULL,
"physicalConfigDedicated is null for UE %d\n",
UE_id);
// drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet
if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED) continue; if (mac_eNB_get_rrc_status
(module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED)
continue;
if ((SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig)!=NULL) { if ((SRconfig =
UE_list->
UE_template[CC_id][UE_id].physicalConfigDedicated->
schedulingRequestConfig) != NULL) {
if (SRconfig->present == SchedulingRequestConfig_PR_setup) { if (SRconfig->present == SchedulingRequestConfig_PR_setup) {
if (SRconfig->choice.setup.sr_ConfigIndex <= 4) { // 5 ms SR period if (SRconfig->choice.setup.sr_ConfigIndex <= 4) { // 5 ms SR period
if ((subframeP%5) != SRconfig->choice.setup.sr_ConfigIndex) if ((subframeP % 5) !=
SRconfig->choice.setup.sr_ConfigIndex)
continue; continue;
} else if (SRconfig->choice.setup.sr_ConfigIndex <= 14) { // 10 ms SR period } else if (SRconfig->choice.setup.sr_ConfigIndex <= 14) { // 10 ms SR period
if (subframeP!=(SRconfig->choice.setup.sr_ConfigIndex-5)) if (subframeP !=
(SRconfig->choice.setup.sr_ConfigIndex - 5))
continue; continue;
} else if (SRconfig->choice.setup.sr_ConfigIndex <= 34) { // 20 ms SR period } else if (SRconfig->choice.setup.sr_ConfigIndex <= 34) { // 20 ms SR period
if ((10*(frameP&1)+subframeP) != (SRconfig->choice.setup.sr_ConfigIndex-15)) if ((10 * (frameP & 1) + subframeP) !=
(SRconfig->choice.setup.sr_ConfigIndex - 15))
continue; continue;
} else if (SRconfig->choice.setup.sr_ConfigIndex <= 74) { // 40 ms SR period } else if (SRconfig->choice.setup.sr_ConfigIndex <= 74) { // 40 ms SR period
if ((10*(frameP&3)+subframeP) != (SRconfig->choice.setup.sr_ConfigIndex-35)) if ((10 * (frameP & 3) + subframeP) !=
(SRconfig->choice.setup.sr_ConfigIndex - 35))
continue; continue;
} else if (SRconfig->choice.setup.sr_ConfigIndex <= 154) { // 80 ms SR period } else if (SRconfig->choice.setup.sr_ConfigIndex <= 154) { // 80 ms SR period
if ((10*(frameP&7)+subframeP) != (SRconfig->choice.setup.sr_ConfigIndex-75)) if ((10 * (frameP & 7) + subframeP) !=
(SRconfig->choice.setup.sr_ConfigIndex - 75))
continue; continue;
} }
} // SRconfig->present == SchedulingRequestConfig_PR_setup) } // SRconfig->present == SchedulingRequestConfig_PR_setup)
...@@ -271,113 +394,178 @@ void schedule_SR(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) ...@@ -271,113 +394,178 @@ void schedule_SR(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
// if we get here there is some PUCCH1 reception to schedule for SR // if we get here there is some PUCCH1 reception to schedule for SR
skip_ue=0; skip_ue = 0;
is_harq = 0; is_harq = 0;
// check that there is no existing UL grant for ULSCH which overrides the SR // check that there is no existing UL grant for ULSCH which overrides the SR
for (i = 0; i < ul_req->number_of_pdus; i++) { for (i = 0; i < ul_req->number_of_pdus; i++) {
if (((ul_req->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE)|| if (((ul_req->ul_config_pdu_list[i].pdu_type ==
(ul_req->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE)|| NFAPI_UL_CONFIG_ULSCH_PDU_TYPE)
(ul_req->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE)|| || (ul_req->ul_config_pdu_list[i].pdu_type ==
(ul_req->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE))&& NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE)
(ul_req->ul_config_pdu_list[i].ulsch_pdu.ulsch_pdu_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) { || (ul_req->ul_config_pdu_list[i].pdu_type ==
skip_ue=1; NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE)
|| (ul_req->ul_config_pdu_list[i].pdu_type ==
NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE))
&& (ul_req->ul_config_pdu_list[i].
ulsch_pdu.ulsch_pdu_rel8.rnti ==
UE_list->UE_template[CC_id][UE_id].rnti)) {
skip_ue = 1;
break; break;
} }
/* if there is already an HARQ pdu, convert to SR_HARQ */ /* if there is already an HARQ pdu, convert to SR_HARQ */
else if ((ul_req->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE)&& else if ((ul_req->ul_config_pdu_list[i].pdu_type ==
(ul_req->ul_config_pdu_list[i].uci_harq_pdu.ue_information.ue_information_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) { NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE)
&& (ul_req->ul_config_pdu_list[i].
uci_harq_pdu.ue_information.
ue_information_rel8.rnti ==
UE_list->UE_template[CC_id][UE_id].rnti)) {
is_harq = 1; is_harq = 1;
break; break;
} }
} }
// drop the allocation because ULSCH with handle it with BSR // drop the allocation because ULSCH with handle it with BSR
if (skip_ue==1) continue; if (skip_ue == 1)
continue;
LOG_D(MAC,"Frame %d, Subframe %d : Scheduling SR for UE %d/%x\n",frameP,subframeP,UE_id,UE_list->UE_template[CC_id][UE_id].rnti); LOG_D(MAC,
"Frame %d, Subframe %d : Scheduling SR for UE %d/%x\n",
frameP, subframeP, UE_id,
UE_list->UE_template[CC_id][UE_id].rnti);
// check Rel10 or Rel8 SR // check Rel10 or Rel8 SR
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
if ((UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2) && if ((UE_list->
(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020)&& UE_template[CC_id][UE_id].physicalConfigDedicated->ext2)
(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020)) { && (UE_list->
UE_template[CC_id][UE_id].physicalConfigDedicated->
ext2->schedulingRequestConfig_v1020)
&& (UE_list->
UE_template[CC_id][UE_id].physicalConfigDedicated->
ext2->schedulingRequestConfig_v1020)) {
sr.sr_information_rel10.number_of_pucch_resources = 1; sr.sr_information_rel10.number_of_pucch_resources = 1;
sr.sr_information_rel10.pucch_index_p1 = *UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020->sr_PUCCH_ResourceIndexP1_r10; sr.sr_information_rel10.pucch_index_p1 =
*UE_list->
UE_template[CC_id][UE_id].physicalConfigDedicated->
ext2->
schedulingRequestConfig_v1020->sr_PUCCH_ResourceIndexP1_r10;
} else } else
#endif #endif
{ {
sr.sr_information_rel8.pucch_index = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex; sr.sr_information_rel8.pucch_index =
UE_list->
UE_template[CC_id][UE_id].physicalConfigDedicated->
schedulingRequestConfig->choice.setup.
sr_PUCCH_ResourceIndex;
} }
/* if there is already an HARQ pdu, convert to SR_HARQ */ /* if there is already an HARQ pdu, convert to SR_HARQ */
if (is_harq) { if (is_harq) {
nfapi_ul_config_harq_information h = ul_req->ul_config_pdu_list[i].uci_harq_pdu.harq_information; nfapi_ul_config_harq_information h =
ul_req->ul_config_pdu_list[i].pdu_type = NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE; ul_req->ul_config_pdu_list[i].uci_harq_pdu.
ul_req->ul_config_pdu_list[i].uci_sr_harq_pdu.sr_information = sr; harq_information;
ul_req->ul_config_pdu_list[i].uci_sr_harq_pdu.harq_information = h; ul_req->ul_config_pdu_list[i].pdu_type =
NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE;
ul_req->ul_config_pdu_list[i].uci_sr_harq_pdu.
sr_information = sr;
ul_req->ul_config_pdu_list[i].uci_sr_harq_pdu.
harq_information = h;
} else { } else {
ul_req->ul_config_pdu_list[ul_req->number_of_pdus].pdu_type = NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE; ul_req->ul_config_pdu_list[ul_req->number_of_pdus].
ul_req->ul_config_pdu_list[ul_req->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; pdu_type = NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE;
ul_req->ul_config_pdu_list[ul_req->number_of_pdus].uci_sr_pdu.sr_information = sr; ul_req->ul_config_pdu_list[ul_req->
number_of_pdus].uci_sr_pdu.
ue_information.ue_information_rel8.rnti =
UE_list->UE_template[CC_id][UE_id].rnti;
ul_req->ul_config_pdu_list[ul_req->
number_of_pdus].uci_sr_pdu.
sr_information = sr;
ul_req->number_of_pdus++; ul_req->number_of_pdus++;
} /* if (is_harq) */ } /* if (is_harq) */
} // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) } // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id])
} // for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) } // for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++)
} }
void check_ul_failure(module_id_t module_idP,int CC_id,int UE_id, void
check_ul_failure(module_id_t module_idP, int CC_id, int UE_id,
frame_t frameP, sub_frame_t subframeP) frame_t frameP, sub_frame_t subframeP)
{ {
UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; UE_list_t *UE_list = &RC.mac[module_idP]->UE_list;
nfapi_dl_config_request_t *DL_req = &RC.mac[module_idP]->DL_req[0]; nfapi_dl_config_request_t *DL_req = &RC.mac[module_idP]->DL_req[0];
uint16_t rnti = UE_RNTI(module_idP,UE_id); uint16_t rnti = UE_RNTI(module_idP, UE_id);
COMMON_channels_t *cc = RC.mac[module_idP]->common_channels; COMMON_channels_t *cc = RC.mac[module_idP]->common_channels;
// check uplink failure // check uplink failure
if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer>0)&& if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 0) &&
(UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync==0)) { (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0)) {
LOG_I(MAC,"UE %d rnti %x: UL Failure timer %d \n",UE_id,rnti,UE_list->UE_sched_ctrl[UE_id].ul_failure_timer); LOG_I(MAC, "UE %d rnti %x: UL Failure timer %d \n", UE_id, rnti,
if (UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent==0) { UE_list->UE_sched_ctrl[UE_id].ul_failure_timer);
UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent=1; if (UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent == 0) {
UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 1;
// add a format 1A dci for this UE to request an RA procedure (only one UE per subframe) // add a format 1A dci for this UE to request an RA procedure (only one UE per subframe)
nfapi_dl_config_request_pdu_t* dl_config_pdu = &DL_req[CC_id].dl_config_request_body.dl_config_pdu_list[DL_req[CC_id].dl_config_request_body.number_pdu]; nfapi_dl_config_request_pdu_t *dl_config_pdu =
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); &DL_req[CC_id].
dl_config_request_body.dl_config_pdu_list[DL_req[CC_id].
dl_config_request_body.number_pdu];
memset((void *) dl_config_pdu, 0,
sizeof(nfapi_dl_config_request_pdu_t));
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu)); dl_config_pdu->pdu_size =
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu));
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP,CC_id),UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id],format1A); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format =
NFAPI_DL_DCI_FORMAT_1A;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level =
get_aggregation(get_bw_index(module_idP, CC_id),
UE_list->UE_sched_ctrl[UE_id].
dl_cqi[CC_id], format1A);
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power
AssertFatal((cc[CC_id].mib->message.dl_Bandwidth >=0) && (cc[CC_id].mib->message.dl_Bandwidth<6), AssertFatal((cc[CC_id].mib->message.dl_Bandwidth >= 0)
"illegal dl_Bandwidth %d\n",(int)cc[CC_id].mib->message.dl_Bandwidth); && (cc[CC_id].mib->message.dl_Bandwidth < 6),
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = pdcch_order_table[cc[CC_id].mib->message.dl_Bandwidth]; "illegal dl_Bandwidth %d\n",
(int) cc[CC_id].mib->message.dl_Bandwidth);
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.
resource_block_coding =
pdcch_order_table[cc[CC_id].mib->message.dl_Bandwidth];
DL_req[CC_id].dl_config_request_body.number_dci++; DL_req[CC_id].dl_config_request_body.number_dci++;
DL_req[CC_id].dl_config_request_body.number_pdu++; DL_req[CC_id].dl_config_request_body.number_pdu++;
LOG_I(MAC,"UE %d rnti %x: sending PDCCH order for RAPROC (failure timer %d), resource_block_coding %d \n",UE_id,rnti,UE_list->UE_sched_ctrl[UE_id].ul_failure_timer,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding); LOG_I(MAC,
} "UE %d rnti %x: sending PDCCH order for RAPROC (failure timer %d), resource_block_coding %d \n",
else { // ra_pdcch_sent==1 UE_id, rnti,
LOG_I(MAC,"UE %d rnti %x: sent PDCCH order for RAPROC waiting (failure timer %d) \n",UE_id,rnti,UE_list->UE_sched_ctrl[UE_id].ul_failure_timer); UE_list->UE_sched_ctrl[UE_id].ul_failure_timer,
dl_config_pdu->dci_dl_pdu.
dci_dl_pdu_rel8.resource_block_coding);
} else { // ra_pdcch_sent==1
LOG_I(MAC,
"UE %d rnti %x: sent PDCCH order for RAPROC waiting (failure timer %d) \n",
UE_id, rnti,
UE_list->UE_sched_ctrl[UE_id].ul_failure_timer);
if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer % 40) == 0) if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer % 40) == 0)
UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent=0; // resend every 4 frames UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 0; // resend every 4 frames
} }
UE_list->UE_sched_ctrl[UE_id].ul_failure_timer++; UE_list->UE_sched_ctrl[UE_id].ul_failure_timer++;
// check threshold // check threshold
if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 200) { if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 200) {
// inform RRC of failure and clear timer // inform RRC of failure and clear timer
LOG_I(MAC,"UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n",UE_id,rnti); LOG_I(MAC,
mac_eNB_rrc_ul_failure(module_idP,CC_id,frameP,subframeP,rnti); "UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n",
UE_list->UE_sched_ctrl[UE_id].ul_failure_timer=0; UE_id, rnti);
UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync=1; mac_eNB_rrc_ul_failure(module_idP, CC_id, frameP, subframeP,
rnti);
UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0;
UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 1;
} }
} // ul_failure_timer>0 } // ul_failure_timer>0
} }
void clear_nfapi_information(eNB_MAC_INST *eNB,int CC_idP,frame_t frameP,sub_frame_t subframeP) void
clear_nfapi_information(eNB_MAC_INST * eNB, int CC_idP,
frame_t frameP, sub_frame_t subframeP)
{ {
nfapi_dl_config_request_t *DL_req = &eNB->DL_req[0]; nfapi_dl_config_request_t *DL_req = &eNB->DL_req[0];
nfapi_ul_config_request_t *UL_req = &eNB->UL_req[0]; nfapi_ul_config_request_t *UL_req = &eNB->UL_req[0];
...@@ -392,7 +580,8 @@ void clear_nfapi_information(eNB_MAC_INST *eNB,int CC_idP,frame_t frameP,sub_fra ...@@ -392,7 +580,8 @@ void clear_nfapi_information(eNB_MAC_INST *eNB,int CC_idP,frame_t frameP,sub_fra
DL_req[CC_idP].dl_config_request_body.number_pdsch_rnti = 0; DL_req[CC_idP].dl_config_request_body.number_pdsch_rnti = 0;
DL_req[CC_idP].dl_config_request_body.transmission_power_pcfich = 6000; DL_req[CC_idP].dl_config_request_body.transmission_power_pcfich = 6000;
HI_DCI0_req[CC_idP].hi_dci0_request_body.sfnsf = subframeP + (frameP<<4); HI_DCI0_req[CC_idP].hi_dci0_request_body.sfnsf =
subframeP + (frameP << 4);
HI_DCI0_req[CC_idP].hi_dci0_request_body.number_of_dci = 0; HI_DCI0_req[CC_idP].hi_dci0_request_body.number_of_dci = 0;
...@@ -406,7 +595,8 @@ void clear_nfapi_information(eNB_MAC_INST *eNB,int CC_idP,frame_t frameP,sub_fra ...@@ -406,7 +595,8 @@ void clear_nfapi_information(eNB_MAC_INST *eNB,int CC_idP,frame_t frameP,sub_fra
} }
void copy_ulreq(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP) void
copy_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
{ {
int CC_id; int CC_id;
eNB_MAC_INST *eNB; eNB_MAC_INST *eNB;
...@@ -415,30 +605,34 @@ void copy_ulreq(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP) ...@@ -415,30 +605,34 @@ void copy_ulreq(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
eNB = RC.mac[module_idP]; eNB = RC.mac[module_idP];
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
ul_req_tmp = &eNB->UL_req_tmp[CC_id][subframeP].ul_config_request_body; ul_req_tmp =
&eNB->UL_req_tmp[CC_id][subframeP].ul_config_request_body;
ul_req = &eNB->UL_req[CC_id].ul_config_request_body; ul_req = &eNB->UL_req[CC_id].ul_config_request_body;
eNB->UL_req[CC_id].sfn_sf = (frameP<<4) + subframeP; eNB->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP;
ul_req->number_of_pdus = ul_req_tmp->number_of_pdus; ul_req->number_of_pdus = ul_req_tmp->number_of_pdus;
ul_req_tmp->number_of_pdus = 0; ul_req_tmp->number_of_pdus = 0;
memcpy((void*)ul_req->ul_config_pdu_list, memcpy((void *) ul_req->ul_config_pdu_list,
(void*)ul_req_tmp->ul_config_pdu_list, (void *) ul_req_tmp->ul_config_pdu_list,
ul_req->number_of_pdus*sizeof(nfapi_ul_config_request_pdu_t)); ul_req->number_of_pdus *
sizeof(nfapi_ul_config_request_pdu_t));
} }
} }
void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) void
eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP,
sub_frame_t subframeP)
{ {
int mbsfn_status[MAX_NUM_CCs]; int mbsfn_status[MAX_NUM_CCs];
protocol_ctxt_t ctxt; protocol_ctxt_t ctxt;
int CC_id,i; //,next_i; int CC_id, i; //,next_i;
UE_list_t *UE_list=&RC.mac[module_idP]->UE_list; UE_list_t *UE_list = &RC.mac[module_idP]->UE_list;
rnti_t rnti; rnti_t rnti;
COMMON_channels_t *cc = RC.mac[module_idP]->common_channels; COMMON_channels_t *cc = RC.mac[module_idP]->common_channels;
...@@ -449,68 +643,82 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame ...@@ -449,68 +643,82 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame
start_meas(&RC.mac[module_idP]->eNB_scheduler); start_meas(&RC.mac[module_idP]->eNB_scheduler);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,
VCD_FUNCTION_IN);
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
mbsfn_status[CC_id]=0; mbsfn_status[CC_id] = 0;
// clear vrb_maps // clear vrb_maps
memset(cc[CC_id].vrb_map,0,100); memset(cc[CC_id].vrb_map, 0, 100);
memset(cc[CC_id].vrb_map_UL,0,100); memset(cc[CC_id].vrb_map_UL, 0, 100);
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
cc[CC_id].mcch_active =0; cc[CC_id].mcch_active = 0;
#endif #endif
RC.mac[module_idP]->frame = frameP; RC.mac[module_idP]->frame = frameP;
RC.mac[module_idP]->subframe = subframeP; RC.mac[module_idP]->subframe = subframeP;
clear_nfapi_information(RC.mac[module_idP],CC_id,frameP,subframeP); clear_nfapi_information(RC.mac[module_idP], CC_id, frameP,
subframeP);
} }
// refresh UE list based on UEs dropped by PHY in previous subframe // refresh UE list based on UEs dropped by PHY in previous subframe
for (i = 0; i < NUMBER_OF_UE_MAX; i++) { for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
if (UE_list->active[i] != TRUE) continue; if (UE_list->active[i] != TRUE)
continue;
rnti = UE_RNTI(module_idP, i); rnti = UE_RNTI(module_idP, i);
CC_id = UE_PCCID(module_idP, i); CC_id = UE_PCCID(module_idP, i);
if ((frameP==0)&&(subframeP==0)) { if ((frameP == 0) && (subframeP == 0)) {
LOG_I(MAC,"UE rnti %x : %s, PHR %d dB DL CQI %d PUSCH SNR %d PUCCH SNR %d\n", rnti, LOG_I(MAC,
UE_list->UE_sched_ctrl[i].ul_out_of_sync==0 ? "in synch" : "out of sync", "UE rnti %x : %s, PHR %d dB DL CQI %d PUSCH SNR %d PUCCH SNR %d\n",
rnti,
UE_list->UE_sched_ctrl[i].ul_out_of_sync ==
0 ? "in synch" : "out of sync",
UE_list->UE_template[CC_id][i].phr_info, UE_list->UE_template[CC_id][i].phr_info,
UE_list->UE_sched_ctrl[i].dl_cqi[CC_id], UE_list->UE_sched_ctrl[i].dl_cqi[CC_id],
(UE_list->UE_sched_ctrl[i].pusch_snr[CC_id]-128)/2, (UE_list->UE_sched_ctrl[i].pusch_snr[CC_id] - 128) / 2,
(UE_list->UE_sched_ctrl[i].pucch1_snr[CC_id]-128)/2); (UE_list->UE_sched_ctrl[i].pucch1_snr[CC_id] - 128) / 2);
} }
RC.eNB[module_idP][CC_id]->pusch_stats_bsr[i][(frameP*10)+subframeP]=-63; RC.eNB[module_idP][CC_id]->pusch_stats_bsr[i][(frameP * 10) +
if (i==UE_list->head) subframeP] = -63;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR,RC.eNB[module_idP][CC_id]->pusch_stats_bsr[i][(frameP*10)+subframeP]); if (i == UE_list->head)
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME
(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR,
RC.eNB[module_idP][CC_id]->
pusch_stats_bsr[i][(frameP * 10) + subframeP]);
// increment this, it is cleared when we receive an sdu // increment this, it is cleared when we receive an sdu
RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ul_inactivity_timer++; RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ul_inactivity_timer++;
RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer++; RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer++;
LOG_D(MAC,"UE %d/%x : ul_inactivity %d, cqi_req %d\n",i,rnti, LOG_D(MAC, "UE %d/%x : ul_inactivity %d, cqi_req %d\n", i, rnti,
RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ul_inactivity_timer, RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].
ul_inactivity_timer,
RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer); RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer);
check_ul_failure(module_idP,CC_id,i,frameP,subframeP); check_ul_failure(module_idP, CC_id, i, frameP, subframeP);
} }
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frameP, subframeP,module_idP); PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES,
NOT_A_RNTI, frameP, subframeP,
module_idP);
pdcp_run(&ctxt); pdcp_run(&ctxt);
rrc_rx_tx(&ctxt, rrc_rx_tx(&ctxt, 0, // eNB index, unused in eNB
0, // eNB index, unused in eNB
CC_id); CC_id);
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
if (cc[CC_id].MBMS_flag >0) { if (cc[CC_id].MBMS_flag > 0) {
start_meas(&RC.mac[module_idP]->schedule_mch); start_meas(&RC.mac[module_idP]->schedule_mch);
mbsfn_status[CC_id] = schedule_MBMS(module_idP,CC_id,frameP,subframeP); mbsfn_status[CC_id] =
schedule_MBMS(module_idP, CC_id, frameP, subframeP);
stop_meas(&RC.mac[module_idP]->schedule_mch); stop_meas(&RC.mac[module_idP]->schedule_mch);
} }
} }
...@@ -518,31 +726,35 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame ...@@ -518,31 +726,35 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame
#endif #endif
// This schedules MIB // This schedules MIB
if ((subframeP==0) && (frameP&3) == 0) schedule_mib(module_idP,frameP,subframeP); if ((subframeP == 0) && (frameP & 3) == 0)
schedule_mib(module_idP, frameP, subframeP);
// This schedules SI for legacy LTE and eMTC starting in subframeP // This schedules SI for legacy LTE and eMTC starting in subframeP
schedule_SI(module_idP,frameP,subframeP); schedule_SI(module_idP, frameP, subframeP);
// This schedules Random-Access for legacy LTE and eMTC starting in subframeP // This schedules Random-Access for legacy LTE and eMTC starting in subframeP
schedule_RA(module_idP,frameP,subframeP); schedule_RA(module_idP, frameP, subframeP);
// copy previously scheduled UL resources (ULSCH + HARQ) // copy previously scheduled UL resources (ULSCH + HARQ)
copy_ulreq(module_idP,frameP,subframeP); copy_ulreq(module_idP, frameP, subframeP);
// This schedules SRS in subframeP // This schedules SRS in subframeP
schedule_SRS(module_idP,frameP,subframeP); schedule_SRS(module_idP, frameP, subframeP);
// This schedules ULSCH in subframeP (dci0) // This schedules ULSCH in subframeP (dci0)
schedule_ulsch(module_idP,frameP,subframeP); schedule_ulsch(module_idP, frameP, subframeP);
// This schedules UCI_SR in subframeP // This schedules UCI_SR in subframeP
schedule_SR(module_idP,frameP,subframeP); schedule_SR(module_idP, frameP, subframeP);
// This schedules UCI_CSI in subframeP // This schedules UCI_CSI in subframeP
schedule_CSI(module_idP, frameP, subframeP); schedule_CSI(module_idP, frameP, subframeP);
// This schedules DLSCH in subframeP // This schedules DLSCH in subframeP
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); schedule_ue_spec(module_idP, frameP, subframeP, mbsfn_status);
// Allocate CCEs for good after scheduling is done // Allocate CCEs for good after scheduling is done
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) allocate_CCEs(module_idP,CC_id,subframeP,0); for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++)
allocate_CCEs(module_idP, CC_id, subframeP, 0);
stop_meas(&RC.mac[module_idP]->eNB_scheduler); stop_meas(&RC.mac[module_idP]->eNB_scheduler);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,
VCD_FUNCTION_OUT);
} }
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
#include "pdcp.h" #include "pdcp.h"
#if defined(ENABLE_ITTI) #if defined(ENABLE_ITTI)
# include "intertask_interface.h" #include "intertask_interface.h"
#endif #endif
#define ENABLE_MAC_PAYLOAD_DEBUG #define ENABLE_MAC_PAYLOAD_DEBUG
...@@ -65,23 +65,23 @@ ...@@ -65,23 +65,23 @@
#ifdef Rel14 #ifdef Rel14
#define size_Sj25 2 #define size_Sj25 2
int Sj25[size_Sj25]={0,3}; int Sj25[size_Sj25] = { 0, 3 };
#define size_Sj50 6 #define size_Sj50 6
int Sj50[size_Sj50]={0,1,2,5,6,7}; int Sj50[size_Sj50] = { 0, 1, 2, 5, 6, 7 };
#define size_Sj75 10 #define size_Sj75 10
int Sj75[size_Sj75]={0,1,2,3,4,7,8,9,10,11}; int Sj75[size_Sj75] = { 0, 1, 2, 3, 4, 7, 8, 9, 10, 11 };
#define size_Sj100 14 #define size_Sj100 14
int Sj100[size_Sj100]={0,1,2,3,4,5,6,9,10,11,12,13,14,15}; int Sj100[size_Sj100] = { 0, 1, 2, 3, 4, 5, 6, 9, 10, 11, 12, 13, 14, 15 };
int SIB1_BR_TBS_table[6] = {208,256,328,504,712,936}; int SIB1_BR_TBS_table[6] = { 208, 256, 328, 504, 712, 936 };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void
schedule_SIB1_BR( schedule_SIB1_BR(module_id_t module_idP,
module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
frame_t frameP,
sub_frame_t subframeP)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
...@@ -95,144 +95,173 @@ schedule_SIB1_BR( ...@@ -95,144 +95,173 @@ schedule_SIB1_BR(
nfapi_dl_config_request_pdu_t *dl_config_pdu; nfapi_dl_config_request_pdu_t *dl_config_pdu;
nfapi_tx_request_pdu_t *TX_req; nfapi_tx_request_pdu_t *TX_req;
nfapi_dl_config_request_body_t *dl_req; nfapi_dl_config_request_body_t *dl_req;
int m,i,N_S_NB; int m, i, N_S_NB;
int *Sj; int *Sj;
int n_NB = 0; int n_NB = 0;
int TBS; int TBS;
int k=0,rvidx; int k = 0, rvidx;
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
cc = &eNB->common_channels[CC_id]; cc = &eNB->common_channels[CC_id];
vrb_map = (void*)&cc->vrb_map; vrb_map = (void *) &cc->vrb_map;
N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth);
dl_req = &eNB->DL_req[CC_id].dl_config_request_body; dl_req = &eNB->DL_req[CC_id].dl_config_request_body;
int foffset = cc->physCellId&1; int foffset = cc->physCellId & 1;
int sfoffset = (cc->tdd_Config==NULL) ? 0 : 1; int sfoffset = (cc->tdd_Config == NULL) ? 0 : 1;
// Time-domain scheduling // Time-domain scheduling
if (cc->mib->message.schedulingInfoSIB1_BR_r13==0) continue; if (cc->mib->message.schedulingInfoSIB1_BR_r13 == 0)
continue;
else else
switch ((cc->mib->message.schedulingInfoSIB1_BR_r13-1)%3) { switch ((cc->mib->message.schedulingInfoSIB1_BR_r13 - 1) % 3) {
case 0: // repetition 4 case 0: // repetition 4
k = (frameP>>1)&3; k = (frameP >> 1) & 3;
if ((subframeP!=(4+sfoffset)) || ((frameP&1)!=foffset)) continue; if ((subframeP != (4 + sfoffset))
|| ((frameP & 1) != foffset))
continue;
break; break;
case 1: // repetition 8 case 1: // repetition 8
k = frameP&3; k = frameP & 3;
AssertFatal(N_RB_DL>15,"SIB1-BR repetition 8 not allowed for N_RB_DL= %d\n",N_RB_DL); AssertFatal(N_RB_DL > 15,
if ((foffset==0) && (subframeP!=(4+sfoffset))) continue; "SIB1-BR repetition 8 not allowed for N_RB_DL= %d\n",
else if ((foffset==1) && (subframeP!=((9+sfoffset)%10))) continue; N_RB_DL);
if ((foffset == 0) && (subframeP != (4 + sfoffset)))
continue;
else if ((foffset == 1)
&& (subframeP != ((9 + sfoffset) % 10)))
continue;
break; break;
case 2: // repetition 16 case 2: // repetition 16
k = ((10*frameP) + subframeP)&3; k = ((10 * frameP) + subframeP) & 3;
AssertFatal(N_RB_DL>15,"SIB1-BR repetition 16 not allowed for N_RB_DL= %d\n",N_RB_DL); AssertFatal(N_RB_DL > 15,
if ((sfoffset == 1) && ((subframeP!=0)||(subframeP!=5))) continue; "SIB1-BR repetition 16 not allowed for N_RB_DL= %d\n",
else if ((sfoffset == 0) && (foffset==0) && (subframeP!=4) && (subframeP!=9)) continue; N_RB_DL);
else if ((sfoffset == 0) && (foffset==1) && (subframeP!=0) && (subframeP!=9)) continue; if ((sfoffset == 1)
&& ((subframeP != 0) || (subframeP != 5)))
continue;
else if ((sfoffset == 0) && (foffset == 0)
&& (subframeP != 4) && (subframeP != 9))
continue;
else if ((sfoffset == 0) && (foffset == 1)
&& (subframeP != 0) && (subframeP != 9))
continue;
break; break;
} }
// if we get here we have to schedule SIB1_BR in this frame/subframe // if we get here we have to schedule SIB1_BR in this frame/subframe
// keep counter of SIB1_BR repetitions in 8 frame period to choose narrowband on which to transmit // keep counter of SIB1_BR repetitions in 8 frame period to choose narrowband on which to transmit
if ((frameP&7) == 0) cc->SIB1_BR_cnt=0; if ((frameP & 7) == 0)
else cc->SIB1_BR_cnt++; cc->SIB1_BR_cnt = 0;
else
cc->SIB1_BR_cnt++;
// Frequency-domain scheduling // Frequency-domain scheduling
switch (N_RB_DL) { switch (N_RB_DL) {
case 6: case 6:
case 15: case 15:
default: default:
m=1; m = 1;
n_NB=0; n_NB = 0;
N_S_NB=0; N_S_NB = 0;
Sj=NULL; Sj = NULL;
break; break;
case 25: case 25:
m=2; m = 2;
N_S_NB = 2; N_S_NB = 2;
Sj = Sj25; Sj = Sj25;
break; break;
case 50: case 50:
m=2; m = 2;
N_S_NB = 6; N_S_NB = 6;
Sj = Sj50; Sj = Sj50;
break; break;
case 75: case 75:
m=4; m = 4;
N_S_NB = 10; N_S_NB = 10;
Sj = Sj75; Sj = Sj75;
break; break;
case 100: case 100:
m=4; m = 4;
N_S_NB = 14; N_S_NB = 14;
Sj = Sj100; Sj = Sj100;
break; break;
} }
// Note: definition of k above and rvidx from 36.321 section 5.3.1 // Note: definition of k above and rvidx from 36.321 section 5.3.1
rvidx = (((3*k)>>1) + (k&1))&3; rvidx = (((3 * k) >> 1) + (k & 1)) & 3;
i = cc->SIB1_BR_cnt & (m-1); i = cc->SIB1_BR_cnt & (m - 1);
n_NB = Sj[((cc->physCellId % N_S_NB) + (i*N_S_NB/m))%N_S_NB]; n_NB = Sj[((cc->physCellId % N_S_NB) + (i * N_S_NB / m)) % N_S_NB];
bcch_sdu_length = mac_rrc_data_req(module_idP, bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SIB1_BR, 1, &cc->BCCH_BR_pdu[0].payload[0], 1, module_idP, 0); // not used in this case
CC_id,
frameP,
BCCH_SIB1_BR,1,
&cc->BCCH_BR_pdu[0].payload[0],
1,
module_idP,
0); // not used in this case
AssertFatal(cc->mib->message.schedulingInfoSIB1_BR_r13<19,"schedulingInfoSIB1_BR_r13 %d > 18\n", AssertFatal(cc->mib->message.schedulingInfoSIB1_BR_r13 < 19,
(int)cc->mib->message.schedulingInfoSIB1_BR_r13); "schedulingInfoSIB1_BR_r13 %d > 18\n",
(int) cc->mib->message.schedulingInfoSIB1_BR_r13);
AssertFatal(bcch_sdu_length>0,"RRC returned 0 bytes for SIB1-BR\n"); AssertFatal(bcch_sdu_length > 0,
"RRC returned 0 bytes for SIB1-BR\n");
TBS = SIB1_BR_TBS_table[(cc->mib->message.schedulingInfoSIB1_BR_r13-1)/3]>>3; TBS =
SIB1_BR_TBS_table[(cc->mib->message.schedulingInfoSIB1_BR_r13 -
1) / 3] >> 3;
AssertFatal(bcch_sdu_length <= TBS, "length returned by RRC %d is not compatible with the TBS %d from MIB\n",bcch_sdu_length,TBS); AssertFatal(bcch_sdu_length <= TBS,
"length returned by RRC %d is not compatible with the TBS %d from MIB\n",
bcch_sdu_length, TBS);
if ((frameP&1023) < 200) LOG_D(MAC,"[eNB %d] Frame %d Subframe %d: SIB1_BR->DLSCH CC_id %d, Received %d bytes, scheduling on NB %d (i %d,m %d,N_S_NB %d) rvidx %d\n",module_idP,frameP,subframeP,CC_id,bcch_sdu_length,n_NB,i,m,N_S_NB,rvidx); if ((frameP & 1023) < 200)
LOG_D(MAC,
"[eNB %d] Frame %d Subframe %d: SIB1_BR->DLSCH CC_id %d, Received %d bytes, scheduling on NB %d (i %d,m %d,N_S_NB %d) rvidx %d\n",
module_idP, frameP, subframeP, CC_id, bcch_sdu_length,
n_NB, i, m, N_S_NB, rvidx);
// allocate all 6 PRBs in narrowband for SIB1_BR // allocate all 6 PRBs in narrowband for SIB1_BR
first_rb = narrowband_to_first_rb(cc,n_NB); first_rb = narrowband_to_first_rb(cc, n_NB);
vrb_map[first_rb] = 1; vrb_map[first_rb] = 1;
vrb_map[first_rb+1] = 1; vrb_map[first_rb + 1] = 1;
vrb_map[first_rb+2] = 1; vrb_map[first_rb + 2] = 1;
vrb_map[first_rb+3] = 1; vrb_map[first_rb + 3] = 1;
vrb_map[first_rb+4] = 1; vrb_map[first_rb + 4] = 1;
vrb_map[first_rb+5] = 1; vrb_map[first_rb + 5] = 1;
dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); memset((void *) dl_config_pdu, 0,
sizeof(nfapi_dl_config_request_pdu_t));
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu)); dl_config_pdu->pdu_size =
(uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu));
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = TBS; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = TBS;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index =
eNB->pdu_index[CC_id];
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL,first_rb,6); dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding =
getRIV(N_RB_DL, first_rb, 6);
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = rvidx; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = rvidx;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; dl_config_pdu->dlsch_pdu.
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB==1 ) ? 0 : 1; dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme =
(cc->p_eNB == 1) ? 0 : 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index =
0;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB==1 ) ? 1 : 2; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode =
(cc->p_eNB == 1) ? 1 : 2;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1;
// Rel10 fields // Rel10 fields
...@@ -246,7 +275,10 @@ schedule_SIB1_BR( ...@@ -246,7 +275,10 @@ schedule_SIB1_BR(
dl_req->number_pdu++; dl_req->number_pdu++;
// Program TX Request // Program TX Request
TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; TX_req =
&eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->
TX_req
[CC_id].tx_request_body.number_of_pdus];
TX_req->pdu_length = bcch_sdu_length; TX_req->pdu_length = bcch_sdu_length;
TX_req->pdu_index = eNB->pdu_index[CC_id]++; TX_req->pdu_index = eNB->pdu_index[CC_id]++;
TX_req->num_segments = 1; TX_req->num_segments = 1;
...@@ -260,26 +292,19 @@ schedule_SIB1_BR( ...@@ -260,26 +292,19 @@ schedule_SIB1_BR(
trace_pdu(1, trace_pdu(1,
&cc->BCCH_BR_pdu[0].payload[0], &cc->BCCH_BR_pdu[0].payload[0],
bcch_sdu_length, bcch_sdu_length,
0xffff, 0xffff, 4, 0xffff, eNB->frame, eNB->subframe, 0, 0);
4, LOG_D(OPT,
0xffff, "[eNB %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n",
eNB->frame,
eNB->subframe,
0,
0);
LOG_D(OPT,"[eNB %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n",
module_idP, frameP, CC_id, 0xffff, bcch_sdu_length); module_idP, frameP, CC_id, 0xffff, bcch_sdu_length);
} }
if (cc->tdd_Config!=NULL) { //TDD if (cc->tdd_Config != NULL) { //TDD
LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH-BR 0->DLSCH (TDD) for CC_id %d SIB1-BR %d bytes\n", LOG_D(MAC,
frameP, "[eNB] Frame %d : Scheduling BCCH-BR 0->DLSCH (TDD) for CC_id %d SIB1-BR %d bytes\n",
CC_id, frameP, CC_id, bcch_sdu_length);
bcch_sdu_length);
} else { } else {
LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH-BR 0->DLSCH (FDD) for CC_id %d SIB1-BR %d bytes\n", LOG_D(MAC,
frameP, "[eNB] Frame %d : Scheduling BCCH-BR 0->DLSCH (FDD) for CC_id %d SIB1-BR %d bytes\n",
CC_id, frameP, CC_id, bcch_sdu_length);
bcch_sdu_length);
} }
} }
...@@ -287,17 +312,16 @@ schedule_SIB1_BR( ...@@ -287,17 +312,16 @@ schedule_SIB1_BR(
return; return;
} }
int si_WindowLength_BR_r13tab[SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_spare] = int si_WindowLength_BR_r13tab
{20,40,60,80,120,160,200}; [SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_spare]
int si_TBS_r13tab[SchedulingInfo_BR_r13__si_TBS_r13_b936+1] = {152,208,256,328,408,504,600,712,808,936}; = { 20, 40, 60, 80, 120, 160, 200 };
int si_TBS_r13tab[SchedulingInfo_BR_r13__si_TBS_r13_b936 + 1] =
{ 152, 208, 256, 328, 408, 504, 600, 712, 808, 936 };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void
schedule_SI_BR( schedule_SI_BR(module_id_t module_idP, frame_t frameP,
module_id_t module_idP,
frame_t frameP,
sub_frame_t subframeP) sub_frame_t subframeP)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
...@@ -313,170 +337,232 @@ schedule_SI_BR( ...@@ -313,170 +337,232 @@ schedule_SI_BR(
nfapi_dl_config_request_body_t *dl_req; nfapi_dl_config_request_body_t *dl_req;
int i; int i;
int rvidx; int rvidx;
int absSF = (frameP*10)+subframeP; int absSF = (frameP * 10) + subframeP;
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
cc = &eNB->common_channels[CC_id]; cc = &eNB->common_channels[CC_id];
vrb_map = (void*)&cc->vrb_map; vrb_map = (void *) &cc->vrb_map;
N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth);
dl_req = &eNB->DL_req[CC_id].dl_config_request_body; dl_req = &eNB->DL_req[CC_id].dl_config_request_body;
// Time-domain scheduling // Time-domain scheduling
if (cc->mib->message.schedulingInfoSIB1_BR_r13==0) continue; if (cc->mib->message.schedulingInfoSIB1_BR_r13 == 0)
continue;
else { else {
AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13!=NULL, AssertFatal(cc->
sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13
!= NULL,
"sib_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); "sib_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n");
SchedulingInfoList_BR_r13_t *schedulingInfoList_BR_r13 = cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->schedulingInfoList_BR_r13; SchedulingInfoList_BR_r13_t *schedulingInfoList_BR_r13 =
AssertFatal(schedulingInfoList_BR_r13!=NULL, cc->sib1_v13ext->
bandwidthReducedAccessRelatedInfo_r13->schedulingInfoList_BR_r13;
AssertFatal(schedulingInfoList_BR_r13 != NULL,
"sib_v13ext->schedulingInfoList_BR_r13 is null\n"); "sib_v13ext->schedulingInfoList_BR_r13 is null\n");
SchedulingInfoList_t *schedulingInfoList = cc->schedulingInfoList; SchedulingInfoList_t *schedulingInfoList =
AssertFatal(schedulingInfoList_BR_r13->list.count==schedulingInfoList->list.count, cc->schedulingInfoList;
AssertFatal(schedulingInfoList_BR_r13->list.count ==
schedulingInfoList->list.count,
"schedulingInfolist_BR.r13->list.count %d != schedulingInfoList.list.count %d\n", "schedulingInfolist_BR.r13->list.count %d != schedulingInfoList.list.count %d\n",
schedulingInfoList_BR_r13->list.count,schedulingInfoList->list.count); schedulingInfoList_BR_r13->list.count,
schedulingInfoList->list.count);
AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13<=SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200, AssertFatal(cc->
sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13
<=
SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200,
"si_WindowLength_BR_r13 %d > %d\n", "si_WindowLength_BR_r13 %d > %d\n",
(int)cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13, (int) cc->
sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13,
SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200); SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200);
// check that SI frequency-hopping is disabled // check that SI frequency-hopping is disabled
AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_HoppingConfigCommon_r13==SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_HoppingConfigCommon_r13_off, AssertFatal(cc->
sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_HoppingConfigCommon_r13
==
SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_HoppingConfigCommon_r13_off,
"Deactivate SI_HoppingConfigCommon_r13 in configuration file, not supported for now\n"); "Deactivate SI_HoppingConfigCommon_r13 in configuration file, not supported for now\n");
long si_WindowLength_BR_r13 = si_WindowLength_BR_r13tab[cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13]; long si_WindowLength_BR_r13 =
si_WindowLength_BR_r13tab[cc->
long si_RepetitionPattern_r13 = cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_RepetitionPattern_r13; sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13];
AssertFatal(si_RepetitionPattern_r13<=SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_RepetitionPattern_r13_every8thRF,
long si_RepetitionPattern_r13 =
cc->sib1_v13ext->
bandwidthReducedAccessRelatedInfo_r13->si_RepetitionPattern_r13;
AssertFatal(si_RepetitionPattern_r13 <=
SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_RepetitionPattern_r13_every8thRF,
"si_RepetitionPattern_r13 %d > %d\n", "si_RepetitionPattern_r13 %d > %d\n",
(int)si_RepetitionPattern_r13, (int) si_RepetitionPattern_r13,
SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_RepetitionPattern_r13_every8thRF); SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_RepetitionPattern_r13_every8thRF);
// cycle through SIB list // cycle through SIB list
for (i=0;i<schedulingInfoList_BR_r13->list.count;i++) { for (i = 0; i < schedulingInfoList_BR_r13->list.count; i++) {
long si_Periodicity = schedulingInfoList->list.array[i]->si_Periodicity; long si_Periodicity =
long si_Narrowband_r13 = schedulingInfoList_BR_r13->list.array[i]->si_Narrowband_r13; schedulingInfoList->list.array[i]->si_Periodicity;
long si_TBS_r13 = si_TBS_r13tab[schedulingInfoList_BR_r13->list.array[i]->si_TBS_r13]; long si_Narrowband_r13 =
schedulingInfoList_BR_r13->list.array[i]->
si_Narrowband_r13;
long si_TBS_r13 =
si_TBS_r13tab[schedulingInfoList_BR_r13->
list.array[i]->si_TBS_r13];
// check if the SI is to be scheduled now // check if the SI is to be scheduled now
int period_in_sf = 80<<si_Periodicity; // 2^i * 80 subframes, note: si_Periodicity is 2^i * 80ms int period_in_sf = 80 << si_Periodicity; // 2^i * 80 subframes, note: si_Periodicity is 2^i * 80ms
int sf_mod_period = absSF%period_in_sf; int sf_mod_period = absSF % period_in_sf;
int k = sf_mod_period&3; int k = sf_mod_period & 3;
// Note: definition of k and rvidx from 36.321 section 5.3.1 // Note: definition of k and rvidx from 36.321 section 5.3.1
rvidx = (((3*k)>>1) + (k&1))&3; rvidx = (((3 * k) >> 1) + (k & 1)) & 3;
if ((sf_mod_period < si_WindowLength_BR_r13) && if ((sf_mod_period < si_WindowLength_BR_r13)
((frameP&(((1<<si_RepetitionPattern_r13)-1)))==0)) { // this SIB is to be scheduled && ((frameP & (((1 << si_RepetitionPattern_r13) - 1))) == 0)) { // this SIB is to be scheduled
bcch_sdu_length = mac_rrc_data_req(module_idP, bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SI_BR + i, 1, &cc->BCCH_BR_pdu[i + 1].payload[0], 1, module_idP, 0); // not used in this case
CC_id,
frameP,
BCCH_SI_BR+i,1,
&cc->BCCH_BR_pdu[i+1].payload[0],
1,
module_idP,
0); // not used in this case
AssertFatal(bcch_sdu_length>0,"RRC returned 0 bytes for SI-BR %d\n",i); AssertFatal(bcch_sdu_length > 0,
"RRC returned 0 bytes for SI-BR %d\n", i);
if (bcch_sdu_length > 0) { if (bcch_sdu_length > 0) {
AssertFatal(bcch_sdu_length <= (si_TBS_r13>>3), AssertFatal(bcch_sdu_length <= (si_TBS_r13 >> 3),
"RRC provided bcch with length %d > %d (si_TBS_r13 %d)\n", "RRC provided bcch with length %d > %d (si_TBS_r13 %d)\n",
bcch_sdu_length,(int)(si_TBS_r13>>3),(int)schedulingInfoList_BR_r13->list.array[i]->si_TBS_r13); bcch_sdu_length,
(int) (si_TBS_r13 >> 3),
(int) schedulingInfoList_BR_r13->
list.array[i]->si_TBS_r13);
// allocate all 6 PRBs in narrowband for SIB1_BR // allocate all 6 PRBs in narrowband for SIB1_BR
// check that SIB1 didn't take this narrowband // check that SIB1 didn't take this narrowband
if (vrb_map[first_rb] > 0) continue; if (vrb_map[first_rb] > 0)
continue;
first_rb = narrowband_to_first_rb(cc,si_Narrowband_r13-1); first_rb =
narrowband_to_first_rb(cc,
si_Narrowband_r13 - 1);
vrb_map[first_rb] = 1; vrb_map[first_rb] = 1;
vrb_map[first_rb+1] = 1; vrb_map[first_rb + 1] = 1;
vrb_map[first_rb+2] = 1; vrb_map[first_rb + 2] = 1;
vrb_map[first_rb+4] = 1; vrb_map[first_rb + 4] = 1;
vrb_map[first_rb+5] = 1; vrb_map[first_rb + 5] = 1;
if ((frameP&1023) < 200) LOG_D(MAC,"[eNB %d] Frame %d Subframe %d: SI_BR->DLSCH CC_id %d, Narrowband %d rvidx %d (sf_mod_period %d : si_WindowLength_BR_r13 %d : si_RepetitionPattern_r13 %d) bcch_sdu_length %d\n", if ((frameP & 1023) < 200)
module_idP,frameP,subframeP,CC_id,(int)si_Narrowband_r13-1,rvidx, LOG_D(MAC,
sf_mod_period,(int)si_WindowLength_BR_r13,(int)si_RepetitionPattern_r13, "[eNB %d] Frame %d Subframe %d: SI_BR->DLSCH CC_id %d, Narrowband %d rvidx %d (sf_mod_period %d : si_WindowLength_BR_r13 %d : si_RepetitionPattern_r13 %d) bcch_sdu_length %d\n",
module_idP, frameP, subframeP, CC_id,
(int) si_Narrowband_r13 - 1, rvidx,
sf_mod_period,
(int) si_WindowLength_BR_r13,
(int) si_RepetitionPattern_r13,
bcch_sdu_length); bcch_sdu_length);
dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; dl_config_pdu =
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); &dl_req->dl_config_pdu_list[dl_req->
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; number_pdu];
dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu)); memset((void *) dl_config_pdu, 0,
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = si_TBS_r13>>3; sizeof(nfapi_dl_config_request_pdu_t));
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; dl_config_pdu->pdu_type =
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
dl_config_pdu->pdu_size =
(uint8_t) (2 +
sizeof(nfapi_dl_config_dlsch_pdu));
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length =
si_TBS_r13 >> 3;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index =
eNB->pdu_index[CC_id];
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti =
0xFFFF;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL,first_rb,6); dl_config_pdu->dlsch_pdu.
dlsch_pdu_rel8.resource_block_coding =
getRIV(N_RB_DL, first_rb, 6);
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = rvidx; dl_config_pdu->dlsch_pdu.
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block dlsch_pdu_rel8.redundancy_version = rvidx;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB==1 ) ? 0 : 1; dl_config_pdu->dlsch_pdu.
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; dlsch_pdu_rel8.transport_block_to_codeword_swap_flag
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; = 0;
dl_config_pdu->dlsch_pdu.
dlsch_pdu_rel8.transmission_scheme =
(cc->p_eNB == 1) ? 0 : 1;
dl_config_pdu->dlsch_pdu.
dlsch_pdu_rel8.number_of_layers = 1;
dl_config_pdu->dlsch_pdu.
dlsch_pdu_rel8.number_of_subbands = 1;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; dl_config_pdu->dlsch_pdu.
dlsch_pdu_rel8.ue_category_capacity = 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; dl_config_pdu->dlsch_pdu.
dlsch_pdu_rel8.delta_power_offset_index = 0;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB==1 ) ? 1 : 2; dl_config_pdu->dlsch_pdu.
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; dlsch_pdu_rel8.transmission_mode =
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; (cc->p_eNB == 1) ? 1 : 2;
dl_config_pdu->dlsch_pdu.
dlsch_pdu_rel8.num_bf_prb_per_subband = 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.
num_bf_vector = 1;
// Rel10 fields (for PDSCH starting symbol) // Rel10 fields (for PDSCH starting symbol)
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.
pdsch_start =
cc[CC_id].
sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
// Rel13 fields // Rel13 fields
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 1; // CEModeA UE dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 1; // CEModeA UE
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 1; // SI-BR dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 1; // SI-BR
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = absSF - sf_mod_period; dl_config_pdu->dlsch_pdu.
dlsch_pdu_rel13.initial_transmission_sf_io =
absSF - sf_mod_period;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ;
dl_req->number_pdu++; dl_req->number_pdu++;
// Program TX Request // Program TX Request
TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; TX_req =
&eNB->TX_req[CC_id].
tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].
tx_request_body.number_of_pdus];
TX_req->pdu_length = bcch_sdu_length; TX_req->pdu_length = bcch_sdu_length;
TX_req->pdu_index = eNB->pdu_index[CC_id]++; TX_req->pdu_index = eNB->pdu_index[CC_id]++;
TX_req->num_segments = 1; TX_req->num_segments = 1;
TX_req->segments[0].segment_length = bcch_sdu_length; TX_req->segments[0].segment_length =
TX_req->segments[0].segment_data = cc->BCCH_BR_pdu[i+1].payload; bcch_sdu_length;
eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; TX_req->segments[0].segment_data =
cc->BCCH_BR_pdu[i + 1].payload;
eNB->TX_req[CC_id].tx_request_body.
number_of_pdus++;
if (opt_enabled == 1) { if (opt_enabled == 1) {
trace_pdu(1, trace_pdu(1,
&cc->BCCH_BR_pdu[i+1].payload[0], &cc->BCCH_BR_pdu[i + 1].payload[0],
bcch_sdu_length, bcch_sdu_length,
0xffff, 0xffff,
4, 4,
0xffff, 0xffff, eNB->frame, eNB->subframe, 0,
eNB->frame,
eNB->subframe,
0,
0); 0);
LOG_D(OPT,"[eNB %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", LOG_D(OPT,
module_idP, frameP, CC_id, 0xffff, bcch_sdu_length); "[eNB %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n",
} module_idP, frameP, CC_id, 0xffff,
if (cc->tdd_Config!=NULL) { //TDD
LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH-BR %d->DLSCH (TDD) for CC_id %d SI-BR %d bytes\n",
frameP,i,
CC_id,
bcch_sdu_length); bcch_sdu_length);
}
if (cc->tdd_Config != NULL) { //TDD
LOG_D(MAC,
"[eNB] Frame %d : Scheduling BCCH-BR %d->DLSCH (TDD) for CC_id %d SI-BR %d bytes\n",
frameP, i, CC_id, bcch_sdu_length);
} else { } else {
LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH-BR %d->DLSCH (FDD) for CC_id %d SI-BR %d bytes\n", LOG_D(MAC,
frameP,i, "[eNB] Frame %d : Scheduling BCCH-BR %d->DLSCH (FDD) for CC_id %d SI-BR %d bytes\n",
CC_id, frameP, i, CC_id, bcch_sdu_length);
bcch_sdu_length);
} }
} }
} // scheduling in current frame/subframe } // scheduling in current frame/subframe
...@@ -487,9 +573,9 @@ schedule_SI_BR( ...@@ -487,9 +573,9 @@ schedule_SI_BR(
} }
#endif #endif
void schedule_mib(module_id_t module_idP, void
frame_t frameP, schedule_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
sub_frame_t subframeP) { {
eNB_MAC_INST *eNB = RC.mac[module_idP]; eNB_MAC_INST *eNB = RC.mac[module_idP];
COMMON_channels_t *cc; COMMON_channels_t *cc;
...@@ -499,47 +585,51 @@ void schedule_mib(module_id_t module_idP, ...@@ -499,47 +585,51 @@ void schedule_mib(module_id_t module_idP,
int CC_id; int CC_id;
nfapi_dl_config_request_body_t *dl_req; nfapi_dl_config_request_body_t *dl_req;
AssertFatal(subframeP==0,"Subframe must be 0\n"); AssertFatal(subframeP == 0, "Subframe must be 0\n");
AssertFatal((frameP&3)==0,"Frame must be a multiple of 4\n"); AssertFatal((frameP & 3) == 0, "Frame must be a multiple of 4\n");
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
dl_req = &eNB->DL_req[CC_id].dl_config_request_body; dl_req = &eNB->DL_req[CC_id].dl_config_request_body;
cc = &eNB->common_channels[CC_id]; cc = &eNB->common_channels[CC_id];
mib_sdu_length = mac_rrc_data_req(module_idP, mib_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MIBCH, 1, &cc->MIB_pdu.payload[0], 1, module_idP, 0); // not used in this case
CC_id,
frameP,
MIBCH,1,
&cc->MIB_pdu.payload[0],
1,
module_idP,
0); // not used in this case
LOG_D(MAC,"Frame %d, subframe %d: BCH PDU length %d\n", LOG_D(MAC, "Frame %d, subframe %d: BCH PDU length %d\n",
frameP,subframeP,mib_sdu_length); frameP, subframeP, mib_sdu_length);
if (mib_sdu_length > 0) { if (mib_sdu_length > 0) {
LOG_D(MAC,"Frame %d, subframe %d: Adding BCH PDU in position %d (length %d)\n", LOG_D(MAC,
frameP,subframeP,dl_req->number_pdu,mib_sdu_length); "Frame %d, subframe %d: Adding BCH PDU in position %d (length %d)\n",
frameP, subframeP, dl_req->number_pdu, mib_sdu_length);
if ((frameP&1023) < 40) LOG_D(MAC,"[eNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes (cc->mib->message.schedulingInfoSIB1_BR_r13 %d)\n",module_idP,frameP,CC_id,mib_sdu_length,(int)cc->mib->message.schedulingInfoSIB1_BR_r13);
if ((frameP & 1023) < 40)
dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; LOG_D(MAC,
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); "[eNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes (cc->mib->message.schedulingInfoSIB1_BR_r13 %d)\n",
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_BCH_PDU_TYPE, module_idP, frameP, CC_id, mib_sdu_length,
dl_config_pdu->pdu_size = 2+sizeof(nfapi_dl_config_bch_pdu); (int) cc->mib->message.schedulingInfoSIB1_BR_r13);
dl_config_pdu =
&dl_req->dl_config_pdu_list[dl_req->number_pdu];
memset((void *) dl_config_pdu, 0,
sizeof(nfapi_dl_config_request_pdu_t));
dl_config_pdu->pdu_type =
NFAPI_DL_CONFIG_BCH_PDU_TYPE, dl_config_pdu->pdu_size =
2 + sizeof(nfapi_dl_config_bch_pdu);
dl_config_pdu->bch_pdu.bch_pdu_rel8.length = mib_sdu_length; dl_config_pdu->bch_pdu.bch_pdu_rel8.length = mib_sdu_length;
dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index =
eNB->pdu_index[CC_id];
dl_config_pdu->bch_pdu.bch_pdu_rel8.transmission_power = 6000; dl_config_pdu->bch_pdu.bch_pdu_rel8.transmission_power = 6000;
dl_req->number_pdu++; dl_req->number_pdu++;
LOG_D(MAC,"eNB->DL_req[0].number_pdu %d (%p)\n", LOG_D(MAC, "eNB->DL_req[0].number_pdu %d (%p)\n",
dl_req->number_pdu,&dl_req->number_pdu); dl_req->number_pdu, &dl_req->number_pdu);
// DL request // DL request
TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; TX_req =
&eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req
[CC_id].tx_request_body.number_of_pdus];
TX_req->pdu_length = 3; TX_req->pdu_length = 3;
TX_req->pdu_index = eNB->pdu_index[CC_id]++; TX_req->pdu_index = eNB->pdu_index[CC_id]++;
TX_req->num_segments = 1; TX_req->num_segments = 1;
...@@ -553,11 +643,7 @@ void schedule_mib(module_id_t module_idP, ...@@ -553,11 +643,7 @@ void schedule_mib(module_id_t module_idP,
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void
schedule_SI( schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
module_id_t module_idP,
frame_t frameP,
sub_frame_t subframeP)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
...@@ -578,25 +664,20 @@ schedule_SI( ...@@ -578,25 +664,20 @@ schedule_SI(
// Only schedule LTE System Information in subframe 5 // Only schedule LTE System Information in subframe 5
if (subframeP == 5) { if (subframeP == 5) {
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
cc = &eNB->common_channels[CC_id]; cc = &eNB->common_channels[CC_id];
vrb_map = (void*)&cc->vrb_map; vrb_map = (void *) &cc->vrb_map;
N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth);
dl_req = &eNB->DL_req[CC_id].dl_config_request_body; dl_req = &eNB->DL_req[CC_id].dl_config_request_body;
bcch_sdu_length = mac_rrc_data_req(module_idP, bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH, 1, &cc->BCCH_pdu.payload[0], 1, module_idP, 0); // not used in this case
CC_id,
frameP,
BCCH,1,
&cc->BCCH_pdu.payload[0],
1,
module_idP,
0); // not used in this case
if (bcch_sdu_length > 0) { if (bcch_sdu_length > 0) {
LOG_D(MAC,"[eNB %d] Frame %d : BCCH->DLSCH CC_id %d, Received %d bytes \n",module_idP,frameP,CC_id,bcch_sdu_length); LOG_D(MAC,
"[eNB %d] Frame %d : BCCH->DLSCH CC_id %d, Received %d bytes \n",
module_idP, frameP, CC_id, bcch_sdu_length);
// Allocate 4 PRBs in a random location // Allocate 4 PRBs in a random location
/* /*
...@@ -628,49 +709,58 @@ schedule_SI( ...@@ -628,49 +709,58 @@ schedule_SI(
} }
vrb_map[first_rb] = 1; vrb_map[first_rb] = 1;
vrb_map[first_rb+1] = 1; vrb_map[first_rb + 1] = 1;
vrb_map[first_rb+2] = 1; vrb_map[first_rb + 2] = 1;
vrb_map[first_rb+3] = 1; vrb_map[first_rb + 3] = 1;
// Get MCS for length of SI, 3 PRBs // Get MCS for length of SI, 3 PRBs
if (bcch_sdu_length <= 7) { if (bcch_sdu_length <= 7) {
mcs=0; mcs = 0;
} else if (bcch_sdu_length <= 11) { } else if (bcch_sdu_length <= 11) {
mcs=1; mcs = 1;
} else if (bcch_sdu_length <= 18) { } else if (bcch_sdu_length <= 18) {
mcs=2; mcs = 2;
} else if (bcch_sdu_length <= 22) { } else if (bcch_sdu_length <= 22) {
mcs=3; mcs = 3;
} else if (bcch_sdu_length <= 26) { } else if (bcch_sdu_length <= 26) {
mcs=4; mcs = 4;
} else if (bcch_sdu_length <= 28) { } else if (bcch_sdu_length <= 28) {
mcs=5; mcs = 5;
} else if (bcch_sdu_length <= 32) { } else if (bcch_sdu_length <= 32) {
mcs=6; mcs = 6;
} else if (bcch_sdu_length <= 41) { } else if (bcch_sdu_length <= 41) {
mcs=7; mcs = 7;
} else if (bcch_sdu_length <= 49) { } else if (bcch_sdu_length <= 49) {
mcs=8; mcs = 8;
} }
dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; dl_config_pdu =
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); &dl_req->dl_config_pdu_list[dl_req->number_pdu];
memset((void *) dl_config_pdu, 0,
sizeof(nfapi_dl_config_request_pdu_t));
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu)); dl_config_pdu->pdu_size =
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu));
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format =
NFAPI_DL_DCI_FORMAT_1A;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.
aggregation_level = 4;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFF; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFF;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // S-RNTI : see Table 4-10 from SCF082 - nFAPI specifications dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // S-RNTI : see Table 4-10 from SCF082 - nFAPI specifications
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 0; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.
new_data_indicator_1 = 0;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.
redundancy_version_1 = 0;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL,first_rb,4); dl_config_pdu->dci_dl_pdu.
dci_dl_pdu_rel8.resource_block_coding =
getRIV(N_RB_DL, first_rb, 4);
// Rel10 fields // Rel10 fields
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3;
...@@ -679,52 +769,79 @@ schedule_SI( ...@@ -679,52 +769,79 @@ schedule_SI(
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SF dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SF
if (!CCE_allocation_infeasible(module_idP,CC_id,0,subframeP, if (!CCE_allocation_infeasible
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,SI_RNTI)) { (module_idP, CC_id, 0, subframeP,
LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for S_RNTI\n", dl_config_pdu->dci_dl_pdu.
frameP,subframeP); dci_dl_pdu_rel8.aggregation_level, SI_RNTI)) {
LOG_D(MAC,
"Frame %d: Subframe %d : Adding common DCI for S_RNTI\n",
frameP, subframeP);
dl_req->number_dci++; dl_req->number_dci++;
dl_req->number_pdu++; dl_req->number_pdu++;
dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; dl_config_pdu =
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); &dl_req->dl_config_pdu_list[dl_req->number_pdu];
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; memset((void *) dl_config_pdu, 0,
dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu)); sizeof(nfapi_dl_config_request_pdu_t));
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; dl_config_pdu->pdu_type =
NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
dl_config_pdu->pdu_size =
(uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu));
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index =
eNB->pdu_index[CC_id];
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL,first_rb,4); dl_config_pdu->dlsch_pdu.
dlsch_pdu_rel8.resource_block_coding =
getRIV(N_RB_DL, first_rb, 4);
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block redundancy_version = 0;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB==1 ) ? 0 : 1; dl_config_pdu->dlsch_pdu.
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; dlsch_pdu_rel8.transport_block_to_codeword_swap_flag
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; = 0;
dl_config_pdu->dlsch_pdu.
dlsch_pdu_rel8.transmission_scheme =
(cc->p_eNB == 1) ? 0 : 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.
number_of_layers = 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.
number_of_subbands = 1;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; dl_config_pdu->dlsch_pdu.
dlsch_pdu_rel8.ue_category_capacity = 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; dl_config_pdu->dlsch_pdu.
dlsch_pdu_rel8.delta_power_offset_index = 0;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB==1 ) ? 1 : 2; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; transmission_mode = (cc->p_eNB == 1) ? 1 : 2;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; dl_config_pdu->dlsch_pdu.
dlsch_pdu_rel8.num_bf_prb_per_subband = 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector =
1;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ;
dl_req->number_pdu++; dl_req->number_pdu++;
// Program TX Request // Program TX Request
TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; TX_req =
&eNB->TX_req[CC_id].
tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].
tx_request_body.number_of_pdus];
TX_req->pdu_length = bcch_sdu_length; TX_req->pdu_length = bcch_sdu_length;
TX_req->pdu_index = eNB->pdu_index[CC_id]++; TX_req->pdu_index = eNB->pdu_index[CC_id]++;
TX_req->num_segments = 1; TX_req->num_segments = 1;
TX_req->segments[0].segment_length = bcch_sdu_length; TX_req->segments[0].segment_length = bcch_sdu_length;
TX_req->segments[0].segment_data = cc->BCCH_pdu.payload; TX_req->segments[0].segment_data =
cc->BCCH_pdu.payload;
eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; eNB->TX_req[CC_id].tx_request_body.number_of_pdus++;
} } else {
else { LOG_E(MAC,
LOG_E(MAC,"[eNB %d] CCid %d Frame %d, subframe %d : Cannot add DCI 1A for SI\n",module_idP, CC_id,frameP,subframeP); "[eNB %d] CCid %d Frame %d, subframe %d : Cannot add DCI 1A for SI\n",
module_idP, CC_id, frameP, subframeP);
} }
if (opt_enabled == 1) { if (opt_enabled == 1) {
...@@ -732,47 +849,38 @@ schedule_SI( ...@@ -732,47 +849,38 @@ schedule_SI(
&cc->BCCH_pdu.payload[0], &cc->BCCH_pdu.payload[0],
bcch_sdu_length, bcch_sdu_length,
0xffff, 0xffff,
4, 4, 0xffff, eNB->frame, eNB->subframe, 0, 0);
0xffff, LOG_D(OPT,
eNB->frame, "[eNB %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n",
eNB->subframe, module_idP, frameP, CC_id, 0xffff,
0, bcch_sdu_length);
0);
LOG_D(OPT,"[eNB %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n",
module_idP, frameP, CC_id, 0xffff, bcch_sdu_length);
} }
if (cc->tdd_Config!=NULL) { //TDD if (cc->tdd_Config != NULL) { //TDD
LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH->DLSCH (TDD) for CC_id %d SI %d bytes (mcs %d, rb 3)\n", LOG_D(MAC,
frameP, "[eNB] Frame %d : Scheduling BCCH->DLSCH (TDD) for CC_id %d SI %d bytes (mcs %d, rb 3)\n",
CC_id, frameP, CC_id, bcch_sdu_length, mcs);
bcch_sdu_length,
mcs);
} else { } else {
LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH->DLSCH (FDD) for CC_id %d SI %d bytes (mcs %d, rb 3)\n", LOG_D(MAC,
frameP, "[eNB] Frame %d : Scheduling BCCH->DLSCH (FDD) for CC_id %d SI %d bytes (mcs %d, rb 3)\n",
CC_id, frameP, CC_id, bcch_sdu_length, mcs);
bcch_sdu_length,
mcs);
} }
eNB->eNB_stats[CC_id].total_num_bcch_pdu+=1; eNB->eNB_stats[CC_id].total_num_bcch_pdu += 1;
eNB->eNB_stats[CC_id].bcch_buffer=bcch_sdu_length; eNB->eNB_stats[CC_id].bcch_buffer = bcch_sdu_length;
eNB->eNB_stats[CC_id].total_bcch_buffer+=bcch_sdu_length; eNB->eNB_stats[CC_id].total_bcch_buffer += bcch_sdu_length;
eNB->eNB_stats[CC_id].bcch_mcs=mcs; eNB->eNB_stats[CC_id].bcch_mcs = mcs;
} else { } else {
//LOG_D(MAC,"[eNB %d] Frame %d : BCCH not active \n",Mod_id,frame); //LOG_D(MAC,"[eNB %d] Frame %d : BCCH not active \n",Mod_id,frame);
} }
} }
} }
#ifdef Rel14 #ifdef Rel14
schedule_SIB1_BR(module_idP,frameP,subframeP); schedule_SIB1_BR(module_idP, frameP, subframeP);
schedule_SI_BR(module_idP,frameP,subframeP); schedule_SI_BR(module_idP, frameP, subframeP);
#endif #endif
stop_meas(&eNB->schedule_si); stop_meas(&eNB->schedule_si);
return; return;
} }
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
#include "SIMULATION/TOOLS/defs.h" // for taus #include "SIMULATION/TOOLS/defs.h" // for taus
#if defined(ENABLE_ITTI) #if defined(ENABLE_ITTI)
# include "intertask_interface.h" #include "intertask_interface.h"
#endif #endif
#include "T.h" #include "T.h"
...@@ -66,17 +66,14 @@ extern RAN_CONTEXT_t RC; ...@@ -66,17 +66,14 @@ extern RAN_CONTEXT_t RC;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void
add_ue_dlsch_info( add_ue_dlsch_info(module_id_t module_idP,
module_id_t module_idP,
int CC_id, int CC_id,
int UE_id, int UE_id, sub_frame_t subframeP, UE_DLSCH_STATUS status)
sub_frame_t subframeP,
UE_DLSCH_STATUS status
)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
eNB_dlsch_info[module_idP][CC_id][UE_id].rnti = UE_RNTI(module_idP,UE_id); eNB_dlsch_info[module_idP][CC_id][UE_id].rnti =
UE_RNTI(module_idP, UE_id);
// eNB_dlsch_info[module_idP][CC_id][ue_mod_idP].weight = weight; // eNB_dlsch_info[module_idP][CC_id][ue_mod_idP].weight = weight;
eNB_dlsch_info[module_idP][CC_id][UE_id].subframe = subframeP; eNB_dlsch_info[module_idP][CC_id][UE_id].subframe = subframeP;
eNB_dlsch_info[module_idP][CC_id][UE_id].status = status; eNB_dlsch_info[module_idP][CC_id][UE_id].status = status;
...@@ -87,37 +84,38 @@ add_ue_dlsch_info( ...@@ -87,37 +84,38 @@ add_ue_dlsch_info(
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int int
schedule_next_dlue( schedule_next_dlue(module_id_t module_idP, int CC_id,
module_id_t module_idP, sub_frame_t subframeP)
int CC_id,
sub_frame_t subframeP
)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
int next_ue; int next_ue;
UE_list_t *UE_list=&RC.mac[module_idP]->UE_list; UE_list_t *UE_list = &RC.mac[module_idP]->UE_list;
for (next_ue=UE_list->head; next_ue>=0; next_ue=UE_list->next[next_ue] ) { for (next_ue = UE_list->head; next_ue >= 0;
if (eNB_dlsch_info[module_idP][CC_id][next_ue].status == S_DL_WAITING) { next_ue = UE_list->next[next_ue]) {
if (eNB_dlsch_info[module_idP][CC_id][next_ue].status ==
S_DL_WAITING) {
return next_ue; return next_ue;
} }
} }
for (next_ue=UE_list->head; next_ue>=0; next_ue=UE_list->next[next_ue] ) { for (next_ue = UE_list->head; next_ue >= 0;
if (eNB_dlsch_info[module_idP][CC_id][next_ue].status == S_DL_BUFFERED) { next_ue = UE_list->next[next_ue]) {
eNB_dlsch_info[module_idP][CC_id][next_ue].status = S_DL_WAITING; if (eNB_dlsch_info[module_idP][CC_id][next_ue].status ==
S_DL_BUFFERED) {
eNB_dlsch_info[module_idP][CC_id][next_ue].status =
S_DL_WAITING;
} }
} }
return(-1);//next_ue; return (-1); //next_ue;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
unsigned char unsigned char
generate_dlsch_header( generate_dlsch_header(unsigned char *mac_header,
unsigned char* mac_header,
unsigned char num_sdus, unsigned char num_sdus,
unsigned short *sdu_lengths, unsigned short *sdu_lengths,
unsigned char *sdu_lcids, unsigned char *sdu_lcids,
...@@ -125,14 +123,14 @@ generate_dlsch_header( ...@@ -125,14 +123,14 @@ generate_dlsch_header(
unsigned short timing_advance_cmd, unsigned short timing_advance_cmd,
unsigned char *ue_cont_res_id, unsigned char *ue_cont_res_id,
unsigned char short_padding, unsigned char short_padding,
unsigned short post_padding unsigned short post_padding)
)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
SCH_SUBHEADER_FIXED *mac_header_ptr = (SCH_SUBHEADER_FIXED *)mac_header; SCH_SUBHEADER_FIXED *mac_header_ptr =
uint8_t first_element=0,last_size=0,i; (SCH_SUBHEADER_FIXED *) mac_header;
uint8_t mac_header_control_elements[16],*ce_ptr; uint8_t first_element = 0, last_size = 0, i;
uint8_t mac_header_control_elements[16], *ce_ptr;
ce_ptr = &mac_header_control_elements[0]; ce_ptr = &mac_header_control_elements[0];
...@@ -142,8 +140,8 @@ generate_dlsch_header( ...@@ -142,8 +140,8 @@ generate_dlsch_header(
mac_header_ptr->R = 0; mac_header_ptr->R = 0;
mac_header_ptr->E = 0; mac_header_ptr->E = 0;
mac_header_ptr->LCID = SHORT_PADDING; mac_header_ptr->LCID = SHORT_PADDING;
first_element=1; first_element = 1;
last_size=1; last_size = 1;
} }
if (short_padding == 2) { if (short_padding == 2) {
...@@ -152,46 +150,48 @@ generate_dlsch_header( ...@@ -152,46 +150,48 @@ generate_dlsch_header(
mac_header_ptr->R = 0; mac_header_ptr->R = 0;
mac_header_ptr->E = 0; mac_header_ptr->E = 0;
mac_header_ptr->LCID = SHORT_PADDING; mac_header_ptr->LCID = SHORT_PADDING;
last_size=1; last_size = 1;
} }
if (drx_cmd != 255) { if (drx_cmd != 255) {
if (first_element>0) { if (first_element > 0) {
mac_header_ptr->E = 1; mac_header_ptr->E = 1;
mac_header_ptr++; mac_header_ptr++;
} else { } else {
first_element=1; first_element = 1;
} }
mac_header_ptr->R = 0; mac_header_ptr->R = 0;
mac_header_ptr->E = 0; mac_header_ptr->E = 0;
mac_header_ptr->LCID = DRX_CMD; mac_header_ptr->LCID = DRX_CMD;
last_size=1; last_size = 1;
} }
if (timing_advance_cmd != 31) { if (timing_advance_cmd != 31) {
if (first_element>0) { if (first_element > 0) {
mac_header_ptr->E = 1; mac_header_ptr->E = 1;
mac_header_ptr++; mac_header_ptr++;
} else { } else {
first_element=1; first_element = 1;
} }
mac_header_ptr->R = 0; mac_header_ptr->R = 0;
mac_header_ptr->E = 0; mac_header_ptr->E = 0;
mac_header_ptr->LCID = TIMING_ADV_CMD; mac_header_ptr->LCID = TIMING_ADV_CMD;
last_size=1; last_size = 1;
// msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); // msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);
((TIMING_ADVANCE_CMD *)ce_ptr)->R=0; ((TIMING_ADVANCE_CMD *) ce_ptr)->R = 0;
AssertFatal(timing_advance_cmd < 64,"timing_advance_cmd %d > 63\n",timing_advance_cmd); AssertFatal(timing_advance_cmd < 64,
((TIMING_ADVANCE_CMD *)ce_ptr)->TA=timing_advance_cmd;//(timing_advance_cmd+31)&0x3f; "timing_advance_cmd %d > 63\n", timing_advance_cmd);
LOG_D(MAC,"timing advance =%d (%d)\n",timing_advance_cmd,((TIMING_ADVANCE_CMD *)ce_ptr)->TA); ((TIMING_ADVANCE_CMD *) ce_ptr)->TA = timing_advance_cmd; //(timing_advance_cmd+31)&0x3f;
ce_ptr+=sizeof(TIMING_ADVANCE_CMD); LOG_D(MAC, "timing advance =%d (%d)\n", timing_advance_cmd,
((TIMING_ADVANCE_CMD *) ce_ptr)->TA);
ce_ptr += sizeof(TIMING_ADVANCE_CMD);
//msg("offset %d\n",ce_ptr-mac_header_control_elements); //msg("offset %d\n",ce_ptr-mac_header_control_elements);
} }
if (ue_cont_res_id) { if (ue_cont_res_id) {
if (first_element>0) { if (first_element > 0) {
mac_header_ptr->E = 1; mac_header_ptr->E = 1;
/* /*
printf("[eNB][MAC] last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, printf("[eNB][MAC] last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr,
...@@ -201,66 +201,67 @@ generate_dlsch_header( ...@@ -201,66 +201,67 @@ generate_dlsch_header(
*/ */
mac_header_ptr++; mac_header_ptr++;
} else { } else {
first_element=1; first_element = 1;
} }
mac_header_ptr->R = 0; mac_header_ptr->R = 0;
mac_header_ptr->E = 0; mac_header_ptr->E = 0;
mac_header_ptr->LCID = UE_CONT_RES; mac_header_ptr->LCID = UE_CONT_RES;
last_size=1; last_size = 1;
LOG_T(MAC,"[eNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n", LOG_T(MAC,
ue_cont_res_id[0], "[eNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n",
ue_cont_res_id[1], ue_cont_res_id[0], ue_cont_res_id[1], ue_cont_res_id[2],
ue_cont_res_id[2], ue_cont_res_id[3], ue_cont_res_id[4], ue_cont_res_id[5]);
ue_cont_res_id[3],
ue_cont_res_id[4], memcpy(ce_ptr, ue_cont_res_id, 6);
ue_cont_res_id[5]); ce_ptr += 6;
memcpy(ce_ptr,ue_cont_res_id,6);
ce_ptr+=6;
// msg("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements); // msg("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements);
} }
//msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);
for (i=0; i<num_sdus; i++) { for (i = 0; i < num_sdus; i++) {
LOG_T(MAC,"[eNB] Generate DLSCH header num sdu %d len sdu %d\n",num_sdus, sdu_lengths[i]); LOG_T(MAC, "[eNB] Generate DLSCH header num sdu %d len sdu %d\n",
num_sdus, sdu_lengths[i]);
if (first_element>0) { if (first_element > 0) {
mac_header_ptr->E = 1; mac_header_ptr->E = 1;
/*msg("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, /*msg("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr,
((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R,
((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E,
((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID);
*/ */
mac_header_ptr+=last_size; mac_header_ptr += last_size;
//msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);
} else { } else {
first_element=1; first_element = 1;
} }
if (sdu_lengths[i] < 128) { if (sdu_lengths[i] < 128) {
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->R = 0; ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->R = 0;
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->E = 0; ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->E = 0;
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F = 0; ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F = 0;
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID = sdu_lcids[i]; ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->LCID = sdu_lcids[i];
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L = (unsigned char)sdu_lengths[i]; ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L =
last_size=2; (unsigned char) sdu_lengths[i];
last_size = 2;
} else { } else {
((SCH_SUBHEADER_LONG *)mac_header_ptr)->R = 0; ((SCH_SUBHEADER_LONG *) mac_header_ptr)->R = 0;
((SCH_SUBHEADER_LONG *)mac_header_ptr)->E = 0; ((SCH_SUBHEADER_LONG *) mac_header_ptr)->E = 0;
((SCH_SUBHEADER_LONG *)mac_header_ptr)->F = 1; ((SCH_SUBHEADER_LONG *) mac_header_ptr)->F = 1;
((SCH_SUBHEADER_LONG *)mac_header_ptr)->LCID = sdu_lcids[i]; ((SCH_SUBHEADER_LONG *) mac_header_ptr)->LCID = sdu_lcids[i];
((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB = ((unsigned short) sdu_lengths[i]>>8)&0x7f; ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB =
((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB = (unsigned short) sdu_lengths[i]&0xff; ((unsigned short) sdu_lengths[i] >> 8) & 0x7f;
((SCH_SUBHEADER_LONG *)mac_header_ptr)->padding = 0x00; ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB =
last_size=3; (unsigned short) sdu_lengths[i] & 0xff;
((SCH_SUBHEADER_LONG *) mac_header_ptr)->padding = 0x00;
last_size = 3;
#ifdef DEBUG_HEADER_PARSING #ifdef DEBUG_HEADER_PARSING
LOG_D(MAC,"[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n", LOG_D(MAC,
"[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n",
sdu_lengths[i], sdu_lengths[i],
((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB, ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB,
((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB); ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB);
#endif #endif
} }
} }
...@@ -282,9 +283,9 @@ generate_dlsch_header( ...@@ -282,9 +283,9 @@ generate_dlsch_header(
printf("F = 1, sdu len (L field) %d\n",(((SCH_SUBHEADER_LONG*)mac_header_ptr)->L)); printf("F = 1, sdu len (L field) %d\n",(((SCH_SUBHEADER_LONG*)mac_header_ptr)->L));
} }
*/ */
if (post_padding>0) {// we have lots of padding at the end of the packet if (post_padding > 0) { // we have lots of padding at the end of the packet
mac_header_ptr->E = 1; mac_header_ptr->E = 1;
mac_header_ptr+=last_size; mac_header_ptr += last_size;
// add a padding element // add a padding element
mac_header_ptr->R = 0; mac_header_ptr->R = 0;
mac_header_ptr->E = 0; mac_header_ptr->E = 0;
...@@ -297,27 +298,23 @@ generate_dlsch_header( ...@@ -297,27 +298,23 @@ generate_dlsch_header(
//msg("After subheaders %d\n",(uint8_t*)mac_header_ptr - mac_header); //msg("After subheaders %d\n",(uint8_t*)mac_header_ptr - mac_header);
if ((ce_ptr-mac_header_control_elements) > 0) { if ((ce_ptr - mac_header_control_elements) > 0) {
// printf("Copying %d bytes for control elements\n",ce_ptr-mac_header_control_elements); // printf("Copying %d bytes for control elements\n",ce_ptr-mac_header_control_elements);
memcpy((void*)mac_header_ptr,mac_header_control_elements,ce_ptr-mac_header_control_elements); memcpy((void *) mac_header_ptr, mac_header_control_elements,
mac_header_ptr+=(unsigned char)(ce_ptr-mac_header_control_elements); ce_ptr - mac_header_control_elements);
mac_header_ptr +=
(unsigned char) (ce_ptr - mac_header_control_elements);
} }
//msg("After CEs %d\n",(uint8_t*)mac_header_ptr - mac_header); //msg("After CEs %d\n",(uint8_t*)mac_header_ptr - mac_header);
return((unsigned char*)mac_header_ptr - mac_header); return ((unsigned char *) mac_header_ptr - mac_header);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void
set_ul_DAI( set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP,
int module_idP, int subframeP)
int UE_idP,
int CC_idP,
int frameP,
int subframeP
)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
...@@ -326,8 +323,10 @@ set_ul_DAI( ...@@ -326,8 +323,10 @@ set_ul_DAI(
unsigned char DAI; unsigned char DAI;
COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; COMMON_channels_t *cc = &eNB->common_channels[CC_idP];
if (cc->tdd_Config != NULL) { //TDD if (cc->tdd_Config != NULL) { //TDD
DAI = (UE_list->UE_template[CC_idP][UE_idP].DAI-1)&3; DAI = (UE_list->UE_template[CC_idP][UE_idP].DAI - 1) & 3;
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframe %d: DAI %d for UE %d\n",module_idP,CC_idP,frameP,subframeP,DAI,UE_idP); LOG_D(MAC,
"[eNB %d] CC_id %d Frame %d, subframe %d: DAI %d for UE %d\n",
module_idP, CC_idP, frameP, subframeP, DAI, UE_idP);
// Save DAI for Format 0 DCI // Save DAI for Format 0 DCI
switch (cc->tdd_Config->subframeAssignment) { switch (cc->tdd_Config->subframeAssignment) {
...@@ -414,12 +413,8 @@ set_ul_DAI( ...@@ -414,12 +413,8 @@ set_ul_DAI(
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void
schedule_ue_spec( schedule_ue_spec(module_id_t module_idP,
module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag)
frame_t frameP,
sub_frame_t subframeP,
int* mbsfn_flag
)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
...@@ -428,12 +423,14 @@ schedule_ue_spec( ...@@ -428,12 +423,14 @@ schedule_ue_spec(
int UE_id; int UE_id;
unsigned char aggregation; unsigned char aggregation;
mac_rlc_status_resp_t rlc_status; mac_rlc_status_resp_t rlc_status;
unsigned char header_len_dcch=0, header_len_dcch_tmp=0; unsigned char header_len_dcch = 0, header_len_dcch_tmp = 0;
unsigned char header_len_dtch=0, header_len_dtch_tmp=0, header_len_dtch_last=0; unsigned char header_len_dtch = 0, header_len_dtch_tmp =
unsigned char ta_len=0; 0, header_len_dtch_last = 0;
unsigned char sdu_lcids[NB_RB_MAX],lcid,offset,num_sdus=0; unsigned char ta_len = 0;
uint16_t nb_rb,nb_rb_temp,nb_available_rb; unsigned char sdu_lcids[NB_RB_MAX], lcid, offset, num_sdus = 0;
uint16_t TBS,j,sdu_lengths[NB_RB_MAX],rnti,padding=0,post_padding=0; uint16_t nb_rb, nb_rb_temp, nb_available_rb;
uint16_t TBS, j, sdu_lengths[NB_RB_MAX], rnti, padding =
0, post_padding = 0;
unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES];
unsigned char round = 0; unsigned char round = 0;
unsigned char harq_pid = 0; unsigned char harq_pid = 0;
...@@ -443,10 +440,10 @@ schedule_ue_spec( ...@@ -443,10 +440,10 @@ schedule_ue_spec(
eNB_MAC_INST *eNB = RC.mac[module_idP]; eNB_MAC_INST *eNB = RC.mac[module_idP];
COMMON_channels_t *cc = eNB->common_channels; COMMON_channels_t *cc = eNB->common_channels;
UE_list_t *UE_list = &eNB->UE_list; UE_list_t *UE_list = &eNB->UE_list;
int continue_flag=0; int continue_flag = 0;
int32_t normalized_rx_power, target_rx_power; int32_t normalized_rx_power, target_rx_power;
int32_t tpc=1; int32_t tpc = 1;
static int32_t tpc_accumulated=0; static int32_t tpc_accumulated = 0;
UE_sched_ctrl *ue_sched_ctl; UE_sched_ctrl *ue_sched_ctl;
int mcs; int mcs;
int i; int i;
...@@ -460,13 +457,14 @@ schedule_ue_spec( ...@@ -460,13 +457,14 @@ schedule_ue_spec(
int ta_update; int ta_update;
#if 0 #if 0
if (UE_list->head==-1) { if (UE_list->head == -1) {
return; return;
} }
#endif #endif
start_meas(&eNB->schedule_dlsch); start_meas(&eNB->schedule_dlsch);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH,VCD_FUNCTION_IN); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN);
// for TDD: check that we have to act here, otherwise return // for TDD: check that we have to act here, otherwise return
...@@ -483,184 +481,199 @@ schedule_ue_spec( ...@@ -483,184 +481,199 @@ schedule_ue_spec(
return; return;
break; break;
case 3: case 3:
if ((tdd_sfa!=2) && (tdd_sfa!=5)) return; if ((tdd_sfa != 2) && (tdd_sfa != 5))
return;
break; break;
case 4: case 4:
if ((tdd_sfa!=1)&&(tdd_sfa!=2)&&(tdd_sfa!=4)&&(tdd_sfa!=5)) return; if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4)
&& (tdd_sfa != 5))
return;
break; break;
case 5: case 5:
break; break;
case 6: case 6:
case 7: case 7:
if ((tdd_sfa!=1)&&(tdd_sfa!=2)&&(tdd_sfa!=4)&&(tdd_sfa!=5)) return; if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4)
&& (tdd_sfa != 5))
return;
break; break;
case 8: case 8:
if ((tdd_sfa!=2)&&(tdd_sfa!=3)&&(tdd_sfa!=4)&&(tdd_sfa!=5)) return; if ((tdd_sfa != 2) && (tdd_sfa != 3) && (tdd_sfa != 4)
&& (tdd_sfa != 5))
return;
break; break;
case 9: case 9:
if ((tdd_sfa!=1)&&(tdd_sfa!=3)&&(tdd_sfa!=4)&&(tdd_sfa!=6)) return; if ((tdd_sfa != 1) && (tdd_sfa != 3) && (tdd_sfa != 4)
&& (tdd_sfa != 6))
return;
break; break;
} }
} }
//weight = get_ue_weight(module_idP,UE_id); //weight = get_ue_weight(module_idP,UE_id);
aggregation = 2; aggregation = 2;
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
N_RB_DL[CC_id] = to_prb(cc[CC_id].mib->message.dl_Bandwidth); N_RB_DL[CC_id] = to_prb(cc[CC_id].mib->message.dl_Bandwidth);
min_rb_unit[CC_id]=get_min_rb_unit(module_idP,CC_id); min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id);
// get number of PRBs less those used by common channels // get number of PRBs less those used by common channels
total_nb_available_rb[CC_id] = N_RB_DL[CC_id]; total_nb_available_rb[CC_id] = N_RB_DL[CC_id];
for (i=0;i<N_RB_DL[CC_id];i++) for (i = 0; i < N_RB_DL[CC_id]; i++)
if (cc[CC_id].vrb_map[i]!=0) if (cc[CC_id].vrb_map[i] != 0)
total_nb_available_rb[CC_id]--; total_nb_available_rb[CC_id]--;
N_RBG[CC_id] = to_rbg(cc[CC_id].mib->message.dl_Bandwidth); N_RBG[CC_id] = to_rbg(cc[CC_id].mib->message.dl_Bandwidth);
// store the global enb stats: // store the global enb stats:
eNB->eNB_stats[CC_id].num_dlactive_UEs = UE_list->num_UEs; eNB->eNB_stats[CC_id].num_dlactive_UEs = UE_list->num_UEs;
eNB->eNB_stats[CC_id].available_prbs = total_nb_available_rb[CC_id]; eNB->eNB_stats[CC_id].available_prbs =
eNB->eNB_stats[CC_id].total_available_prbs += total_nb_available_rb[CC_id]; total_nb_available_rb[CC_id];
eNB->eNB_stats[CC_id].total_available_prbs +=
total_nb_available_rb[CC_id];
eNB->eNB_stats[CC_id].dlsch_bytes_tx = 0; eNB->eNB_stats[CC_id].dlsch_bytes_tx = 0;
eNB->eNB_stats[CC_id].dlsch_pdus_tx = 0; eNB->eNB_stats[CC_id].dlsch_pdus_tx = 0;
} }
/// CALLING Pre_Processor for downlink scheduling (Returns estimation of RBs required by each UE and the allocation on sub-band) /// CALLING Pre_Processor for downlink scheduling (Returns estimation of RBs required by each UE and the allocation on sub-band)
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,VCD_FUNCTION_IN); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_IN);
start_meas(&eNB->schedule_dlsch_preprocessor); start_meas(&eNB->schedule_dlsch_preprocessor);
dlsch_scheduler_pre_processor(module_idP, dlsch_scheduler_pre_processor(module_idP,
frameP, frameP, subframeP, N_RBG, mbsfn_flag);
subframeP,
N_RBG,
mbsfn_flag);
stop_meas(&eNB->schedule_dlsch_preprocessor); stop_meas(&eNB->schedule_dlsch_preprocessor);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT);
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n",CC_id); LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n", CC_id);
dl_req = &eNB->DL_req[CC_id].dl_config_request_body; dl_req = &eNB->DL_req[CC_id].dl_config_request_body;
if (mbsfn_flag[CC_id]>0) if (mbsfn_flag[CC_id] > 0)
continue; continue;
for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { for (UE_id = UE_list->head; UE_id >= 0;
continue_flag=0; // reset the flag to allow allocation for the remaining UEs UE_id = UE_list->next[UE_id]) {
rnti = UE_RNTI(module_idP,UE_id); continue_flag = 0; // reset the flag to allow allocation for the remaining UEs
rnti = UE_RNTI(module_idP, UE_id);
eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
if (rnti==NOT_A_RNTI) { if (rnti == NOT_A_RNTI) {
LOG_D(MAC,"Cannot find rnti for UE_id %d (num_UEs %d)\n",UE_id,UE_list->num_UEs); LOG_D(MAC, "Cannot find rnti for UE_id %d (num_UEs %d)\n",
continue_flag=1; UE_id, UE_list->num_UEs);
continue_flag = 1;
} }
if (eNB_UE_stats==NULL) { if (eNB_UE_stats == NULL) {
LOG_D(MAC,"[eNB] Cannot find eNB_UE_stats\n"); LOG_D(MAC, "[eNB] Cannot find eNB_UE_stats\n");
continue_flag=1; continue_flag = 1;
} }
if (continue_flag != 1){ if (continue_flag != 1) {
switch(get_tmode(module_idP,CC_id,UE_id)){ switch (get_tmode(module_idP, CC_id, UE_id)) {
case 1: case 1:
case 2: case 2:
case 7: case 7:
aggregation = get_aggregation(get_bw_index(module_idP,CC_id), aggregation =
get_aggregation(get_bw_index(module_idP, CC_id),
ue_sched_ctl->dl_cqi[CC_id], ue_sched_ctl->dl_cqi[CC_id],
format1); format1);
break; break;
case 3: case 3:
aggregation = get_aggregation(get_bw_index(module_idP,CC_id), aggregation =
get_aggregation(get_bw_index(module_idP, CC_id),
ue_sched_ctl->dl_cqi[CC_id], ue_sched_ctl->dl_cqi[CC_id],
format2A); format2A);
break; break;
default: default:
LOG_W(MAC,"Unsupported transmission mode %d\n", get_tmode(module_idP,CC_id,UE_id)); LOG_W(MAC, "Unsupported transmission mode %d\n",
get_tmode(module_idP, CC_id, UE_id));
aggregation = 2; aggregation = 2;
} }
} /* if (continue_flag != 1 */ }
/* if (continue_flag != 1 */
if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated
CCE_allocation_infeasible(module_idP,CC_id,1,subframeP,aggregation,rnti) CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP,
) { aggregation, rnti)) {
LOG_D(MAC,"[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n", LOG_D(MAC,
"[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n",
module_idP, frameP, UE_id, CC_id); module_idP, frameP, UE_id, CC_id);
continue_flag=1; //to next user (there might be rbs availiable for other UEs in TM5 continue_flag = 1; //to next user (there might be rbs availiable for other UEs in TM5
} }
if (cc[CC_id].tdd_Config != NULL) { //TDD if (cc[CC_id].tdd_Config != NULL) { //TDD
set_ue_dai (subframeP, set_ue_dai(subframeP,
UE_id, UE_id,
CC_id, CC_id,
cc[CC_id].tdd_Config->subframeAssignment, cc[CC_id].tdd_Config->subframeAssignment,
UE_list); UE_list);
// update UL DAI after DLSCH scheduling // update UL DAI after DLSCH scheduling
set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP); set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP);
} }
if (continue_flag == 1 ) { if (continue_flag == 1) {
add_ue_dlsch_info(module_idP, add_ue_dlsch_info(module_idP,
CC_id, CC_id, UE_id, subframeP, S_DL_NONE);
UE_id,
subframeP,
S_DL_NONE);
continue; continue;
} }
#warning RK->CR This old API call has to be revisited for FAPI, or logic must be changed #warning RK->CR This old API call has to be revisited for FAPI, or logic must be changed
#if 0 #if 0
/* add "fake" DCI to have CCE_allocation_infeasible work properly for next allocations */ /* add "fake" DCI to have CCE_allocation_infeasible work properly for next allocations */
/* if we don't add it, next allocations may succeed but overall allocations may fail */ /* if we don't add it, next allocations may succeed but overall allocations may fail */
/* will be removed at the end of this function */ /* will be removed at the end of this function */
add_ue_spec_dci(&eNB->common_channels[CC_id].DCI_pdu, add_ue_spec_dci(&eNB->common_channels[CC_id].DCI_pdu, &(char[]) {
&(char[]){0}, 0}, rnti, 1, aggregation, 1, format1, 0);
rnti,
1,
aggregation,
1,
format1,
0);
#endif #endif
nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id]; nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id];
if (cc->tdd_Config) harq_pid = ((frameP*10)+subframeP)%10; if (cc->tdd_Config)
else harq_pid = ((frameP*10)+subframeP)&7; harq_pid = ((frameP * 10) + subframeP) % 10;
else
harq_pid = ((frameP * 10) + subframeP) & 7;
round = ue_sched_ctl->round[CC_id][harq_pid]; round = ue_sched_ctl->round[CC_id][harq_pid];
UE_list->eNB_UE_stats[CC_id][UE_id].crnti= rnti; UE_list->eNB_UE_stats[CC_id][UE_id].crnti = rnti;
UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status=mac_eNB_get_rrc_status(module_idP,rnti); UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status =
mac_eNB_get_rrc_status(module_idP, rnti);
UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid;
UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round; UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round;
if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status < RRC_CONNECTED) continue; if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status <
RRC_CONNECTED)
continue;
sdu_length_total=0; sdu_length_total = 0;
num_sdus=0; num_sdus = 0;
/* /*
DevCheck(((eNB_UE_stats->dl_cqi < MIN_CQI_VALUE) || (eNB_UE_stats->dl_cqi > MAX_CQI_VALUE)), DevCheck(((eNB_UE_stats->dl_cqi < MIN_CQI_VALUE) || (eNB_UE_stats->dl_cqi > MAX_CQI_VALUE)),
eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE); eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE);
*/ */
eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; eNB_UE_stats->dlsch_mcs1 =
eNB_UE_stats->dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1;//cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]];
eNB_UE_stats->dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; //cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs);
// store stats // store stats
//UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->dl_cqi; //UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->dl_cqi;
// initializing the rb allocation indicator for each UE // initializing the rb allocation indicator for each UE
for(j=0; j<N_RBG[CC_id]; j++) { for (j = 0; j < N_RBG[CC_id]; j++) {
UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = 0; UE_list->
UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]
= 0;
} }
LOG_D(MAC,"[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n", LOG_D(MAC,
module_idP, frameP, UE_id,CC_id,rnti,harq_pid, round,nb_available_rb, "[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n",
ue_sched_ctl->dl_cqi[CC_id], eNB_UE_stats->dlsch_mcs1, module_idP, frameP, UE_id, CC_id, rnti, harq_pid, round,
nb_available_rb, ue_sched_ctl->dl_cqi[CC_id],
eNB_UE_stats->dlsch_mcs1,
UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status); UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status);
...@@ -671,38 +684,59 @@ schedule_ue_spec( ...@@ -671,38 +684,59 @@ schedule_ue_spec(
// get freq_allocation // get freq_allocation
nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
TBS = get_TBS_DL(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid],nb_rb); TBS =
get_TBS_DL(UE_list->
UE_template[CC_id][UE_id].oldmcs1[harq_pid],
nb_rb);
if (nb_rb <= nb_available_rb) { if (nb_rb <= nb_available_rb) {
if (cc[CC_id].tdd_Config != NULL) { if (cc[CC_id].tdd_Config != NULL) {
UE_list->UE_template[CC_id][UE_id].DAI++; UE_list->UE_template[CC_id][UE_id].DAI++;
update_ul_dci(module_idP,CC_id,rnti,UE_list->UE_template[CC_id][UE_id].DAI); update_ul_dci(module_idP, CC_id, rnti,
LOG_D(MAC,"DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n", CC_id,subframeP,UE_id,UE_list->UE_template[CC_id][UE_id].DAI); UE_list->UE_template[CC_id][UE_id].
DAI);
LOG_D(MAC,
"DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n",
CC_id, subframeP, UE_id,
UE_list->UE_template[CC_id][UE_id].DAI);
} }
if(nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) {
for(j=0; j<N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band
UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; UE_list->UE_template[CC_id][UE_id].
rballoc_subband[harq_pid][j] =
ue_sched_ctl->rballoc_sub_UE[CC_id][j];
} }
} else { } else {
nb_rb_temp = nb_rb; nb_rb_temp = nb_rb;
j = 0; j = 0;
while((nb_rb_temp > 0) && (j<N_RBG[CC_id])) { while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) {
if(ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] ==
if (UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]) printf("WARN: rballoc_subband not free for retrans?\n"); 1) {
UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; if (UE_list->
UE_template[CC_id]
if((j == N_RBG[CC_id]-1) && [UE_id].rballoc_subband[harq_pid][j])
((N_RB_DL[CC_id] == 25)|| printf
("WARN: rballoc_subband not free for retrans?\n");
UE_list->
UE_template[CC_id]
[UE_id].rballoc_subband[harq_pid][j] =
ue_sched_ctl->rballoc_sub_UE[CC_id][j];
if ((j == N_RBG[CC_id] - 1) &&
((N_RB_DL[CC_id] == 25) ||
(N_RB_DL[CC_id] == 50))) { (N_RB_DL[CC_id] == 50))) {
nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]+1; nb_rb_temp =
nb_rb_temp - min_rb_unit[CC_id] +
1;
} else { } else {
nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; nb_rb_temp =
nb_rb_temp - min_rb_unit[CC_id];
} }
} }
j = j+1; j = j + 1;
} }
} }
...@@ -716,54 +750,83 @@ schedule_ue_spec( ...@@ -716,54 +750,83 @@ schedule_ue_spec(
} }
*/ */
switch (get_tmode(module_idP,CC_id,UE_id)) { switch (get_tmode(module_idP, CC_id, UE_id)) {
case 1: case 1:
case 2: case 2:
case 7: case 7:
default: default:
dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; dl_config_pdu =
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); &dl_req->dl_config_pdu_list[dl_req->
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; number_pdu];
dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu)); memset((void *) dl_config_pdu, 0,
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; sizeof(nfapi_dl_config_request_pdu_t));
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP,CC_id),ue_sched_ctl->dl_cqi[CC_id],format1); dl_config_pdu->pdu_type =
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
dl_config_pdu->pdu_size =
(uint8_t) (2 +
sizeof(nfapi_dl_config_dci_dl_pdu));
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.
dci_format = NFAPI_DL_DCI_FORMAT_1;
dl_config_pdu->dci_dl_pdu.
dci_dl_pdu_rel8.aggregation_level =
get_aggregation(get_bw_index
(module_idP, CC_id),
ue_sched_ctl->dl_cqi[CC_id],
format1);
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti =
rnti;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.
harq_process = harq_pid;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // dont adjust power when retransmitting dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // dont adjust power when retransmitting
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; dl_config_pdu->dci_dl_pdu.
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]; dci_dl_pdu_rel8.new_data_indicator_1 =
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = round&3; UE_list->UE_template[CC_id][UE_id].
oldNDI[harq_pid];
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 =
UE_list->UE_template[CC_id][UE_id].
oldmcs1[harq_pid];
dl_config_pdu->dci_dl_pdu.
dci_dl_pdu_rel8.redundancy_version_1 =
round & 3;
if (cc[CC_id].tdd_Config != NULL) { //TDD if (cc[CC_id].tdd_Config != NULL) { //TDD
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; dl_config_pdu->dci_dl_pdu.
LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n", dci_dl_pdu_rel8.downlink_assignment_index =
module_idP,CC_id,harq_pid,round, (UE_list->UE_template[CC_id][UE_id].DAI -
(UE_list->UE_template[CC_id][UE_id].DAI-1), 1) & 3;
UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]); LOG_D(MAC,
"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n",
module_idP, CC_id, harq_pid, round,
(UE_list->UE_template[CC_id][UE_id].DAI -
1),
UE_list->
UE_template[CC_id][UE_id].oldmcs1
[harq_pid]);
} else { } else {
LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n", LOG_D(MAC,
module_idP,CC_id,harq_pid,round, "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n",
UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]); module_idP, CC_id, harq_pid, round,
UE_list->
UE_template[CC_id][UE_id].oldmcs1
[harq_pid]);
} }
if (!CCE_allocation_infeasible(module_idP,CC_id,1,subframeP, if (!CCE_allocation_infeasible
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, (module_idP, CC_id, 1, subframeP,
rnti)) { dl_config_pdu->dci_dl_pdu.
dci_dl_pdu_rel8.aggregation_level, rnti)) {
dl_req->number_dci++; dl_req->number_dci++;
dl_req->number_pdu++; dl_req->number_pdu++;
fill_nfapi_dlsch_config(eNB,dl_req, fill_nfapi_dlsch_config(eNB, dl_req, TBS, -1
TBS, /* retransmission, no pdu_index */
-1 /* retransmission, no pdu_index */, , rnti, 0, // type 0 allocation from 7.1.6 in 36.213
rnti,
0, // type 0 allocation from 7.1.6 in 36.213
0, // virtual_resource_block_assignment_flag, unused here 0, // virtual_resource_block_assignment_flag, unused here
0, // resource_block_coding, to be filled in later 0, // resource_block_coding, to be filled in later
getQm(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]), getQm(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]), round & 3, // redundancy version
round&3 , // redundancy version
1, // transport blocks 1, // transport blocks
0, // transport block to codeword swap flag 0, // transport block to codeword swap flag
cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme
...@@ -771,8 +834,7 @@ schedule_ue_spec( ...@@ -771,8 +834,7 @@ schedule_ue_spec(
1, // number of subbands 1, // number of subbands
// uint8_t codebook_index, // uint8_t codebook_index,
4, // UE category capacity 4, // UE category capacity
UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0, // delta_power_offset for TM5
0, // delta_power_offset for TM5
0, // ngap 0, // ngap
0, // nprb 0, // nprb
cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode
...@@ -780,32 +842,42 @@ schedule_ue_spec( ...@@ -780,32 +842,42 @@ schedule_ue_spec(
0 // number of beamforming vectors, not used here 0 // number of beamforming vectors, not used here
); );
LOG_D(MAC,"Filled NFAPI configuration for DCI/DLSCH %d, retransmission round %d\n",eNB->pdu_index[CC_id],round); LOG_D(MAC,
"Filled NFAPI configuration for DCI/DLSCH %d, retransmission round %d\n",
program_dlsch_acknak(module_idP,CC_id,UE_id,frameP,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); eNB->pdu_index[CC_id], round);
program_dlsch_acknak(module_idP, CC_id, UE_id,
frameP, subframeP,
dl_config_pdu->
dci_dl_pdu.dci_dl_pdu_rel8.
cce_idx);
// No TX request for retransmission (check if null request for FAPI) // No TX request for retransmission (check if null request for FAPI)
} } else {
else { LOG_W(MAC,
LOG_W(MAC,"Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d\%x, infeasible CCE allocation\n", "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d\%x, infeasible CCE allocation\n",
frameP,subframeP,UE_id,rnti); frameP, subframeP, UE_id, rnti);
} }
} }
add_ue_dlsch_info(module_idP, add_ue_dlsch_info(module_idP,
CC_id, CC_id, UE_id, subframeP,
UE_id,
subframeP,
S_DL_SCHEDULED); S_DL_SCHEDULED);
//eNB_UE_stats->dlsch_trials[round]++; //eNB_UE_stats->dlsch_trials[round]++;
UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission+=1; UE_list->eNB_UE_stats[CC_id][UE_id].
UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx=nb_rb; num_retransmission += 1;
UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_retx+=nb_rb; UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx =
UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1=eNB_UE_stats->dlsch_mcs1; nb_rb;
UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2=eNB_UE_stats->dlsch_mcs1; UE_list->eNB_UE_stats[CC_id][UE_id].
total_rbs_used_retx += nb_rb;
UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 =
eNB_UE_stats->dlsch_mcs1;
UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 =
eNB_UE_stats->dlsch_mcs1;
} else { } else {
LOG_D(MAC,"[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n", LOG_D(MAC,
"[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n",
module_idP, frameP, CC_id, UE_id); module_idP, frameP, CC_id, UE_id);
} }
} else { /* This is a potentially new SDU opportunity */ } else { /* This is a potentially new SDU opportunity */
...@@ -813,7 +885,8 @@ schedule_ue_spec( ...@@ -813,7 +885,8 @@ schedule_ue_spec(
rlc_status.bytes_in_buffer = 0; rlc_status.bytes_in_buffer = 0;
// Now check RLC information to compute number of required RBs // Now check RLC information to compute number of required RBs
// get maximum TBS size for RLC request // get maximum TBS size for RLC request
TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_available_rb); TBS =
get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb);
// check first for RLC data on DCCH // check first for RLC data on DCCH
// add the length for all the control elements (timing adv, drx, etc) : header + payload // add the length for all the control elements (timing adv, drx, etc) : header + payload
...@@ -832,123 +905,113 @@ schedule_ue_spec( ...@@ -832,123 +905,113 @@ schedule_ue_spec(
header_len_dcch = 2; // 2 bytes DCCH SDU subheader header_len_dcch = 2; // 2 bytes DCCH SDU subheader
if ( TBS-ta_len-header_len_dcch > 0 ) { if (TBS - ta_len - header_len_dcch > 0) {
rlc_status = mac_rlc_status_ind( rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, (TBS - ta_len - header_len_dcch)); // transport block set size
module_idP,
rnti,
module_idP,
frameP,
subframeP,
ENB_FLAG_YES,
MBMS_FLAG_NO,
DCCH,
(TBS-ta_len-header_len_dcch)); // transport block set size
sdu_lengths[0]=0; sdu_lengths[0] = 0;
if (rlc_status.bytes_in_buffer > 0) { // There is DCCH to transmit if (rlc_status.bytes_in_buffer > 0) { // There is DCCH to transmit
LOG_D(MAC,"[eNB %d] Frame %d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", LOG_D(MAC,
module_idP,frameP,CC_id,TBS-header_len_dcch); "[eNB %d] Frame %d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
sdu_lengths[0] = mac_rlc_data_req( module_idP, frameP, CC_id,
module_idP, TBS - header_len_dcch);
rnti, sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, TBS, //not used
module_idP, (char *)
frameP, &dlsch_buffer
ENB_FLAG_YES, [0]);
MBMS_FLAG_NO,
DCCH, T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP),
TBS, //not used T_INT(CC_id), T_INT(rnti), T_INT(frameP),
(char *)&dlsch_buffer[0]); T_INT(subframeP), T_INT(harq_pid), T_INT(DCCH),
T_INT(sdu_lengths[0]));
T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP),
T_INT(harq_pid), T_INT(DCCH), T_INT(sdu_lengths[0]));
LOG_D(MAC,"[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n",module_idP,CC_id,sdu_lengths[0]); LOG_D(MAC,
"[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n",
module_idP, CC_id, sdu_lengths[0]);
sdu_length_total = sdu_lengths[0]; sdu_length_total = sdu_lengths[0];
sdu_lcids[0] = DCCH; sdu_lcids[0] = DCCH;
UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH]+=1; UE_list->eNB_UE_stats[CC_id][UE_id].
UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH]+=sdu_lengths[0]; num_pdu_tx[DCCH] += 1;
UE_list->
eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH]
+= sdu_lengths[0];
num_sdus = 1; num_sdus = 1;
#ifdef DEBUG_eNB_SCHEDULER #ifdef DEBUG_eNB_SCHEDULER
LOG_T(MAC,"[eNB %d][DCCH] CC_id %d Got %d bytes :",module_idP,CC_id,sdu_lengths[0]); LOG_T(MAC,
"[eNB %d][DCCH] CC_id %d Got %d bytes :",
module_idP, CC_id, sdu_lengths[0]);
for (j=0; j<sdu_lengths[0]; j++) { for (j = 0; j < sdu_lengths[0]; j++) {
LOG_T(MAC,"%x ",dlsch_buffer[j]); LOG_T(MAC, "%x ", dlsch_buffer[j]);
} }
LOG_T(MAC,"\n"); LOG_T(MAC, "\n");
#endif #endif
} else { } else {
header_len_dcch = 0; header_len_dcch = 0;
sdu_length_total = 0; sdu_length_total = 0;
} }
} }
// check for DCCH1 and update header information (assume 2 byte sub-header) // check for DCCH1 and update header information (assume 2 byte sub-header)
if (TBS-ta_len-header_len_dcch-sdu_length_total > 0 ) { if (TBS - ta_len - header_len_dcch - sdu_length_total > 0) {
rlc_status = mac_rlc_status_ind( rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, (TBS - ta_len - header_len_dcch - sdu_length_total)); // transport block set size less allocations for timing advance and
module_idP,
rnti,
module_idP,
frameP,
subframeP,
ENB_FLAG_YES,
MBMS_FLAG_NO,
DCCH+1,
(TBS-ta_len-header_len_dcch-sdu_length_total)); // transport block set size less allocations for timing advance and
// DCCH SDU // DCCH SDU
sdu_lengths[num_sdus] = 0; sdu_lengths[num_sdus] = 0;
if (rlc_status.bytes_in_buffer > 0) { if (rlc_status.bytes_in_buffer > 0) {
LOG_D(MAC,"[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n", LOG_D(MAC,
module_idP,frameP,CC_id,TBS-header_len_dcch-sdu_length_total); "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
sdu_lengths[num_sdus] += mac_rlc_data_req( module_idP, frameP, CC_id,
module_idP, TBS - header_len_dcch - sdu_length_total);
rnti, sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, TBS, //not used
module_idP, (char *)
frameP, &dlsch_buffer
ENB_FLAG_YES, [sdu_length_total]);
MBMS_FLAG_NO,
DCCH+1, T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP),
TBS, //not used T_INT(CC_id), T_INT(rnti), T_INT(frameP),
(char *)&dlsch_buffer[sdu_length_total]); T_INT(subframeP), T_INT(harq_pid),
T_INT(DCCH + 1), T_INT(sdu_lengths[num_sdus]));
T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP),
T_INT(harq_pid), T_INT(DCCH+1), T_INT(sdu_lengths[num_sdus]));
sdu_lcids[num_sdus] = DCCH1; sdu_lcids[num_sdus] = DCCH1;
sdu_length_total += sdu_lengths[num_sdus]; sdu_length_total += sdu_lengths[num_sdus];
header_len_dcch += 2; header_len_dcch += 2;
UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH1]+=1; UE_list->eNB_UE_stats[CC_id][UE_id].
UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1]+=sdu_lengths[num_sdus]; num_pdu_tx[DCCH1] += 1;
UE_list->
eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1]
+= sdu_lengths[num_sdus];
num_sdus++; num_sdus++;
#ifdef DEBUG_eNB_SCHEDULER #ifdef DEBUG_eNB_SCHEDULER
LOG_T(MAC,"[eNB %d][DCCH1] CC_id %d Got %d bytes :",module_idP,CC_id,sdu_lengths[num_sdus]); LOG_T(MAC,
"[eNB %d][DCCH1] CC_id %d Got %d bytes :",
module_idP, CC_id, sdu_lengths[num_sdus]);
for (j=0; j<sdu_lengths[num_sdus]; j++) { for (j = 0; j < sdu_lengths[num_sdus]; j++) {
LOG_T(MAC,"%x ",dlsch_buffer[j]); LOG_T(MAC, "%x ", dlsch_buffer[j]);
} }
LOG_T(MAC,"\n"); LOG_T(MAC, "\n");
#endif #endif
} }
} }
// assume the max dtch header size, and adjust it later // assume the max dtch header size, and adjust it later
header_len_dtch=0; header_len_dtch = 0;
header_len_dtch_last=0; // the header length of the last mac sdu header_len_dtch_last = 0; // the header length of the last mac sdu
// lcid has to be sorted before the actual allocation (similar struct as ue_list). // lcid has to be sorted before the actual allocation (similar struct as ue_list).
for (lcid=NB_RB_MAX-1; lcid>=DTCH ; lcid--){ for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) {
// TBD: check if the lcid is active // TBD: check if the lcid is active
header_len_dtch+=3; header_len_dtch += 3;
header_len_dtch_last=3; header_len_dtch_last = 3;
LOG_D(MAC,"[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", LOG_D(MAC,
module_idP,frameP,lcid,TBS, "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n",
TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch); module_idP, frameP, lcid, TBS,
TBS - ta_len - header_len_dcch -
sdu_length_total - header_len_dtch);
if (TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch > 0 ) { // NN: > 2 ? if (TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch > 0) { // NN: > 2 ?
rlc_status = mac_rlc_status_ind(module_idP, rlc_status = mac_rlc_status_ind(module_idP,
rnti, rnti,
module_idP, module_idP,
...@@ -957,30 +1020,41 @@ schedule_ue_spec( ...@@ -957,30 +1020,41 @@ schedule_ue_spec(
ENB_FLAG_YES, ENB_FLAG_YES,
MBMS_FLAG_NO, MBMS_FLAG_NO,
lcid, lcid,
TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch); TBS - ta_len -
header_len_dcch -
sdu_length_total -
header_len_dtch);
if (rlc_status.bytes_in_buffer > 0) { if (rlc_status.bytes_in_buffer > 0) {
LOG_D(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n", LOG_D(MAC,
module_idP,frameP,TBS-header_len_dcch-sdu_length_total-header_len_dtch,lcid, header_len_dtch); "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n",
sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, module_idP, frameP,
rnti, TBS - header_len_dcch -
module_idP, sdu_length_total - header_len_dtch, lcid,
frameP, header_len_dtch);
ENB_FLAG_YES, sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, TBS, //not used
MBMS_FLAG_NO, (char
lcid, *)
TBS, //not used &dlsch_buffer
(char*)&dlsch_buffer[sdu_length_total]); [sdu_length_total]);
T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP),
T_INT(harq_pid), T_INT(lcid), T_INT(sdu_lengths[num_sdus])); T_INT(CC_id), T_INT(rnti), T_INT(frameP),
T_INT(subframeP), T_INT(harq_pid),
T_INT(lcid), T_INT(sdu_lengths[num_sdus]));
LOG_D(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n",module_idP,sdu_lengths[num_sdus],lcid); LOG_D(MAC,
"[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n",
module_idP, sdu_lengths[num_sdus], lcid);
sdu_lcids[num_sdus] = lcid; sdu_lcids[num_sdus] = lcid;
sdu_length_total += sdu_lengths[num_sdus]; sdu_length_total += sdu_lengths[num_sdus];
UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid]+=1; UE_list->
UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid]+=sdu_lengths[num_sdus]; eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid]
+= 1;
UE_list->
eNB_UE_stats[CC_id][UE_id].num_bytes_tx
[lcid] += sdu_lengths[num_sdus];
if (sdu_lengths[num_sdus] < 128) { if (sdu_lengths[num_sdus] < 128) {
header_len_dtch--; header_len_dtch--;
header_len_dtch_last--; header_len_dtch_last--;
...@@ -988,195 +1062,240 @@ schedule_ue_spec( ...@@ -988,195 +1062,240 @@ schedule_ue_spec(
num_sdus++; num_sdus++;
} // no data for this LCID } // no data for this LCID
else { else {
header_len_dtch-=3; header_len_dtch -= 3;
} }
} // no TBS left } // no TBS left
else { else {
header_len_dtch-=3; header_len_dtch -= 3;
break; break;
} }
} }
if (header_len_dtch == 0 ) if (header_len_dtch == 0)
header_len_dtch_last= 0; header_len_dtch_last = 0;
// there is at least one SDU // there is at least one SDU
// if (num_sdus > 0 ){ // if (num_sdus > 0 ){
if ((sdu_length_total + header_len_dcch + header_len_dtch )> 0) { if ((sdu_length_total + header_len_dcch +
header_len_dtch) > 0) {
// Now compute number of required RBs for total sdu length // Now compute number of required RBs for total sdu length
// Assume RAH format 2 // Assume RAH format 2
// adjust header lengths // adjust header lengths
header_len_dcch_tmp = header_len_dcch; header_len_dcch_tmp = header_len_dcch;
header_len_dtch_tmp = header_len_dtch; header_len_dtch_tmp = header_len_dtch;
if (header_len_dtch==0) { if (header_len_dtch == 0) {
header_len_dcch = (header_len_dcch >0) ? 1 : 0;//header_len_dcch; // remove length field header_len_dcch = (header_len_dcch > 0) ? 1 : 0; //header_len_dcch; // remove length field
} else { } else {
header_len_dtch_last-=1; // now use it to find how many bytes has to be removed for the last MAC SDU header_len_dtch_last -= 1; // now use it to find how many bytes has to be removed for the last MAC SDU
header_len_dtch = (header_len_dtch > 0) ? header_len_dtch - header_len_dtch_last :header_len_dtch; // remove length field for the last SDU header_len_dtch = (header_len_dtch > 0) ? header_len_dtch - header_len_dtch_last : header_len_dtch; // remove length field for the last SDU
} }
mcs = eNB_UE_stats->dlsch_mcs1; mcs = eNB_UE_stats->dlsch_mcs1;
if (mcs==0) { if (mcs == 0) {
nb_rb = 4; // don't let the TBS get too small nb_rb = 4; // don't let the TBS get too small
} else { } else {
nb_rb=min_rb_unit[CC_id]; nb_rb = min_rb_unit[CC_id];
} }
TBS = get_TBS_DL(mcs,nb_rb); TBS = get_TBS_DL(mcs, nb_rb);
while (TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) { while (TBS <
(sdu_length_total + header_len_dcch +
header_len_dtch + ta_len)) {
nb_rb += min_rb_unit[CC_id]; // nb_rb += min_rb_unit[CC_id]; //
if (nb_rb>nb_available_rb) { // if we've gone beyond the maximum number of RBs if (nb_rb > nb_available_rb) { // if we've gone beyond the maximum number of RBs
// (can happen if N_RB_DL is odd) // (can happen if N_RB_DL is odd)
TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_available_rb); TBS =
get_TBS_DL(eNB_UE_stats->dlsch_mcs1,
nb_available_rb);
nb_rb = nb_available_rb; nb_rb = nb_available_rb;
break; break;
} }
TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_rb); TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rb);
} }
if(nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) {
for(j=0; j<N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band
UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; UE_list->UE_template[CC_id][UE_id].
rballoc_subband[harq_pid][j] =
ue_sched_ctl->rballoc_sub_UE[CC_id][j];
} }
} else { } else {
nb_rb_temp = nb_rb; nb_rb_temp = nb_rb;
j = 0; j = 0;
while((nb_rb_temp > 0) && (j<N_RBG[CC_id])) { while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) {
if(ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] ==
UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; 1) {
UE_list->
UE_template[CC_id]
[UE_id].rballoc_subband[harq_pid][j] =
ue_sched_ctl->rballoc_sub_UE[CC_id][j];
if ((j == N_RBG[CC_id]-1) && if ((j == N_RBG[CC_id] - 1) &&
((N_RB_DL[CC_id] == 25)|| ((N_RB_DL[CC_id] == 25) ||
(N_RB_DL[CC_id] == 50))) { (N_RB_DL[CC_id] == 50))) {
nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]+1; nb_rb_temp =
nb_rb_temp - min_rb_unit[CC_id] +
1;
} else { } else {
nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; nb_rb_temp =
nb_rb_temp - min_rb_unit[CC_id];
} }
} }
j = j+1; j = j + 1;
} }
} }
// decrease mcs until TBS falls below required length // decrease mcs until TBS falls below required length
while ((TBS > (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && (mcs>0)) { while ((TBS >
(sdu_length_total + header_len_dcch +
header_len_dtch + ta_len)) && (mcs > 0)) {
mcs--; mcs--;
TBS = get_TBS_DL(mcs,nb_rb); TBS = get_TBS_DL(mcs, nb_rb);
} }
// if we have decreased too much or we don't have enough RBs, increase MCS // if we have decreased too much or we don't have enough RBs, increase MCS
while ((TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && ((( ue_sched_ctl->dl_pow_off[CC_id]>0) && (mcs<28)) while ((TBS <
|| ( (ue_sched_ctl->dl_pow_off[CC_id]==0) && (mcs<=15)))) { (sdu_length_total + header_len_dcch +
header_len_dtch + ta_len))
&& (((ue_sched_ctl->dl_pow_off[CC_id] > 0)
&& (mcs < 28))
|| ((ue_sched_ctl->dl_pow_off[CC_id] == 0)
&& (mcs <= 15)))) {
mcs++; mcs++;
TBS = get_TBS_DL(mcs,nb_rb); TBS = get_TBS_DL(mcs, nb_rb);
} }
LOG_D(MAC,"dlsch_mcs before and after the rate matching = (%d, %d)\n",eNB_UE_stats->dlsch_mcs1, mcs); LOG_D(MAC,
"dlsch_mcs before and after the rate matching = (%d, %d)\n",
eNB_UE_stats->dlsch_mcs1, mcs);
#ifdef DEBUG_eNB_SCHEDULER #ifdef DEBUG_eNB_SCHEDULER
LOG_D(MAC,"[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n", LOG_D(MAC,
module_idP,CC_id,mcs,TBS,nb_rb); "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n",
module_idP, CC_id, mcs, TBS, nb_rb);
// msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n", // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n",
// TBS, sdu_length_total, offset, TBS-sdu_length_total-offset); // TBS, sdu_length_total, offset, TBS-sdu_length_total-offset);
#endif #endif
if ((TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len) <= 2) { if ((TBS - header_len_dcch - header_len_dtch -
padding = (TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len); sdu_length_total - ta_len) <= 2) {
padding =
(TBS - header_len_dcch - header_len_dtch -
sdu_length_total - ta_len);
post_padding = 0; post_padding = 0;
} else { } else {
padding = 0; padding = 0;
// adjust the header len // adjust the header len
if (header_len_dtch==0) { if (header_len_dtch == 0) {
header_len_dcch = header_len_dcch_tmp; header_len_dcch = header_len_dcch_tmp;
} else { //if (( header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2))) } else { //if (( header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2)))
header_len_dtch = header_len_dtch_tmp; header_len_dtch = header_len_dtch_tmp;
} }
post_padding = TBS - sdu_length_total - header_len_dcch - header_len_dtch - ta_len ; // 1 is for the postpadding header post_padding = TBS - sdu_length_total - header_len_dcch - header_len_dtch - ta_len; // 1 is for the postpadding header
} }
offset = generate_dlsch_header((unsigned char*)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], offset = generate_dlsch_header((unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], num_sdus, //num_sdus
num_sdus, //num_sdus
sdu_lengths, // sdu_lengths, //
sdu_lcids, sdu_lcids, 255, // no drx
255, // no drx
ta_update, // timing advance ta_update, // timing advance
NULL, // contention res id NULL, // contention res id
padding, padding, post_padding);
post_padding);
//#ifdef DEBUG_eNB_SCHEDULER //#ifdef DEBUG_eNB_SCHEDULER
if (ta_update != 31) { if (ta_update != 31) {
LOG_D(MAC, LOG_D(MAC,
"[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_dcch %d, header_dtch %d\n", "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_dcch %d, header_dtch %d\n",
module_idP,frameP, UE_id, CC_id, sdu_length_total,num_sdus,sdu_lengths[0],sdu_lcids[0],offset, module_idP, frameP, UE_id, CC_id,
ta_update,padding,post_padding,mcs,TBS,nb_rb,header_len_dcch,header_len_dtch); sdu_length_total, num_sdus, sdu_lengths[0],
sdu_lcids[0], offset, ta_update, padding,
post_padding, mcs, TBS, nb_rb,
header_len_dcch, header_len_dtch);
} }
//#endif //#endif
#ifdef DEBUG_eNB_SCHEDULER #ifdef DEBUG_eNB_SCHEDULER
LOG_T(MAC,"[eNB %d] First 16 bytes of DLSCH : \n"); LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n");
for (i=0; i<16; i++) { for (i = 0; i < 16; i++) {
LOG_T(MAC,"%x.",dlsch_buffer[i]); LOG_T(MAC, "%x.", dlsch_buffer[i]);
} }
LOG_T(MAC,"\n"); LOG_T(MAC, "\n");
#endif #endif
// cycle through SDUs and place in dlsch_buffer // cycle through SDUs and place in dlsch_buffer
memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset],dlsch_buffer,sdu_length_total); memcpy(&UE_list->
DLSCH_pdu[CC_id][0][UE_id].payload[0][offset],
dlsch_buffer, sdu_length_total);
// memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); // memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]);
// fill remainder of DLSCH with random data // fill remainder of DLSCH with random data
for (j=0; j<(TBS-sdu_length_total-offset); j++) { for (j = 0; j < (TBS - sdu_length_total - offset); j++) {
UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset+sdu_length_total+j] = (char)(taus()&0xff); UE_list->DLSCH_pdu[CC_id][0][UE_id].
payload[0][offset + sdu_length_total + j] =
(char) (taus() & 0xff);
} }
if (opt_enabled == 1) { if (opt_enabled == 1) {
trace_pdu(1, (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], trace_pdu(1, (uint8_t *)
TBS, module_idP, 3, UE_RNTI(module_idP,UE_id), UE_list->DLSCH_pdu[CC_id][0][UE_id].
eNB->frame, eNB->subframe,0,0); payload[0], TBS, module_idP, 3,
LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", UE_RNTI(module_idP, UE_id), eNB->frame,
module_idP, CC_id, frameP, UE_RNTI(module_idP,UE_id), TBS); eNB->subframe, 0, 0);
} LOG_D(OPT,
"[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n",
T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), module_idP, CC_id, frameP,
T_INT(harq_pid), T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS)); UE_RNTI(module_idP, UE_id), TBS);
}
UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb;
T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP),
T_INT(CC_id), T_INT(rnti), T_INT(frameP),
T_INT(subframeP), T_INT(harq_pid),
T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id].
payload[0], TBS));
UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] =
nb_rb;
add_ue_dlsch_info(module_idP, add_ue_dlsch_info(module_idP,
CC_id, CC_id, UE_id, subframeP,
UE_id,
subframeP,
S_DL_SCHEDULED); S_DL_SCHEDULED);
// store stats // store stats
eNB->eNB_stats[CC_id].dlsch_bytes_tx+=sdu_length_total; eNB->eNB_stats[CC_id].dlsch_bytes_tx +=
eNB->eNB_stats[CC_id].dlsch_pdus_tx+=1; sdu_length_total;
eNB->eNB_stats[CC_id].dlsch_pdus_tx += 1;
UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb; UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb;
UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used += nb_rb; UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used +=
UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1=eNB_UE_stats->dlsch_mcs1; nb_rb;
UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2=mcs; UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 =
eNB_UE_stats->dlsch_mcs1;
UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = mcs;
UE_list->eNB_UE_stats[CC_id][UE_id].TBS = TBS; UE_list->eNB_UE_stats[CC_id][UE_id].TBS = TBS;
UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes= TBS- sdu_length_total; UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes =
UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes+= sdu_length_total; TBS - sdu_length_total;
UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes+= TBS; UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes +=
UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus+=1; sdu_length_total;
UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes +=
TBS;
UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus +=
1;
if (cc[CC_id].tdd_Config != NULL) { // TDD if (cc[CC_id].tdd_Config != NULL) { // TDD
UE_list->UE_template[CC_id][UE_id].DAI++; UE_list->UE_template[CC_id][UE_id].DAI++;
update_ul_dci(module_idP,CC_id,rnti,UE_list->UE_template[CC_id][UE_id].DAI); update_ul_dci(module_idP, CC_id, rnti,
UE_list->UE_template[CC_id][UE_id].
DAI);
} }
// do PUCCH power control // do PUCCH power control
// this is the normalized RX power // this is the normalized RX power
eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
...@@ -1187,28 +1306,40 @@ schedule_ue_spec( ...@@ -1187,28 +1306,40 @@ schedule_ue_spec(
// this assumes accumulated tpc // this assumes accumulated tpc
// make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out
int32_t framex10psubframe = UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame*10+UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe; int32_t framex10psubframe =
if (((framex10psubframe+10)<=(frameP*10+subframeP)) || //normal case UE_list->UE_template[CC_id][UE_id].
((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=10)))) //frame wrap-around pucch_tpc_tx_frame * 10 +
UE_list->UE_template[CC_id][UE_id].
pucch_tpc_tx_subframe;
if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || //normal case
((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) //frame wrap-around
if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) { if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) {
ue_sched_ctl->pucch1_cqi_update[CC_id] = 0; ue_sched_ctl->pucch1_cqi_update[CC_id] = 0;
UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame=frameP; UE_list->
UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe=subframeP; UE_template[CC_id]
[UE_id].pucch_tpc_tx_frame = frameP;
UE_list->
UE_template[CC_id]
[UE_id].pucch_tpc_tx_subframe = subframeP;
if (normalized_rx_power>(target_rx_power+4)) { if (normalized_rx_power >
(target_rx_power + 4)) {
tpc = 0; //-1 tpc = 0; //-1
tpc_accumulated--; tpc_accumulated--;
} else if (normalized_rx_power<(target_rx_power-4)) { } else if (normalized_rx_power <
(target_rx_power - 4)) {
tpc = 2; //+1 tpc = 2; //+1
tpc_accumulated++; tpc_accumulated++;
} else { } else {
tpc = 1; //0 tpc = 1; //0
} }
LOG_D(MAC,"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", LOG_D(MAC,
module_idP,frameP, subframeP,harq_pid,tpc, "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n",
tpc_accumulated,normalized_rx_power,target_rx_power); module_idP, frameP, subframeP, harq_pid,
tpc, tpc_accumulated,
normalized_rx_power, target_rx_power);
} // Po_PUCCH has been updated } // Po_PUCCH has been updated
else { else {
...@@ -1218,37 +1349,62 @@ schedule_ue_spec( ...@@ -1218,37 +1349,62 @@ schedule_ue_spec(
tpc = 1; //0 tpc = 1; //0
} }
dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; dl_config_pdu =
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); &dl_req->dl_config_pdu_list[dl_req->number_pdu];
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; memset((void *) dl_config_pdu, 0,
dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu)); sizeof(nfapi_dl_config_request_pdu_t));
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; dl_config_pdu->pdu_type =
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP,CC_id),ue_sched_ctl->dl_cqi[CC_id],format1); NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
dl_config_pdu->pdu_size =
(uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu));
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format =
NFAPI_DL_DCI_FORMAT_1;
dl_config_pdu->dci_dl_pdu.
dci_dl_pdu_rel8.aggregation_level =
get_aggregation(get_bw_index(module_idP, CC_id),
ue_sched_ctl->dl_cqi[CC_id],
format1);
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.
harq_process = harq_pid;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; // dont adjust power when retransmitting dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; // dont adjust power when retransmitting
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; dl_config_pdu->dci_dl_pdu.
dci_dl_pdu_rel8.new_data_indicator_1 =
1 -
UE_list->UE_template[CC_id][UE_id].
oldNDI[harq_pid];
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; dl_config_pdu->dci_dl_pdu.
dci_dl_pdu_rel8.redundancy_version_1 = 0;
//deactivate second codeword //deactivate second codeword
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1; dl_config_pdu->dci_dl_pdu.
dci_dl_pdu_rel8.redundancy_version_2 = 1;
if (cc[CC_id].tdd_Config != NULL) { //TDD if (cc[CC_id].tdd_Config != NULL) { //TDD
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; dl_config_pdu->dci_dl_pdu.
LOG_D(MAC,"[eNB %d] Initial transmission CC_id %d : harq_pid %d, dai %d, mcs %d\n", dci_dl_pdu_rel8.downlink_assignment_index =
module_idP,CC_id,harq_pid, (UE_list->UE_template[CC_id][UE_id].DAI -
(UE_list->UE_template[CC_id][UE_id].DAI-1), 1) & 3;
LOG_D(MAC,
"[eNB %d] Initial transmission CC_id %d : harq_pid %d, dai %d, mcs %d\n",
module_idP, CC_id, harq_pid,
(UE_list->UE_template[CC_id][UE_id].DAI - 1),
mcs); mcs);
} else { } else {
LOG_D(MAC,"[eNB %d] Initial transmission CC_id %d : harq_pid %d, mcs %d\n", LOG_D(MAC,
module_idP,CC_id,harq_pid,mcs); "[eNB %d] Initial transmission CC_id %d : harq_pid %d, mcs %d\n",
module_idP, CC_id, harq_pid, mcs);
} }
LOG_D(MAC,"Checking feasibility pdu %d (new sdu)\n",dl_req->number_pdu); LOG_D(MAC, "Checking feasibility pdu %d (new sdu)\n",
if (!CCE_allocation_infeasible(module_idP,CC_id,1,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,rnti)) { dl_req->number_pdu);
if (!CCE_allocation_infeasible
(module_idP, CC_id, 1, subframeP,
dl_config_pdu->dci_dl_pdu.
dci_dl_pdu_rel8.aggregation_level, rnti)) {
ue_sched_ctl->round[CC_id][harq_pid] = 0; ue_sched_ctl->round[CC_id][harq_pid] = 0;
...@@ -1256,25 +1412,36 @@ schedule_ue_spec( ...@@ -1256,25 +1412,36 @@ schedule_ue_spec(
dl_req->number_pdu++; dl_req->number_pdu++;
// Toggle NDI for next time // Toggle NDI for next time
LOG_D(MAC,"CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n", LOG_D(MAC,
CC_id, frameP,subframeP,UE_id, "CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n",
rnti,harq_pid,UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]); CC_id, frameP, subframeP, UE_id, rnti,
harq_pid,
UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]=1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; UE_list->
UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid] = mcs; UE_template[CC_id][UE_id].oldNDI[harq_pid]);
UE_list->UE_template[CC_id][UE_id].oldmcs2[harq_pid] = 0;
AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated!=NULL,"physicalConfigDedicated is NULL\n"); UE_list->UE_template[CC_id][UE_id].
AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated!=NULL,"physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n"); oldNDI[harq_pid] =
1 -
fill_nfapi_dlsch_config(eNB,dl_req, UE_list->UE_template[CC_id][UE_id].
TBS, oldNDI[harq_pid];
eNB->pdu_index[CC_id], UE_list->UE_template[CC_id][UE_id].
rnti, oldmcs1[harq_pid] = mcs;
0, // type 0 allocation from 7.1.6 in 36.213 UE_list->UE_template[CC_id][UE_id].
oldmcs2[harq_pid] = 0;
AssertFatal(UE_list->UE_template[CC_id]
[UE_id].physicalConfigDedicated !=
NULL,
"physicalConfigDedicated is NULL\n");
AssertFatal(UE_list->UE_template[CC_id]
[UE_id].
physicalConfigDedicated->pdsch_ConfigDedicated
!= NULL,
"physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n");
fill_nfapi_dlsch_config(eNB, dl_req, TBS, eNB->pdu_index[CC_id], rnti, 0, // type 0 allocation from 7.1.6 in 36.213
0, // virtual_resource_block_assignment_flag, unused here 0, // virtual_resource_block_assignment_flag, unused here
0, // resource_block_coding, to be filled in later 0, // resource_block_coding, to be filled in later
getQm(mcs), getQm(mcs), 0, // redundancy version
0, // redundancy version
1, // transport blocks 1, // transport blocks
0, // transport block to codeword swap flag 0, // transport block to codeword swap flag
cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme
...@@ -1282,37 +1449,47 @@ schedule_ue_spec( ...@@ -1282,37 +1449,47 @@ schedule_ue_spec(
1, // number of subbands 1, // number of subbands
// uint8_t codebook_index, // uint8_t codebook_index,
4, // UE category capacity 4, // UE category capacity
UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0, // delta_power_offset for TM5
0, // delta_power_offset for TM5
0, // ngap 0, // ngap
0, // nprb 0, // nprb
cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode
0, //number of PRBs treated as one subband, not used here 0, //number of PRBs treated as one subband, not used here
0 // number of beamforming vectors, not used here 0 // number of beamforming vectors, not used here
); );
eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB->TX_req[CC_id].tx_request_body, eNB->TX_req[CC_id].sfn_sf =
(frameP*10)+subframeP, fill_nfapi_tx_req(&eNB->
TBS, TX_req
eNB->pdu_index[CC_id], [CC_id].tx_request_body,
eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0]); (frameP * 10) + subframeP,
TBS, eNB->pdu_index[CC_id],
eNB->
UE_list.DLSCH_pdu[CC_id][0][(unsigned char)
UE_id].payload
[0]);
LOG_D(MAC,"Filled NFAPI configuration for DCI/DLSCH/TXREQ %d, new SDU\n",eNB->pdu_index[CC_id]); LOG_D(MAC,
"Filled NFAPI configuration for DCI/DLSCH/TXREQ %d, new SDU\n",
eNB->pdu_index[CC_id]);
eNB->pdu_index[CC_id]++; eNB->pdu_index[CC_id]++;
program_dlsch_acknak(module_idP,CC_id,UE_id,frameP,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); program_dlsch_acknak(module_idP, CC_id, UE_id,
frameP, subframeP,
dl_config_pdu->
dci_dl_pdu.dci_dl_pdu_rel8.
cce_idx);
} } else {
else { LOG_W(MAC,
LOG_W(MAC,"Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d/%x, infeasible CCE allocations\n", "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d/%x, infeasible CCE allocations\n",
frameP,subframeP,UE_id,rnti); frameP, subframeP, UE_id, rnti);
} }
} else { // There is no data from RLC or MAC header, so don't schedule } else { // There is no data from RLC or MAC header, so don't schedule
} }
} }
if (cc[CC_id].tdd_Config != NULL){ // TDD if (cc[CC_id].tdd_Config != NULL) { // TDD
set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP); set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP);
} }
} // UE_id loop } // UE_id loop
...@@ -1320,27 +1497,24 @@ schedule_ue_spec( ...@@ -1320,27 +1497,24 @@ schedule_ue_spec(
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_flag); fill_DLSCH_dci(module_idP, frameP, subframeP, mbsfn_flag);
stop_meas(&eNB->schedule_dlsch); stop_meas(&eNB->schedule_dlsch);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH,VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void
fill_DLSCH_dci( fill_DLSCH_dci(module_id_t module_idP,
module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, int *mbsfn_flagP)
frame_t frameP,
sub_frame_t subframeP,
int* mbsfn_flagP
)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
// loop over all allocated UEs and compute frequency allocations for PDSCH // loop over all allocated UEs and compute frequency allocations for PDSCH
int UE_id = -1; int UE_id = -1;
uint8_t /* first_rb, */ nb_rb=3; uint8_t /* first_rb, */ nb_rb = 3;
rnti_t rnti; rnti_t rnti;
//unsigned char *vrb_map; //unsigned char *vrb_map;
uint8_t rballoc_sub[25]; uint8_t rballoc_sub[25];
...@@ -1350,19 +1524,20 @@ fill_DLSCH_dci( ...@@ -1350,19 +1524,20 @@ fill_DLSCH_dci(
unsigned char harq_pid; unsigned char harq_pid;
int i; int i;
int CC_id; int CC_id;
eNB_MAC_INST *eNB =RC.mac[module_idP]; eNB_MAC_INST *eNB = RC.mac[module_idP];
UE_list_t *UE_list = &eNB->UE_list; UE_list_t *UE_list = &eNB->UE_list;
int N_RBG; int N_RBG;
int N_RB_DL; int N_RB_DL;
COMMON_channels_t *cc; COMMON_channels_t *cc;
start_meas(&eNB->fill_DLSCH_dci); start_meas(&eNB->fill_DLSCH_dci);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI,VCD_FUNCTION_IN); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_IN);
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
LOG_D(MAC,"Doing fill DCI for CC_id %d\n",CC_id); LOG_D(MAC, "Doing fill DCI for CC_id %d\n", CC_id);
if (mbsfn_flagP[CC_id]>0) if (mbsfn_flagP[CC_id] > 0)
continue; continue;
cc = &eNB->common_channels[CC_id]; cc = &eNB->common_channels[CC_id];
...@@ -1370,40 +1545,68 @@ fill_DLSCH_dci( ...@@ -1370,40 +1545,68 @@ fill_DLSCH_dci(
N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth);
// UE specific DCIs // UE specific DCIs
for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { for (UE_id = UE_list->head; UE_id >= 0;
LOG_T(MAC,"CC_id %d, UE_id: %d => status %d\n",CC_id,UE_id,eNB_dlsch_info[module_idP][CC_id][UE_id].status); UE_id = UE_list->next[UE_id]) {
LOG_T(MAC, "CC_id %d, UE_id: %d => status %d\n", CC_id, UE_id,
eNB_dlsch_info[module_idP][CC_id][UE_id].status);
if (eNB_dlsch_info[module_idP][CC_id][UE_id].status == S_DL_SCHEDULED) { if (eNB_dlsch_info[module_idP][CC_id][UE_id].status ==
S_DL_SCHEDULED) {
// clear scheduling flag // clear scheduling flag
eNB_dlsch_info[module_idP][CC_id][UE_id].status = S_DL_WAITING; eNB_dlsch_info[module_idP][CC_id][UE_id].status =
rnti = UE_RNTI(module_idP,UE_id); S_DL_WAITING;
if (cc->tdd_Config) harq_pid = ((frameP*10)+subframeP)%10; rnti = UE_RNTI(module_idP, UE_id);
else harq_pid = ((frameP*10)+subframeP)&7; if (cc->tdd_Config)
harq_pid = ((frameP * 10) + subframeP) % 10;
else
harq_pid = ((frameP * 10) + subframeP) & 7;
nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
/// Synchronizing rballoc with rballoc_sub /// Synchronizing rballoc with rballoc_sub
for(i=0; i<N_RBG; i++) { for (i = 0; i < N_RBG; i++) {
rballoc_sub[i] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][i]; rballoc_sub[i] =
UE_list->
UE_template[CC_id][UE_id].rballoc_subband[harq_pid]
[i];
} }
nfapi_dl_config_request_t *DL_req = &RC.mac[module_idP]->DL_req[0]; nfapi_dl_config_request_t *DL_req =
nfapi_dl_config_request_pdu_t* dl_config_pdu; &RC.mac[module_idP]->DL_req[0];
nfapi_dl_config_request_pdu_t *dl_config_pdu;
for (i=0;i<DL_req[CC_id].dl_config_request_body.number_pdu;i++) { for (i = 0;
dl_config_pdu = &DL_req[CC_id].dl_config_request_body.dl_config_pdu_list[i]; i < DL_req[CC_id].dl_config_request_body.number_pdu;
if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE)&& i++) {
(dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == rnti) && dl_config_pdu =
(dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format != 1)) { &DL_req[CC_id].
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb,N_RB_DL,N_RBG,rballoc_sub); dl_config_request_body.dl_config_pdu_list[i];
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0; if ((dl_config_pdu->pdu_type ==
} NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE)
else if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE)&& && (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.
(dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == rnti) && rnti == rnti)
(dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type==0)) { && (dl_config_pdu->dci_dl_pdu.
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb,N_RB_DL,N_RBG,rballoc_sub); dci_dl_pdu_rel8.dci_format != 1)) {
dl_config_pdu->dci_dl_pdu.
dci_dl_pdu_rel8.resource_block_coding =
allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG,
rballoc_sub);
dl_config_pdu->dci_dl_pdu.
dci_dl_pdu_rel8.resource_allocation_type = 0;
} else
if ((dl_config_pdu->pdu_type ==
NFAPI_DL_CONFIG_DLSCH_PDU_TYPE)
&& (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.
rnti == rnti)
&& (dl_config_pdu->dlsch_pdu.
dlsch_pdu_rel8.resource_allocation_type ==
0)) {
dl_config_pdu->dlsch_pdu.
dlsch_pdu_rel8.resource_block_coding =
allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG,
rballoc_sub);
} }
} }
} }
...@@ -1412,37 +1615,40 @@ fill_DLSCH_dci( ...@@ -1412,37 +1615,40 @@ fill_DLSCH_dci(
} }
stop_meas(&eNB->fill_DLSCH_dci); stop_meas(&eNB->fill_DLSCH_dci);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI,VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_OUT);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
unsigned char* unsigned char *get_dlsch_sdu(module_id_t module_idP,
get_dlsch_sdu( int CC_id, frame_t frameP, rnti_t rntiP,
module_id_t module_idP, uint8_t TBindex)
int CC_id,
frame_t frameP,
rnti_t rntiP,
uint8_t TBindex
)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
int UE_id; int UE_id;
eNB_MAC_INST *eNB=RC.mac[module_idP]; eNB_MAC_INST *eNB = RC.mac[module_idP];
if (rntiP==SI_RNTI) { if (rntiP == SI_RNTI) {
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d Get DLSCH sdu for BCCH \n", module_idP, CC_id, frameP); LOG_D(MAC, "[eNB %d] CC_id %d Frame %d Get DLSCH sdu for BCCH \n",
module_idP, CC_id, frameP);
return((unsigned char *)&eNB->common_channels[CC_id].BCCH_pdu.payload[0]); return ((unsigned char *) &eNB->common_channels[CC_id].
BCCH_pdu.payload[0]);
} }
UE_id = find_UE_id(module_idP,rntiP); UE_id = find_UE_id(module_idP, rntiP);
if (UE_id != -1) { if (UE_id != -1) {
LOG_D(MAC,"[eNB %d] Frame %d: CC_id %d Get DLSCH sdu for rnti %x => UE_id %d\n",module_idP,frameP,CC_id,rntiP,UE_id); LOG_D(MAC,
return((unsigned char *)&eNB->UE_list.DLSCH_pdu[CC_id][TBindex][UE_id].payload[0]); "[eNB %d] Frame %d: CC_id %d Get DLSCH sdu for rnti %x => UE_id %d\n",
module_idP, frameP, CC_id, rntiP, UE_id);
return ((unsigned char *) &eNB->
UE_list.DLSCH_pdu[CC_id][TBindex][UE_id].payload[0]);
} else { } else {
LOG_E(MAC,"[eNB %d] Frame %d: CC_id %d UE with RNTI %x does not exist\n", module_idP,frameP,CC_id,rntiP); LOG_E(MAC,
"[eNB %d] Frame %d: CC_id %d UE with RNTI %x does not exist\n",
module_idP, frameP, CC_id, rntiP);
return NULL; return NULL;
} }
...@@ -1450,25 +1656,30 @@ get_dlsch_sdu( ...@@ -1450,25 +1656,30 @@ get_dlsch_sdu(
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void update_ul_dci(module_id_t module_idP, void
uint8_t CC_idP, update_ul_dci(module_id_t module_idP,
rnti_t rntiP, uint8_t CC_idP, rnti_t rntiP, uint8_t daiP)
uint8_t daiP)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
nfapi_hi_dci0_request_t *HI_DCI0_req = &RC.mac[module_idP]->HI_DCI0_req[CC_idP]; nfapi_hi_dci0_request_t *HI_DCI0_req =
nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[0]; &RC.mac[module_idP]->HI_DCI0_req[CC_idP];
nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu =
&HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[0];
COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_idP]; COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_idP];
int i; int i;
if (cc->tdd_Config != NULL) { // TDD if (cc->tdd_Config != NULL) { // TDD
for (i=0; i<HI_DCI0_req->hi_dci0_request_body.number_of_dci + HI_DCI0_req->hi_dci0_request_body.number_of_dci; i++) { for (i = 0;
i <
HI_DCI0_req->hi_dci0_request_body.number_of_dci +
HI_DCI0_req->hi_dci0_request_body.number_of_dci; i++) {
if ((hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) && if ((hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) &&
(hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti == rntiP)) (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti == rntiP))
hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.dl_assignment_index = (daiP-1)&3; hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.dl_assignment_index =
(daiP - 1) & 3;
} }
} }
...@@ -1476,60 +1687,60 @@ void update_ul_dci(module_id_t module_idP, ...@@ -1476,60 +1687,60 @@ void update_ul_dci(module_id_t module_idP,
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void set_ue_dai( void
sub_frame_t subframeP, set_ue_dai(sub_frame_t subframeP,
int UE_id, int UE_id, uint8_t CC_id, uint8_t tdd_config,
uint8_t CC_id, UE_list_t * UE_list)
uint8_t tdd_config,
UE_list_t* UE_list
)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
switch (tdd_config) { switch (tdd_config) {
case 0: case 0:
if ((subframeP==0)||(subframeP==1)||(subframeP==3)||(subframeP==5)||(subframeP==6)||(subframeP==8)) { if ((subframeP == 0) || (subframeP == 1) || (subframeP == 3)
|| (subframeP == 5) || (subframeP == 6) || (subframeP == 8)) {
UE_list->UE_template[CC_id][UE_id].DAI = 0; UE_list->UE_template[CC_id][UE_id].DAI = 0;
} }
break; break;
case 1: case 1:
if ((subframeP==0)||(subframeP==4)||(subframeP==5)||(subframeP==9)) { if ((subframeP == 0) || (subframeP == 4) || (subframeP == 5)
|| (subframeP == 9)) {
UE_list->UE_template[CC_id][UE_id].DAI = 0; UE_list->UE_template[CC_id][UE_id].DAI = 0;
} }
break; break;
case 2: case 2:
if ((subframeP==4)||(subframeP==5)) { if ((subframeP == 4) || (subframeP == 5)) {
UE_list->UE_template[CC_id][UE_id].DAI = 0; UE_list->UE_template[CC_id][UE_id].DAI = 0;
} }
break; break;
case 3: case 3:
if ((subframeP==5)||(subframeP==7)||(subframeP==9)) { if ((subframeP == 5) || (subframeP == 7) || (subframeP == 9)) {
UE_list->UE_template[CC_id][UE_id].DAI = 0; UE_list->UE_template[CC_id][UE_id].DAI = 0;
} }
break; break;
case 4: case 4:
if ((subframeP==0)||(subframeP==6)) { if ((subframeP == 0) || (subframeP == 6)) {
UE_list->UE_template[CC_id][UE_id].DAI = 0; UE_list->UE_template[CC_id][UE_id].DAI = 0;
} }
break; break;
case 5: case 5:
if (subframeP==9) { if (subframeP == 9) {
UE_list->UE_template[CC_id][UE_id].DAI = 0; UE_list->UE_template[CC_id][UE_id].DAI = 0;
} }
break; break;
case 6: case 6:
if ((subframeP==0)||(subframeP==1)||(subframeP==5)||(subframeP==6)||(subframeP==9)) { if ((subframeP == 0) || (subframeP == 1) || (subframeP == 5)
|| (subframeP == 6) || (subframeP == 9)) {
UE_list->UE_template[CC_id][UE_id].DAI = 0; UE_list->UE_template[CC_id][UE_id].DAI = 0;
} }
...@@ -1537,7 +1748,7 @@ void set_ue_dai( ...@@ -1537,7 +1748,7 @@ void set_ue_dai(
default: default:
UE_list->UE_template[CC_id][UE_id].DAI = 0; UE_list->UE_template[CC_id][UE_id].DAI = 0;
LOG_N(MAC,"unknow TDD config %d\n",tdd_config); LOG_N(MAC, "unknow TDD config %d\n", tdd_config);
break; break;
} }
} }
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
#include "pdcp.h" #include "pdcp.h"
#if defined(ENABLE_ITTI) #if defined(ENABLE_ITTI)
# include "intertask_interface.h" #include "intertask_interface.h"
#endif #endif
#include "SIMULATION/TOOLS/defs.h" // for taus #include "SIMULATION/TOOLS/defs.h" // for taus
...@@ -63,58 +63,75 @@ ...@@ -63,58 +63,75 @@
extern RAN_CONTEXT_t RC; extern RAN_CONTEXT_t RC;
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
int8_t get_mbsfn_sf_alloction (module_id_t module_idP, uint8_t CC_id, uint8_t mbsfn_sync_area) int8_t
get_mbsfn_sf_alloction(module_id_t module_idP, uint8_t CC_id,
uint8_t mbsfn_sync_area)
{ {
// currently there is one-to-one mapping between sf allocation pattern and sync area // currently there is one-to-one mapping between sf allocation pattern and sync area
if (mbsfn_sync_area > MAX_MBSFN_AREA) { if (mbsfn_sync_area > MAX_MBSFN_AREA) {
LOG_W(MAC,"[eNB %d] CC_id %d MBSFN synchronization area %d out of range\n ", module_idP, CC_id, mbsfn_sync_area); LOG_W(MAC,
"[eNB %d] CC_id %d MBSFN synchronization area %d out of range\n ",
module_idP, CC_id, mbsfn_sync_area);
return -1; return -1;
} else if (RC.mac[module_idP]->common_channels[CC_id].mbsfn_SubframeConfig[mbsfn_sync_area] != NULL) { } else if (RC.mac[module_idP]->
common_channels[CC_id].mbsfn_SubframeConfig[mbsfn_sync_area]
!= NULL) {
return mbsfn_sync_area; return mbsfn_sync_area;
} else { } else {
LOG_W(MAC,"[eNB %d] CC_id %d MBSFN Subframe Config pattern %d not found \n ", module_idP, CC_id, mbsfn_sync_area); LOG_W(MAC,
"[eNB %d] CC_id %d MBSFN Subframe Config pattern %d not found \n ",
module_idP, CC_id, mbsfn_sync_area);
return -1; return -1;
} }
} }
int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_frame_t subframeP) int
schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
sub_frame_t subframeP)
{ {
int mcch_flag=0,mtch_flag=0, msi_flag=0; int mcch_flag = 0, mtch_flag = 0, msi_flag = 0;
int mbsfn_period =0;// 1<<(RC.mac[module_idP]->mbsfn_SubframeConfig[0]->radioframeAllocationPeriod); int mbsfn_period = 0; // 1<<(RC.mac[module_idP]->mbsfn_SubframeConfig[0]->radioframeAllocationPeriod);
int mcch_period = 0;//32<<(RC.mac[module_idP]->mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_RepetitionPeriod_r9); int mcch_period = 0; //32<<(RC.mac[module_idP]->mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_RepetitionPeriod_r9);
int mch_scheduling_period = 8<<(RC.mac[module_idP]->common_channels[CC_id].pmch_Config[0]->mch_SchedulingPeriod_r9); int mch_scheduling_period =
8 << (RC.mac[module_idP]->common_channels[CC_id].
pmch_Config[0]->mch_SchedulingPeriod_r9);
unsigned char mcch_sdu_length; unsigned char mcch_sdu_length;
unsigned char header_len_mcch=0,header_len_msi=0,header_len_mtch=0, header_len_mtch_temp=0, header_len_mcch_temp=0, header_len_msi_temp=0; unsigned char header_len_mcch = 0, header_len_msi =
int ii=0, msi_pos=0; 0, header_len_mtch = 0, header_len_mtch_temp =
0, header_len_mcch_temp = 0, header_len_msi_temp = 0;
int ii = 0, msi_pos = 0;
int mcch_mcs = -1; int mcch_mcs = -1;
uint16_t TBS,j=-1,padding=0,post_padding=0; uint16_t TBS, j = -1, padding = 0, post_padding = 0;
mac_rlc_status_resp_t rlc_status; mac_rlc_status_resp_t rlc_status;
int num_mtch; int num_mtch;
int msi_length,i,k; int msi_length, i, k;
unsigned char sdu_lcids[11], num_sdus=0, offset=0; unsigned char sdu_lcids[11], num_sdus = 0, offset = 0;
uint16_t sdu_lengths[11], sdu_length_total=0; uint16_t sdu_lengths[11], sdu_length_total = 0;
unsigned char mch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; // check the max value, this is for dlsch only unsigned char mch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; // check the max value, this is for dlsch only
COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id]; COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id];
cc->MCH_pdu.Pdu_size=0; cc->MCH_pdu.Pdu_size = 0;
for (i=0; for (i = 0; i < cc->num_active_mbsfn_area; i++) {
i< cc->num_active_mbsfn_area;
i++ ) {
// assume, that there is always a mapping // assume, that there is always a mapping
if ((j=get_mbsfn_sf_alloction(module_idP,CC_id,i)) == -1) { if ((j = get_mbsfn_sf_alloction(module_idP, CC_id, i)) == -1) {
return 0; return 0;
} }
mbsfn_period = 1<<(cc->mbsfn_SubframeConfig[j]->radioframeAllocationPeriod); mbsfn_period =
mcch_period = 32<<(cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9); 1 << (cc->mbsfn_SubframeConfig[j]->radioframeAllocationPeriod);
msi_pos=0; mcch_period =
ii=0; 32 << (cc->mbsfn_AreaInfo[i]->
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d : Checking MBSFN Sync Area %d/%d with SF allocation %d/%d for MCCH and MTCH (mbsfn period %d, mcch period %d)\n", mcch_Config_r9.mcch_RepetitionPeriod_r9);
module_idP, CC_id, frameP, subframeP,i,cc->num_active_mbsfn_area, msi_pos = 0;
j,cc->num_sf_allocation_pattern,mbsfn_period,mcch_period); ii = 0;
LOG_D(MAC,
"[eNB %d] CC_id %d Frame %d subframeP %d : Checking MBSFN Sync Area %d/%d with SF allocation %d/%d for MCCH and MTCH (mbsfn period %d, mcch period %d)\n",
module_idP, CC_id, frameP, subframeP, i,
cc->num_active_mbsfn_area, j, cc->num_sf_allocation_pattern,
mbsfn_period, mcch_period);
switch (cc->mbsfn_AreaInfo[i]->mcch_Config_r9.signallingMCS_r9) { switch (cc->mbsfn_AreaInfo[i]->mcch_Config_r9.signallingMCS_r9) {
...@@ -140,28 +157,43 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra ...@@ -140,28 +157,43 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra
if (cc->mbsfn_SubframeConfig[j]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { // one-frameP format if (cc->mbsfn_SubframeConfig[j]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { // one-frameP format
// Find the first subframeP in this MCH to transmit MSI // Find the first subframeP in this MCH to transmit MSI
if (frameP % mch_scheduling_period == cc->mbsfn_SubframeConfig[j]->radioframeAllocationOffset ) { if (frameP % mch_scheduling_period ==
cc->mbsfn_SubframeConfig[j]->
radioframeAllocationOffset) {
while (ii == 0) { while (ii == 0) {
ii = cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & (0x80>>msi_pos); ii = cc->
mbsfn_SubframeConfig[j]->subframeAllocation.
choice.oneFrame.buf[0] & (0x80 >> msi_pos);
msi_pos++; msi_pos++;
} }
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d : sync area %d sf allocation pattern %d sf alloc %x msi pos is %d \n", LOG_D(MAC,
module_idP, CC_id, frameP, subframeP,i,j, "[eNB %d] CC_id %d Frame %d subframeP %d : sync area %d sf allocation pattern %d sf alloc %x msi pos is %d \n",
cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0], msi_pos); module_idP, CC_id, frameP, subframeP, i, j,
cc->mbsfn_SubframeConfig[j]->
subframeAllocation.choice.oneFrame.buf[0],
msi_pos);
} }
// Check if the subframeP is for MSI, MCCH or MTCHs and Set the correspoding flag to 1 // Check if the subframeP is for MSI, MCCH or MTCHs and Set the correspoding flag to 1
switch (subframeP) { switch (subframeP) {
case 1: case 1:
if (cc->tdd_Config == NULL) { if (cc->tdd_Config == NULL) {
if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) { if ((cc->
mbsfn_SubframeConfig[j]->subframeAllocation.
choice.oneFrame.buf[0] & MBSFN_FDD_SF1) ==
MBSFN_FDD_SF1) {
if (msi_pos == 1) { if (msi_pos == 1) {
msi_flag = 1; msi_flag = 1;
} }
if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && if ((frameP % mcch_period ==
((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) ) { cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.mcch_Offset_r9)
&&
((cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.sf_AllocInfo_r9.
buf[0] & MBSFN_FDD_SF1) ==
MBSFN_FDD_SF1)) {
mcch_flag = 1; mcch_flag = 1;
} }
...@@ -173,13 +205,22 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra ...@@ -173,13 +205,22 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra
case 2: case 2:
if (cc->tdd_Config == NULL) { if (cc->tdd_Config == NULL) {
if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) { if ((cc->
mbsfn_SubframeConfig[j]->subframeAllocation.
choice.oneFrame.buf[0] & MBSFN_FDD_SF2) ==
MBSFN_FDD_SF2) {
if (msi_pos == 2) { if (msi_pos == 2) {
msi_flag = 1; msi_flag = 1;
} }
if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && if ((frameP % mcch_period ==
((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) ) { cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.mcch_Offset_r9)
&&
((cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.sf_AllocInfo_r9.
buf[0] & MBSFN_FDD_SF2) ==
MBSFN_FDD_SF2)) {
mcch_flag = 1; mcch_flag = 1;
} }
...@@ -191,26 +232,44 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra ...@@ -191,26 +232,44 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra
case 3: case 3:
if (cc->tdd_Config != NULL) { // TDD if (cc->tdd_Config != NULL) { // TDD
if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) { if ((cc->
mbsfn_SubframeConfig[j]->subframeAllocation.
choice.oneFrame.buf[0] & MBSFN_TDD_SF3) ==
MBSFN_TDD_SF3) {
if (msi_pos == 1) { if (msi_pos == 1) {
msi_flag = 1; msi_flag = 1;
} }
if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && if ((frameP % mcch_period ==
((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) ) { cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.mcch_Offset_r9)
&&
((cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.sf_AllocInfo_r9.
buf[0] & MBSFN_TDD_SF3) ==
MBSFN_TDD_SF3)) {
mcch_flag = 1; mcch_flag = 1;
} }
mtch_flag = 1; mtch_flag = 1;
} }
} else { // FDD } else { // FDD
if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) { if ((cc->
mbsfn_SubframeConfig[j]->subframeAllocation.
choice.oneFrame.buf[0] & MBSFN_FDD_SF3) ==
MBSFN_FDD_SF3) {
if (msi_pos == 3) { if (msi_pos == 3) {
msi_flag = 1; msi_flag = 1;
} }
if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && if ((frameP % mcch_period ==
((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) ) { cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.mcch_Offset_r9)
&&
((cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.sf_AllocInfo_r9.
buf[0] & MBSFN_FDD_SF3) ==
MBSFN_FDD_SF3)) {
mcch_flag = 1; mcch_flag = 1;
} }
...@@ -222,13 +281,22 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra ...@@ -222,13 +281,22 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra
case 4: case 4:
if (cc->tdd_Config != NULL) { if (cc->tdd_Config != NULL) {
if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) { if ((cc->
mbsfn_SubframeConfig[j]->subframeAllocation.
choice.oneFrame.buf[0] & MBSFN_TDD_SF4) ==
MBSFN_TDD_SF4) {
if (msi_pos == 2) { if (msi_pos == 2) {
msi_flag = 1; msi_flag = 1;
} }
if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && if ((frameP % mcch_period ==
((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) ) { cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.mcch_Offset_r9)
&&
((cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.sf_AllocInfo_r9.
buf[0] & MBSFN_TDD_SF4) ==
MBSFN_TDD_SF4)) {
mcch_flag = 1; mcch_flag = 1;
} }
...@@ -240,13 +308,22 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra ...@@ -240,13 +308,22 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra
case 6: case 6:
if (cc->tdd_Config == NULL) { if (cc->tdd_Config == NULL) {
if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) { if ((cc->
mbsfn_SubframeConfig[j]->subframeAllocation.
choice.oneFrame.buf[0] & MBSFN_FDD_SF6) ==
MBSFN_FDD_SF6) {
if (msi_pos == 4) { if (msi_pos == 4) {
msi_flag = 1; msi_flag = 1;
} }
if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && if ((frameP % mcch_period ==
((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) ) { cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.mcch_Offset_r9)
&&
((cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.sf_AllocInfo_r9.
buf[0] & MBSFN_FDD_SF6) ==
MBSFN_FDD_SF6)) {
mcch_flag = 1; mcch_flag = 1;
} }
...@@ -258,26 +335,44 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra ...@@ -258,26 +335,44 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra
case 7: case 7:
if (cc->tdd_Config != NULL) { // TDD if (cc->tdd_Config != NULL) { // TDD
if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) { if ((cc->
mbsfn_SubframeConfig[j]->subframeAllocation.
choice.oneFrame.buf[0] & MBSFN_TDD_SF7) ==
MBSFN_TDD_SF7) {
if (msi_pos == 3) { if (msi_pos == 3) {
msi_flag = 1; msi_flag = 1;
} }
if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && if ((frameP % mcch_period ==
((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) ) { cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.mcch_Offset_r9)
&&
((cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.sf_AllocInfo_r9.
buf[0] & MBSFN_TDD_SF7) ==
MBSFN_TDD_SF7)) {
mcch_flag = 1; mcch_flag = 1;
} }
mtch_flag = 1; mtch_flag = 1;
} }
} else { // FDD } else { // FDD
if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) { if ((cc->
mbsfn_SubframeConfig[j]->subframeAllocation.
choice.oneFrame.buf[0] & MBSFN_FDD_SF7) ==
MBSFN_FDD_SF7) {
if (msi_pos == 5) { if (msi_pos == 5) {
msi_flag = 1; msi_flag = 1;
} }
if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && if ((frameP % mcch_period ==
((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) ) { cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.mcch_Offset_r9)
&&
((cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.sf_AllocInfo_r9.
buf[0] & MBSFN_FDD_SF7) ==
MBSFN_FDD_SF7)) {
mcch_flag = 1; mcch_flag = 1;
} }
...@@ -289,26 +384,44 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra ...@@ -289,26 +384,44 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra
case 8: case 8:
if (cc->tdd_Config != NULL) { //TDD if (cc->tdd_Config != NULL) { //TDD
if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) { if ((cc->
mbsfn_SubframeConfig[j]->subframeAllocation.
choice.oneFrame.buf[0] & MBSFN_TDD_SF8) ==
MBSFN_TDD_SF8) {
if (msi_pos == 4) { if (msi_pos == 4) {
msi_flag = 1; msi_flag = 1;
} }
if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && if ((frameP % mcch_period ==
((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) ) { cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.mcch_Offset_r9)
&&
((cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.sf_AllocInfo_r9.
buf[0] & MBSFN_TDD_SF8) ==
MBSFN_TDD_SF8)) {
mcch_flag = 1; mcch_flag = 1;
} }
mtch_flag = 1; mtch_flag = 1;
} }
} else { // FDD } else { // FDD
if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) { if ((cc->
mbsfn_SubframeConfig[j]->subframeAllocation.
choice.oneFrame.buf[0] & MBSFN_FDD_SF8) ==
MBSFN_FDD_SF8) {
if (msi_pos == 6) { if (msi_pos == 6) {
msi_flag = 1; msi_flag = 1;
} }
if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && if ((frameP % mcch_period ==
((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) ) { cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.mcch_Offset_r9)
&&
((cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.sf_AllocInfo_r9.
buf[0] & MBSFN_FDD_SF8) ==
MBSFN_FDD_SF8)) {
mcch_flag = 1; mcch_flag = 1;
} }
...@@ -320,13 +433,22 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra ...@@ -320,13 +433,22 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra
case 9: case 9:
if (cc->tdd_Config != NULL) { if (cc->tdd_Config != NULL) {
if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) { if ((cc->
mbsfn_SubframeConfig[j]->subframeAllocation.
choice.oneFrame.buf[0] & MBSFN_TDD_SF9) ==
MBSFN_TDD_SF9) {
if (msi_pos == 5) { if (msi_pos == 5) {
msi_flag = 1; msi_flag = 1;
} }
if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && if ((frameP % mcch_period ==
((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) ) { cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.mcch_Offset_r9)
&&
((cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.sf_AllocInfo_r9.
buf[0] & MBSFN_TDD_SF9) ==
MBSFN_TDD_SF9)) {
mcch_flag = 1; mcch_flag = 1;
} }
...@@ -335,12 +457,15 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra ...@@ -335,12 +457,15 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra
} }
break; break;
}// end switch } // end switch
// sf allocation is non-overlapping // sf allocation is non-overlapping
if ((msi_flag==1) || (mcch_flag==1) || (mtch_flag==1)) { if ((msi_flag == 1) || (mcch_flag == 1)
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n", || (mtch_flag == 1)) {
module_idP, CC_id, frameP, subframeP,i,j,msi_flag,mcch_flag,mtch_flag); LOG_D(MAC,
"[eNB %d] CC_id %d Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n",
module_idP, CC_id, frameP, subframeP, i, j,
msi_flag, mcch_flag, mtch_flag);
break; break;
} }
} else { // four-frameP format } else { // four-frameP format
...@@ -348,18 +473,16 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra ...@@ -348,18 +473,16 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra
} }
} // end of for loop } // end of for loop
cc->msi_active=0; cc->msi_active = 0;
cc->mcch_active=0; cc->mcch_active = 0;
cc->mtch_active=0; cc->mtch_active = 0;
// Calculate the mcs // Calculate the mcs
if ((msi_flag==1) || (mcch_flag==1)) { if ((msi_flag == 1) || (mcch_flag == 1)) {
cc->MCH_pdu.mcs = mcch_mcs; cc->MCH_pdu.mcs = mcch_mcs;
} else if (mtch_flag == 1) { // only MTCH in this subframeP } else if (mtch_flag == 1) { // only MTCH in this subframeP
cc->MCH_pdu.mcs = cc->pmch_Config[0]->dataMCS_r9; cc->MCH_pdu.mcs = cc->pmch_Config[0]->dataMCS_r9;
} }
// 2nd: Create MSI, get MCCH from RRC and MTCHs from RLC // 2nd: Create MSI, get MCCH from RRC and MTCHs from RLC
// there is MSI (MCH Scheduling Info) // there is MSI (MCH Scheduling Info)
...@@ -370,105 +493,102 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra ...@@ -370,105 +493,102 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra
msi_ptr = &msi_control_element[0]; msi_ptr = &msi_control_element[0];
((MSI_ELEMENT *) msi_ptr)->lcid = MCCH_LCHANID; //MCCH ((MSI_ELEMENT *) msi_ptr)->lcid = MCCH_LCHANID; //MCCH
if (mcch_flag==1) { if (mcch_flag == 1) {
((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0;
((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0; ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0;
} else { // no mcch for this MSP } else { // no mcch for this MSP
((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x7;// stop value is 2047 ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x7; // stop value is 2047
((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xff; ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xff;
} }
msi_ptr+= sizeof(MSI_ELEMENT); msi_ptr += sizeof(MSI_ELEMENT);
//Header for MTCHs //Header for MTCHs
num_mtch = cc->mbms_SessionList[0]->list.count; num_mtch = cc->mbms_SessionList[0]->list.count;
for (k=0; k<num_mtch; k++) { // loop for all session in this MCH (MCH[0]) at this moment for (k = 0; k < num_mtch; k++) { // loop for all session in this MCH (MCH[0]) at this moment
((MSI_ELEMENT *) msi_ptr)->lcid = cc->mbms_SessionList[0]->list.array[k]->logicalChannelIdentity_r9;//mtch_lcid; ((MSI_ELEMENT *) msi_ptr)->lcid = cc->mbms_SessionList[0]->list.array[k]->logicalChannelIdentity_r9; //mtch_lcid;
((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; // last subframeP of this mtch (only one mtch now) ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; // last subframeP of this mtch (only one mtch now)
((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xB; ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xB;
msi_ptr+=sizeof(MSI_ELEMENT); msi_ptr += sizeof(MSI_ELEMENT);
} }
msi_length = msi_ptr-msi_control_element; msi_length = msi_ptr - msi_control_element;
if (msi_length<128) { if (msi_length < 128) {
header_len_msi = 2; header_len_msi = 2;
} else { } else {
header_len_msi = 3; header_len_msi = 3;
} }
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d : MSI->MCH, length of MSI is %d bytes \n", LOG_D(MAC,
module_idP,CC_id,frameP,msi_length); "[eNB %d] CC_id %d Frame %d : MSI->MCH, length of MSI is %d bytes \n",
module_idP, CC_id, frameP, msi_length);
//LOG_D(MAC,"Scheduler: MSI is transmitted in this subframeP \n" ); //LOG_D(MAC,"Scheduler: MSI is transmitted in this subframeP \n" );
// LOG_D(MAC,"Scheduler: MSI length is %d bytes\n",msi_length); // LOG_D(MAC,"Scheduler: MSI length is %d bytes\n",msi_length);
// Store MSI data to mch_buffer[0] // Store MSI data to mch_buffer[0]
memcpy((char *)&mch_buffer[sdu_length_total], memcpy((char *) &mch_buffer[sdu_length_total],
msi_control_element, msi_control_element, msi_length);
msi_length);
sdu_lcids[num_sdus] = MCH_SCHDL_INFO; sdu_lcids[num_sdus] = MCH_SCHDL_INFO;
sdu_lengths[num_sdus] = msi_length; sdu_lengths[num_sdus] = msi_length;
sdu_length_total += sdu_lengths[num_sdus]; sdu_length_total += sdu_lengths[num_sdus];
LOG_I(MAC,"[eNB %d] CC_id %d Create %d bytes for MSI\n", module_idP, CC_id, sdu_lengths[num_sdus]); LOG_I(MAC, "[eNB %d] CC_id %d Create %d bytes for MSI\n",
module_idP, CC_id, sdu_lengths[num_sdus]);
num_sdus++; num_sdus++;
cc->msi_active=1; cc->msi_active = 1;
} }
// there is MCCH // there is MCCH
if (mcch_flag == 1) { if (mcch_flag == 1) {
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d Subframe %d: Schedule MCCH MESSAGE (area %d, sfAlloc %d)\n", LOG_D(MAC,
"[eNB %d] CC_id %d Frame %d Subframe %d: Schedule MCCH MESSAGE (area %d, sfAlloc %d)\n",
module_idP, CC_id, frameP, subframeP, i, j); module_idP, CC_id, frameP, subframeP, i, j);
mcch_sdu_length = mac_rrc_data_req(module_idP, mcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MCCH, 1, &cc->MCCH_pdu.payload[0], 1, // this is eNB
CC_id,
frameP,
MCCH,1,
&cc->MCCH_pdu.payload[0],
1,// this is eNB
module_idP, // index module_idP, // index
i); // this is the mbsfn sync area index i); // this is the mbsfn sync area index
if (mcch_sdu_length > 0) { if (mcch_sdu_length > 0) {
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d : MCCH->MCH, Received %d bytes from RRC \n", LOG_D(MAC,
module_idP,CC_id,frameP,subframeP,mcch_sdu_length); "[eNB %d] CC_id %d Frame %d subframeP %d : MCCH->MCH, Received %d bytes from RRC \n",
module_idP, CC_id, frameP, subframeP, mcch_sdu_length);
header_len_mcch = 2; header_len_mcch = 2;
if (cc->tdd_Config != NULL) { if (cc->tdd_Config != NULL) {
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d: Scheduling MCCH->MCH (TDD) for MCCH message %d bytes (mcs %d )\n", LOG_D(MAC,
module_idP, CC_id, "[eNB %d] CC_id %d Frame %d subframeP %d: Scheduling MCCH->MCH (TDD) for MCCH message %d bytes (mcs %d )\n",
frameP,subframeP, module_idP, CC_id, frameP, subframeP,
mcch_sdu_length, mcch_sdu_length, mcch_mcs);
mcch_mcs);
} else { } else {
LOG_I(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d: Scheduling MCCH->MCH (FDD) for MCCH message %d bytes (mcs %d)\n", LOG_I(MAC,
module_idP, CC_id, "[eNB %d] CC_id %d Frame %d subframeP %d: Scheduling MCCH->MCH (FDD) for MCCH message %d bytes (mcs %d)\n",
frameP, subframeP, module_idP, CC_id, frameP, subframeP,
mcch_sdu_length, mcch_sdu_length, mcch_mcs);
mcch_mcs);
} }
cc->mcch_active=1; cc->mcch_active = 1;
memcpy((char *)&mch_buffer[sdu_length_total], memcpy((char *) &mch_buffer[sdu_length_total],
&cc->MCCH_pdu.payload[0], &cc->MCCH_pdu.payload[0], mcch_sdu_length);
mcch_sdu_length);
sdu_lcids[num_sdus] = MCCH_LCHANID; sdu_lcids[num_sdus] = MCCH_LCHANID;
sdu_lengths[num_sdus] = mcch_sdu_length; sdu_lengths[num_sdus] = mcch_sdu_length;
if (sdu_lengths[num_sdus]>128) { if (sdu_lengths[num_sdus] > 128) {
header_len_mcch = 3; header_len_mcch = 3;
} }
sdu_length_total += sdu_lengths[num_sdus]; sdu_length_total += sdu_lengths[num_sdus];
LOG_D(MAC,"[eNB %d] CC_id %d Got %d bytes for MCCH from RRC \n",module_idP,CC_id,sdu_lengths[num_sdus]); LOG_D(MAC,
"[eNB %d] CC_id %d Got %d bytes for MCCH from RRC \n",
module_idP, CC_id, sdu_lengths[num_sdus]);
num_sdus++; num_sdus++;
} }
} }
TBS = get_TBS_DL(cc->MCH_pdu.mcs, to_prb(cc->mib->message.dl_Bandwidth)); TBS =
get_TBS_DL(cc->MCH_pdu.mcs, to_prb(cc->mib->message.dl_Bandwidth));
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
// do not let mcch and mtch multiplexing when relaying is active // do not let mcch and mtch multiplexing when relaying is active
// for sync area 1, so not transmit data // for sync area 1, so not transmit data
...@@ -500,35 +620,43 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra ...@@ -500,35 +620,43 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra
*/ */
// get MTCH data from RLC (like for DTCH) // get MTCH data from RLC (like for DTCH)
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d: Schedule MTCH (area %d, sfAlloc %d)\n",module_idP,CC_id,frameP,subframeP,i,j); LOG_D(MAC,
"[eNB %d] CC_id %d Frame %d subframeP %d: Schedule MTCH (area %d, sfAlloc %d)\n",
module_idP, CC_id, frameP, subframeP, i, j);
header_len_mtch = 3; header_len_mtch = 3;
LOG_D(MAC,"[eNB %d], CC_id %d, Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n", LOG_D(MAC,
module_idP,CC_id,frameP,MTCH,TBS, "[eNB %d], CC_id %d, Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n",
TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch); module_idP, CC_id, frameP, MTCH, TBS,
TBS - header_len_mcch - header_len_msi - sdu_length_total -
rlc_status = mac_rlc_status_ind(module_idP,0,frameP,subframeP,module_idP,ENB_FLAG_YES,MBMS_FLAG_YES,MTCH, header_len_mtch);
TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch);
LOG_D(MAC,"e-MBMS log channel %u frameP %d, subframeP %d, rlc_status.bytes_in_buffer is %d\n", rlc_status =
MTCH,frameP,subframeP, rlc_status.bytes_in_buffer); mac_rlc_status_ind(module_idP, 0, frameP, subframeP,
module_idP, ENB_FLAG_YES, MBMS_FLAG_YES,
if (rlc_status.bytes_in_buffer >0) {
LOG_I(MAC,"[eNB %d][MBMS USER-PLANE], CC_id %d, Frame %d, MTCH->MCH, Requesting %d bytes from RLC (header len mtch %d)\n",
module_idP,CC_id,frameP,TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch,header_len_mtch);
sdu_lengths[num_sdus] = mac_rlc_data_req(
module_idP,
0,
module_idP,
frameP,
ENB_FLAG_YES,
MBMS_FLAG_YES,
MTCH, MTCH,
0, //not used TBS - header_len_mcch - header_len_msi -
(char*)&mch_buffer[sdu_length_total]); sdu_length_total - header_len_mtch);
LOG_D(MAC,
"e-MBMS log channel %u frameP %d, subframeP %d, rlc_status.bytes_in_buffer is %d\n",
MTCH, frameP, subframeP, rlc_status.bytes_in_buffer);
if (rlc_status.bytes_in_buffer > 0) {
LOG_I(MAC,
"[eNB %d][MBMS USER-PLANE], CC_id %d, Frame %d, MTCH->MCH, Requesting %d bytes from RLC (header len mtch %d)\n",
module_idP, CC_id, frameP,
TBS - header_len_mcch - header_len_msi -
sdu_length_total - header_len_mtch, header_len_mtch);
sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 0, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_YES, MTCH, 0, //not used
(char *)
&mch_buffer
[sdu_length_total]);
//sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,frameP, MBMS_FLAG_NO, MTCH+(MAX_NUM_RB*(NUMBER_OF_UE_MAX+1)), (char*)&mch_buffer[sdu_length_total]); //sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,frameP, MBMS_FLAG_NO, MTCH+(MAX_NUM_RB*(NUMBER_OF_UE_MAX+1)), (char*)&mch_buffer[sdu_length_total]);
LOG_I(MAC,"[eNB %d][MBMS USER-PLANE] CC_id %d Got %d bytes for MTCH %d\n",module_idP,CC_id,sdu_lengths[num_sdus],MTCH); LOG_I(MAC,
cc->mtch_active=1; "[eNB %d][MBMS USER-PLANE] CC_id %d Got %d bytes for MTCH %d\n",
module_idP, CC_id, sdu_lengths[num_sdus], MTCH);
cc->mtch_active = 1;
sdu_lcids[num_sdus] = MTCH; sdu_lcids[num_sdus] = MTCH;
sdu_length_total += sdu_lengths[num_sdus]; sdu_length_total += sdu_lengths[num_sdus];
...@@ -541,13 +669,13 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra ...@@ -541,13 +669,13 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra
header_len_mtch = 0; header_len_mtch = 0;
} }
} }
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
// } // }
#endif #endif
// FINAL STEP: Prepare and multiplexe MSI, MCCH and MTCHs // FINAL STEP: Prepare and multiplexe MSI, MCCH and MTCHs
if ((sdu_length_total + header_len_msi + header_len_mcch + header_len_mtch) >0) { if ((sdu_length_total + header_len_msi + header_len_mcch +
header_len_mtch) > 0) {
// Adjust the last subheader // Adjust the last subheader
/* if ((msi_flag==1) || (mcch_flag==1)) { /* if ((msi_flag==1) || (mcch_flag==1)) {
RC.mac[module_idP]->MCH_pdu.mcs = mcch_mcs; RC.mac[module_idP]->MCH_pdu.mcs = mcch_mcs;
...@@ -560,87 +688,97 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra ...@@ -560,87 +688,97 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra
header_len_mcch_temp = header_len_mcch; header_len_mcch_temp = header_len_mcch;
header_len_msi_temp = header_len_msi; header_len_msi_temp = header_len_msi;
if (header_len_mtch>0) { if (header_len_mtch > 0) {
header_len_mtch=1; // remove Length field in the subheader for the last PDU header_len_mtch = 1; // remove Length field in the subheader for the last PDU
} else if (header_len_mcch>0) { } else if (header_len_mcch > 0) {
header_len_mcch=1; header_len_mcch = 1;
} else { } else {
header_len_msi=1; header_len_msi = 1;
} }
// Calculate the padding // Calculate the padding
if ((TBS - header_len_mtch - header_len_mcch - header_len_msi - sdu_length_total) < 0) { if ((TBS - header_len_mtch - header_len_mcch - header_len_msi -
LOG_E(MAC,"Error in building MAC PDU, TBS %d < PDU %d \n", sdu_length_total) < 0) {
TBS, header_len_mtch + header_len_mcch + header_len_msi + sdu_length_total); LOG_E(MAC, "Error in building MAC PDU, TBS %d < PDU %d \n",
TBS,
header_len_mtch + header_len_mcch + header_len_msi +
sdu_length_total);
return 0; return 0;
} else if ((TBS - header_len_mtch - header_len_mcch - header_len_msi - sdu_length_total) <= 2) { } else
padding = (TBS - header_len_mtch - header_len_mcch - header_len_msi - sdu_length_total); if ((TBS - header_len_mtch - header_len_mcch - header_len_msi -
sdu_length_total) <= 2) {
padding =
(TBS - header_len_mtch - header_len_mcch - header_len_msi -
sdu_length_total);
post_padding = 0; post_padding = 0;
} else { // using post_padding, give back the Length field of subheader for the last PDU } else { // using post_padding, give back the Length field of subheader for the last PDU
padding = 0; padding = 0;
if (header_len_mtch>0) { if (header_len_mtch > 0) {
header_len_mtch = header_len_mtch_temp; header_len_mtch = header_len_mtch_temp;
} else if (header_len_mcch>0) { } else if (header_len_mcch > 0) {
header_len_mcch = header_len_mcch_temp; header_len_mcch = header_len_mcch_temp;
} else { } else {
header_len_msi = header_len_msi_temp; header_len_msi = header_len_msi_temp;
} }
post_padding = TBS - sdu_length_total - header_len_msi - header_len_mcch - header_len_mtch; post_padding =
TBS - sdu_length_total - header_len_msi - header_len_mcch -
header_len_mtch;
} }
// Generate the MAC Header for MCH // Generate the MAC Header for MCH
// here we use the function for DLSCH because DLSCH & MCH have the same Header structure // here we use the function for DLSCH because DLSCH & MCH have the same Header structure
offset = generate_dlsch_header((unsigned char*)cc->MCH_pdu.payload, offset = generate_dlsch_header((unsigned char *) cc->MCH_pdu.payload, num_sdus, sdu_lengths, sdu_lcids, 255, // no drx
num_sdus,
sdu_lengths,
sdu_lcids,
255, // no drx
31, // no timing advance 31, // no timing advance
NULL, // no contention res id NULL, // no contention res id
padding, padding, post_padding);
post_padding);
cc->MCH_pdu.Pdu_size = TBS;
cc->MCH_pdu.Pdu_size=TBS; cc->MCH_pdu.sync_area = i;
cc->MCH_pdu.sync_area=i; cc->MCH_pdu.msi_active = cc->msi_active;
cc->MCH_pdu.msi_active= cc->msi_active; cc->MCH_pdu.mcch_active = cc->mcch_active;
cc->MCH_pdu.mcch_active= cc->mcch_active; cc->MCH_pdu.mtch_active = cc->mtch_active;
cc->MCH_pdu.mtch_active= cc->mtch_active; LOG_D(MAC,
LOG_D(MAC," MCS for this sf is %d (mcch active %d, mtch active %d)\n", cc->MCH_pdu.mcs, " MCS for this sf is %d (mcch active %d, mtch active %d)\n",
cc->MCH_pdu.mcch_active,cc->MCH_pdu.mtch_active ); cc->MCH_pdu.mcs, cc->MCH_pdu.mcch_active,
cc->MCH_pdu.mtch_active);
LOG_I(MAC, LOG_I(MAC,
"[eNB %d][MBMS USER-PLANE ] CC_id %d Generate header : sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,padding %d,post_padding %d (mcs %d, TBS %d), header MTCH %d, header MCCH %d, header MSI %d\n", "[eNB %d][MBMS USER-PLANE ] CC_id %d Generate header : sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,padding %d,post_padding %d (mcs %d, TBS %d), header MTCH %d, header MCCH %d, header MSI %d\n",
module_idP,CC_id,sdu_length_total,num_sdus,sdu_lengths[0],sdu_lcids[0],offset,padding,post_padding,cc->MCH_pdu.mcs,TBS, module_idP, CC_id, sdu_length_total, num_sdus,
header_len_mtch, header_len_mcch, header_len_msi); sdu_lengths[0], sdu_lcids[0], offset, padding, post_padding,
cc->MCH_pdu.mcs, TBS, header_len_mtch, header_len_mcch,
header_len_msi);
// copy SDU to mch_pdu after the MAC Header // copy SDU to mch_pdu after the MAC Header
memcpy(&cc->MCH_pdu.payload[offset],mch_buffer,sdu_length_total); memcpy(&cc->MCH_pdu.payload[offset], mch_buffer, sdu_length_total);
// filling remainder of MCH with random data if necessery // filling remainder of MCH with random data if necessery
for (j=0; j<(TBS-sdu_length_total-offset); j++) { for (j = 0; j < (TBS - sdu_length_total - offset); j++) {
cc->MCH_pdu.payload[offset+sdu_length_total+j] = (char)(taus()&0xff); cc->MCH_pdu.payload[offset + sdu_length_total + j] =
(char) (taus() & 0xff);
} }
/* Tracing of PDU is done on UE side */ /* Tracing of PDU is done on UE side */
if (opt_enabled ==1 ) { if (opt_enabled == 1) {
trace_pdu(1, (uint8_t *)cc->MCH_pdu.payload, trace_pdu(1, (uint8_t *) cc->MCH_pdu.payload, TBS, module_idP, 6, 0xffff, // M_RNTI = 6 in wirehsark
TBS, module_idP, 6, 0xffff, // M_RNTI = 6 in wirehsark RC.mac[module_idP]->frame,
RC.mac[module_idP]->frame, RC.mac[module_idP]->subframe,0,0); RC.mac[module_idP]->subframe, 0, 0);
LOG_D(OPT,"[eNB %d][MCH] CC_id %d Frame %d : MAC PDU with size %d\n", LOG_D(OPT,
"[eNB %d][MCH] CC_id %d Frame %d : MAC PDU with size %d\n",
module_idP, CC_id, frameP, TBS); module_idP, CC_id, frameP, TBS);
} }
/* /*
for (j=0;j<sdu_length_total;j++) for (j=0;j<sdu_length_total;j++)
printf("%2x.",RC.mac[module_idP]->MCH_pdu.payload[j+offset]); printf("%2x.",RC.mac[module_idP]->MCH_pdu.payload[j+offset]);
printf(" \n");*/ printf(" \n"); */
return 1; return 1;
} else { } else {
cc->MCH_pdu.Pdu_size=0; cc->MCH_pdu.Pdu_size = 0;
cc->MCH_pdu.sync_area=0; cc->MCH_pdu.sync_area = 0;
cc->MCH_pdu.msi_active=0; cc->MCH_pdu.msi_active = 0;
cc->MCH_pdu.mcch_active=0; cc->MCH_pdu.mcch_active = 0;
cc->MCH_pdu.mtch_active=0; cc->MCH_pdu.mtch_active = 0;
// for testing purpose, fill with random data // for testing purpose, fill with random data
//for (j=0;j<(TBS-sdu_length_total-offset);j++) //for (j=0;j<(TBS-sdu_length_total-offset);j++)
// RC.mac[module_idP]->MCH_pdu.payload[offset+sdu_length_total+j] = (char)(taus()&0xff); // RC.mac[module_idP]->MCH_pdu.payload[offset+sdu_length_total+j] = (char)(taus()&0xff);
...@@ -658,12 +796,13 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra ...@@ -658,12 +796,13 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra
*/ */
} }
MCH_PDU *get_mch_sdu(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t subframeP) MCH_PDU *get_mch_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
sub_frame_t subframeP)
{ {
// RC.mac[module_idP]->MCH_pdu.mcs=0; // RC.mac[module_idP]->MCH_pdu.mcs=0;
//LOG_D(MAC," MCH_pdu.mcs is %d\n", RC.mac[module_idP]->MCH_pdu.mcs); //LOG_D(MAC," MCH_pdu.mcs is %d\n", RC.mac[module_idP]->MCH_pdu.mcs);
//#warning "MCH pdu should take the CC_id index" //#warning "MCH pdu should take the CC_id index"
return(&RC.mac[module_idP]->common_channels[CC_id].MCH_pdu); return (&RC.mac[module_idP]->common_channels[CC_id].MCH_pdu);
} }
#endif #endif
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
*/ */
/* indented with: indent -kr eNB_scheduler_RA.c */
#include "assertions.h" #include "assertions.h"
#include "PHY/defs.h" #include "PHY/defs.h"
#include "PHY/extern.h" #include "PHY/extern.h"
...@@ -52,7 +54,7 @@ ...@@ -52,7 +54,7 @@
#include "pdcp.h" #include "pdcp.h"
#if defined(ENABLE_ITTI) #if defined(ENABLE_ITTI)
# include "intertask_interface.h" #include "intertask_interface.h"
#endif #endif
#include "T.h" #include "T.h"
...@@ -61,160 +63,211 @@ ...@@ -61,160 +63,211 @@
#define DEBUG_eNB_SCHEDULER 1 #define DEBUG_eNB_SCHEDULER 1
// This table holds the allowable PRB sizes for ULSCH transmissions // This table holds the allowable PRB sizes for ULSCH transmissions
uint8_t rb_table[34] = {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,64,72,75,80,81,90,96,100}; uint8_t rb_table[34] =
{ 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, 64, 72, 75, 80, 81, 90, 96, 100
};
void rx_sdu(const module_id_t enb_mod_idP, void
rx_sdu(const module_id_t enb_mod_idP,
const int CC_idP, const int CC_idP,
const frame_t frameP, const frame_t frameP,
const sub_frame_t subframeP, const sub_frame_t subframeP,
const rnti_t rntiP, const rnti_t rntiP,
uint8_t *sduP, uint8_t * sduP,
const uint16_t sdu_lenP, const uint16_t sdu_lenP,
const uint16_t timing_advance, const uint16_t timing_advance, const uint8_t ul_cqi)
const uint8_t ul_cqi)
{ {
int current_rnti = rntiP; int current_rnti = rntiP;
unsigned char rx_ces[MAX_NUM_CE],num_ce,num_sdu,i,*payload_ptr; unsigned char rx_ces[MAX_NUM_CE], num_ce, num_sdu, i, *payload_ptr;
unsigned char rx_lcids[NB_RB_MAX]; unsigned char rx_lcids[NB_RB_MAX];
unsigned short rx_lengths[NB_RB_MAX]; unsigned short rx_lengths[NB_RB_MAX];
int UE_id = find_UE_id(enb_mod_idP, current_rnti); int UE_id = find_UE_id(enb_mod_idP, current_rnti);
int RA_id; int RA_id;
int ii,j; int ii, j;
eNB_MAC_INST *eNB = RC.mac[enb_mod_idP]; eNB_MAC_INST *mac = RC.mac[enb_mod_idP];
int harq_pid = subframe2harqpid(&eNB->common_channels[CC_idP],frameP,subframeP); int harq_pid =
subframe2harqpid(&mac->common_channels[CC_idP], frameP, subframeP);
UE_list_t *UE_list= &eNB->UE_list; UE_list_t *UE_list = &mac->UE_list;
int crnti_rx=0; int crnti_rx = 0;
int old_buffer_info; int old_buffer_info;
RA_TEMPLATE *RA_template = (RA_TEMPLATE *)&RC.mac[enb_mod_idP]->common_channels[CC_idP].RA_template[0]; RA_t *ra =
(RA_t *) & RC.mac[enb_mod_idP]->common_channels[CC_idP].ra[0];
int first_rb = 0; int first_rb = 0;
start_meas(&eNB->rx_ulsch_sdu); start_meas(&mac->rx_ulsch_sdu);
if ((UE_id > NUMBER_OF_UE_MAX) || (UE_id == -1) ) if ((UE_id > NUMBER_OF_UE_MAX) || (UE_id == -1))
for(ii=0; ii<NB_RB_MAX; ii++) { for (ii = 0; ii < NB_RB_MAX; ii++) {
rx_lengths[ii] = 0; rx_lengths[ii] = 0;
} }
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 1);
if (opt_enabled == 1) { if (opt_enabled == 1) {
trace_pdu(0, sduP,sdu_lenP, 0, 3, current_rnti, frameP, subframeP, 0,0); trace_pdu(0, sduP, sdu_lenP, 0, 3, current_rnti, frameP, subframeP,
LOG_D(OPT,"[eNB %d][ULSCH] Frame %d rnti %x with size %d\n", 0, 0);
LOG_D(OPT, "[eNB %d][ULSCH] Frame %d rnti %x with size %d\n",
enb_mod_idP, frameP, current_rnti, sdu_lenP); enb_mod_idP, frameP, current_rnti, sdu_lenP);
} }
if (UE_id!=-1) { if (UE_id != -1) {
LOG_D(MAC,"[eNB %d][PUSCH %d] CC_id %d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n",enb_mod_idP,harq_pid,CC_idP, UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid], LOG_D(MAC,
current_rnti, UE_id,ul_cqi); "[eNB %d][PUSCH %d] CC_id %d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n",
enb_mod_idP, harq_pid, CC_idP,
AssertFatal(UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] < 8, UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid],
"round >= 8\n"); current_rnti, UE_id, ul_cqi);
if (sduP!=NULL) {
AssertFatal(UE_list->UE_sched_ctrl[UE_id].
round_UL[CC_idP][harq_pid] < 8, "round >= 8\n");
if (sduP != NULL) {
UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0; UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0;
UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0;
UE_list->UE_sched_ctrl[UE_id].ul_scheduled &= (~(1<<harq_pid)); UE_list->UE_sched_ctrl[UE_id].ul_scheduled &=
(~(1 << harq_pid));
/* Update with smoothing: 3/4 of old value and 1/4 of new. /* Update with smoothing: 3/4 of old value and 1/4 of new.
* This is the logic that was done in the function * This is the logic that was done in the function
* lte_est_timing_advance_pusch, maybe it's not necessary? * lte_est_timing_advance_pusch, maybe it's not necessary?
* maybe it's even not correct at all? * maybe it's even not correct at all?
*/ */
UE_list->UE_sched_ctrl[UE_id].ta_update = UE_list->UE_sched_ctrl[UE_id].ta_update =
(UE_list->UE_sched_ctrl[UE_id].ta_update * 3 + timing_advance)/4; (UE_list->UE_sched_ctrl[UE_id].ta_update * 3 +
timing_advance) / 4;
UE_list->UE_sched_ctrl[UE_id].pusch_snr[CC_idP] = ul_cqi; UE_list->UE_sched_ctrl[UE_id].pusch_snr[CC_idP] = ul_cqi;
UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors = 0; UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors = 0;
first_rb = UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid]; first_rb =
UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid];
if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) { if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) {
UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync=0; UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0;
mac_eNB_rrc_ul_in_sync(enb_mod_idP,CC_idP,frameP,subframeP,UE_RNTI(enb_mod_idP,UE_id)); mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP,
} subframeP, UE_RNTI(enb_mod_idP,
UE_id));
} }
else { // we've got an error } else { // we've got an error
LOG_D(MAC,"[eNB %d][PUSCH %d] CC_id %d ULSCH in error in round %d, ul_cqi %d\n",enb_mod_idP,harq_pid,CC_idP, LOG_D(MAC,
UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid],ul_cqi); "[eNB %d][PUSCH %d] CC_id %d ULSCH in error in round %d, ul_cqi %d\n",
enb_mod_idP, harq_pid, CC_idP,
UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid],
ul_cqi);
// AssertFatal(1==0,"ulsch in error\n"); // AssertFatal(1==0,"ulsch in error\n");
if (UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] == 3) { if (UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] ==
UE_list->UE_sched_ctrl[UE_id].ul_scheduled &= (~(1<<harq_pid)); 3) {
UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]=0; UE_list->UE_sched_ctrl[UE_id].ul_scheduled &=
if (UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors++ == 10) (~(1 << harq_pid));
UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] =
0;
if (UE_list->UE_sched_ctrl[UE_id].
ul_consecutive_errors++ == 10)
UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 1; UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 1;
} } else
else UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]++; UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]++;
return; return;
} }
} } else if ((RA_id = find_RA_id(enb_mod_idP, CC_idP, current_rnti)) != -1) { // Check if this is an RA process for the rnti
else if ((RA_id = find_RA_id(enb_mod_idP,CC_idP,current_rnti))!=-1) { // Check if this is an RA process for the rnti AssertFatal(mac->common_channels[CC_idP].
AssertFatal(eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx>1, radioResourceConfigCommon->rach_ConfigCommon.
maxHARQ_Msg3Tx > 1,
"maxHARQ %d should be greater than 1\n", "maxHARQ %d should be greater than 1\n",
(int)eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx); (int) mac->common_channels[CC_idP].
radioResourceConfigCommon->rach_ConfigCommon.
LOG_D(MAC,"[eNB %d][PUSCH %d] CC_id %d Received ULSCH sdu round %d from PHY (rnti %x, RA_id %d) ul_cqi %d\n",enb_mod_idP,harq_pid,CC_idP, maxHARQ_Msg3Tx);
RA_template[RA_id].msg3_round,
current_rnti,RA_id,ul_cqi); LOG_D(MAC,
"[eNB %d][PUSCH %d] CC_id %d Received ULSCH sdu round %d from PHY (rnti %x, RA_id %d) ul_cqi %d\n",
first_rb = RA_template->msg3_first_rb; enb_mod_idP, harq_pid, CC_idP, ra[RA_id].msg3_round,
current_rnti, RA_id, ul_cqi);
if (sduP==NULL) { // we've got an error on Msg3
LOG_D(MAC,"[eNB %d] CC_id %d, RA %d ULSCH in error in round %d/%d\n",enb_mod_idP,CC_idP,RA_id, first_rb = ra->msg3_first_rb;
RA_template[RA_id].msg3_round,
(int)eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx); if (sduP == NULL) { // we've got an error on Msg3
if (RA_template[RA_id].msg3_round == eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx-1) { LOG_D(MAC,
cancel_ra_proc(enb_mod_idP,CC_idP,frameP,current_rnti); "[eNB %d] CC_id %d, RA %d ULSCH in error in round %d/%d\n",
enb_mod_idP, CC_idP, RA_id,
ra[RA_id].msg3_round,
(int) mac->common_channels[CC_idP].
radioResourceConfigCommon->rach_ConfigCommon.
maxHARQ_Msg3Tx);
if (ra[RA_id].msg3_round ==
mac->common_channels[CC_idP].radioResourceConfigCommon->
rach_ConfigCommon.maxHARQ_Msg3Tx - 1) {
cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti);
} }
else { else {
first_rb = UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid]; first_rb =
RA_template[RA_id].msg3_round++; UE_list->UE_template[CC_idP][UE_id].
first_rb_ul[harq_pid];
ra[RA_id].msg3_round++;
// prepare handling of retransmission // prepare handling of retransmission
RA_template[RA_id].Msg3_frame += ((RA_template[RA_id].Msg3_subframe>1) ? 1 : 0); ra[RA_id].Msg3_frame +=
RA_template[RA_id].Msg3_subframe = (RA_template[RA_id].Msg3_subframe+8)%10; ((ra[RA_id].Msg3_subframe > 1) ? 1 : 0);
add_msg3(enb_mod_idP,CC_idP, &RA_template[RA_id],frameP,subframeP); ra[RA_id].Msg3_subframe =
(ra[RA_id].Msg3_subframe + 8) % 10;
add_msg3(enb_mod_idP, CC_idP, &ra[RA_id], frameP,
subframeP);
} }
return; return;
} }
} } else {
else { LOG_W(MAC,
LOG_W(MAC,"Cannot find UE or RA corresponding to ULSCH rnti %x, dropping it\n", current_rnti); "Cannot find UE or RA corresponding to ULSCH rnti %x, dropping it\n",
current_rnti);
return; return;
} }
payload_ptr = parse_ulsch_header(sduP,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,sdu_lenP); payload_ptr =
parse_ulsch_header(sduP, &num_ce, &num_sdu, rx_ces, rx_lcids,
rx_lengths, sdu_lenP);
T(T_ENB_MAC_UE_UL_PDU, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), T(T_ENB_MAC_UE_UL_PDU, T_INT(enb_mod_idP), T_INT(CC_idP),
T_INT(current_rnti), T_INT(frameP), T_INT(subframeP),
T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu)); T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu));
T(T_ENB_MAC_UE_UL_PDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), T(T_ENB_MAC_UE_UL_PDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP),
T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu), T_BUFFER(sduP, sdu_lenP)); T_INT(current_rnti), T_INT(frameP), T_INT(subframeP),
T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu),
T_BUFFER(sduP, sdu_lenP));
eNB->eNB_stats[CC_idP].ulsch_bytes_rx=sdu_lenP; mac->eNB_stats[CC_idP].ulsch_bytes_rx = sdu_lenP;
eNB->eNB_stats[CC_idP].total_ulsch_bytes_rx+=sdu_lenP; mac->eNB_stats[CC_idP].total_ulsch_bytes_rx += sdu_lenP;
eNB->eNB_stats[CC_idP].total_ulsch_pdus_rx+=1; mac->eNB_stats[CC_idP].total_ulsch_pdus_rx += 1;
UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = 0; UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = 0;
// control element // control element
for (i=0; i<num_ce; i++) { for (i = 0; i < num_ce; i++) {
T(T_ENB_MAC_UE_UL_CE, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), T(T_ENB_MAC_UE_UL_CE, T_INT(enb_mod_idP), T_INT(CC_idP),
T_INT(current_rnti), T_INT(frameP), T_INT(subframeP),
T_INT(rx_ces[i])); T_INT(rx_ces[i]));
switch (rx_ces[i]) { // implement and process BSR + CRNTI + switch (rx_ces[i]) { // implement and process BSR + CRNTI +
case POWER_HEADROOM: case POWER_HEADROOM:
if (UE_id != -1) { if (UE_id != -1) {
UE_list->UE_template[CC_idP][UE_id].phr_info = (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET; UE_list->UE_template[CC_idP][UE_id].phr_info =
LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received PHR PH = %d (db)\n", (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET;
enb_mod_idP, CC_idP, rx_ces[i], UE_list->UE_template[CC_idP][UE_id].phr_info); LOG_D(MAC,
UE_list->UE_template[CC_idP][UE_id].phr_info_configured=1; "[eNB %d] CC_id %d MAC CE_LCID %d : Received PHR PH = %d (db)\n",
enb_mod_idP, CC_idP, rx_ces[i],
UE_list->UE_template[CC_idP][UE_id].phr_info);
UE_list->UE_template[CC_idP][UE_id].phr_info_configured =
1;
UE_list->UE_sched_ctrl[UE_id].phr_received = 1; UE_list->UE_sched_ctrl[UE_id].phr_received = 1;
} }
payload_ptr+=sizeof(POWER_HEADROOM_CMD); payload_ptr += sizeof(POWER_HEADROOM_CMD);
break; break;
case CRNTI: { case CRNTI:
int old_rnti = (((uint16_t)payload_ptr[0])<<8) + payload_ptr[1]; {
int old_rnti =
(((uint16_t) payload_ptr[0]) << 8) + payload_ptr[1];
int old_UE_id = find_UE_id(enb_mod_idP, old_rnti); int old_UE_id = find_UE_id(enb_mod_idP, old_rnti);
LOG_D(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d MAC CE_LCID %d (ce %d/%d): CRNTI %x (UE_id %d) in Msg3\n", LOG_D(MAC,
enb_mod_idP, frameP, subframeP, CC_idP, rx_ces[i], i, num_ce, old_rnti, old_UE_id); "[eNB %d] Frame %d, Subframe %d CC_id %d MAC CE_LCID %d (ce %d/%d): CRNTI %x (UE_id %d) in Msg3\n",
enb_mod_idP, frameP, subframeP, CC_idP, rx_ces[i], i,
num_ce, old_rnti, old_UE_id);
if (old_UE_id != -1) { if (old_UE_id != -1) {
/* TODO: if the UE did random access (followed by a MAC uplink with /* TODO: if the UE did random access (followed by a MAC uplink with
* CRNTI) because none of its scheduling request was granted, then * CRNTI) because none of its scheduling request was granted, then
...@@ -232,335 +285,458 @@ void rx_sdu(const module_id_t enb_mod_idP, ...@@ -232,335 +285,458 @@ void rx_sdu(const module_id_t enb_mod_idP,
UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0;
if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) { if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) {
UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0; UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0;
mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, subframeP, old_rnti); mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP,
subframeP, old_rnti);
} }
/* receiving CRNTI means that the current rnti has to go away */ /* receiving CRNTI means that the current rnti has to go away */
cancel_ra_proc(enb_mod_idP,CC_idP,frameP,current_rnti); cancel_ra_proc(enb_mod_idP, CC_idP, frameP,
current_rnti);
current_rnti = old_rnti; current_rnti = old_rnti;
} }
crnti_rx=1; crnti_rx = 1;
payload_ptr+=2; payload_ptr += 2;
break; break;
} }
case TRUNCATED_BSR: case TRUNCATED_BSR:
case SHORT_BSR: { case SHORT_BSR:
{
uint8_t lcgid; uint8_t lcgid;
lcgid = (payload_ptr[0] >> 6); lcgid = (payload_ptr[0] >> 6);
LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", LOG_D(MAC,
enb_mod_idP, CC_idP, rx_ces[i], lcgid, payload_ptr[0] & 0x3f); "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n",
enb_mod_idP, CC_idP, rx_ces[i], lcgid,
payload_ptr[0] & 0x3f);
if (crnti_rx==1) if (crnti_rx == 1)
LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", LOG_D(MAC,
enb_mod_idP, CC_idP, rx_ces[i], lcgid, payload_ptr[0] & 0x3f); "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n",
enb_mod_idP, CC_idP, rx_ces[i], lcgid,
payload_ptr[0] & 0x3f);
if (UE_id != -1) { if (UE_id != -1) {
UE_list->UE_template[CC_idP][UE_id].bsr_info[lcgid] = (payload_ptr[0] & 0x3f); UE_list->UE_template[CC_idP][UE_id].bsr_info[lcgid] =
(payload_ptr[0] & 0x3f);
// update buffer info // update buffer info
UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[lcgid]]; UE_list->UE_template[CC_idP][UE_id].
ul_buffer_info[lcgid] =
BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].
bsr_info[lcgid]];
UE_list->UE_template[CC_idP][UE_id].ul_total_buffer= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid]; UE_list->UE_template[CC_idP][UE_id].ul_total_buffer =
UE_list->UE_template[CC_idP][UE_id].
ul_buffer_info[lcgid];
RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP*10)+subframeP] = (payload_ptr[0] & 0x3f); RC.eNB[enb_mod_idP][CC_idP]->
pusch_stats_bsr[UE_id][(frameP * 10) + subframeP]
= (payload_ptr[0] & 0x3f);
if (UE_id == UE_list->head) if (UE_id == UE_list->head)
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR,RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP*10)+subframeP]); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME
if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] == 0 ) { (VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR,
UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid]=frameP; RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr
} [UE_id][(frameP * 10) + subframeP]);
if (mac_eNB_get_rrc_status(enb_mod_idP,UE_RNTI(enb_mod_idP,UE_id)) < RRC_CONNECTED) if (UE_list->UE_template[CC_idP][UE_id].
LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : ul_total_buffer = %d (lcg increment %d)\n", ul_buffer_creation_time[lcgid]
enb_mod_idP, CC_idP, rx_ces[i], UE_list->UE_template[CC_idP][UE_id].ul_total_buffer, == 0) {
UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid]); UE_list->UE_template[CC_idP]
} [UE_id].ul_buffer_creation_time[lcgid] =
else { frameP;
}
if (mac_eNB_get_rrc_status
(enb_mod_idP,
UE_RNTI(enb_mod_idP, UE_id)) < RRC_CONNECTED)
LOG_D(MAC,
"[eNB %d] CC_id %d MAC CE_LCID %d : ul_total_buffer = %d (lcg increment %d)\n",
enb_mod_idP, CC_idP, rx_ces[i],
UE_list->UE_template[CC_idP][UE_id].
ul_total_buffer,
UE_list->UE_template[CC_idP][UE_id].
ul_buffer_info[lcgid]);
} else {
} }
payload_ptr += 1;//sizeof(SHORT_BSR); // fixme payload_ptr += 1; //sizeof(SHORT_BSR); // fixme
} }
break; break;
case LONG_BSR: case LONG_BSR:
if (UE_id != -1) { if (UE_id != -1) {
UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] = ((payload_ptr[0] & 0xFC) >> 2); UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] =
((payload_ptr[0] & 0xFC) >> 2);
UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] = UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] =
((payload_ptr[0] & 0x03) << 4) | ((payload_ptr[1] & 0xF0) >> 4); ((payload_ptr[0] & 0x03) << 4) |
((payload_ptr[1] & 0xF0) >> 4);
UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] = UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] =
((payload_ptr[1] & 0x0F) << 2) | ((payload_ptr[2] & 0xC0) >> 6); ((payload_ptr[1] & 0x0F) << 2) |
UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] = (payload_ptr[2] & 0x3F); ((payload_ptr[2] & 0xC0) >> 6);
UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] =
(payload_ptr[2] & 0x3F);
// update buffer info // update buffer info
old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0]; old_buffer_info =
UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0]]; UE_list->UE_template[CC_idP][UE_id].
ul_buffer_info[LCGID0];
UE_list->UE_template[CC_idP][UE_id].ul_total_buffer+= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0]; UE_list->UE_template[CC_idP][UE_id].
if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info) ul_buffer_info[LCGID0] =
UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info; BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].
bsr_info[LCGID0]];
UE_list->UE_template[CC_idP][UE_id].ul_total_buffer +=
UE_list->UE_template[CC_idP][UE_id].
ul_buffer_info[LCGID0];
if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >=
old_buffer_info)
UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -=
old_buffer_info;
else else
UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0; UE_list->UE_template[CC_idP][UE_id].ul_total_buffer =
0;
old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1];
UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1]]; old_buffer_info =
UE_list->UE_template[CC_idP][UE_id].ul_total_buffer+= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1]; UE_list->UE_template[CC_idP][UE_id].
if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info) ul_buffer_info[LCGID1];
UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info; UE_list->UE_template[CC_idP][UE_id].
ul_buffer_info[LCGID1] =
BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].
bsr_info[LCGID1]];
UE_list->UE_template[CC_idP][UE_id].ul_total_buffer +=
UE_list->UE_template[CC_idP][UE_id].
ul_buffer_info[LCGID1];
if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >=
old_buffer_info)
UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -=
old_buffer_info;
else else
UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0; UE_list->UE_template[CC_idP][UE_id].ul_total_buffer =
0;
old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2];
UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2]]; old_buffer_info =
UE_list->UE_template[CC_idP][UE_id].ul_total_buffer+= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2]; UE_list->UE_template[CC_idP][UE_id].
if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info) ul_buffer_info[LCGID2];
UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info; UE_list->UE_template[CC_idP][UE_id].
ul_buffer_info[LCGID2] =
BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].
bsr_info[LCGID2]];
UE_list->UE_template[CC_idP][UE_id].ul_total_buffer +=
UE_list->UE_template[CC_idP][UE_id].
ul_buffer_info[LCGID2];
if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >=
old_buffer_info)
UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -=
old_buffer_info;
else else
UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0; UE_list->UE_template[CC_idP][UE_id].ul_total_buffer =
0;
old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3];
UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3]]; old_buffer_info =
UE_list->UE_template[CC_idP][UE_id].ul_total_buffer+= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]; UE_list->UE_template[CC_idP][UE_id].
if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info) ul_buffer_info[LCGID3];
UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info; UE_list->UE_template[CC_idP][UE_id].
ul_buffer_info[LCGID3] =
BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].
bsr_info[LCGID3]];
UE_list->UE_template[CC_idP][UE_id].ul_total_buffer +=
UE_list->UE_template[CC_idP][UE_id].
ul_buffer_info[LCGID3];
if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >=
old_buffer_info)
UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -=
old_buffer_info;
else else
UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0; UE_list->UE_template[CC_idP][UE_id].ul_total_buffer =
0;
LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = " LOG_D(MAC,
"%u LCGID2 = %u LCGID3 = %u\n", "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
enb_mod_idP, CC_idP, "%u LCGID2 = %u LCGID3 = %u\n", enb_mod_idP, CC_idP,
rx_ces[i],
UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0],
UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1],
UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2],
UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3]);
if (crnti_rx==1)
LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
"%u LCGID2 = %u LCGID3 = %u\n",
enb_mod_idP, CC_idP,
rx_ces[i], rx_ces[i],
UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0], UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0],
UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1], UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1],
UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2], UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2],
UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3]); UE_list->UE_template[CC_idP][UE_id].
bsr_info[LCGID3]);
if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] == 0 ) { if (crnti_rx == 1)
UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=0; LOG_D(MAC,
} else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] == 0) { "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=frameP; "%u LCGID2 = %u LCGID3 = %u\n", enb_mod_idP,
} CC_idP, rx_ces[i],
UE_list->UE_template[CC_idP][UE_id].
if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] == 0 ) { bsr_info[LCGID0],
UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=0; UE_list->UE_template[CC_idP][UE_id].
} else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] == 0) { bsr_info[LCGID1],
UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=frameP; UE_list->UE_template[CC_idP][UE_id].
} bsr_info[LCGID2],
UE_list->UE_template[CC_idP][UE_id].
if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] == 0 ) { bsr_info[LCGID3]);
UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2]=0;
} else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] == 0) { if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] ==
UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2]=frameP; 0) {
} UE_list->UE_template[CC_idP][UE_id].
ul_buffer_creation_time[LCGID0] = 0;
if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] == 0 ) { } else if (UE_list->UE_template[CC_idP]
UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3]= 0; [UE_id].ul_buffer_creation_time[LCGID0] == 0) {
} else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] == 0) { UE_list->UE_template[CC_idP][UE_id].
UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3]=frameP; ul_buffer_creation_time[LCGID0] = frameP;
}
}
} if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] ==
0) {
payload_ptr += 3;////sizeof(LONG_BSR); UE_list->UE_template[CC_idP][UE_id].
ul_buffer_creation_time[LCGID1] = 0;
} else if (UE_list->UE_template[CC_idP]
[UE_id].ul_buffer_creation_time[LCGID1] == 0) {
UE_list->UE_template[CC_idP][UE_id].
ul_buffer_creation_time[LCGID1] = frameP;
}
if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] ==
0) {
UE_list->UE_template[CC_idP][UE_id].
ul_buffer_creation_time[LCGID2] = 0;
} else if (UE_list->UE_template[CC_idP]
[UE_id].ul_buffer_creation_time[LCGID2] == 0) {
UE_list->UE_template[CC_idP][UE_id].
ul_buffer_creation_time[LCGID2] = frameP;
}
if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] ==
0) {
UE_list->UE_template[CC_idP][UE_id].
ul_buffer_creation_time[LCGID3] = 0;
} else if (UE_list->UE_template[CC_idP]
[UE_id].ul_buffer_creation_time[LCGID3] == 0) {
UE_list->UE_template[CC_idP][UE_id].
ul_buffer_creation_time[LCGID3] = frameP;
}
}
payload_ptr += 3; ////sizeof(LONG_BSR);
break; break;
default: default:
LOG_E(MAC, "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", enb_mod_idP, CC_idP, rx_ces[i]); LOG_E(MAC,
"[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n",
enb_mod_idP, CC_idP, rx_ces[i]);
break; break;
} }
} }
for (i=0; i<num_sdu; i++) { 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]); LOG_D(MAC, "SDU Number %d MAC Subheader SDU_LCID %d, length %d\n",
i, rx_lcids[i], rx_lengths[i]);
T(T_ENB_MAC_UE_UL_SDU, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), T(T_ENB_MAC_UE_UL_SDU, T_INT(enb_mod_idP), T_INT(CC_idP),
T_INT(current_rnti), T_INT(frameP), T_INT(subframeP),
T_INT(rx_lcids[i]), T_INT(rx_lengths[i])); T_INT(rx_lcids[i]), T_INT(rx_lengths[i]));
T(T_ENB_MAC_UE_UL_SDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), T(T_ENB_MAC_UE_UL_SDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP),
T_INT(rx_lcids[i]), T_INT(rx_lengths[i]), T_BUFFER(payload_ptr, rx_lengths[i])); T_INT(current_rnti), T_INT(frameP), T_INT(subframeP),
T_INT(rx_lcids[i]), T_INT(rx_lengths[i]), T_BUFFER(payload_ptr,
rx_lengths
[i]));
switch (rx_lcids[i]) { switch (rx_lcids[i]) {
case CCCH : case CCCH:
if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) { if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) {
LOG_E(MAC, "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d, sdu_len %d), dropping packet\n", LOG_E(MAC,
enb_mod_idP, CC_idP, frameP, rx_lengths[i], CCCH_PAYLOAD_SIZE_MAX,sdu_lenP); "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d, sdu_len %d), dropping packet\n",
enb_mod_idP, CC_idP, frameP, rx_lengths[i],
CCCH_PAYLOAD_SIZE_MAX, sdu_lenP);
break; break;
} }
LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, Received CCCH: %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n", LOG_D(MAC,
enb_mod_idP,CC_idP,frameP, "[eNB %d][RAPROC] CC_id %d Frame %d, Received CCCH: %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n",
payload_ptr[0],payload_ptr[1],payload_ptr[2],payload_ptr[3],payload_ptr[4], payload_ptr[5], current_rnti); enb_mod_idP, CC_idP, frameP, payload_ptr[0],
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC,1); payload_ptr[1], payload_ptr[2], payload_ptr[3],
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC,0); payload_ptr[4], payload_ptr[5], current_rnti);
for (ii=0; ii<NB_RA_PROC_MAX; ii++) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
RA_TEMPLATE *RA_template = &eNB->common_channels[CC_idP].RA_template[ii]; (VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 1);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), active %d\n", (VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 0);
enb_mod_idP, CC_idP, ii, for (ii = 0; ii < NB_RA_PROC_MAX; ii++) {
RA_template->rnti, current_rnti, RA_t *ra = &mac->common_channels[CC_idP].ra[ii];
RA_template->RA_active);
LOG_D(MAC,
if ((RA_template->rnti==current_rnti) && "[mac %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), state %d\n",
(RA_template->RA_active==TRUE)) { enb_mod_idP, CC_idP, ii, ra->rnti,
current_rnti, ra->state);
if ((ra->rnti == current_rnti) && (ra->state != IDLE)) {
//payload_ptr = parse_ulsch_header(msg3,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,msg3_len); //payload_ptr = parse_ulsch_header(msg3,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,msg3_len);
if (UE_id < 0) { if (UE_id < 0) {
memcpy(&RA_template->cont_res_id[0],payload_ptr,6); memcpy(&ra->cont_res_id[0], payload_ptr, 6);
LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %ld\n", LOG_D(MAC,
enb_mod_idP,CC_idP,frameP,rx_lengths[i],payload_ptr-sduP); "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %ld\n",
enb_mod_idP, CC_idP, frameP, rx_lengths[i],
if ((UE_id=add_new_ue(enb_mod_idP,CC_idP,eNB->common_channels[CC_idP].RA_template[ii].rnti,harq_pid payload_ptr - sduP);
#ifdef Rel14
,eNB->common_channels[CC_idP].RA_template[ii].rach_resource_type if ((UE_id =
#endif add_new_ue(enb_mod_idP, CC_idP,
)) == -1 ) { mac->common_channels[CC_idP].
AssertFatal(1==0,"[MAC][eNB] Max user count reached\n"); ra[ii].rnti, harq_pid
#ifdef Rel14
,
mac->common_channels[CC_idP].
ra[ii].rach_resource_type
#endif
)) == -1) {
AssertFatal(1 == 0,
"[MAC][eNB] Max user count reached\n");
// kill RA procedure // kill RA procedure
} else } else
LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n", LOG_D(MAC,
enb_mod_idP,CC_idP,frameP,RA_template->rnti,UE_id); "[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n",
enb_mod_idP, CC_idP, frameP, ra->rnti,
UE_id);
} else { } else {
LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n", LOG_D(MAC,
enb_mod_idP,CC_idP,frameP,UE_id,rx_lengths[i],payload_ptr-sduP); "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n",
enb_mod_idP, CC_idP, frameP, UE_id,
rx_lengths[i], payload_ptr - sduP);
// kill RA procedure // kill RA procedure
} }
mac_rrc_data_ind( mac_rrc_data_ind(enb_mod_idP,
enb_mod_idP,
CC_idP, CC_idP,
frameP,subframeP, frameP, subframeP,
current_rnti, current_rnti,
CCCH, CCCH,
(uint8_t*)payload_ptr, (uint8_t *) payload_ptr,
rx_lengths[i], rx_lengths[i],
ENB_FLAG_YES, ENB_FLAG_YES, enb_mod_idP, 0);
enb_mod_idP,
0
);
if (num_ce >0) { // handle msg3 which is not RRCConnectionRequest if (num_ce > 0) { // handle msg3 which is not RRCConnectionRequest
// process_ra_message(msg3,num_ce,rx_lcids,rx_ces); // process_ra_message(msg3,num_ce,rx_lcids,rx_ces);
} }
// prepare transmission of Msg4 // prepare transmission of Msg4
RA_template->generate_Msg4 = 1; ra->state = MSG4;
RA_template->wait_ack_Msg4 = 0;
// Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, // Check if this is ok for BL/CE, or if the rule is different // Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, // Check if this is ok for BL/CE, or if the rule is different
RA_template->Msg4_frame = frameP + ((subframeP>5) ? 1 : 0); ra->Msg4_frame = frameP + ((subframeP > 5) ? 1 : 0);
RA_template->Msg4_subframe = (subframeP+4)%10; ra->Msg4_subframe = (subframeP + 4) % 10;
} // if process is active } // if process is active
} // loop on RA processes } // loop on RA processes
break ; break;
case DCCH : case DCCH:
case DCCH1 : case DCCH1:
// if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){ // if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){
#if defined(ENABLE_MAC_PAYLOAD_DEBUG) #if defined(ENABLE_MAC_PAYLOAD_DEBUG)
LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP)); LOG_T(MAC, "offset: %d\n",
for (j=0; j<32; j++) { (unsigned char) ((unsigned char *) payload_ptr - sduP));
LOG_T(MAC,"%x ",payload_ptr[j]); for (j = 0; j < 32; j++) {
LOG_T(MAC, "%x ", payload_ptr[j]);
} }
LOG_T(MAC,"\n"); LOG_T(MAC, "\n");
#endif #endif
if (UE_id != -1) { if (UE_id != -1) {
// adjust buffer occupancy of the correponding logical channel group // adjust buffer occupancy of the correponding logical channel group
if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) if (UE_list->UE_template[CC_idP][UE_id].
UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; ul_buffer_info[UE_list->UE_template[CC_idP]
[UE_id].lcgidmap[rx_lcids[i]]] >=
rx_lengths[i])
UE_list->UE_template[CC_idP][UE_id].
ul_buffer_info[UE_list->UE_template[CC_idP]
[UE_id].lcgidmap[rx_lcids[i]]] -=
rx_lengths[i];
else else
UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0; UE_list->UE_template[CC_idP][UE_id].
ul_buffer_info[UE_list->UE_template[CC_idP]
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DCCH, received %d bytes form UE %d on LCID %d \n", [UE_id].lcgidmap[rx_lcids[i]]] = 0;
enb_mod_idP,CC_idP,frameP, rx_lengths[i], UE_id, rx_lcids[i]);
mac_rlc_data_ind( LOG_D(MAC,
enb_mod_idP, "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DCCH, received %d bytes form UE %d on LCID %d \n",
current_rnti, enb_mod_idP, CC_idP, frameP, rx_lengths[i], UE_id,
enb_mod_idP, rx_lcids[i]);
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_idP][UE_id].num_pdu_rx[rx_lcids[i]]+=1;
UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]]+=rx_lengths[i];
mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, 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_idP][UE_id].
num_pdu_rx[rx_lcids[i]] += 1;
UE_list->eNB_UE_stats[CC_idP][UE_id].
num_bytes_rx[rx_lcids[i]]
+= rx_lengths[i];
} /* UE_id != -1 */
}
/* UE_id != -1 */
// } // }
break; break;
// all the DRBS // all the DRBS
case DTCH: case DTCH:
default : default:
#if defined(ENABLE_MAC_PAYLOAD_DEBUG) #if defined(ENABLE_MAC_PAYLOAD_DEBUG)
LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP)); LOG_T(MAC, "offset: %d\n",
for (j=0; j<32; j++) { (unsigned char) ((unsigned char *) payload_ptr - sduP));
LOG_T(MAC,"%x ",payload_ptr[j]); for (j = 0; j < 32; j++) {
LOG_T(MAC, "%x ", payload_ptr[j]);
} }
LOG_T(MAC,"\n"); LOG_T(MAC, "\n");
#endif #endif
if (rx_lcids[i] < NB_RB_MAX ) { if (rx_lcids[i] < NB_RB_MAX) {
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d\n", LOG_D(MAC,
enb_mod_idP,CC_idP,frameP, rx_lengths[i], UE_id, rx_lcids[i]); "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d\n",
enb_mod_idP, CC_idP, frameP, rx_lengths[i], UE_id,
rx_lcids[i]);
if (UE_id != -1) { if (UE_id != -1) {
// adjust buffer occupancy of the correponding logical channel group // adjust buffer occupancy of the correponding logical channel group
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d, removing from LCGID %ld, %d\n", LOG_D(MAC,
enb_mod_idP,CC_idP,frameP, rx_lengths[i], UE_id,rx_lcids[i], "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d, removing from LCGID %ld, %d\n",
UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]], enb_mod_idP, CC_idP, frameP, rx_lengths[i],
UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]]); UE_id, rx_lcids[i],
UE_list->UE_template[CC_idP][UE_id].
if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) lcgidmap[rx_lcids[i]],
UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; UE_list->UE_template[CC_idP][UE_id].
ul_buffer_info[UE_list->UE_template[CC_idP]
[UE_id].lcgidmap[rx_lcids[i]]]);
if (UE_list->UE_template[CC_idP][UE_id].
ul_buffer_info[UE_list->UE_template[CC_idP]
[UE_id].lcgidmap[rx_lcids[i]]]
>= rx_lengths[i])
UE_list->UE_template[CC_idP][UE_id].
ul_buffer_info[UE_list->UE_template[CC_idP]
[UE_id].lcgidmap[rx_lcids[i]]]
-= rx_lengths[i];
else else
UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0; UE_list->UE_template[CC_idP][UE_id].ul_buffer_info
if ((rx_lengths[i] <SCH_PAYLOAD_SIZE_MAX) && (rx_lengths[i] > 0) ) { // MAX SIZE OF transport block [UE_list->UE_template[CC_idP][UE_id].lcgidmap
mac_rlc_data_ind( [rx_lcids[i]]] = 0;
enb_mod_idP, if ((rx_lengths[i] < SCH_PAYLOAD_SIZE_MAX)
current_rnti, && (rx_lengths[i] > 0)) { // MAX SIZE OF transport block
enb_mod_idP, mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); //(unsigned int*)crc_status);
frameP,
ENB_FLAG_YES, UE_list->eNB_UE_stats[CC_idP][UE_id].
MBMS_FLAG_NO, num_pdu_rx[rx_lcids[i]] += 1;
rx_lcids[i], UE_list->eNB_UE_stats[CC_idP][UE_id].
(char *)payload_ptr, num_bytes_rx[rx_lcids[i]] += rx_lengths[i];
rx_lengths[i], } else { /* rx_length[i] */
1, UE_list->eNB_UE_stats[CC_idP][UE_id].
NULL);//(unsigned int*)crc_status); num_errors_rx += 1;
LOG_E(MAC,
UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]]+=1; "[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ",
UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]]+=rx_lengths[i]; enb_mod_idP, CC_idP, frameP, rx_lcids[i],
} UE_id);
else { /* rx_length[i] */ }
UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx+=1; } else { /*(UE_id != -1 */
LOG_E(MAC,"[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ", LOG_E(MAC,
enb_mod_idP, CC_idP, frameP, rx_lcids[i], UE_id); "[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ",
}
}
else {/*(UE_id != -1*/
LOG_E(MAC,"[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ",
enb_mod_idP, CC_idP, frameP, rx_lcids[i], UE_id); enb_mod_idP, CC_idP, frameP, rx_lcids[i], UE_id);
} }
} }
...@@ -568,63 +744,72 @@ void rx_sdu(const module_id_t enb_mod_idP, ...@@ -568,63 +744,72 @@ void rx_sdu(const module_id_t enb_mod_idP,
break; break;
} }
payload_ptr+=rx_lengths[i]; payload_ptr += rx_lengths[i];
} }
// Program ACK for PHICH // Program ACK for PHICH
LOG_D(MAC,"Programming PHICH ACK for rnti %x harq_pid %d (first_rb %d)\n",current_rnti,harq_pid,first_rb); LOG_D(MAC,
nfapi_hi_dci0_request_body_t *hi_dci0_req = &eNB->HI_DCI0_req[CC_idP].hi_dci0_request_body; "Programming PHICH ACK for rnti %x harq_pid %d (first_rb %d)\n",
nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi]; current_rnti, harq_pid, first_rb);
memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t)); nfapi_hi_dci0_request_body_t *hi_dci0_req =
&mac->HI_DCI0_req[CC_idP].hi_dci0_request_body;
nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu =
&hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci +
hi_dci0_req->number_of_hi];
memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t));
hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE;
hi_dci0_pdu->pdu_size = 2+sizeof(nfapi_hi_dci0_hi_pdu); hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu);
hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = first_rb; hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = first_rb;
hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0; hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0;
hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 1; hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 1;
hi_dci0_req->number_of_hi++; hi_dci0_req->number_of_hi++;
/* NN--> FK: we could either check the payload, or use a phy helper to detect a false msg3 */ /* NN--> FK: we could either check the payload, or use a phy helper to detect a false msg3 */
if ((num_sdu == 0) && (num_ce==0)) { if ((num_sdu == 0) && (num_ce == 0)) {
if (UE_id != -1) if (UE_id != -1)
UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx+=1; UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx += 1;
/* /*
if (msg3_flagP != NULL) { if (msg3_flagP != NULL) {
if( *msg3_flagP == 1 ) { if( *msg3_flagP == 1 ) {
LOG_N(MAC,"[eNB %d] CC_id %d frame %d : false msg3 detection: signal phy to canceling RA and remove the UE\n", enb_mod_idP, CC_idP, frameP); LOG_N(MAC,"[eNB %d] CC_id %d frame %d : false msg3 detection: signal phy to canceling RA and remove the UE\n", enb_mod_idP, CC_idP, frameP);
*msg3_flagP=0; *msg3_flagP=0;
} }
}*/ } */
} else { } else {
if (UE_id != -1) { if (UE_id != -1) {
UE_list->eNB_UE_stats[CC_idP][UE_id].pdu_bytes_rx=sdu_lenP; UE_list->eNB_UE_stats[CC_idP][UE_id].pdu_bytes_rx = sdu_lenP;
UE_list->eNB_UE_stats[CC_idP][UE_id].total_pdu_bytes_rx+=sdu_lenP; UE_list->eNB_UE_stats[CC_idP][UE_id].total_pdu_bytes_rx +=
UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_pdus_rx+=1; sdu_lenP;
UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_pdus_rx += 1;
} }
} }
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
stop_meas(&eNB->rx_ulsch_sdu); (VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 0);
stop_meas(&mac->rx_ulsch_sdu);
} }
uint32_t bytes_to_bsr_index(int32_t nbytes) uint32_t bytes_to_bsr_index(int32_t nbytes)
{ {
uint32_t i=0; uint32_t i = 0;
if (nbytes<0) { if (nbytes < 0) {
return(0); return (0);
} }
while ((i<BSR_TABLE_SIZE)&& while ((i < BSR_TABLE_SIZE) && (BSR_TABLE[i] <= nbytes)) {
(BSR_TABLE[i]<=nbytes)) {
i++; i++;
} }
return(i-1); return (i - 1);
} }
void add_ue_ulsch_info(module_id_t module_idP, int CC_id, int UE_id, 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][CC_id][UE_id].rnti = UE_RNTI(module_idP,UE_id); eNB_ulsch_info[module_idP][CC_id][UE_id].rnti =
UE_RNTI(module_idP, UE_id);
eNB_ulsch_info[module_idP][CC_id][UE_id].subframe = subframeP; eNB_ulsch_info[module_idP][CC_id][UE_id].subframe = subframeP;
eNB_ulsch_info[module_idP][CC_id][UE_id].status = status; eNB_ulsch_info[module_idP][CC_id][UE_id].status = status;
...@@ -639,38 +824,46 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header, ...@@ -639,38 +824,46 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header,
unsigned short *rx_lengths, unsigned short *rx_lengths,
unsigned short tb_length) unsigned short tb_length)
{ {
unsigned char not_done=1,num_ces=0,num_sdus=0,lcid,num_sdu_cnt; unsigned char not_done = 1, num_ces = 0, num_sdus =
0, lcid, num_sdu_cnt;
unsigned char *mac_header_ptr = mac_header; unsigned char *mac_header_ptr = mac_header;
unsigned short length, ce_len=0; unsigned short length, ce_len = 0;
while (not_done==1) { while (not_done == 1) {
if (((SCH_SUBHEADER_FIXED*)mac_header_ptr)->E == 0) { if (((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E == 0) {
not_done = 0; not_done = 0;
} }
lcid = ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID; lcid = ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID;
if (lcid < EXTENDED_POWER_HEADROOM) { if (lcid < EXTENDED_POWER_HEADROOM) {
if (not_done==0) { // last MAC SDU, length is implicit if (not_done == 0) { // last MAC SDU, length is implicit
mac_header_ptr++; mac_header_ptr++;
length = tb_length-(mac_header_ptr-mac_header)-ce_len; length =
tb_length - (mac_header_ptr - mac_header) - ce_len;
for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++) { for (num_sdu_cnt = 0; num_sdu_cnt < num_sdus;
num_sdu_cnt++) {
length -= rx_lengths[num_sdu_cnt]; length -= rx_lengths[num_sdu_cnt];
} }
} else { } else {
if (((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F == 0) { if (((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F == 0) {
length = ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L; length = ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L;
mac_header_ptr += 2;//sizeof(SCH_SUBHEADER_SHORT); mac_header_ptr += 2; //sizeof(SCH_SUBHEADER_SHORT);
} else { // F = 1 } else { // F = 1
length = ((((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB & 0x7f ) << 8 ) | (((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB & 0xff); length =
mac_header_ptr += 3;//sizeof(SCH_SUBHEADER_LONG); ((((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB &
0x7f) << 8) | (((SCH_SUBHEADER_LONG *)
mac_header_ptr)->L_LSB & 0xff);
mac_header_ptr += 3; //sizeof(SCH_SUBHEADER_LONG);
} }
} }
LOG_D(MAC,"[eNB] sdu %d lcid %d tb_length %d length %d (offset now %ld)\n", LOG_D(MAC,
num_sdus,lcid,tb_length, length,mac_header_ptr-mac_header); "[eNB] sdu %d lcid %d tb_length %d length %d (offset now %ld)\n",
num_sdus, lcid, tb_length, length,
mac_header_ptr - mac_header);
rx_lcids[num_sdus] = lcid; rx_lcids[num_sdus] = lcid;
rx_lengths[num_sdus] = length; rx_lengths[num_sdus] = length;
num_sdus++; num_sdus++;
...@@ -682,15 +875,17 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header, ...@@ -682,15 +875,17 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header,
num_ces++; num_ces++;
mac_header_ptr++; mac_header_ptr++;
if (lcid==LONG_BSR) { if (lcid == LONG_BSR) {
ce_len+=3; ce_len += 3;
} else if (lcid==CRNTI) { } else if (lcid == CRNTI) {
ce_len+=2; ce_len += 2;
} else if ((lcid==POWER_HEADROOM) || (lcid==TRUNCATED_BSR)|| (lcid== SHORT_BSR)) { } else if ((lcid == POWER_HEADROOM)
|| (lcid == TRUNCATED_BSR)
|| (lcid == SHORT_BSR)) {
ce_len++; ce_len++;
} else { } else {
LOG_E(MAC,"unknown CE %d \n", lcid); LOG_E(MAC, "unknown CE %d \n", lcid);
AssertFatal(1==0,"unknown CE"); AssertFatal(1 == 0, "unknown CE");
} }
} }
} }
...@@ -699,7 +894,7 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header, ...@@ -699,7 +894,7 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header,
*num_ce = num_ces; *num_ce = num_ces;
*num_sdu = num_sdus; *num_sdu = num_sdus;
return(mac_header_ptr); return (mac_header_ptr);
} }
/* This function is called by PHY layer when it schedules some /* This function is called by PHY layer when it schedules some
...@@ -707,55 +902,56 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header, ...@@ -707,55 +902,56 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header,
* The MAC scheduler has to skip the RBs used by this message 3 * The MAC scheduler has to skip the RBs used by this message 3
* (done below in schedule_ulsch). * (done below in schedule_ulsch).
*/ */
void set_msg3_subframe(module_id_t Mod_id, void
set_msg3_subframe(module_id_t Mod_id,
int CC_id, int CC_id,
int frame, int frame,
int subframe, int subframe, int rnti, int Msg3_frame,
int rnti,
int Msg3_frame,
int Msg3_subframe) int Msg3_subframe)
{ {
eNB_MAC_INST *eNB=RC.mac[Mod_id]; eNB_MAC_INST *mac = RC.mac[Mod_id];
int i; int i;
for (i=0; i<NB_RA_PROC_MAX; i++) { for (i = 0; i < NB_RA_PROC_MAX; i++) {
if (eNB->common_channels[CC_id].RA_template[i].RA_active == TRUE && if (mac->common_channels[CC_id].ra[i].state != IDLE &&
eNB->common_channels[CC_id].RA_template[i].rnti == rnti) { mac->common_channels[CC_id].ra[i].rnti == rnti) {
eNB->common_channels[CC_id].RA_template[i].Msg3_subframe = Msg3_subframe; mac->common_channels[CC_id].ra[i].Msg3_subframe =
Msg3_subframe;
break; break;
} }
} }
} }
void schedule_ulsch(module_id_t module_idP, void
frame_t frameP, schedule_ulsch(module_id_t module_idP, frame_t frameP,
sub_frame_t subframeP) sub_frame_t subframeP)
{ {
uint16_t first_rb[MAX_NUM_CCs],i; uint16_t first_rb[MAX_NUM_CCs], i;
int CC_id; int CC_id;
eNB_MAC_INST *eNB=RC.mac[module_idP]; eNB_MAC_INST *mac = RC.mac[module_idP];
COMMON_channels_t *cc; COMMON_channels_t *cc;
start_meas(&eNB->schedule_ulsch); start_meas(&mac->schedule_ulsch);
int sched_subframe = (subframeP+4)%10; int sched_subframe = (subframeP + 4) % 10;
cc = &eNB->common_channels[0]; cc = &mac->common_channels[0];
int tdd_sfa; int tdd_sfa;
// for TDD: check subframes where we have to act and return if nothing should be done now // for TDD: check subframes where we have to act and return if nothing should be done now
if (cc->tdd_Config) { if (cc->tdd_Config) {
tdd_sfa = cc->tdd_Config->subframeAssignment; tdd_sfa = cc->tdd_Config->subframeAssignment;
switch (subframeP) { switch (subframeP) {
case 0: case 0:
if ((tdd_sfa == 0)|| if ((tdd_sfa == 0) || (tdd_sfa == 3) || (tdd_sfa == 6))
(tdd_sfa == 3)|| sched_subframe = 4;
(tdd_sfa == 6)) sched_subframe = 4; else
else return; return;
break; break;
case 1: case 1:
if ((tdd_sfa==0)|| if ((tdd_sfa == 0) || (tdd_sfa == 1))
(tdd_sfa==1)) sched_subframe = 7; sched_subframe = 7;
else if (tdd_sfa==6) sched_subframe = 8; else if (tdd_sfa == 6)
sched_subframe = 8;
break; break;
default: default:
return; return;
...@@ -763,37 +959,52 @@ void schedule_ulsch(module_id_t module_idP, ...@@ -763,37 +959,52 @@ void schedule_ulsch(module_id_t module_idP,
case 2: // Don't schedule UL in subframe 2 for TDD case 2: // Don't schedule UL in subframe 2 for TDD
return; return;
case 3: case 3:
if (tdd_sfa==2) sched_subframe = 7; if (tdd_sfa == 2)
else return; sched_subframe = 7;
else
return;
break; break;
case 4: case 4:
if (tdd_sfa==1) sched_subframe = 8; if (tdd_sfa == 1)
else return; sched_subframe = 8;
else
return;
break; break;
case 5: case 5:
if (tdd_sfa==0) sched_subframe = 9; if (tdd_sfa == 0)
else if (tdd_sfa==6) sched_subframe = 3; sched_subframe = 9;
else return; else if (tdd_sfa == 6)
sched_subframe = 3;
else
return;
break; break;
case 6: case 6:
if (tdd_sfa==1) sched_subframe = 2; if (tdd_sfa == 1)
else if (tdd_sfa==6) sched_subframe = 3; sched_subframe = 2;
else return; else if (tdd_sfa == 6)
sched_subframe = 3;
else
return;
break; break;
case 7: case 7:
return; return;
case 8: case 8:
if ((tdd_sfa>=2) || (tdd_sfa<=5)) sched_subframe=2; if ((tdd_sfa >= 2) || (tdd_sfa <= 5))
else return; sched_subframe = 2;
else
return;
break; break;
case 9: case 9:
if ((tdd_sfa==1) || (tdd_sfa==3) || (tdd_sfa==4)) sched_subframe=3; if ((tdd_sfa == 1) || (tdd_sfa == 3) || (tdd_sfa == 4))
else if (tdd_sfa==6) sched_subframe=4; sched_subframe = 3;
else return; else if (tdd_sfa == 6)
sched_subframe = 4;
else
return;
break; break;
} }
} }
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
...@@ -814,29 +1025,27 @@ void schedule_ulsch(module_id_t module_idP, ...@@ -814,29 +1025,27 @@ void schedule_ulsch(module_id_t module_idP,
// not sure about the break (can there be more than 1 active RA procedure?) // not sure about the break (can there be more than 1 active RA procedure?)
for (i=0; i<NB_RA_PROC_MAX; i++) { for (i = 0; i < NB_RA_PROC_MAX; i++) {
if ((cc->RA_template[i].RA_active == TRUE) && if ((cc->ra[i].state == WAITMSG3) &&
(cc->RA_template[i].generate_rar == 0) && (cc->ra[i].Msg3_subframe == sched_subframe)) {
(cc->RA_template[i].generate_Msg4 == 0) &&
(cc->RA_template[i].wait_ack_Msg4 == 0) &&
(cc->RA_template[i].Msg3_subframe == sched_subframe)) {
first_rb[CC_id]++; first_rb[CC_id]++;
// cc->RA_template[i].Msg3_subframe = -1; // cc->ray[i].Msg3_subframe = -1;
break; break;
} }
} }
} }
schedule_ulsch_rnti(module_idP, frameP, subframeP, sched_subframe,first_rb); schedule_ulsch_rnti(module_idP, frameP, subframeP, sched_subframe,
first_rb);
stop_meas(&eNB->schedule_ulsch); stop_meas(&mac->schedule_ulsch);
} }
void schedule_ulsch_rnti(module_id_t module_idP, void
schedule_ulsch_rnti(module_id_t module_idP,
frame_t frameP, frame_t frameP,
sub_frame_t subframeP, sub_frame_t subframeP,
unsigned char sched_subframeP, unsigned char sched_subframeP, uint16_t * first_rb)
uint16_t *first_rb)
{ {
int UE_id; int UE_id;
uint8_t aggregation = 2; uint8_t aggregation = 2;
...@@ -845,53 +1054,57 @@ void schedule_ulsch_rnti(module_id_t module_idP, ...@@ -845,53 +1054,57 @@ void schedule_ulsch_rnti(module_id_t module_idP,
uint8_t harq_pid = 0; uint8_t harq_pid = 0;
uint8_t status = 0; uint8_t status = 0;
uint8_t rb_table_index = -1; uint8_t rb_table_index = -1;
uint32_t cqi_req,cshift,ndi,tpc; uint32_t cqi_req, cshift, ndi, tpc;
int32_t normalized_rx_power; int32_t normalized_rx_power;
int32_t target_rx_power=-90; int32_t target_rx_power = -90;
static int32_t tpc_accumulated=0; static int32_t tpc_accumulated = 0;
int n; int n;
int CC_id = 0; int CC_id = 0;
int drop_ue=0; int drop_ue = 0;
int N_RB_UL; int N_RB_UL;
eNB_MAC_INST *eNB = RC.mac[module_idP]; eNB_MAC_INST *mac = RC.mac[module_idP];
COMMON_channels_t *cc = eNB->common_channels; COMMON_channels_t *cc = mac->common_channels;
UE_list_t *UE_list=&eNB->UE_list; UE_list_t *UE_list = &mac->UE_list;
UE_TEMPLATE *UE_template; UE_TEMPLATE *UE_template;
UE_sched_ctrl *UE_sched_ctrl; UE_sched_ctrl *UE_sched_ctrl;
int sched_frame=frameP; int sched_frame = frameP;
int rvidx_tab[4] = {0,2,3,1}; int rvidx_tab[4] = { 0, 2, 3, 1 };
if (sched_subframeP<subframeP) sched_frame++; if (sched_subframeP < subframeP)
sched_frame++;
nfapi_hi_dci0_request_body_t *hi_dci0_req = &eNB->HI_DCI0_req[CC_id].hi_dci0_request_body; nfapi_hi_dci0_request_body_t *hi_dci0_req =
&mac->HI_DCI0_req[CC_id].hi_dci0_request_body;
nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu; nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu;
nfapi_ul_config_request_body_t *ul_req_tmp = &eNB->UL_req_tmp[CC_id][sched_subframeP].ul_config_request_body; nfapi_ul_config_request_body_t *ul_req_tmp =
&mac->UL_req_tmp[CC_id][sched_subframeP].ul_config_request_body;
LOG_D(MAC,"entering ulsch preprocesor\n"); LOG_D(MAC, "entering ulsch preprocesor\n");
ulsch_scheduler_pre_processor(module_idP, ulsch_scheduler_pre_processor(module_idP, frameP, subframeP, first_rb);
frameP,
subframeP,
first_rb);
LOG_D(MAC,"exiting ulsch preprocesor\n"); LOG_D(MAC, "exiting ulsch preprocesor\n");
eNB->HI_DCI0_req[CC_id].sfn_sf = (frameP<<4)+subframeP; mac->HI_DCI0_req[CC_id].sfn_sf = (frameP << 4) + subframeP;
// loop over all active UEs // loop over all active UEs
for (UE_id=UE_list->head_ul; UE_id>=0; UE_id=UE_list->next_ul[UE_id]) { for (UE_id = UE_list->head_ul; UE_id >= 0;
UE_id = UE_list->next_ul[UE_id]) {
// don't schedule if Msg4 is not received yet // don't schedule if Msg4 is not received yet
if (UE_list->UE_template[UE_PCCID(module_idP,UE_id)][UE_id].configured==FALSE) { if (UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id].
LOG_D(MAC,"[eNB %d] frame %d subfarme %d, UE %d: not configured, skipping UE scheduling \n", configured == FALSE) {
module_idP,frameP,subframeP,UE_id); LOG_D(MAC,
"[eNB %d] frame %d subfarme %d, UE %d: not configured, skipping UE scheduling \n",
module_idP, frameP, subframeP, UE_id);
continue; continue;
} }
rnti = UE_RNTI(module_idP,UE_id); rnti = UE_RNTI(module_idP, UE_id);
if (rnti==NOT_A_RNTI) { if (rnti == NOT_A_RNTI) {
LOG_W(MAC,"[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n", module_idP,frameP,subframeP,UE_id); LOG_W(MAC, "[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n",
module_idP, frameP, subframeP, UE_id);
continue; continue;
} }
...@@ -907,10 +1120,10 @@ void schedule_ulsch_rnti(module_id_t module_idP, ...@@ -907,10 +1120,10 @@ void schedule_ulsch_rnti(module_id_t module_idP,
drop_ue = 1; drop_ue = 1;
break; break;
} }
}*/ } */
if (drop_ue == 1) { if (drop_ue == 1) {
/* we can't come here, ulsch_scheduler_pre_processor won't put in the list a UE with no PHY context */ /* we can't come here, ulsch_scheduler_pre_processor won't put in the list a UE with no PHY context */
abort(); abort();
/* TODO: this is a hack. Sometimes the UE has no PHY context but /* TODO: this is a hack. Sometimes the UE has no PHY context but
* is still present in the MAC with 'ul_failure_timer' = 0 and * is still present in the MAC with 'ul_failure_timer' = 0 and
* 'ul_out_of_sync' = 0. It seems wrong and the UE stays there forever. Let's * 'ul_out_of_sync' = 0. It seems wrong and the UE stays there forever. Let's
...@@ -920,18 +1133,19 @@ abort(); ...@@ -920,18 +1133,19 @@ abort();
*/ */
if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 0 && if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 0 &&
UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0) { UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0) {
LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: UE in weird state, let's put it 'out of sync'\n", LOG_W(MAC,
module_idP,frameP,subframeP,UE_id,rnti,CC_id); "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: UE in weird state, let's put it 'out of sync'\n",
module_idP, frameP, subframeP, UE_id, rnti, CC_id);
// inform RRC of failure and clear timer // inform RRC of failure and clear timer
mac_eNB_rrc_ul_failure(module_idP,CC_id,frameP,subframeP,rnti); mac_eNB_rrc_ul_failure(module_idP, CC_id, frameP,
UE_list->UE_sched_ctrl[UE_id].ul_failure_timer=0; subframeP, rnti);
UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync=1; UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0;
UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 1;
} }
continue; continue;
} }
// loop over all active UL CC_ids for this UE // loop over all active UL CC_ids for this UE
for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) { for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) {
// This is the actual CC_id in the list // This is the actual CC_id in the list
CC_id = UE_list->ordered_ULCCids[n][UE_id]; CC_id = UE_list->ordered_ULCCids[n][UE_id];
N_RB_UL = to_prb(cc[CC_id].ul_Bandwidth); N_RB_UL = to_prb(cc[CC_id].ul_Bandwidth);
...@@ -942,50 +1156,63 @@ abort(); ...@@ -942,50 +1156,63 @@ abort();
format0); format0);
*/ */
if (CCE_allocation_infeasible(module_idP,CC_id,1,subframeP,aggregation,rnti)) { if (CCE_allocation_infeasible
LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: not enough nCCE\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id); (module_idP, CC_id, 1, subframeP, aggregation, rnti)) {
LOG_W(MAC,
"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: not enough nCCE\n",
module_idP, frameP, subframeP, UE_id, rnti, CC_id);
continue; // break; continue; // break;
} }
/* be sure that there are some free RBs */ /* be sure that there are some free RBs */
if (first_rb[CC_id] >= N_RB_UL-1) { if (first_rb[CC_id] >= N_RB_UL - 1) {
LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n", LOG_W(MAC,
module_idP,frameP,subframeP,UE_id,rnti,CC_id); "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n",
module_idP, frameP, subframeP, UE_id, rnti, CC_id);
continue; continue;
} }
// if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel // if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel
UE_template = &UE_list->UE_template[CC_id][UE_id]; UE_template = &UE_list->UE_template[CC_id][UE_id];
UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id]; UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id];
harq_pid = subframe2harqpid(&cc[CC_id],sched_frame,sched_subframeP); harq_pid =
subframe2harqpid(&cc[CC_id], sched_frame, sched_subframeP);
round = UE_sched_ctrl->round_UL[CC_id][harq_pid]; round = UE_sched_ctrl->round_UL[CC_id][harq_pid];
AssertFatal(round<8,"round %d > 7 for UE %d/%x\n",round,UE_id,rnti); AssertFatal(round < 8, "round %d > 7 for UE %d/%x\n", round,
LOG_D(MAC,"[eNB %d] frame %d subframe %d,Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n", UE_id, rnti);
module_idP,frameP,subframeP,harq_pid,UE_id,rnti,CC_id, aggregation,N_RB_UL); LOG_D(MAC,
"[eNB %d] frame %d subframe %d,Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n",
RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->ul_total_buffer; module_idP, frameP, subframeP, harq_pid, UE_id, rnti,
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO,RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP]); CC_id, aggregation, N_RB_UL);
if (UE_is_to_be_scheduled(module_idP,CC_id,UE_id) > 0 || round > 0)// || ((frameP%10)==0))
RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP *
10) +
subframeP] =
UE_template->ul_total_buffer;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME
(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO,
RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP *
10) +
subframeP]);
if (UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0 || round > 0) // || ((frameP%10)==0))
// if there is information on bsr of DCCH, DTCH or if there is UL_SR, or if there is a packet to retransmit, or we want to schedule a periodic feedback every 10 frames // if there is information on bsr of DCCH, DTCH or if there is UL_SR, or if there is a packet to retransmit, or we want to schedule a periodic feedback every 10 frames
{ {
LOG_D(MAC,"[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n", LOG_D(MAC,
module_idP,harq_pid,frameP,subframeP,UE_id,rnti,round,UE_template->ul_SR, "[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n",
module_idP, harq_pid, frameP, subframeP, UE_id, rnti,
round, UE_template->ul_SR,
UE_sched_ctrl->ul_inactivity_timer, UE_sched_ctrl->ul_inactivity_timer,
UE_sched_ctrl->ul_failure_timer, UE_sched_ctrl->ul_failure_timer,
UE_sched_ctrl->cqi_req_timer); UE_sched_ctrl->cqi_req_timer);
// reset the scheduling request // reset the scheduling request
UE_template->ul_SR = 0; UE_template->ul_SR = 0;
status = mac_eNB_get_rrc_status(module_idP,rnti); status = mac_eNB_get_rrc_status(module_idP, rnti);
if (status < RRC_CONNECTED) if (status < RRC_CONNECTED)
cqi_req = 0; cqi_req = 0;
else if (UE_sched_ctrl->cqi_req_timer>30) { else if (UE_sched_ctrl->cqi_req_timer > 30) {
cqi_req = 1; cqi_req = 1;
UE_sched_ctrl->cqi_req_timer=0; UE_sched_ctrl->cqi_req_timer = 0;
} } else
else
cqi_req = 0; cqi_req = 0;
//power control //power control
...@@ -997,16 +1224,18 @@ abort(); ...@@ -997,16 +1224,18 @@ abort();
// this assumes accumulated tpc // this assumes accumulated tpc
// make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out
int32_t framex10psubframe = UE_template->pusch_tpc_tx_frame*10+UE_template->pusch_tpc_tx_subframe; int32_t framex10psubframe =
if (((framex10psubframe+10)<=(frameP*10+subframeP)) || //normal case UE_template->pusch_tpc_tx_frame * 10 +
((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=10)))) //frame wrap-around UE_template->pusch_tpc_tx_subframe;
if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || //normal case
((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) //frame wrap-around
{ {
UE_template->pusch_tpc_tx_frame=frameP; UE_template->pusch_tpc_tx_frame = frameP;
UE_template->pusch_tpc_tx_subframe=subframeP; UE_template->pusch_tpc_tx_subframe = subframeP;
if (normalized_rx_power>(target_rx_power+4)) { if (normalized_rx_power > (target_rx_power + 4)) {
tpc = 0; //-1 tpc = 0; //-1
tpc_accumulated--; tpc_accumulated--;
} else if (normalized_rx_power<(target_rx_power-4)) { } else if (normalized_rx_power < (target_rx_power - 4)) {
tpc = 2; //+1 tpc = 2; //+1
tpc_accumulated++; tpc_accumulated++;
} else { } else {
...@@ -1016,109 +1245,156 @@ abort(); ...@@ -1016,109 +1245,156 @@ abort();
tpc = 1; //0 tpc = 1; //0
} }
//tpc = 1; //tpc = 1;
if (tpc!=1) { if (tpc != 1) {
LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", LOG_D(MAC,
module_idP,frameP,subframeP,harq_pid,tpc, "[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n",
tpc_accumulated,normalized_rx_power,target_rx_power); module_idP, frameP, subframeP, harq_pid, tpc,
tpc_accumulated, normalized_rx_power,
target_rx_power);
} }
// new transmission // new transmission
if (round==0) { if (round == 0) {
ndi = 1-UE_template->oldNDI_UL[harq_pid]; ndi = 1 - UE_template->oldNDI_UL[harq_pid];
UE_template->oldNDI_UL[harq_pid]=ndi; UE_template->oldNDI_UL[harq_pid] = ndi;
UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power=normalized_rx_power; UE_list->eNB_UE_stats[CC_id][UE_id].
UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power=target_rx_power; normalized_rx_power = normalized_rx_power;
UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=UE_template->pre_assigned_mcs_ul; UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power =
UE_template->mcs_UL[harq_pid] = UE_template->pre_assigned_mcs_ul;//cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS target_rx_power;
if (UE_template->pre_allocated_rb_table_index_ul >=0) { UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1 =
rb_table_index=UE_template->pre_allocated_rb_table_index_ul; UE_template->pre_assigned_mcs_ul;
UE_template->mcs_UL[harq_pid] = UE_template->pre_assigned_mcs_ul; //cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS
if (UE_template->pre_allocated_rb_table_index_ul >= 0) {
rb_table_index =
UE_template->pre_allocated_rb_table_index_ul;
} else { } else {
UE_template->mcs_UL[harq_pid]=10;//cmin (10, openair_daq_vars.target_ue_ul_mcs); UE_template->mcs_UL[harq_pid] = 10; //cmin (10, openair_daq_vars.target_ue_ul_mcs);
rb_table_index=5; // for PHR rb_table_index = 5; // for PHR
} }
UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=UE_template->mcs_UL[harq_pid]; UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 =
UE_template->mcs_UL[harq_pid];
// buffer_occupancy = UE_template->ul_total_buffer; // buffer_occupancy = UE_template->ul_total_buffer;
while (((rb_table[rb_table_index]>(N_RB_UL-1-first_rb[CC_id])) || while (((rb_table[rb_table_index] >
(rb_table[rb_table_index]>45)) && (N_RB_UL - 1 - first_rb[CC_id]))
(rb_table_index>0)) { || (rb_table[rb_table_index] > 45))
&& (rb_table_index > 0)) {
rb_table_index--; rb_table_index--;
} }
UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid],rb_table[rb_table_index]); UE_template->TBS_UL[harq_pid] =
UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=rb_table[rb_table_index]; get_TBS_UL(UE_template->mcs_UL[harq_pid],
UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS=UE_template->TBS_UL[harq_pid]; rb_table[rb_table_index]);
UE_list->eNB_UE_stats[CC_id][UE_id].
total_rbs_used_rx += rb_table[rb_table_index];
UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS =
UE_template->TBS_UL[harq_pid];
// buffer_occupancy -= TBS; // buffer_occupancy -= TBS;
T(T_ENB_MAC_UE_UL_SCHEDULE, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T(T_ENB_MAC_UE_UL_SCHEDULE, T_INT(module_idP),
T_INT(subframeP), T_INT(harq_pid), T_INT(UE_template->mcs_UL[harq_pid]), T_INT(first_rb[CC_id]), T_INT(rb_table[rb_table_index]), T_INT(CC_id), T_INT(rnti), T_INT(frameP),
T_INT(subframeP), T_INT(harq_pid),
T_INT(UE_template->mcs_UL[harq_pid]),
T_INT(first_rb[CC_id]),
T_INT(rb_table[rb_table_index]),
T_INT(UE_template->TBS_UL[harq_pid]), T_INT(ndi)); T_INT(UE_template->TBS_UL[harq_pid]), T_INT(ndi));
if (mac_eNB_get_rrc_status(module_idP,rnti) < RRC_CONNECTED) if (mac_eNB_get_rrc_status(module_idP, rnti) <
LOG_D(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n", RRC_CONNECTED)
module_idP,harq_pid,rnti,CC_id,frameP,subframeP,UE_id,UE_template->mcs_UL[harq_pid], LOG_D(MAC,
first_rb[CC_id],rb_table[rb_table_index], "[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n",
rb_table_index,UE_template->TBS_UL[harq_pid],harq_pid); module_idP, harq_pid, rnti, CC_id, frameP,
subframeP, UE_id,
UE_template->mcs_UL[harq_pid],
first_rb[CC_id], rb_table[rb_table_index],
rb_table_index,
UE_template->TBS_UL[harq_pid], harq_pid);
// bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB) // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB)
//store for possible retransmission //store for possible retransmission
UE_template->nb_rb_ul[harq_pid] = rb_table[rb_table_index]; UE_template->nb_rb_ul[harq_pid] =
rb_table[rb_table_index];
UE_template->first_rb_ul[harq_pid] = first_rb[CC_id]; UE_template->first_rb_ul[harq_pid] = first_rb[CC_id];
UE_sched_ctrl->ul_scheduled |= (1<<harq_pid); UE_sched_ctrl->ul_scheduled |= (1 << harq_pid);
if (UE_id == UE_list->head) if (UE_id == UE_list->head)
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED,UE_sched_ctrl->ul_scheduled); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME
(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED,
UE_sched_ctrl->ul_scheduled);
// adjust total UL buffer status by TBS, wait for UL sdus to do final update // adjust total UL buffer status by TBS, wait for UL sdus to do final update
LOG_D(MAC,"[eNB %d] CC_id %d UE %d/%x : adjusting ul_total_buffer, old %d, TBS %d\n", module_idP,CC_id,UE_id,rnti,UE_template->ul_total_buffer,UE_template->TBS_UL[harq_pid]); LOG_D(MAC,
if (UE_template->ul_total_buffer > UE_template->TBS_UL[harq_pid]) "[eNB %d] CC_id %d UE %d/%x : adjusting ul_total_buffer, old %d, TBS %d\n",
UE_template->ul_total_buffer -= UE_template->TBS_UL[harq_pid]; module_idP, CC_id, UE_id, rnti,
UE_template->ul_total_buffer,
UE_template->TBS_UL[harq_pid]);
if (UE_template->ul_total_buffer >
UE_template->TBS_UL[harq_pid])
UE_template->ul_total_buffer -=
UE_template->TBS_UL[harq_pid];
else else
UE_template->ul_total_buffer = 0; UE_template->ul_total_buffer = 0;
LOG_D(MAC,"ul_total_buffer, new %d\n", UE_template->ul_total_buffer); LOG_D(MAC, "ul_total_buffer, new %d\n",
UE_template->ul_total_buffer);
// Cyclic shift for DM RS // Cyclic shift for DM RS
cshift = 0;// values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1) cshift = 0; // values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1)
// save it for a potential retransmission // save it for a potential retransmission
UE_template->cshift[harq_pid] = cshift; UE_template->cshift[harq_pid] = cshift;
hi_dci0_pdu = &hi_dci0_req->hi_dci0_pdu_list[eNB->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_dci+eNB->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_hi]; hi_dci0_pdu =
memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t)); &hi_dci0_req->hi_dci0_pdu_list[mac->HI_DCI0_req
[CC_id].
hi_dci0_request_body.
number_of_dci +
mac->HI_DCI0_req
[CC_id].
hi_dci0_request_body.
number_of_hi];
memset((void *) hi_dci0_pdu, 0,
sizeof(nfapi_hi_dci0_request_pdu_t));
hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE;
hi_dci0_pdu->pdu_size = 2+sizeof(nfapi_hi_dci0_dci_pdu); hi_dci0_pdu->pdu_size =
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format = NFAPI_UL_DCI_FORMAT_0; 2 + sizeof(nfapi_hi_dci0_dci_pdu);
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format =
NFAPI_UL_DCI_FORMAT_0;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level =
aggregation;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power = 6000; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power =
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.resource_block_start = first_rb[CC_id]; 6000;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.number_of_resource_block = rb_table[rb_table_index]; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 = UE_template->mcs_UL[harq_pid]; resource_block_start = first_rb[CC_id];
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = cshift; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.frequency_hopping_enabled_flag = 0; number_of_resource_block =
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.new_data_indication_1 = ndi; rb_table[rb_table_index];
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 =
UE_template->mcs_UL[harq_pid];
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.
cyclic_shift_2_for_drms = cshift;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.
frequency_hopping_enabled_flag = 0;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.
new_data_indication_1 = ndi;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc = tpc; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc = tpc;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request = cqi_req; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request =
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = UE_template->DAI_ul[sched_subframeP]; cqi_req;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index =
UE_template->DAI_ul[sched_subframeP];
eNB->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_dci++; mac->HI_DCI0_req[CC_id].hi_dci0_request_body.
number_of_dci++;
LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", LOG_D(MAC,
harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP); "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n",
harq_pid, frameP, subframeP, UE_id, rnti,
sched_frame, sched_subframeP);
// Add UL_config PDUs // Add UL_config PDUs
fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, first_rb[CC_id], // resource_block_start
cqi_req,
cc,
UE_template->physicalConfigDedicated,
get_tmode(module_idP,CC_id,UE_id),
eNB->ul_handle,
rnti,
first_rb[CC_id], // resource_block_start
rb_table[rb_table_index], // number_of_resource_blocks rb_table[rb_table_index], // number_of_resource_blocks
UE_template->mcs_UL[harq_pid], UE_template->mcs_UL[harq_pid], cshift, // cyclic_shift_2_for_drms
cshift, // cyclic_shift_2_for_drms
0, // frequency_hopping_enabled_flag 0, // frequency_hopping_enabled_flag
0, // frequency_hopping_bits 0, // frequency_hopping_bits
ndi, // new_data_indication ndi, // new_data_indication
...@@ -1127,88 +1403,98 @@ abort(); ...@@ -1127,88 +1403,98 @@ abort();
0, // ul_tx_mode 0, // ul_tx_mode
0, // current_tx_nb 0, // current_tx_nb
0, // n_srs 0, // n_srs
get_TBS_UL(UE_template->mcs_UL[harq_pid], get_TBS_UL
rb_table[rb_table_index]) (UE_template->
); mcs_UL[harq_pid],
rb_table
[rb_table_index]));
#ifdef Rel14 #ifdef Rel14
if (UE_template->rach_resource_type>0) { // This is a BL/CE UE allocation if (UE_template->rach_resource_type > 0) { // This is a BL/CE UE allocation
fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions
UE_template->rach_resource_type>2 ? 2 : 1,
1, //total_number_of_repetitions
1, //repetition_number 1, //repetition_number
(frameP*10)+subframeP); (frameP *
10) +
subframeP);
} }
#endif #endif
ul_req_tmp->number_of_pdus++; ul_req_tmp->number_of_pdus++;
eNB->ul_handle++; mac->ul_handle++;
add_ue_ulsch_info(module_idP, add_ue_ulsch_info(module_idP,
CC_id, CC_id, UE_id, subframeP,
UE_id,
subframeP,
S_UL_SCHEDULED); S_UL_SCHEDULED);
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", module_idP,CC_id,frameP,subframeP,UE_id); LOG_D(MAC,
"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n",
module_idP, CC_id, frameP, subframeP, UE_id);
// increment first rb for next UE allocation // increment first rb for next UE allocation
first_rb[CC_id]+=rb_table[rb_table_index]; first_rb[CC_id] += rb_table[rb_table_index];
} } else { // round > 0 => retransmission
else { // round > 0 => retransmission T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION,
T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(module_idP), T_INT(CC_id), T_INT(rnti),
T_INT(subframeP), T_INT(harq_pid), T_INT(UE_template->mcs_UL[harq_pid]), T_INT(first_rb[CC_id]), T_INT(rb_table[rb_table_index]), T_INT(frameP), T_INT(subframeP), T_INT(harq_pid),
T_INT(round)); T_INT(UE_template->mcs_UL[harq_pid]),
T_INT(first_rb[CC_id]),
T_INT(rb_table[rb_table_index]), T_INT(round));
// fill in NAK information // fill in NAK information
hi_dci0_pdu = &hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi]; hi_dci0_pdu =
memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t)); &hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->
number_of_dci +
hi_dci0_req->
number_of_hi];
memset((void *) hi_dci0_pdu, 0,
sizeof(nfapi_hi_dci0_request_pdu_t));
hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE;
hi_dci0_pdu->pdu_size = 2+sizeof(nfapi_hi_dci0_hi_pdu); hi_dci0_pdu->pdu_size =
hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = UE_template->first_rb_ul[harq_pid]; 2 + sizeof(nfapi_hi_dci0_hi_pdu);
hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = UE_template->cshift[harq_pid]; hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start =
UE_template->first_rb_ul[harq_pid];
hi_dci0_pdu->hi_pdu.hi_pdu_rel8.
cyclic_shift_2_for_drms =
UE_template->cshift[harq_pid];
hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 0; hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 0;
hi_dci0_req->number_of_hi++; hi_dci0_req->number_of_hi++;
LOG_D(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) UE %d (mcs %d, first rb %d, nb_rb %d, TBS %d, round %d)\n", LOG_D(MAC,
module_idP,harq_pid,rnti,CC_id,frameP,subframeP,UE_id,UE_template->mcs_UL[harq_pid], "[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) UE %d (mcs %d, first rb %d, nb_rb %d, TBS %d, round %d)\n",
UE_template->first_rb_ul[harq_pid], UE_template->nb_rb_ul[harq_pid], module_idP, harq_pid, rnti, CC_id, frameP,
UE_template->TBS_UL[harq_pid],round); subframeP, UE_id, UE_template->mcs_UL[harq_pid],
UE_template->first_rb_ul[harq_pid],
UE_template->nb_rb_ul[harq_pid],
UE_template->TBS_UL[harq_pid], round);
// Add UL_config PDUs // Add UL_config PDUs
LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", LOG_D(MAC,
harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP); "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n",
fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], harq_pid, frameP, subframeP, UE_id, rnti,
cqi_req, sched_frame, sched_subframeP);
cc, fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, UE_template->first_rb_ul[harq_pid], // resource_block_start
UE_template->physicalConfigDedicated,
get_tmode(module_idP,CC_id,UE_id),
eNB->ul_handle,
rnti,
UE_template->first_rb_ul[harq_pid], // resource_block_start
UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks
UE_template->mcs_UL[harq_pid], UE_template->mcs_UL[harq_pid], cshift, // cyclic_shift_2_for_drms
cshift, // cyclic_shift_2_for_drms
0, // frequency_hopping_enabled_flag 0, // frequency_hopping_enabled_flag
0, // frequency_hopping_bits 0, // frequency_hopping_bits
UE_template->oldNDI_UL[harq_pid], // new_data_indication UE_template->oldNDI_UL[harq_pid], // new_data_indication
rvidx_tab[round&3], // redundancy_version rvidx_tab[round & 3], // redundancy_version
harq_pid, // harq_process_number harq_pid, // harq_process_number
0, // ul_tx_mode 0, // ul_tx_mode
0, // current_tx_nb 0, // current_tx_nb
0, // n_srs 0, // n_srs
UE_template->TBS_UL[harq_pid] UE_template->
); TBS_UL[harq_pid]);
#ifdef Rel14 #ifdef Rel14
if (UE_template->rach_resource_type>0) { // This is a BL/CE UE allocation if (UE_template->rach_resource_type > 0) { // This is a BL/CE UE allocation
fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions
UE_template->rach_resource_type>2 ? 2 : 1,
1, //total_number_of_repetitions
1, //repetition_number 1, //repetition_number
(frameP*10)+subframeP); (frameP *
10) +
subframeP);
} }
#endif #endif
ul_req_tmp->number_of_pdus++; ul_req_tmp->number_of_pdus++;
eNB->ul_handle++; mac->ul_handle++;
}/* } /*
else if (round > 0) { //we schedule a retransmission else if (round > 0) { //we schedule a retransmission
ndi = UE_template->oldNDI_UL[harq_pid]; ndi = UE_template->oldNDI_UL[harq_pid];
......
...@@ -102,5 +102,3 @@ extern DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu2; ...@@ -102,5 +102,3 @@ extern DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu2;
extern DCI1E_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu1E; extern DCI1E_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu1E;
#endif //DEF_H #endif //DEF_H
...@@ -39,12 +39,12 @@ ...@@ -39,12 +39,12 @@
/* /*
* slice specific scheduler * slice specific scheduler
*/ */
typedef void (*slice_scheduler)(module_id_t mod_id, typedef void (*slice_scheduler) (module_id_t mod_id,
int slice_id, int slice_id,
uint32_t frame, uint32_t frame,
uint32_t subframe, uint32_t subframe,
int *mbsfn_flag, int *mbsfn_flag,
Protocol__FlexranMessage **dl_info); Protocol__FlexranMessage ** dl_info);
...@@ -55,7 +55,7 @@ void flexran_schedule_ue_spec_default(mid_t mod_id, ...@@ -55,7 +55,7 @@ void flexran_schedule_ue_spec_default(mid_t mod_id,
uint32_t frame, uint32_t frame,
uint32_t subframe, uint32_t subframe,
int *mbsfn_flag, int *mbsfn_flag,
Protocol__FlexranMessage **dl_info); Protocol__FlexranMessage ** dl_info);
/* /*
* slice specific scheduler for embb * slice specific scheduler for embb
*/ */
...@@ -65,7 +65,7 @@ flexran_schedule_ue_spec_embb(mid_t mod_id, ...@@ -65,7 +65,7 @@ flexran_schedule_ue_spec_embb(mid_t mod_id,
uint32_t frame, uint32_t frame,
uint32_t subframe, uint32_t subframe,
int *mbsfn_flag, int *mbsfn_flag,
Protocol__FlexranMessage **dl_info); Protocol__FlexranMessage ** dl_info);
/* /*
* slice specific scheduler for urllc * slice specific scheduler for urllc
*/ */
...@@ -75,7 +75,7 @@ flexran_schedule_ue_spec_urllc(mid_t mod_id, ...@@ -75,7 +75,7 @@ flexran_schedule_ue_spec_urllc(mid_t mod_id,
uint32_t frame, uint32_t frame,
uint32_t subframe, uint32_t subframe,
int *mbsfn_flag, int *mbsfn_flag,
Protocol__FlexranMessage **dl_info); Protocol__FlexranMessage ** dl_info);
/* /*
* slice specific scheduler for mmtc * slice specific scheduler for mmtc
...@@ -86,7 +86,7 @@ flexran_schedule_ue_spec_mmtc(mid_t mod_id, ...@@ -86,7 +86,7 @@ flexran_schedule_ue_spec_mmtc(mid_t mod_id,
uint32_t frame, uint32_t frame,
uint32_t subframe, uint32_t subframe,
int *mbsfn_flag, int *mbsfn_flag,
Protocol__FlexranMessage **dl_info); Protocol__FlexranMessage ** dl_info);
/* /*
* slice specific scheduler for best effort traffic * slice specific scheduler for best effort traffic
*/ */
...@@ -96,7 +96,7 @@ flexran_schedule_ue_spec_be(mid_t mod_id, ...@@ -96,7 +96,7 @@ flexran_schedule_ue_spec_be(mid_t mod_id,
uint32_t frame, uint32_t frame,
uint32_t subframe, uint32_t subframe,
int *mbsfn_flag, int *mbsfn_flag,
Protocol__FlexranMessage **dl_info); Protocol__FlexranMessage ** dl_info);
/* /*
* common flexran scheduler function * common flexran scheduler function
...@@ -107,82 +107,110 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -107,82 +107,110 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
uint32_t frame, uint32_t frame,
uint32_t subframe, uint32_t subframe,
int *mbsfn_flag, int *mbsfn_flag,
Protocol__FlexranMessage **dl_info); Protocol__FlexranMessage ** dl_info);
uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage, uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage, int total_rbs);
int total_rbs);
int flexran_slice_member(int UE_id, int flexran_slice_member(int UE_id, int slice_id);
int slice_id);
int flexran_slice_maxmcs(int slice_id) ; int flexran_slice_maxmcs(int slice_id);
void _store_dlsch_buffer (module_id_t Mod_id, void _store_dlsch_buffer(module_id_t Mod_id,
int slice_id, int slice_id,
frame_t frameP, frame_t frameP, sub_frame_t subframeP);
sub_frame_t subframeP);
void _assign_rbs_required (module_id_t Mod_id, void _assign_rbs_required(module_id_t Mod_id,
int slice_id, int slice_id,
frame_t frameP, frame_t frameP,
sub_frame_t subframe, sub_frame_t subframe,
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], uint16_t
uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES], nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
int min_rb_unit[MAX_NUM_CCs]); uint16_t
nb_rbs_allowed_slice[MAX_NUM_CCs]
[MAX_NUM_SLICES], int min_rb_unit[MAX_NUM_CCs]);
void _dlsch_scheduler_pre_processor (module_id_t Mod_id, void _dlsch_scheduler_pre_processor(module_id_t Mod_id,
int slice_id, int slice_id,
frame_t frameP, frame_t frameP,
sub_frame_t subframeP, sub_frame_t subframeP,
int N_RBG[MAX_NUM_CCs], int N_RBG[MAX_NUM_CCs],
int *mbsfn_flag); int *mbsfn_flag);
void _dlsch_scheduler_pre_processor_reset (int module_idP, void _dlsch_scheduler_pre_processor_reset(int module_idP,
int UE_id, int UE_id,
uint8_t CC_id, uint8_t CC_id,
int frameP, int frameP,
int subframeP, int subframeP,
int N_RBG, int N_RBG,
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], uint16_t
uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX], nb_rbs_required[MAX_NUM_CCs]
uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES], [NUMBER_OF_UE_MAX],
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX], uint16_t
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]); nb_rbs_required_remaining
[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
void _dlsch_scheduler_pre_processor_allocate (module_id_t Mod_id, uint16_t
nb_rbs_allowed_slice[MAX_NUM_CCs]
[MAX_NUM_SLICES],
unsigned char
rballoc_sub[MAX_NUM_CCs]
[N_RBG_MAX],
unsigned char
MIMO_mode_indicator[MAX_NUM_CCs]
[N_RBG_MAX]);
void _dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id,
int UE_id, int UE_id,
uint8_t CC_id, uint8_t CC_id,
int N_RBG, int N_RBG,
int transmission_mode, int transmission_mode,
int min_rb_unit, int min_rb_unit,
uint8_t N_RB_DL, uint8_t N_RB_DL,
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], uint16_t
uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX], nb_rbs_required[MAX_NUM_CCs]
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX], [NUMBER_OF_UE_MAX],
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]); uint16_t
nb_rbs_required_remaining
[MAX_NUM_CCs]
[NUMBER_OF_UE_MAX],
unsigned char
rballoc_sub[MAX_NUM_CCs]
[N_RBG_MAX],
unsigned char
MIMO_mode_indicator
[MAX_NUM_CCs][N_RBG_MAX]);
/* /*
* Default scheduler used by the eNB agent * Default scheduler used by the eNB agent
*/ */
void flexran_schedule_ue_spec_default(mid_t mod_id, uint32_t frame, uint32_t subframe, void flexran_schedule_ue_spec_default(mid_t mod_id, uint32_t frame,
int *mbsfn_flag, Protocol__FlexranMessage **dl_info); uint32_t subframe, int *mbsfn_flag,
Protocol__FlexranMessage ** dl_info);
/* /*
* Data plane function for applying the DL decisions of the scheduler * Data plane function for applying the DL decisions of the scheduler
*/ */
void flexran_apply_dl_scheduling_decisions(mid_t mod_id, uint32_t frame, uint32_t subframe, int *mbsfn_flag, void flexran_apply_dl_scheduling_decisions(mid_t mod_id, uint32_t frame,
Protocol__FlexranMessage *dl_scheduling_info); uint32_t subframe,
int *mbsfn_flag,
Protocol__FlexranMessage *
dl_scheduling_info);
/* /*
* Data plane function for applying the UE specific DL decisions of the scheduler * Data plane function for applying the UE specific DL decisions of the scheduler
*/ */
void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id, uint32_t frame, uint32_t subframe, int *mbsfn_flag, void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
uint32_t n_dl_ue_data, Protocol__FlexDlData **dl_ue_data); uint32_t frame,
uint32_t subframe,
int *mbsfn_flag,
uint32_t n_dl_ue_data,
Protocol__FlexDlData **
dl_ue_data);
/* /*
* Data plane function for filling the DCI structure * Data plane function for filling the DCI structure
*/ */
void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti, Protocol__FlexDlDci *dl_dci); void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti,
Protocol__FlexDlDci * dl_dci);
#endif #endif
...@@ -59,48 +59,56 @@ ...@@ -59,48 +59,56 @@
#include "SIMULATION/TOOLS/defs.h" // for taus #include "SIMULATION/TOOLS/defs.h" // for taus
void flexran_apply_dl_scheduling_decisions(mid_t mod_id, void
flexran_apply_dl_scheduling_decisions(mid_t mod_id,
uint32_t frame, uint32_t frame,
uint32_t subframe, uint32_t subframe,
int *mbsfn_flag, int *mbsfn_flag,
Protocol__FlexranMessage *dl_scheduling_info) { Protocol__FlexranMessage *
dl_scheduling_info)
{
Protocol__FlexDlMacConfig *mac_config = dl_scheduling_info->dl_mac_config_msg; Protocol__FlexDlMacConfig *mac_config =
dl_scheduling_info->dl_mac_config_msg;
// Check if there is anything to schedule for random access // Check if there is anything to schedule for random access
if (mac_config->n_dl_rar > 0) { if (mac_config->n_dl_rar > 0) {
/*TODO: call the random access data plane function*/ /*TODO: call the random access data plane function */
} }
// Check if there is anything to schedule for paging/broadcast // Check if there is anything to schedule for paging/broadcast
if (mac_config->n_dl_broadcast > 0) { if (mac_config->n_dl_broadcast > 0) {
/*TODO: call the broadcast/paging data plane function*/ /*TODO: call the broadcast/paging data plane function */
} }
// Check if there is anything to schedule for the UEs // Check if there is anything to schedule for the UEs
if (mac_config->n_dl_ue_data > 0) { if (mac_config->n_dl_ue_data > 0) {
flexran_apply_ue_spec_scheduling_decisions(mod_id, frame, subframe, mbsfn_flag, flexran_apply_ue_spec_scheduling_decisions(mod_id, frame, subframe,
mac_config->n_dl_ue_data, mac_config->dl_ue_data); mbsfn_flag,
mac_config->
n_dl_ue_data,
mac_config->dl_ue_data);
} }
} }
void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id, void
flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
uint32_t frame, uint32_t frame,
uint32_t subframe, uint32_t subframe,
int *mbsfn_flag, int *mbsfn_flag,
uint32_t n_dl_ue_data, uint32_t n_dl_ue_data,
Protocol__FlexDlData **dl_ue_data) { Protocol__FlexDlData **
dl_ue_data)
{
uint8_t CC_id; uint8_t CC_id;
int UE_id; int UE_id;
mac_rlc_status_resp_t rlc_status; mac_rlc_status_resp_t rlc_status;
unsigned char ta_len=0; unsigned char ta_len = 0;
unsigned char header_len = 0, header_len_tmp = 0; unsigned char header_len = 0, header_len_tmp = 0;
unsigned char sdu_lcids[11],offset,num_sdus=0; unsigned char sdu_lcids[11], offset, num_sdus = 0;
uint16_t nb_rb; uint16_t nb_rb;
uint16_t TBS, sdu_lengths[11],rnti,padding=0,post_padding=0; uint16_t TBS, sdu_lengths[11], rnti, padding = 0, post_padding = 0;
unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES];
uint8_t round = 0; uint8_t round = 0;
uint8_t harq_pid = 0; uint8_t harq_pid = 0;
...@@ -135,7 +143,7 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id, ...@@ -135,7 +143,7 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
UE_id = find_ue(rnti, PHY_vars_eNB_g[mod_id][CC_id]); UE_id = find_ue(rnti, PHY_vars_eNB_g[mod_id][CC_id]);
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id,CC_id,rnti); eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti);
round = dl_dci->rv[0]; round = dl_dci->rv[0];
harq_pid = dl_dci->harq_process; harq_pid = dl_dci->harq_process;
...@@ -152,7 +160,10 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id, ...@@ -152,7 +160,10 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
if (dl_data->n_ce_bitmap > 0) { if (dl_data->n_ce_bitmap > 0) {
//Check if there is TA command and set the length appropriately //Check if there is TA command and set the length appropriately
ta_len = (dl_data->ce_bitmap[0] & PROTOCOL__FLEX_CE_TYPE__FLPCET_TA) ? 2 : 0; ta_len =
(dl_data->
ce_bitmap[0] & PROTOCOL__FLEX_CE_TYPE__FLPCET_TA) ? 2
: 0;
} }
num_sdus = 0; num_sdus = 0;
...@@ -164,9 +175,11 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id, ...@@ -164,9 +175,11 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
last_sdu_header_len = 0; last_sdu_header_len = 0;
for (j = 0; j < n_lc; j++) { for (j = 0; j < n_lc; j++) {
sdu_lengths[j] = 0; sdu_lengths[j] = 0;
lcid = dl_data->rlc_pdu[j]->rlc_pdu_tb[0]->logical_channel_id; lcid =
dl_data->rlc_pdu[j]->rlc_pdu_tb[0]->logical_channel_id;
rlc_size = dl_data->rlc_pdu[j]->rlc_pdu_tb[0]->size; rlc_size = dl_data->rlc_pdu[j]->rlc_pdu_tb[0]->size;
LOG_D(MAC,"[TEST] [eNB %d] [Frame %d] [Subframe %d], LCID %d, CC_id %d, Requesting %d bytes from RLC (RRC message)\n", LOG_D(MAC,
"[TEST] [eNB %d] [Frame %d] [Subframe %d], LCID %d, CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
mod_id, frame, subframe, lcid, CC_id, rlc_size); mod_id, frame, subframe, lcid, CC_id, rlc_size);
if (rlc_size > 0) { if (rlc_size > 0) {
...@@ -176,9 +189,7 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id, ...@@ -176,9 +189,7 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
frame, frame,
subframe, subframe,
ENB_FLAG_YES, ENB_FLAG_YES,
MBMS_FLAG_NO, MBMS_FLAG_NO, lcid, 0);
lcid,
0);
if (rlc_status.bytes_in_buffer > 0) { if (rlc_status.bytes_in_buffer > 0) {
...@@ -190,36 +201,31 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id, ...@@ -190,36 +201,31 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
rlc_size = 3; rlc_size = 3;
} }
rlc_status = mac_rlc_status_ind(mod_id, rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, subframe, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, rlc_size); // transport block set size
rnti,
mod_id,
frame,
subframe,
ENB_FLAG_YES,
MBMS_FLAG_NO,
lcid,
rlc_size); // transport block set size
LOG_D(MAC, "[TEST] RLC can give %d bytes for LCID %d during second call\n", rlc_status.bytes_in_buffer, lcid); LOG_D(MAC,
"[TEST] RLC can give %d bytes for LCID %d during second call\n",
rlc_status.bytes_in_buffer, lcid);
if (rlc_status.bytes_in_buffer > 0) { if (rlc_status.bytes_in_buffer > 0) {
sdu_lengths[j] = mac_rlc_data_req(mod_id, sdu_lengths[j] = mac_rlc_data_req(mod_id, rnti, mod_id, frame, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, rlc_size, //not used
rnti, (char *)
mod_id, &dlsch_buffer
frame, [sdu_length_total]);
ENB_FLAG_YES,
MBMS_FLAG_NO,
lcid,
rlc_size, //not used
(char *)&dlsch_buffer[sdu_length_total]);
LOG_D(MAC,"[eNB %d][LCID %d] CC_id %d Got %d bytes from RLC\n",mod_id, lcid, CC_id, sdu_lengths[j]); LOG_D(MAC,
"[eNB %d][LCID %d] CC_id %d Got %d bytes from RLC\n",
mod_id, lcid, CC_id, sdu_lengths[j]);
sdu_length_total += sdu_lengths[j]; sdu_length_total += sdu_lengths[j];
sdu_lcids[j] = lcid; sdu_lcids[j] = lcid;
UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid] += 1; UE_list->
UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[j]; eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid]
+= 1;
UE_list->
eNB_UE_stats[CC_id][UE_id].num_bytes_tx
[lcid] += sdu_lengths[j];
if (sdu_lengths[j] < 128) { if (sdu_lengths[j] < 128) {
header_len += 2; header_len += 2;
...@@ -248,9 +254,9 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id, ...@@ -248,9 +254,9 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
} }
// If we need a 1 or 2 bit padding or no padding at all // If we need a 1 or 2 bit padding or no padding at all
if ((TBS - header_len - sdu_length_total - ta_len) <= 2 if ((TBS - header_len - sdu_length_total - ta_len) <= 2 || (TBS - header_len - sdu_length_total - ta_len) > TBS) { //protect from overflow
|| (TBS - header_len - sdu_length_total - ta_len) > TBS) { //protect from overflow padding =
padding = (TBS - header_len - sdu_length_total - ta_len); (TBS - header_len - sdu_length_total - ta_len);
post_padding = 0; post_padding = 0;
} else { // The last sdu needs to have a length field, since we add padding } else { // The last sdu needs to have a length field, since we add padding
padding = 0; padding = 0;
...@@ -273,87 +279,101 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id, ...@@ -273,87 +279,101 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
harq_pid_round[UE_id][harq_pid] = 0; harq_pid_round[UE_id][harq_pid] = 0;
continue; continue;
} }
// LOG_I(FLEXRAN_AGENT, "[Frame %d][Subframe %d] TBS is %d and bytes are %d\n", frame, subframe, TBS, sdu_length_total); // LOG_I(FLEXRAN_AGENT, "[Frame %d][Subframe %d] TBS is %d and bytes are %d\n", frame, subframe, TBS, sdu_length_total);
offset = generate_dlsch_header((unsigned char*)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], offset = generate_dlsch_header((unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], num_sdus, //num_sdus
num_sdus, //num_sdus
sdu_lengths, // sdu_lengths, //
sdu_lcids, sdu_lcids, 255, // no drx
255, // no drx
ta_update, // timing advance ta_update, // timing advance
NULL, // contention res id NULL, // contention res id
padding, padding, post_padding);
post_padding);
#ifdef DEBUG_eNB_SCHEDULER #ifdef DEBUG_eNB_SCHEDULER
LOG_T(MAC,"[eNB %d] First 16 bytes of DLSCH : \n"); LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n");
for (i=0; i<16; i++) { for (i = 0; i < 16; i++) {
LOG_T(MAC,"%x.",dlsch_buffer[i]); LOG_T(MAC, "%x.", dlsch_buffer[i]);
} }
LOG_T(MAC,"\n"); LOG_T(MAC, "\n");
#endif #endif
// cycle through SDUs and place in dlsch_buffer // cycle through SDUs and place in dlsch_buffer
memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset],dlsch_buffer,sdu_length_total); memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].
payload[0][offset], dlsch_buffer, sdu_length_total);
// memcpy(&eNB_mac_inst[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); // memcpy(&eNB_mac_inst[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]);
// fill remainder of DLSCH with random data // fill remainder of DLSCH with random data
for (j=0; j<(TBS-sdu_length_total-offset); j++) { for (j = 0; j < (TBS - sdu_length_total - offset); j++) {
UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset+sdu_length_total+j] = (char)(taus()&0xff); UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset +
sdu_length_total
+ j] =
(char) (taus() & 0xff);
} }
//eNB_mac_inst[0].DLSCH_pdu[0][0].payload[0][offset+sdu_lengths[0]+j] = (char)(taus()&0xff); //eNB_mac_inst[0].DLSCH_pdu[0][0].payload[0][offset+sdu_lengths[0]+j] = (char)(taus()&0xff);
if (opt_enabled == 1) { if (opt_enabled == 1) {
trace_pdu(1, (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], trace_pdu(1,
TBS, mod_id, 3, UE_RNTI(mod_id, UE_id), (uint8_t *)
eNB->frame, eNB->subframe,0,0); UE_list->DLSCH_pdu[CC_id][0][UE_id].
LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", payload[0], TBS, mod_id, 3, UE_RNTI(mod_id,
mod_id, CC_id, frame, UE_RNTI(mod_id,UE_id), TBS); UE_id),
eNB->frame, eNB->subframe, 0, 0);
LOG_D(OPT,
"[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n",
mod_id, CC_id, frame, UE_RNTI(mod_id, UE_id),
TBS);
} }
// store stats // store stats
eNB->eNB_stats[CC_id].dlsch_bytes_tx+=sdu_length_total; eNB->eNB_stats[CC_id].dlsch_bytes_tx += sdu_length_total;
eNB->eNB_stats[CC_id].dlsch_pdus_tx+=1; eNB->eNB_stats[CC_id].dlsch_pdus_tx += 1;
UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->DL_cqi[0]; UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi =
eNB_UE_stats->DL_cqi[0];
UE_list->eNB_UE_stats[CC_id][UE_id].crnti= rnti;
UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status=mac_eNB_get_rrc_status(mod_id, rnti); UE_list->eNB_UE_stats[CC_id][UE_id].crnti = rnti;
UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status =
mac_eNB_get_rrc_status(mod_id, rnti);
UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid;
UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round; UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round;
//nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; //nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
//Find the number of resource blocks and set them to the template for retransmissions //Find the number of resource blocks and set them to the template for retransmissions
nb_rb = get_min_rb_unit(mod_id, CC_id); nb_rb = get_min_rb_unit(mod_id, CC_id);
uint16_t stats_tbs = mac_xface->get_TBS_DL(dl_dci->mcs[0], nb_rb); uint16_t stats_tbs =
mac_xface->get_TBS_DL(dl_dci->mcs[0], nb_rb);
while (stats_tbs < TBS) { while (stats_tbs < TBS) {
nb_rb += get_min_rb_unit(mod_id, CC_id); nb_rb += get_min_rb_unit(mod_id, CC_id);
stats_tbs = mac_xface->get_TBS_DL(dl_dci->mcs[0], nb_rb); stats_tbs =
mac_xface->get_TBS_DL(dl_dci->mcs[0], nb_rb);
} }
// LOG_I(FLEXRAN_AGENT, "The MCS was %d\n", dl_dci->mcs[0]); // LOG_I(FLEXRAN_AGENT, "The MCS was %d\n", dl_dci->mcs[0]);
UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb; UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb;
UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used += nb_rb; UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used +=
UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1=dl_dci->mcs[0]; nb_rb;
UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2=dl_dci->mcs[0]; UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 =
dl_dci->mcs[0];
UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 =
dl_dci->mcs[0];
UE_list->eNB_UE_stats[CC_id][UE_id].TBS = TBS; UE_list->eNB_UE_stats[CC_id][UE_id].TBS = TBS;
UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes= TBS - sdu_length_total; UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes =
UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes+= sdu_length_total; TBS - sdu_length_total;
UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes+= TBS; UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes +=
UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus+=1; sdu_length_total;
UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes += TBS;
UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus += 1;
//eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[eNB_UE_stats->DL_cqi[0]]; //eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[eNB_UE_stats->DL_cqi[0]];
//eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); //eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs);
} else { } else {
LOG_D(FLEXRAN_AGENT, "No need to schedule a dci after all. Just drop it\n"); LOG_D(FLEXRAN_AGENT,
"No need to schedule a dci after all. Just drop it\n");
harq_pid_updated[UE_id][harq_pid] = 1; harq_pid_updated[UE_id][harq_pid] = 1;
harq_pid_round[UE_id][harq_pid] = 0; harq_pid_round[UE_id][harq_pid] = 0;
continue; continue;
...@@ -375,8 +395,11 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id, ...@@ -375,8 +395,11 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
flexran_fill_oai_dci(mod_id, CC_id, rnti, dl_dci); flexran_fill_oai_dci(mod_id, CC_id, rnti, dl_dci);
} }
} }
void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti,
Protocol__FlexDlDci *dl_dci) { void
flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti,
Protocol__FlexDlDci * dl_dci)
{
void *DLSCH_dci = NULL; void *DLSCH_dci = NULL;
DCI_PDU *DCI_pdu; DCI_PDU *DCI_pdu;
...@@ -397,7 +420,8 @@ void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti, ...@@ -397,7 +420,8 @@ void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti,
// round = dl_dci->rv[0]; // round = dl_dci->rv[0];
// Note this code is for a specific DCI format // Note this code is for a specific DCI format
DLSCH_dci = (void *)UE_list->UE_template[CC_id][UE_id].DLSCH_DCI[harq_pid]; DLSCH_dci =
(void *) UE_list->UE_template[CC_id][UE_id].DLSCH_DCI[harq_pid];
DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu; DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu;
frame_parms[CC_id] = mac_xface->get_lte_frame_parms(mod_id, CC_id); frame_parms[CC_id] = mac_xface->get_lte_frame_parms(mod_id, CC_id);
...@@ -405,7 +429,8 @@ void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti, ...@@ -405,7 +429,8 @@ void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti,
if (dl_dci->has_tpc == 1) { if (dl_dci->has_tpc == 1) {
// Check if tpc has been set and reset measurement */ // Check if tpc has been set and reset measurement */
if ((dl_dci->tpc == 0) || (dl_dci->tpc == 2)) { if ((dl_dci->tpc == 0) || (dl_dci->tpc == 2)) {
eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti); eNB_UE_stats =
mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti);
eNB_UE_stats->Po_PUCCH_update = 0; eNB_UE_stats->Po_PUCCH_update = 0;
} }
} }
...@@ -418,9 +443,11 @@ void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti, ...@@ -418,9 +443,11 @@ void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti,
FILL_DCI_TDD_1(DCI1_1_5MHz_TDD_t, DLSCH_dci, dl_dci); FILL_DCI_TDD_1(DCI1_1_5MHz_TDD_t, DLSCH_dci, dl_dci);
size_bytes = sizeof(DCI1_1_5MHz_TDD_t); size_bytes = sizeof(DCI1_1_5MHz_TDD_t);
size_bits = sizeof_DCI1_1_5MHz_TDD_t; size_bits = sizeof_DCI1_1_5MHz_TDD_t;
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) { } else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
//TODO //TODO
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) { } else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
//TODO //TODO
} }
} else { } else {
...@@ -428,9 +455,11 @@ void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti, ...@@ -428,9 +455,11 @@ void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti,
FILL_DCI_FDD_1(DCI1_1_5MHz_FDD_t, DLSCH_dci, dl_dci); FILL_DCI_FDD_1(DCI1_1_5MHz_FDD_t, DLSCH_dci, dl_dci);
size_bytes = sizeof(DCI1_1_5MHz_FDD_t); size_bytes = sizeof(DCI1_1_5MHz_FDD_t);
size_bits = sizeof_DCI1_1_5MHz_FDD_t; size_bits = sizeof_DCI1_1_5MHz_FDD_t;
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) { } else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
//TODO //TODO
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) { } else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
//TODO //TODO
} }
} }
...@@ -441,9 +470,11 @@ void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti, ...@@ -441,9 +470,11 @@ void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti,
FILL_DCI_TDD_1(DCI1_5MHz_TDD_t, DLSCH_dci, dl_dci); FILL_DCI_TDD_1(DCI1_5MHz_TDD_t, DLSCH_dci, dl_dci);
size_bytes = sizeof(DCI1_5MHz_TDD_t); size_bytes = sizeof(DCI1_5MHz_TDD_t);
size_bits = sizeof_DCI1_5MHz_TDD_t; size_bits = sizeof_DCI1_5MHz_TDD_t;
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) { } else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
//TODO //TODO
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) { } else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
//TODO //TODO
} }
} else { } else {
...@@ -451,9 +482,11 @@ void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti, ...@@ -451,9 +482,11 @@ void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti,
FILL_DCI_FDD_1(DCI1_5MHz_FDD_t, DLSCH_dci, dl_dci); FILL_DCI_FDD_1(DCI1_5MHz_FDD_t, DLSCH_dci, dl_dci);
size_bytes = sizeof(DCI1_5MHz_FDD_t); size_bytes = sizeof(DCI1_5MHz_FDD_t);
size_bits = sizeof_DCI1_5MHz_FDD_t; size_bits = sizeof_DCI1_5MHz_FDD_t;
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) { } else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
//TODO //TODO
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) { } else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
//TODO //TODO
} }
} }
...@@ -464,9 +497,11 @@ void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti, ...@@ -464,9 +497,11 @@ void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti,
FILL_DCI_TDD_1(DCI1_10MHz_TDD_t, DLSCH_dci, dl_dci); FILL_DCI_TDD_1(DCI1_10MHz_TDD_t, DLSCH_dci, dl_dci);
size_bytes = sizeof(DCI1_10MHz_TDD_t); size_bytes = sizeof(DCI1_10MHz_TDD_t);
size_bits = sizeof_DCI1_10MHz_TDD_t; size_bits = sizeof_DCI1_10MHz_TDD_t;
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) { } else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
//TODO //TODO
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) { } else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
//TODO //TODO
} }
} else { } else {
...@@ -474,9 +509,11 @@ void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti, ...@@ -474,9 +509,11 @@ void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti,
FILL_DCI_FDD_1(DCI1_10MHz_FDD_t, DLSCH_dci, dl_dci); FILL_DCI_FDD_1(DCI1_10MHz_FDD_t, DLSCH_dci, dl_dci);
size_bytes = sizeof(DCI1_10MHz_FDD_t); size_bytes = sizeof(DCI1_10MHz_FDD_t);
size_bits = sizeof_DCI1_10MHz_FDD_t; size_bits = sizeof_DCI1_10MHz_FDD_t;
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) { } else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
//TODO //TODO
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) { } else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
//TODO //TODO
} }
} }
...@@ -487,9 +524,11 @@ void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti, ...@@ -487,9 +524,11 @@ void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti,
FILL_DCI_TDD_1(DCI1_20MHz_TDD_t, DLSCH_dci, dl_dci); FILL_DCI_TDD_1(DCI1_20MHz_TDD_t, DLSCH_dci, dl_dci);
size_bytes = sizeof(DCI1_20MHz_TDD_t); size_bytes = sizeof(DCI1_20MHz_TDD_t);
size_bits = sizeof_DCI1_20MHz_TDD_t; size_bits = sizeof_DCI1_20MHz_TDD_t;
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) { } else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
//TODO //TODO
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) { } else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
//TODO //TODO
} }
} else { } else {
...@@ -497,9 +536,11 @@ void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti, ...@@ -497,9 +536,11 @@ void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti,
FILL_DCI_FDD_1(DCI1_20MHz_FDD_t, DLSCH_dci, dl_dci); FILL_DCI_FDD_1(DCI1_20MHz_FDD_t, DLSCH_dci, dl_dci);
size_bytes = sizeof(DCI1_20MHz_FDD_t); size_bytes = sizeof(DCI1_20MHz_FDD_t);
size_bits = sizeof_DCI1_20MHz_FDD_t; size_bits = sizeof_DCI1_20MHz_FDD_t;
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) { } else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
//TODO //TODO
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) { } else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
//TODO //TODO
} }
} }
...@@ -507,7 +548,7 @@ void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti, ...@@ -507,7 +548,7 @@ void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti,
} }
//Set format to the proper type //Set format to the proper type
switch(dl_dci->format) { switch (dl_dci->format) {
case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1: case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1:
format = format1; format = format1;
break; break;
...@@ -536,16 +577,12 @@ void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti, ...@@ -536,16 +577,12 @@ void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti,
format = 3; format = 3;
break; break;
default: default:
/*TODO: Need to deal with unsupported DCI type*/ /*TODO: Need to deal with unsupported DCI type */
return; return;
} }
add_ue_spec_dci(DCI_pdu, add_ue_spec_dci(DCI_pdu,
DLSCH_dci, DLSCH_dci,
rnti, rnti,
size_bytes, size_bytes, dl_dci->aggr_level, size_bits, format, 0);
dl_dci->aggr_level,
size_bits,
format,
0);
} }
...@@ -61,7 +61,7 @@ ...@@ -61,7 +61,7 @@
#include "SIMULATION/TOOLS/defs.h" // for taus #include "SIMULATION/TOOLS/defs.h" // for taus
#if defined(ENABLE_ITTI) #if defined(ENABLE_ITTI)
# include "intertask_interface.h" #include "intertask_interface.h"
#endif #endif
#define ENABLE_MAC_PAYLOAD_DEBUG #define ENABLE_MAC_PAYLOAD_DEBUG
...@@ -96,26 +96,28 @@ int slicing_strategy = UEID_TO_SLICEID; ...@@ -96,26 +96,28 @@ int slicing_strategy = UEID_TO_SLICEID;
int slicing_strategy_current = UEID_TO_SLICEID; int slicing_strategy_current = UEID_TO_SLICEID;
// RB share for each slice for past and current time // RB share for each slice for past and current time
float slice_percentage[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; float slice_percentage[MAX_NUM_SLICES] = { 1.0, 0.0, 0.0, 0.0 };
float slice_percentage_current[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; float slice_percentage_current[MAX_NUM_SLICES] = { 1.0, 0.0, 0.0, 0.0 };
float total_slice_percentage = 0; float total_slice_percentage = 0;
// MAX MCS for each slice for past and current time // MAX MCS for each slice for past and current time
int slice_maxmcs[MAX_NUM_SLICES] = {28, 28, 28, 28}; int slice_maxmcs[MAX_NUM_SLICES] = { 28, 28, 28, 28 };
int slice_maxmcs_current[MAX_NUM_SLICES] = {28, 28, 28, 28}; int slice_maxmcs_current[MAX_NUM_SLICES] = { 28, 28, 28, 28 };
int update_dl_scheduler[MAX_NUM_SLICES] = {1, 1, 1, 1}; int update_dl_scheduler[MAX_NUM_SLICES] = { 1, 1, 1, 1 };
int update_dl_scheduler_current[MAX_NUM_SLICES] = {1, 1, 1, 1}; int update_dl_scheduler_current[MAX_NUM_SLICES] = { 1, 1, 1, 1 };
// name of available scheduler // name of available scheduler
char *dl_scheduler_type[MAX_NUM_SLICES] = {"flexran_schedule_ue_spec_embb", char *dl_scheduler_type[MAX_NUM_SLICES] =
{ "flexran_schedule_ue_spec_embb",
"flexran_schedule_ue_spec_urllc", "flexran_schedule_ue_spec_urllc",
"flexran_schedule_ue_spec_mmtc", "flexran_schedule_ue_spec_mmtc",
"flexran_schedule_ue_spec_be" // best effort "flexran_schedule_ue_spec_be" // best effort
}; };
// pointer to the slice specific scheduler // pointer to the slice specific scheduler
slice_scheduler slice_sched[MAX_NUM_SLICES] = {0}; slice_scheduler slice_sched[MAX_NUM_SLICES] = { 0 };
/** /**
...@@ -125,78 +127,87 @@ slice_scheduler slice_sched[MAX_NUM_SLICES] = {0}; ...@@ -125,78 +127,87 @@ slice_scheduler slice_sched[MAX_NUM_SLICES] = {0};
// This function stores the downlink buffer for all the logical channels // This function stores the downlink buffer for all the logical channels
void _store_dlsch_buffer (module_id_t Mod_id, void
int slice_id, _store_dlsch_buffer(module_id_t Mod_id,
frame_t frameP, int slice_id, frame_t frameP, sub_frame_t subframeP)
sub_frame_t subframeP)
{ {
int UE_id,i; int UE_id, i;
rnti_t rnti; rnti_t rnti;
mac_rlc_status_resp_t rlc_status; mac_rlc_status_resp_t rlc_status;
UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list; UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
UE_TEMPLATE *UE_template; UE_TEMPLATE *UE_template;
for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
if (UE_list->active[UE_id] != TRUE) continue; if (UE_list->active[UE_id] != TRUE)
continue;
if (flexran_slice_member(UE_id, slice_id) == 0) if (flexran_slice_member(UE_id, slice_id) == 0)
continue; continue;
UE_template = &UE_list->UE_template[UE_PCCID(Mod_id,UE_id)][UE_id]; UE_template =
&UE_list->UE_template[UE_PCCID(Mod_id, UE_id)][UE_id];
// clear logical channel interface variables // clear logical channel interface variables
UE_template->dl_buffer_total = 0; UE_template->dl_buffer_total = 0;
UE_template->dl_pdus_total = 0; UE_template->dl_pdus_total = 0;
for(i=0; i< MAX_NUM_LCID; i++) { for (i = 0; i < MAX_NUM_LCID; i++) {
UE_template->dl_buffer_info[i]=0; UE_template->dl_buffer_info[i] = 0;
UE_template->dl_pdus_in_buffer[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_creation_time[i] = 0;
UE_template->dl_buffer_head_sdu_remaining_size_to_send[i]=0; UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = 0;
} }
rnti = UE_RNTI(Mod_id,UE_id); rnti = UE_RNTI(Mod_id, UE_id);
for(i=0; i< MAX_NUM_LCID; i++) { // loop over all the logical channels for (i = 0; i < MAX_NUM_LCID; i++) { // loop over all the logical channels
rlc_status = mac_rlc_status_ind(Mod_id,rnti, Mod_id,frameP,subframeP,ENB_FLAG_YES,MBMS_FLAG_NO,i,0 ); rlc_status =
mac_rlc_status_ind(Mod_id, rnti, Mod_id, frameP, subframeP,
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_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_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_creation_time[i] =
UE_template->dl_buffer_head_sdu_creation_time_max = cmax(UE_template->dl_buffer_head_sdu_creation_time_max, rlc_status.head_sdu_creation_time;
rlc_status.head_sdu_creation_time ); UE_template->dl_buffer_head_sdu_creation_time_max =
UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = rlc_status.head_sdu_remaining_size_to_send; cmax(UE_template->dl_buffer_head_sdu_creation_time_max,
UE_template->dl_buffer_head_sdu_is_segmented[i] = rlc_status.head_sdu_is_segmented; rlc_status.head_sdu_creation_time);
UE_template->dl_buffer_total += UE_template->dl_buffer_info[i];//storing the total dlsch buffer UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] =
UE_template->dl_pdus_total += UE_template->dl_pdus_in_buffer[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_info[i]; //storing the total dlsch buffer
UE_template->dl_pdus_total +=
UE_template->dl_pdus_in_buffer[i];
#ifdef DEBUG_eNB_SCHEDULER #ifdef DEBUG_eNB_SCHEDULER
/* note for dl_buffer_head_sdu_remaining_size_to_send[i] : /* note for dl_buffer_head_sdu_remaining_size_to_send[i] :
* 0 if head SDU has not been segmented (yet), else remaining size not already segmented and sent * 0 if head SDU has not been segmented (yet), else remaining size not already segmented and sent
*/ */
if (UE_template->dl_buffer_info[i]>0) if (UE_template->dl_buffer_info[i] > 0)
LOG_D(MAC, LOG_D(MAC,
"[eNB %d][SLICE %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", "[eNB %d][SLICE %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, slice_id,frameP, subframeP, UE_id, Mod_id, slice_id, frameP, subframeP, UE_id,
i, UE_template->dl_pdus_in_buffer[i],UE_template->dl_buffer_info[i], 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_creation_time[i],
UE_template->dl_buffer_head_sdu_remaining_size_to_send[i], UE_template->
UE_template->dl_buffer_head_sdu_is_segmented[i] dl_buffer_head_sdu_remaining_size_to_send[i],
); UE_template->dl_buffer_head_sdu_is_segmented[i]);
#endif #endif
} }
//#ifdef DEBUG_eNB_SCHEDULER //#ifdef DEBUG_eNB_SCHEDULER
if ( UE_template->dl_buffer_total>0) if (UE_template->dl_buffer_total > 0)
LOG_D(MAC,"[eNB %d] Frame %d Subframe %d : RLC status for UE %d : total DL buffer size %d and total number of pdu %d \n", LOG_D(MAC,
"[eNB %d] Frame %d Subframe %d : RLC status for UE %d : total DL buffer size %d and total number of pdu %d \n",
Mod_id, frameP, subframeP, UE_id, Mod_id, frameP, subframeP, UE_id,
UE_template->dl_buffer_total, UE_template->dl_buffer_total,
UE_template->dl_pdus_total UE_template->dl_pdus_total);
);
//#endif //#endif
} }
...@@ -204,31 +215,34 @@ void _store_dlsch_buffer (module_id_t Mod_id, ...@@ -204,31 +215,34 @@ void _store_dlsch_buffer (module_id_t Mod_id,
// This function returns the estimated number of RBs required by each UE for downlink scheduling // This function returns the estimated number of RBs required by each UE for downlink scheduling
void _assign_rbs_required (module_id_t Mod_id, void
_assign_rbs_required(module_id_t Mod_id,
int slice_id, int slice_id,
frame_t frameP, frame_t frameP,
sub_frame_t subframe, sub_frame_t subframe,
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], uint16_t
uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES], nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
int min_rb_unit[MAX_NUM_CCs]) uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs]
[MAX_NUM_SLICES], int min_rb_unit[MAX_NUM_CCs])
{ {
rnti_t rnti; rnti_t rnti;
uint16_t TBS = 0; uint16_t TBS = 0;
LTE_eNB_UE_stats *eNB_UE_stats[MAX_NUM_CCs]; LTE_eNB_UE_stats *eNB_UE_stats[MAX_NUM_CCs];
int UE_id,n,i,j,CC_id,pCCid,tmp; int UE_id, n, i, j, CC_id, pCCid, tmp;
UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list; UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
// UE_TEMPLATE *UE_template; // UE_TEMPLATE *UE_template;
// clear rb allocations across all CC_ids // clear rb allocations across all CC_ids
for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
if (UE_list->active[UE_id] != TRUE) continue; if (UE_list->active[UE_id] != TRUE)
continue;
if (flexran_slice_member(UE_id, slice_id) == 0) if (flexran_slice_member(UE_id, slice_id) == 0)
continue; continue;
pCCid = UE_PCCID(Mod_id,UE_id); pCCid = UE_PCCID(Mod_id, UE_id);
rnti = UE_list->UE_template[pCCid][UE_id].rnti; rnti = UE_list->UE_template[pCCid][UE_id].rnti;
/* skip UE not present in PHY (for any of its active CCs) */ /* skip UE not present in PHY (for any of its active CCs) */
...@@ -236,21 +250,26 @@ void _assign_rbs_required (module_id_t Mod_id, ...@@ -236,21 +250,26 @@ void _assign_rbs_required (module_id_t Mod_id,
continue; continue;
//update CQI information across component carriers //update CQI information across component carriers
for (n=0; n<UE_list->numactiveCCs[UE_id]; n++) { for (n = 0; n < UE_list->numactiveCCs[UE_id]; n++) {
CC_id = UE_list->ordered_CCids[n][UE_id]; CC_id = UE_list->ordered_CCids[n][UE_id];
eNB_UE_stats[CC_id] = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti); eNB_UE_stats[CC_id] =
eNB_UE_stats[CC_id]->dlsch_mcs1 = cqi_to_mcs[flexran_get_ue_wcqi(Mod_id, UE_id)]; mac_xface->get_eNB_UE_stats(Mod_id, CC_id, rnti);
eNB_UE_stats[CC_id]->dlsch_mcs1 =
cqi_to_mcs[flexran_get_ue_wcqi(Mod_id, UE_id)];
} }
// provide the list of CCs sorted according to MCS // provide the list of CCs sorted according to MCS
for (i=0; i<UE_list->numactiveCCs[UE_id]; i++) { for (i = 0; i < UE_list->numactiveCCs[UE_id]; i++) {
for (j=i+1; j<UE_list->numactiveCCs[UE_id]; j++) { for (j = i + 1; j < UE_list->numactiveCCs[UE_id]; j++) {
DevAssert( j < MAX_NUM_CCs ); DevAssert(j < MAX_NUM_CCs);
if (eNB_UE_stats[UE_list->ordered_CCids[i][UE_id]]->dlsch_mcs1 > if (eNB_UE_stats[UE_list->ordered_CCids[i][UE_id]]->
eNB_UE_stats[UE_list->ordered_CCids[j][UE_id]]->dlsch_mcs1) { dlsch_mcs1 >
eNB_UE_stats[UE_list->ordered_CCids[j][UE_id]]->
dlsch_mcs1) {
tmp = UE_list->ordered_CCids[i][UE_id]; 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[i][UE_id] =
UE_list->ordered_CCids[j][UE_id];
UE_list->ordered_CCids[j][UE_id] = tmp; UE_list->ordered_CCids[j][UE_id] = tmp;
} }
} }
...@@ -259,90 +278,138 @@ void _assign_rbs_required (module_id_t Mod_id, ...@@ -259,90 +278,138 @@ void _assign_rbs_required (module_id_t Mod_id,
/* NN --> RK /* NN --> RK
* check the index of UE_template" * check the index of UE_template"
*/ */
if (UE_list->UE_template[pCCid][UE_id].dl_buffer_total> 0) { if (UE_list->UE_template[pCCid][UE_id].dl_buffer_total > 0) {
LOG_D(MAC,"[preprocessor] assign RB for UE %d\n",UE_id); LOG_D(MAC, "[preprocessor] assign RB for UE %d\n", UE_id);
for (i=0; i<UE_list->numactiveCCs[UE_id]; i++) { for (i = 0; i < UE_list->numactiveCCs[UE_id]; i++) {
CC_id = UE_list->ordered_CCids[i][UE_id]; CC_id = UE_list->ordered_CCids[i][UE_id];
eNB_UE_stats[CC_id] = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti); eNB_UE_stats[CC_id] =
mac_xface->get_eNB_UE_stats(Mod_id, CC_id, rnti);
if (cqi_to_mcs[flexran_get_ue_wcqi(Mod_id, UE_id)] == 0) {//eNB_UE_stats[CC_id]->dlsch_mcs1==0) { if (cqi_to_mcs[flexran_get_ue_wcqi(Mod_id, UE_id)] == 0) { //eNB_UE_stats[CC_id]->dlsch_mcs1==0) {
nb_rbs_required[CC_id][UE_id] = 4; // don't let the TBS get too small nb_rbs_required[CC_id][UE_id] = 4; // don't let the TBS get too small
} else { } else {
nb_rbs_required[CC_id][UE_id] = min_rb_unit[CC_id]; nb_rbs_required[CC_id][UE_id] = min_rb_unit[CC_id];
} }
TBS = mac_xface->get_TBS_DL(cqi_to_mcs[flexran_get_ue_wcqi(Mod_id, UE_id)], nb_rbs_required[CC_id][UE_id]); TBS =
nb_rbs_allowed_slice[CC_id][slice_id] = flexran_nb_rbs_allowed_slice(slice_percentage[slice_id], mac_xface->get_TBS_DL(cqi_to_mcs
flexran_get_N_RB_DL(Mod_id, CC_id)); [flexran_get_ue_wcqi
LOG_D(MAC,"[preprocessor] start RB assignement for UE %d CC_id %d dl buffer %d (RB unit %d, MCS %d, TBS %d) \n", (Mod_id, UE_id)],
UE_id, CC_id, UE_list->UE_template[pCCid][UE_id].dl_buffer_total, nb_rbs_required[CC_id][UE_id]);
nb_rbs_required[CC_id][UE_id], flexran_get_ue_wcqi(Mod_id, UE_id), TBS); nb_rbs_allowed_slice[CC_id][slice_id] =
flexran_nb_rbs_allowed_slice(slice_percentage
[slice_id],
flexran_get_N_RB_DL
(Mod_id, CC_id));
LOG_D(MAC,
"[preprocessor] start RB assignement for UE %d CC_id %d dl buffer %d (RB unit %d, MCS %d, TBS %d) \n",
UE_id, CC_id,
UE_list->UE_template[pCCid][UE_id].dl_buffer_total,
nb_rbs_required[CC_id][UE_id],
flexran_get_ue_wcqi(Mod_id, UE_id), TBS);
/* calculating required number of RBs for each UE */ /* calculating required number of RBs for each UE */
while (TBS < UE_list->UE_template[pCCid][UE_id].dl_buffer_total) { while (TBS <
UE_list->UE_template[pCCid][UE_id].
dl_buffer_total) {
nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id]; nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id];
if (nb_rbs_required[CC_id][UE_id] > nb_rbs_allowed_slice[CC_id][slice_id]) { if (nb_rbs_required[CC_id][UE_id] >
TBS = mac_xface->get_TBS_DL(flexran_get_ue_wcqi(Mod_id, UE_id), nb_rbs_allowed_slice[CC_id][slice_id]); nb_rbs_allowed_slice[CC_id][slice_id]) {
nb_rbs_required[CC_id][UE_id] = nb_rbs_allowed_slice[CC_id][slice_id]; TBS =
mac_xface->get_TBS_DL(flexran_get_ue_wcqi
(Mod_id, UE_id),
nb_rbs_allowed_slice
[CC_id]
[slice_id]);
nb_rbs_required[CC_id][UE_id] =
nb_rbs_allowed_slice[CC_id][slice_id];
break; break;
} }
TBS = mac_xface->get_TBS_DL(cqi_to_mcs[flexran_get_ue_wcqi(Mod_id, UE_id)], nb_rbs_required[CC_id][UE_id]); TBS =
mac_xface->get_TBS_DL(cqi_to_mcs
[flexran_get_ue_wcqi
(Mod_id, UE_id)],
nb_rbs_required[CC_id]
[UE_id]);
} // end of while } // end of while
LOG_D(MAC,"[eNB %d][SLICE %d] Frame %d: UE %d on CC %d: RB unit %d, nb_required RB %d (TBS %d, mcs %d)\n", LOG_D(MAC,
Mod_id, slice_id,frameP,UE_id, CC_id, min_rb_unit[CC_id], nb_rbs_required[CC_id][UE_id], TBS, cqi_to_mcs[flexran_get_ue_wcqi(Mod_id, UE_id)]); "[eNB %d][SLICE %d] Frame %d: UE %d on CC %d: RB unit %d, nb_required RB %d (TBS %d, mcs %d)\n",
Mod_id, slice_id, frameP, UE_id, CC_id,
min_rb_unit[CC_id], nb_rbs_required[CC_id][UE_id],
TBS, cqi_to_mcs[flexran_get_ue_wcqi(Mod_id, UE_id)]);
} }
} }
} }
} }
void _dlsch_scheduler_pre_processor_allocate (module_id_t Mod_id, void
_dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id,
int UE_id, int UE_id,
uint8_t CC_id, uint8_t CC_id,
int N_RBG, int N_RBG,
int transmission_mode, int transmission_mode,
int min_rb_unit, int min_rb_unit,
uint8_t N_RB_DL, uint8_t N_RB_DL,
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], uint16_t
uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX], nb_rbs_required[MAX_NUM_CCs]
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX], [NUMBER_OF_UE_MAX],
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]) { uint16_t
nb_rbs_required_remaining
[MAX_NUM_CCs]
[NUMBER_OF_UE_MAX], unsigned char
rballoc_sub[MAX_NUM_CCs]
[N_RBG_MAX], unsigned char
MIMO_mode_indicator
[MAX_NUM_CCs][N_RBG_MAX])
{
int i; int i;
UE_list_t *UE_list=&eNB_mac_inst[Mod_id].UE_list; UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
for(i=0; i<N_RBG; i++) { for (i = 0; i < N_RBG; i++) {
if((rballoc_sub[CC_id][i] == 0) && if ((rballoc_sub[CC_id][i] == 0) &&
(ue_sched_ctl->rballoc_sub_UE[CC_id][i] == 0) && (ue_sched_ctl->rballoc_sub_UE[CC_id][i] == 0) &&
(nb_rbs_required_remaining[CC_id][UE_id]>0) && (nb_rbs_required_remaining[CC_id][UE_id] > 0) &&
(ue_sched_ctl->pre_nb_available_rbs[CC_id] < nb_rbs_required[CC_id][UE_id])) { (ue_sched_ctl->pre_nb_available_rbs[CC_id] <
nb_rbs_required[CC_id][UE_id])) {
// if this UE is not scheduled for TM5 // if this UE is not scheduled for TM5
if (ue_sched_ctl->dl_pow_off[CC_id] != 0 ) { if (ue_sched_ctl->dl_pow_off[CC_id] != 0) {
if ((i == N_RBG-1) && ((N_RB_DL == 25) || (N_RB_DL == 50))) { if ((i == N_RBG - 1)
&& ((N_RB_DL == 25) || (N_RB_DL == 50))) {
rballoc_sub[CC_id][i] = 1; rballoc_sub[CC_id][i] = 1;
ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1; ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1;
MIMO_mode_indicator[CC_id][i] = 1; MIMO_mode_indicator[CC_id][i] = 1;
if (transmission_mode == 5 ) { if (transmission_mode == 5) {
ue_sched_ctl->dl_pow_off[CC_id] = 1; ue_sched_ctl->dl_pow_off[CC_id] = 1;
} }
nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit+1; nb_rbs_required_remaining[CC_id][UE_id] =
ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit - 1; nb_rbs_required_remaining[CC_id][UE_id] -
min_rb_unit + 1;
ue_sched_ctl->pre_nb_available_rbs[CC_id] =
ue_sched_ctl->pre_nb_available_rbs[CC_id] +
min_rb_unit - 1;
} else { } else {
if (nb_rbs_required_remaining[CC_id][UE_id] >= min_rb_unit){ if (nb_rbs_required_remaining[CC_id][UE_id] >=
min_rb_unit) {
rballoc_sub[CC_id][i] = 1; rballoc_sub[CC_id][i] = 1;
ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1; ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1;
MIMO_mode_indicator[CC_id][i] = 1; MIMO_mode_indicator[CC_id][i] = 1;
if (transmission_mode == 5 ) { if (transmission_mode == 5) {
ue_sched_ctl->dl_pow_off[CC_id] = 1; ue_sched_ctl->dl_pow_off[CC_id] = 1;
} }
nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit; nb_rbs_required_remaining[CC_id][UE_id] =
ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit; nb_rbs_required_remaining[CC_id][UE_id] -
min_rb_unit;
ue_sched_ctl->pre_nb_available_rbs[CC_id] =
ue_sched_ctl->pre_nb_available_rbs[CC_id] +
min_rb_unit;
} }
} }
} // dl_pow_off[CC_id][UE_id] ! = 0 } // dl_pow_off[CC_id][UE_id] ! = 0
...@@ -350,94 +417,109 @@ void _dlsch_scheduler_pre_processor_allocate (module_id_t Mod_id, ...@@ -350,94 +417,109 @@ void _dlsch_scheduler_pre_processor_allocate (module_id_t Mod_id,
} }
} }
void _dlsch_scheduler_pre_processor_reset (int module_idP, void
_dlsch_scheduler_pre_processor_reset(int module_idP,
int UE_id, int UE_id,
uint8_t CC_id, uint8_t CC_id,
int frameP, int frameP,
int subframeP, int subframeP,
int N_RBG, int N_RBG,
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], uint16_t nb_rbs_required[MAX_NUM_CCs]
uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX], [NUMBER_OF_UE_MAX],
uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES], uint16_t
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX], nb_rbs_required_remaining
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]) { [MAX_NUM_CCs][NUMBER_OF_UE_MAX],
int i,j; uint16_t
UE_list_t *UE_list=&eNB_mac_inst[module_idP].UE_list; nb_rbs_allowed_slice[MAX_NUM_CCs]
[MAX_NUM_SLICES], unsigned char
rballoc_sub[MAX_NUM_CCs]
[N_RBG_MAX], unsigned char
MIMO_mode_indicator[MAX_NUM_CCs]
[N_RBG_MAX])
{
int i, j;
UE_list_t *UE_list = &eNB_mac_inst[module_idP].UE_list;
UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
uint8_t *vrb_map = eNB_mac_inst[module_idP].common_channels[CC_id].vrb_map; uint8_t *vrb_map =
int RBGsize = PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.N_RB_DL/N_RBG; eNB_mac_inst[module_idP].common_channels[CC_id].vrb_map;
int RBGsize =
PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.N_RB_DL / N_RBG;
#ifdef SF05_LIMIT #ifdef SF05_LIMIT
//int subframe05_limit=0; //int subframe05_limit=0;
int sf05_upper=-1,sf05_lower=-1; int sf05_upper = -1, sf05_lower = -1;
#endif #endif
// LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti); // LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti);
flexran_update_TA(module_idP, UE_id, CC_id); flexran_update_TA(module_idP, UE_id, CC_id);
if (UE_id==0) { if (UE_id == 0) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_TIMING_ADVANCE,ue_sched_ctl->ta_update); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME
(VCD_SIGNAL_DUMPER_VARIABLES_UE0_TIMING_ADVANCE,
ue_sched_ctl->ta_update);
} }
nb_rbs_required[CC_id][UE_id]=0; nb_rbs_required[CC_id][UE_id] = 0;
ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0; ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0;
ue_sched_ctl->dl_pow_off[CC_id] = 2; ue_sched_ctl->dl_pow_off[CC_id] = 2;
nb_rbs_required_remaining[CC_id][UE_id] = 0; nb_rbs_required_remaining[CC_id][UE_id] = 0;
for (i=0; i<n_active_slices;i++) for (i = 0; i < n_active_slices; i++)
nb_rbs_allowed_slice[CC_id][i] = 0; nb_rbs_allowed_slice[CC_id][i] = 0;
#ifdef SF05_LIMIT #ifdef SF05_LIMIT
switch (N_RBG) { switch (N_RBG) {
case 6: case 6:
sf05_lower=0; sf05_lower = 0;
sf05_upper=5; sf05_upper = 5;
break; break;
case 8: case 8:
sf05_lower=2; sf05_lower = 2;
sf05_upper=5; sf05_upper = 5;
break; break;
case 13: case 13:
sf05_lower=4; sf05_lower = 4;
sf05_upper=7; sf05_upper = 7;
break; break;
case 17: case 17:
sf05_lower=7; sf05_lower = 7;
sf05_upper=9; sf05_upper = 9;
break; break;
case 25: case 25:
sf05_lower=11; sf05_lower = 11;
sf05_upper=13; sf05_upper = 13;
break; break;
} }
#endif #endif
// Initialize Subbands according to VRB map // Initialize Subbands according to VRB map
for (i=0; i<N_RBG; i++) { for (i = 0; i < N_RBG; i++) {
ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0; ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0;
rballoc_sub[CC_id][i] = 0; rballoc_sub[CC_id][i] = 0;
#ifdef SF05_LIMIT #ifdef SF05_LIMIT
// for avoiding 6+ PRBs around DC in subframe 0-5 (avoid excessive errors) // for avoiding 6+ PRBs around DC in subframe 0-5 (avoid excessive errors)
if ((subframeP==0 || subframeP==5) && if ((subframeP == 0 || subframeP == 5) &&
(i>=sf05_lower && i<=sf05_upper)) (i >= sf05_lower && i <= sf05_upper))
rballoc_sub[CC_id][i]=1; rballoc_sub[CC_id][i] = 1;
#endif #endif
// for SI-RNTI,RA-RNTI and P-RNTI allocations // for SI-RNTI,RA-RNTI and P-RNTI allocations
for (j=0;j<RBGsize;j++) { for (j = 0; j < RBGsize; j++) {
if (vrb_map[j+(i*RBGsize)]!=0) { if (vrb_map[j + (i * RBGsize)] != 0) {
rballoc_sub[CC_id][i] = 1; rballoc_sub[CC_id][i] = 1;
LOG_D(MAC,"Frame %d, subframe %d : vrb %d allocated\n",frameP,subframeP,j+(i*RBGsize)); LOG_D(MAC, "Frame %d, subframe %d : vrb %d allocated\n",
frameP, subframeP, j + (i * RBGsize));
break; break;
} }
} }
LOG_D(MAC,"Frame %d Subframe %d CC_id %d RBG %i : rb_alloc %d\n",frameP,subframeP,CC_id,i,rballoc_sub[CC_id][i]); LOG_D(MAC, "Frame %d Subframe %d CC_id %d RBG %i : rb_alloc %d\n",
frameP, subframeP, CC_id, i, rballoc_sub[CC_id][i]);
MIMO_mode_indicator[CC_id][i] = 2; MIMO_mode_indicator[CC_id][i] = 2;
} }
} }
// This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done // This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done
void _dlsch_scheduler_pre_processor (module_id_t Mod_id, void
_dlsch_scheduler_pre_processor(module_id_t Mod_id,
int slice_id, int slice_id,
frame_t frameP, frame_t frameP,
sub_frame_t subframeP, sub_frame_t subframeP,
int N_RBG[MAX_NUM_CCs], int N_RBG[MAX_NUM_CCs], int *mbsfn_flag)
int *mbsfn_flag)
{ {
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX], total_ue_count; unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX], total_ue_count;
...@@ -445,35 +527,36 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id, ...@@ -445,35 +527,36 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
int UE_id, i; int UE_id, i;
uint8_t round = 0; uint8_t round = 0;
uint8_t harq_pid = 0; uint8_t harq_pid = 0;
uint16_t ii,j; uint16_t ii, j;
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES]; uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES];
uint16_t nb_rbs_required_remaining[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 nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
uint16_t average_rbs_per_user[MAX_NUM_CCs] = {0}; uint16_t average_rbs_per_user[MAX_NUM_CCs] = { 0 };
rnti_t rnti; rnti_t rnti;
int min_rb_unit[MAX_NUM_CCs]; int min_rb_unit[MAX_NUM_CCs];
uint16_t r1=0; uint16_t r1 = 0;
uint8_t CC_id; uint8_t CC_id;
UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list; UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs] = {0}; LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs] = { 0 };
int transmission_mode = 0; int transmission_mode = 0;
UE_sched_ctrl *ue_sched_ctl; UE_sched_ctrl *ue_sched_ctl;
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { 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 if (mbsfn_flag[CC_id] > 0) // If this CC is allocated for MBSFN skip it here
continue; continue;
frame_parms[CC_id] = mac_xface->get_lte_frame_parms(Mod_id,CC_id); frame_parms[CC_id] = mac_xface->get_lte_frame_parms(Mod_id, CC_id);
min_rb_unit[CC_id]=get_min_rb_unit(Mod_id,CC_id); min_rb_unit[CC_id] = get_min_rb_unit(Mod_id, CC_id);
for (i = 0; i < NUMBER_OF_UE_MAX; i++) { for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
if (UE_list->active[i] != TRUE) continue; if (UE_list->active[i] != TRUE)
continue;
UE_id = i; UE_id = i;
// Initialize scheduling information for all active UEs // Initialize scheduling information for all active UEs
...@@ -496,20 +579,22 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id, ...@@ -496,20 +579,22 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
} }
// Store the DLSCH buffer for each logical channel // Store the DLSCH buffer for each logical channel
_store_dlsch_buffer (Mod_id,slice_id,frameP,subframeP); _store_dlsch_buffer(Mod_id, slice_id, frameP, subframeP);
// Calculate the number of RBs required by each UE on the basis of logical channel's buffer // Calculate the number of RBs required by each UE on the basis of logical channel's buffer
_assign_rbs_required (Mod_id,slice_id, frameP,subframeP,nb_rbs_required,nb_rbs_allowed_slice,min_rb_unit); _assign_rbs_required(Mod_id, slice_id, frameP, subframeP,
nb_rbs_required, nb_rbs_allowed_slice,
min_rb_unit);
// Sorts the user on the basis of dlsch logical channel buffer and CQI // Sorts the user on the basis of dlsch logical channel buffer and CQI
sort_UEs (Mod_id,frameP,subframeP); sort_UEs(Mod_id, frameP, subframeP);
total_ue_count = 0; total_ue_count = 0;
// loop over all active UEs // loop over all active UEs
for (i=UE_list->head; i>=0; i=UE_list->next[i]) { for (i = UE_list->head; i >= 0; i = UE_list->next[i]) {
rnti = flexran_get_ue_crnti(Mod_id, i); rnti = flexran_get_ue_crnti(Mod_id, i);
if(rnti == NOT_A_RNTI) if (rnti == NOT_A_RNTI)
continue; continue;
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
continue; continue;
...@@ -522,32 +607,33 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id, ...@@ -522,32 +607,33 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
if (!phy_stats_exist(Mod_id, rnti)) if (!phy_stats_exist(Mod_id, rnti))
continue; continue;
for (ii=0; ii < UE_num_active_CC(UE_list,UE_id); ii++) { for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) {
CC_id = UE_list->ordered_CCids[ii][UE_id]; CC_id = UE_list->ordered_CCids[ii][UE_id];
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
ue_sched_ctl->max_allowed_rbs[CC_id]=nb_rbs_allowed_slice[CC_id][slice_id]; ue_sched_ctl->max_allowed_rbs[CC_id] =
flexran_get_harq(Mod_id, CC_id, UE_id, frameP, subframeP, &harq_pid, &round); nb_rbs_allowed_slice[CC_id][slice_id];
flexran_get_harq(Mod_id, CC_id, UE_id, frameP, subframeP,
&harq_pid, &round);
// if there is no available harq_process, skip the UE // if there is no available harq_process, skip the UE
if (UE_list->UE_sched_ctrl[UE_id].harq_pid[CC_id]<0) if (UE_list->UE_sched_ctrl[UE_id].harq_pid[CC_id] < 0)
continue; continue;
average_rbs_per_user[CC_id]=0; average_rbs_per_user[CC_id] = 0;
frame_parms[CC_id] = mac_xface->get_lte_frame_parms(Mod_id,CC_id); frame_parms[CC_id] =
mac_xface->get_lte_frame_parms(Mod_id, CC_id);
// mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frameP,subframeP,&harq_pid,&round,0); // mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frameP,subframeP,&harq_pid,&round,0);
if(round>0) { if (round > 0) {
nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; nb_rbs_required[CC_id][UE_id] =
UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
} }
//nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id]; //nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id];
if (nb_rbs_required[CC_id][UE_id] > 0) { if (nb_rbs_required[CC_id][UE_id] > 0) {
total_ue_count = total_ue_count + 1; total_ue_count = total_ue_count + 1;
} }
// hypotetical assignement // hypotetical assignement
/* /*
* If schedule is enabled and if the priority of the UEs is modified * If schedule is enabled and if the priority of the UEs is modified
...@@ -560,8 +646,11 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id, ...@@ -560,8 +646,11 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
if (total_ue_count == 0) { if (total_ue_count == 0) {
average_rbs_per_user[CC_id] = 0; average_rbs_per_user[CC_id] = 0;
} else if( (min_rb_unit[CC_id] * total_ue_count) <= nb_rbs_allowed_slice[CC_id][slice_id] ) { } else if ((min_rb_unit[CC_id] * total_ue_count) <=
average_rbs_per_user[CC_id] = (uint16_t) floor(nb_rbs_allowed_slice[CC_id][slice_id]/total_ue_count); nb_rbs_allowed_slice[CC_id][slice_id]) {
average_rbs_per_user[CC_id] =
(uint16_t) floor(nb_rbs_allowed_slice[CC_id][slice_id]
/ total_ue_count);
} else { } else {
average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; // consider the total number of use that can be scheduled UE average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; // consider the total number of use that can be scheduled UE
} }
...@@ -570,10 +659,10 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id, ...@@ -570,10 +659,10 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
// note: nb_rbs_required is assigned according to total_buffer_dl // note: nb_rbs_required is assigned according to total_buffer_dl
// extend nb_rbs_required to capture per LCID RB required // extend nb_rbs_required to capture per LCID RB required
for(i=UE_list->head; i>=0; i=UE_list->next[i]) { for (i = UE_list->head; i >= 0; i = UE_list->next[i]) {
rnti = UE_RNTI(Mod_id,i); rnti = UE_RNTI(Mod_id, i);
if(rnti == NOT_A_RNTI) if (rnti == NOT_A_RNTI)
continue; continue;
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
...@@ -585,14 +674,17 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id, ...@@ -585,14 +674,17 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
if (flexran_slice_member(i, slice_id) == 0) if (flexran_slice_member(i, slice_id) == 0)
continue; continue;
for (ii=0; ii<UE_num_active_CC(UE_list,i); ii++) { for (ii = 0; ii < UE_num_active_CC(UE_list, i); ii++) {
CC_id = UE_list->ordered_CCids[ii][i]; CC_id = UE_list->ordered_CCids[ii][i];
// control channel // control channel
if (mac_eNB_get_rrc_status(Mod_id,rnti) < RRC_RECONFIGURED) { if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_RECONFIGURED) {
nb_rbs_required_remaining_1[CC_id][i] = nb_rbs_required[CC_id][i]; nb_rbs_required_remaining_1[CC_id][i] =
nb_rbs_required[CC_id][i];
} else { } else {
nb_rbs_required_remaining_1[CC_id][i] = cmin(average_rbs_per_user[CC_id],nb_rbs_required[CC_id][i]); nb_rbs_required_remaining_1[CC_id][i] =
cmin(average_rbs_per_user[CC_id],
nb_rbs_required[CC_id][i]);
} }
} }
...@@ -601,50 +693,56 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id, ...@@ -601,50 +693,56 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
//Allocation to UEs is done in 2 rounds, //Allocation to UEs is done in 2 rounds,
// 1st stage: average number of RBs allocated to each UE // 1st stage: average number of RBs allocated to each UE
// 2nd stage: remaining RBs are allocated to high priority UEs // 2nd stage: remaining RBs are allocated to high priority UEs
for(r1=0; r1<2; r1++) { for (r1 = 0; r1 < 2; r1++) {
for(i=UE_list->head; i>=0; i=UE_list->next[i]) { for (i = UE_list->head; i >= 0; i = UE_list->next[i]) {
if (flexran_slice_member(i, slice_id) == 0) if (flexran_slice_member(i, slice_id) == 0)
continue; continue;
for (ii=0; ii<UE_num_active_CC(UE_list,i); ii++) { for (ii = 0; ii < UE_num_active_CC(UE_list, i); ii++) {
CC_id = UE_list->ordered_CCids[ii][i]; CC_id = UE_list->ordered_CCids[ii][i];
if(r1 == 0) { if (r1 == 0) {
nb_rbs_required_remaining[CC_id][i] = nb_rbs_required_remaining_1[CC_id][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 } else { // rb required based only on the buffer - rb allloctaed in the 1st round + extra reaming rb form the 1st round
nb_rbs_required_remaining[CC_id][i] = nb_rbs_required[CC_id][i]-nb_rbs_required_remaining_1[CC_id][i]+nb_rbs_required_remaining[CC_id][i]; 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];
} }
if (nb_rbs_required[CC_id][i]> 0 ) if (nb_rbs_required[CC_id][i] > 0)
LOG_D(MAC,"round %d : nb_rbs_required_remaining[%d][%d]= %d (remaining_1 %d, required %d, pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n", LOG_D(MAC,
"round %d : nb_rbs_required_remaining[%d][%d]= %d (remaining_1 %d, required %d, pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n",
r1, CC_id, i, r1, CC_id, i,
nb_rbs_required_remaining[CC_id][i], nb_rbs_required_remaining[CC_id][i],
nb_rbs_required_remaining_1[CC_id][i], nb_rbs_required_remaining_1[CC_id][i],
nb_rbs_required[CC_id][i], nb_rbs_required[CC_id][i],
UE_list->UE_sched_ctrl[i].pre_nb_available_rbs[CC_id], UE_list->UE_sched_ctrl[i].
N_RBG[CC_id], pre_nb_available_rbs[CC_id], N_RBG[CC_id],
min_rb_unit[CC_id]); min_rb_unit[CC_id]);
} }
} }
if (total_ue_count > 0 ) { if (total_ue_count > 0) {
for(i=UE_list->head; i>=0; i=UE_list->next[i]) { for (i = UE_list->head; i >= 0; i = UE_list->next[i]) {
UE_id = i; UE_id = i;
if (flexran_slice_member(UE_id, slice_id) == 0) if (flexran_slice_member(UE_id, slice_id) == 0)
continue; continue;
for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) { for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) {
CC_id = UE_list->ordered_CCids[ii][UE_id]; CC_id = UE_list->ordered_CCids[ii][UE_id];
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
flexran_get_harq(Mod_id, CC_id, UE_id, frameP, subframeP, &harq_pid, &round); flexran_get_harq(Mod_id, CC_id, UE_id, frameP,
rnti = UE_RNTI(Mod_id,UE_id); subframeP, &harq_pid, &round);
rnti = UE_RNTI(Mod_id, UE_id);
// LOG_D(MAC,"UE %d rnti 0x\n", UE_id, rnti ); // LOG_D(MAC,"UE %d rnti 0x\n", UE_id, rnti );
if(rnti == NOT_A_RNTI) if (rnti == NOT_A_RNTI)
continue; continue;
if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1)
...@@ -653,21 +751,26 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id, ...@@ -653,21 +751,26 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
if (!phy_stats_exist(Mod_id, rnti)) if (!phy_stats_exist(Mod_id, rnti))
continue; continue;
transmission_mode = mac_xface->get_transmission_mode(Mod_id,CC_id,rnti); transmission_mode =
mac_xface->get_transmission_mode(Mod_id, CC_id,
rnti);
//rrc_status = mac_eNB_get_rrc_status(Mod_id,rnti); //rrc_status = mac_eNB_get_rrc_status(Mod_id,rnti);
/* 1st allocate for the retx */ /* 1st allocate for the retx */
// retransmission in data channels // retransmission in data channels
// control channel in the 1st transmission // control channel in the 1st transmission
// data channel for all TM // data channel for all TM
LOG_T(MAC,"calling dlsch_scheduler_pre_processor_allocate .. \n "); LOG_T(MAC,
_dlsch_scheduler_pre_processor_allocate (Mod_id, "calling dlsch_scheduler_pre_processor_allocate .. \n ");
UE_id, _dlsch_scheduler_pre_processor_allocate(Mod_id, UE_id,
CC_id, CC_id,
N_RBG[CC_id], N_RBG[CC_id],
transmission_mode, transmission_mode,
min_rb_unit[CC_id], min_rb_unit
frame_parms[CC_id]->N_RB_DL, [CC_id],
frame_parms
[CC_id]->
N_RB_DL,
nb_rbs_required, nb_rbs_required,
nb_rbs_required_remaining, nb_rbs_required_remaining,
rballoc_sub, rballoc_sub,
...@@ -677,30 +780,39 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id, ...@@ -677,30 +780,39 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
} // total_ue_count } // total_ue_count
} // end of for for r1 and r2 } // end of for for r1 and r2
for(i=UE_list->head; i>=0; i=UE_list->next[i]) { for (i = UE_list->head; i >= 0; i = UE_list->next[i]) {
UE_id = i; UE_id = i;
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
if (flexran_slice_member(UE_id, slice_id) == 0) if (flexran_slice_member(UE_id, slice_id) == 0)
continue; continue;
for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) { for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) {
CC_id = UE_list->ordered_CCids[ii][UE_id]; CC_id = UE_list->ordered_CCids[ii][UE_id];
//PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id]; //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id];
if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0 ) { if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0) {
LOG_D(MAC,"******************DL Scheduling Information for UE%d ************************\n",UE_id); LOG_D(MAC,
LOG_D(MAC,"dl power offset UE%d = %d \n",UE_id,ue_sched_ctl->dl_pow_off[CC_id]); "******************DL Scheduling Information for UE%d ************************\n",
LOG_D(MAC,"***********RB Alloc for every subband for UE%d ***********\n",UE_id); UE_id);
LOG_D(MAC, "dl power offset UE%d = %d \n", UE_id,
ue_sched_ctl->dl_pow_off[CC_id]);
LOG_D(MAC,
"***********RB Alloc for every subband for UE%d ***********\n",
UE_id);
for(j=0; j<N_RBG[CC_id]; j++) { for (j = 0; j < N_RBG[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]; //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,ue_sched_ctl->rballoc_sub_UE[CC_id][j]); LOG_D(MAC, "RB Alloc for UE%d and Subband%d = %d\n",
UE_id, j,
ue_sched_ctl->rballoc_sub_UE[CC_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]; //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,"[eNB %d][SLICE %d] Total RBs allocated for UE%d = %d\n", LOG_D(MAC,
Mod_id, slice_id, UE_id,ue_sched_ctl->pre_nb_available_rbs[CC_id]); "[eNB %d][SLICE %d] Total RBs allocated for UE%d = %d\n",
Mod_id, slice_id, UE_id,
ue_sched_ctl->pre_nb_available_rbs[CC_id]);
} }
} }
} }
...@@ -718,142 +830,164 @@ flexran_schedule_ue_spec_default(mid_t mod_id, ...@@ -718,142 +830,164 @@ flexran_schedule_ue_spec_default(mid_t mod_id,
uint32_t frame, uint32_t frame,
uint32_t subframe, uint32_t subframe,
int *mbsfn_flag, int *mbsfn_flag,
Protocol__FlexranMessage **dl_info) Protocol__FlexranMessage ** dl_info)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
int i=0; int i = 0;
flexran_agent_mac_create_empty_dl_config(mod_id, dl_info); flexran_agent_mac_create_empty_dl_config(mod_id, dl_info);
for (i = 0; i < n_active_slices; i++) { for (i = 0; i < n_active_slices; i++) {
// Load any updated functions // Load any updated functions
if (update_dl_scheduler[i] > 0 ) { if (update_dl_scheduler[i] > 0) {
slice_sched[i] = dlsym(NULL, dl_scheduler_type[i]); slice_sched[i] = dlsym(NULL, dl_scheduler_type[i]);
update_dl_scheduler[i] = 0; update_dl_scheduler[i] = 0;
update_dl_scheduler_current[i] = 0; update_dl_scheduler_current[i] = 0;
slice_percentage_current[i]= slice_percentage[i]; slice_percentage_current[i] = slice_percentage[i];
total_slice_percentage+=slice_percentage[i]; total_slice_percentage += slice_percentage[i];
LOG_N(MAC,"update dl scheduler slice %d\n", i); LOG_N(MAC, "update dl scheduler slice %d\n", i);
} }
// check if the number of slices has changed, and log // check if the number of slices has changed, and log
if (n_active_slices_current != n_active_slices ){ if (n_active_slices_current != n_active_slices) {
if ((n_active_slices > 0) && (n_active_slices <= MAX_NUM_SLICES)) { if ((n_active_slices > 0)
LOG_N(MAC,"[eNB %d]frame %d subframe %d: number of active slices has changed: %d-->%d\n", && (n_active_slices <= MAX_NUM_SLICES)) {
mod_id, frame, subframe, n_active_slices_current, n_active_slices); LOG_N(MAC,
"[eNB %d]frame %d subframe %d: number of active slices has changed: %d-->%d\n",
mod_id, frame, subframe, n_active_slices_current,
n_active_slices);
n_active_slices_current = n_active_slices; n_active_slices_current = n_active_slices;
} else { } else {
LOG_W(MAC,"invalid number of slices %d, revert to the previous value %d\n",n_active_slices, n_active_slices_current); LOG_W(MAC,
"invalid number of slices %d, revert to the previous value %d\n",
n_active_slices, n_active_slices_current);
n_active_slices = n_active_slices_current; n_active_slices = n_active_slices_current;
} }
} }
// check if the slice rb share has changed, and log the console // check if the slice rb share has changed, and log the console
if (slice_percentage_current[i] != slice_percentage[i]){ if (slice_percentage_current[i] != slice_percentage[i]) {
if ((slice_percentage[i] >= 0.0) && (slice_percentage[i] <= 1.0)){ if ((slice_percentage[i] >= 0.0)
if ((total_slice_percentage - slice_percentage_current[i] + slice_percentage[i]) <= 1.0) { && (slice_percentage[i] <= 1.0)) {
total_slice_percentage=total_slice_percentage - slice_percentage_current[i] + slice_percentage[i]; if ((total_slice_percentage - slice_percentage_current[i] +
LOG_N(MAC,"[eNB %d][SLICE %d] frame %d subframe %d: total percentage %f, slice RB percentage has changed: %f-->%f\n", slice_percentage[i]) <= 1.0) {
mod_id, i, frame, subframe, total_slice_percentage, slice_percentage_current[i], slice_percentage[i]); total_slice_percentage =
total_slice_percentage -
slice_percentage_current[i] + slice_percentage[i];
LOG_N(MAC,
"[eNB %d][SLICE %d] frame %d subframe %d: total percentage %f, slice RB percentage has changed: %f-->%f\n",
mod_id, i, frame, subframe,
total_slice_percentage,
slice_percentage_current[i],
slice_percentage[i]);
slice_percentage_current[i] = slice_percentage[i]; slice_percentage_current[i] = slice_percentage[i];
} else { } else {
LOG_W(MAC,"[eNB %d][SLICE %d] invalid total RB share (%f->%f), revert the previous value (%f->%f)\n", LOG_W(MAC,
mod_id,i, "[eNB %d][SLICE %d] invalid total RB share (%f->%f), revert the previous value (%f->%f)\n",
total_slice_percentage, mod_id, i, total_slice_percentage,
total_slice_percentage - slice_percentage_current[i] + slice_percentage[i], total_slice_percentage -
slice_percentage[i],slice_percentage_current[i]); slice_percentage_current[i] +
slice_percentage[i]= slice_percentage_current[i]; slice_percentage[i], slice_percentage[i],
slice_percentage_current[i]);
slice_percentage[i] = slice_percentage_current[i];
} }
} else { } else {
LOG_W(MAC,"[eNB %d][SLICE %d] invalid slice RB share, revert the previous value (%f->%f)\n",mod_id, i, slice_percentage[i],slice_percentage_current[i]); LOG_W(MAC,
slice_percentage[i]= slice_percentage_current[i]; "[eNB %d][SLICE %d] invalid slice RB share, revert the previous value (%f->%f)\n",
mod_id, i, slice_percentage[i],
slice_percentage_current[i]);
slice_percentage[i] = slice_percentage_current[i];
} }
} }
// check if the slice max MCS, and log the console // check if the slice max MCS, and log the console
if (slice_maxmcs_current[i] != slice_maxmcs[i]){ if (slice_maxmcs_current[i] != slice_maxmcs[i]) {
if ((slice_maxmcs[i] >= 0) && (slice_maxmcs[i] < 29)){ if ((slice_maxmcs[i] >= 0) && (slice_maxmcs[i] < 29)) {
LOG_N(MAC,"[eNB %d][SLICE %d] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", LOG_N(MAC,
mod_id, i, frame, subframe, slice_maxmcs_current[i], slice_maxmcs[i]); "[eNB %d][SLICE %d] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n",
mod_id, i, frame, subframe, slice_maxmcs_current[i],
slice_maxmcs[i]);
slice_maxmcs_current[i] = slice_maxmcs[i]; slice_maxmcs_current[i] = slice_maxmcs[i];
} else { } else {
LOG_W(MAC,"[eNB %d][SLICE %d] invalid slice max mcs %d, revert the previous value %d\n",mod_id, i, slice_percentage[i],slice_percentage[i]); LOG_W(MAC,
slice_maxmcs[i]= slice_maxmcs_current[i]; "[eNB %d][SLICE %d] invalid slice max mcs %d, revert the previous value %d\n",
mod_id, i, slice_percentage[i], slice_percentage[i]);
slice_maxmcs[i] = slice_maxmcs_current[i];
} }
} }
// check if a new scheduler, and log the console // check if a new scheduler, and log the console
if (update_dl_scheduler_current[i] != update_dl_scheduler[i]){ if (update_dl_scheduler_current[i] != update_dl_scheduler[i]) {
LOG_N(MAC,"[eNB %d][SLICE %d] frame %d subframe %d: DL scheduler for this slice is updated: %s \n", LOG_N(MAC,
"[eNB %d][SLICE %d] frame %d subframe %d: DL scheduler for this slice is updated: %s \n",
mod_id, i, frame, subframe, dl_scheduler_type[i]); mod_id, i, frame, subframe, dl_scheduler_type[i]);
update_dl_scheduler_current[i] = update_dl_scheduler[i]; update_dl_scheduler_current[i] = update_dl_scheduler[i];
} }
// Run each enabled slice-specific schedulers one by one // Run each enabled slice-specific schedulers one by one
//LOG_N(MAC,"[eNB %d]frame %d subframe %d slice %d: calling the scheduler\n", mod_id, frame, subframe,i); //LOG_N(MAC,"[eNB %d]frame %d subframe %d slice %d: calling the scheduler\n", mod_id, frame, subframe,i);
slice_sched[i](mod_id, i, frame, subframe, mbsfn_flag,dl_info); slice_sched[i] (mod_id, i, frame, subframe, mbsfn_flag, dl_info);
} }
} }
uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage, int total_rbs){ uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage, int total_rbs)
{
return (uint16_t) floor(rb_percentage * total_rbs); return (uint16_t) floor(rb_percentage * total_rbs);
} }
int flexran_slice_maxmcs(int slice_id) { int flexran_slice_maxmcs(int slice_id)
{
return slice_maxmcs[slice_id]; return slice_maxmcs[slice_id];
} }
int flexran_slice_member(int UE_id, int slice_id){ int flexran_slice_member(int UE_id, int slice_id)
{
// group membership definition // group membership definition
int slice_member = 0 ; int slice_member = 0;
if ((slice_id < 0) || (slice_id > n_active_slices)) if ((slice_id < 0) || (slice_id > n_active_slices))
LOG_W(MAC,"out of range slice id %d\n",slice_id); LOG_W(MAC, "out of range slice id %d\n", slice_id);
switch (slicing_strategy) { switch (slicing_strategy) {
case SLICE_MASK: case SLICE_MASK:
switch (slice_id){ switch (slice_id) {
case 0: case 0:
if (SLICE0_MASK&UE_id){ if (SLICE0_MASK & UE_id) {
slice_member=1; slice_member = 1;
} }
break; break;
case 1: case 1:
if (SLICE1_MASK&UE_id){ if (SLICE1_MASK & UE_id) {
slice_member=1; slice_member = 1;
} }
break; break;
case 2: case 2:
if (SLICE2_MASK&UE_id){ if (SLICE2_MASK & UE_id) {
slice_member=1; slice_member = 1;
} }
break; break;
case 3: case 3:
if (SLICE3_MASK&UE_id){ if (SLICE3_MASK & UE_id) {
slice_member=1; slice_member = 1;
} }
break; break;
default : default:
LOG_W(MAC,"unknown slice_id %d\n", slice_id); LOG_W(MAC, "unknown slice_id %d\n", slice_id);
break; break;
} }
break; break;
case UEID_TO_SLICEID: case UEID_TO_SLICEID:
default: default:
if ((UE_id % n_active_slices) == slice_id){ if ((UE_id % n_active_slices) == slice_id) {
slice_member= 1; // this ue is a member of this slice slice_member = 1; // this ue is a member of this slice
} }
break; break;
} }
return slice_member; return slice_member;
} }
/* more aggressive rb and mcs allocation with medium priority and the traffic qci */ /* more aggressive rb and mcs allocation with medium priority and the traffic qci */
void void
flexran_schedule_ue_spec_embb(mid_t mod_id, flexran_schedule_ue_spec_embb(mid_t mod_id,
...@@ -861,17 +995,14 @@ flexran_schedule_ue_spec_embb(mid_t mod_id, ...@@ -861,17 +995,14 @@ flexran_schedule_ue_spec_embb(mid_t mod_id,
uint32_t frame, uint32_t frame,
uint32_t subframe, uint32_t subframe,
int *mbsfn_flag, int *mbsfn_flag,
Protocol__FlexranMessage **dl_info) Protocol__FlexranMessage ** dl_info)
{ {
flexran_schedule_ue_spec_common(mod_id, flexran_schedule_ue_spec_common(mod_id,
slice_id, slice_id,
frame, frame, subframe, mbsfn_flag, dl_info);
subframe,
mbsfn_flag,
dl_info);
} }
/* more conservative mcs allocation with high priority and the traffic qci */ /* more conservative mcs allocation with high priority and the traffic qci */
void void
flexran_schedule_ue_spec_urllc(mid_t mod_id, flexran_schedule_ue_spec_urllc(mid_t mod_id,
...@@ -879,17 +1010,14 @@ flexran_schedule_ue_spec_urllc(mid_t mod_id, ...@@ -879,17 +1010,14 @@ flexran_schedule_ue_spec_urllc(mid_t mod_id,
uint32_t frame, uint32_t frame,
uint32_t subframe, uint32_t subframe,
int *mbsfn_flag, int *mbsfn_flag,
Protocol__FlexranMessage **dl_info) Protocol__FlexranMessage ** dl_info)
{ {
flexran_schedule_ue_spec_common(mod_id, flexran_schedule_ue_spec_common(mod_id,
slice_id, slice_id,
frame, frame, subframe, mbsfn_flag, dl_info);
subframe,
mbsfn_flag,
dl_info);
} }
/* constant rb allocation with low mcs with low priority and given the UE capabilities */ /* constant rb allocation with low mcs with low priority and given the UE capabilities */
void void
flexran_schedule_ue_spec_mmtc(mid_t mod_id, flexran_schedule_ue_spec_mmtc(mid_t mod_id,
...@@ -897,18 +1025,15 @@ flexran_schedule_ue_spec_mmtc(mid_t mod_id, ...@@ -897,18 +1025,15 @@ flexran_schedule_ue_spec_mmtc(mid_t mod_id,
uint32_t frame, uint32_t frame,
uint32_t subframe, uint32_t subframe,
int *mbsfn_flag, int *mbsfn_flag,
Protocol__FlexranMessage **dl_info) Protocol__FlexranMessage ** dl_info)
{ {
flexran_schedule_ue_spec_common(mod_id, flexran_schedule_ue_spec_common(mod_id,
slice_id, slice_id,
frame, frame, subframe, mbsfn_flag, dl_info);
subframe,
mbsfn_flag,
dl_info);
} }
/* regular rb and mcs allocation with low priority */ /* regular rb and mcs allocation with low priority */
void void
flexran_schedule_ue_spec_be(mid_t mod_id, flexran_schedule_ue_spec_be(mid_t mod_id,
...@@ -916,16 +1041,12 @@ flexran_schedule_ue_spec_be(mid_t mod_id, ...@@ -916,16 +1041,12 @@ flexran_schedule_ue_spec_be(mid_t mod_id,
uint32_t frame, uint32_t frame,
uint32_t subframe, uint32_t subframe,
int *mbsfn_flag, int *mbsfn_flag,
Protocol__FlexranMessage **dl_info) Protocol__FlexranMessage ** dl_info)
{ {
flexran_schedule_ue_spec_common(mod_id, flexran_schedule_ue_spec_common(mod_id,
slice_id, slice_id,
frame, frame, subframe, mbsfn_flag, dl_info);
subframe,
mbsfn_flag,
dl_info);
} }
...@@ -936,7 +1057,7 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -936,7 +1057,7 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
uint32_t frame, uint32_t frame,
uint32_t subframe, uint32_t subframe,
int *mbsfn_flag, int *mbsfn_flag,
Protocol__FlexranMessage **dl_info) Protocol__FlexranMessage ** dl_info)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
uint8_t CC_id; uint8_t CC_id;
...@@ -945,7 +1066,8 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -945,7 +1066,8 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
unsigned char aggregation; unsigned char aggregation;
mac_rlc_status_resp_t rlc_status; mac_rlc_status_resp_t rlc_status;
unsigned char header_len = 0, header_len_last = 0, ta_len = 0; unsigned char header_len = 0, header_len_last = 0, ta_len = 0;
uint16_t nb_rb, nb_rb_temp, total_nb_available_rb[MAX_NUM_CCs], nb_available_rb; uint16_t nb_rb, nb_rb_temp, total_nb_available_rb[MAX_NUM_CCs],
nb_available_rb;
uint16_t TBS, j, rnti; uint16_t TBS, j, rnti;
uint8_t round = 0; uint8_t round = 0;
uint8_t harq_pid = 0; uint8_t harq_pid = 0;
...@@ -957,7 +1079,7 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -957,7 +1079,7 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
UE_list_t *UE_list = &eNB->UE_list; UE_list_t *UE_list = &eNB->UE_list;
int32_t normalized_rx_power, target_rx_power; int32_t normalized_rx_power, target_rx_power;
int32_t tpc = 1; int32_t tpc = 1;
static int32_t tpc_accumulated=0; static int32_t tpc_accumulated = 0;
UE_sched_ctrl *ue_sched_ctl; UE_sched_ctrl *ue_sched_ctl;
LTE_eNB_UE_stats *eNB_UE_stats = NULL; LTE_eNB_UE_stats *eNB_UE_stats = NULL;
Protocol__FlexDlData *dl_data[NUM_MAX_UE]; Protocol__FlexDlData *dl_data[NUM_MAX_UE];
...@@ -977,23 +1099,23 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -977,23 +1099,23 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
#if 0 #if 0
if (UE_list->head==-1) { if (UE_list->head == -1) {
return; return;
} }
#endif #endif
start_meas(&eNB->schedule_dlsch); start_meas(&eNB->schedule_dlsch);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH,VCD_FUNCTION_IN); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN);
//weight = get_ue_weight(module_idP,UE_id); //weight = get_ue_weight(module_idP,UE_id);
aggregation = 1; // set to the maximum aggregation level aggregation = 1; // set to the maximum aggregation level
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
min_rb_unit[CC_id] = get_min_rb_unit(mod_id, CC_id); min_rb_unit[CC_id] = get_min_rb_unit(mod_id, CC_id);
// get number of PRBs less those used by common channels // get number of PRBs less those used by common channels
total_nb_available_rb[CC_id] = flexran_get_N_RB_DL(mod_id, CC_id); total_nb_available_rb[CC_id] = flexran_get_N_RB_DL(mod_id, CC_id);
for (i=0;i < flexran_get_N_RB_DL(mod_id, CC_id); i++) for (i = 0; i < flexran_get_N_RB_DL(mod_id, CC_id); i++)
if (eNB->common_channels[CC_id].vrb_map[i] != 0) if (eNB->common_channels[CC_id].vrb_map[i] != 0)
total_nb_available_rb[CC_id]--; total_nb_available_rb[CC_id]--;
...@@ -1001,38 +1123,41 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -1001,38 +1123,41 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
// store the global enb stats: // store the global enb stats:
eNB->eNB_stats[CC_id].num_dlactive_UEs = UE_list->num_UEs; eNB->eNB_stats[CC_id].num_dlactive_UEs = UE_list->num_UEs;
eNB->eNB_stats[CC_id].available_prbs = total_nb_available_rb[CC_id]; eNB->eNB_stats[CC_id].available_prbs =
eNB->eNB_stats[CC_id].total_available_prbs += total_nb_available_rb[CC_id]; total_nb_available_rb[CC_id];
eNB->eNB_stats[CC_id].dlsch_bytes_tx=0; eNB->eNB_stats[CC_id].total_available_prbs +=
eNB->eNB_stats[CC_id].dlsch_pdus_tx=0; total_nb_available_rb[CC_id];
eNB->eNB_stats[CC_id].dlsch_bytes_tx = 0;
eNB->eNB_stats[CC_id].dlsch_pdus_tx = 0;
} }
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,VCD_FUNCTION_IN); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_IN);
start_meas(&eNB->schedule_dlsch_preprocessor); start_meas(&eNB->schedule_dlsch_preprocessor);
_dlsch_scheduler_pre_processor(mod_id, _dlsch_scheduler_pre_processor(mod_id,
slice_id, slice_id,
frame, frame, subframe, N_RBG, mbsfn_flag);
subframe,
N_RBG,
mbsfn_flag);
stop_meas(&eNB->schedule_dlsch_preprocessor); stop_meas(&eNB->schedule_dlsch_preprocessor);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT);
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n",CC_id); LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n", CC_id);
if (mbsfn_flag[CC_id]>0) if (mbsfn_flag[CC_id] > 0)
continue; continue;
for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { for (UE_id = UE_list->head; UE_id >= 0;
UE_id = UE_list->next[UE_id]) {
rnti = flexran_get_ue_crnti(mod_id, UE_id); rnti = flexran_get_ue_crnti(mod_id, UE_id);
eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id,CC_id,rnti); eNB_UE_stats =
mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti);
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
if (eNB_UE_stats==NULL) { if (eNB_UE_stats == NULL) {
LOG_D(MAC,"[eNB] Cannot find eNB_UE_stats\n"); LOG_D(MAC, "[eNB] Cannot find eNB_UE_stats\n");
// mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n"); // mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n");
continue; continue;
} }
...@@ -1040,33 +1165,38 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -1040,33 +1165,38 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
if (flexran_slice_member(UE_id, slice_id) == 0) if (flexran_slice_member(UE_id, slice_id) == 0)
continue; continue;
if (rnti==NOT_A_RNTI) { if (rnti == NOT_A_RNTI) {
LOG_D(MAC,"Cannot find rnti for UE_id %d (num_UEs %d)\n", UE_id,UE_list->num_UEs); LOG_D(MAC, "Cannot find rnti for UE_id %d (num_UEs %d)\n",
UE_id, UE_list->num_UEs);
// mac_xface->macphy_exit("Cannot find rnti for UE_id"); // mac_xface->macphy_exit("Cannot find rnti for UE_id");
continue; continue;
} }
switch(mac_xface->get_transmission_mode(mod_id,CC_id,rnti)){ switch (mac_xface->get_transmission_mode(mod_id, CC_id, rnti)) {
case 1: case 1:
case 2: case 2:
case 7: case 7:
aggregation = get_aggregation(get_bw_index(mod_id,CC_id), aggregation = get_aggregation(get_bw_index(mod_id, CC_id),
eNB_UE_stats->DL_cqi[0], eNB_UE_stats->DL_cqi[0],
format1); format1);
break; break;
case 3: case 3:
aggregation = get_aggregation(get_bw_index(mod_id,CC_id), aggregation = get_aggregation(get_bw_index(mod_id, CC_id),
eNB_UE_stats->DL_cqi[0], eNB_UE_stats->DL_cqi[0],
format2A); format2A);
break; break;
default: default:
LOG_W(MAC,"Unsupported transmission mode %d\n", mac_xface->get_transmission_mode(mod_id,CC_id,rnti)); LOG_W(MAC, "Unsupported transmission mode %d\n",
mac_xface->get_transmission_mode(mod_id, CC_id,
rnti));
aggregation = 2; aggregation = 2;
} }
if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated
CCE_allocation_infeasible(mod_id, CC_id, 0, subframe, aggregation, rnti)) { CCE_allocation_infeasible(mod_id, CC_id, 0, subframe,
LOG_D(MAC,"[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n", aggregation, rnti)) {
LOG_D(MAC,
"[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n",
mod_id, frame, UE_id, CC_id); mod_id, frame, UE_id, CC_id);
//if(mac_xface->get_transmission_mode(module_idP,rnti)==5) //if(mac_xface->get_transmission_mode(module_idP,rnti)==5)
continue; //to next user (there might be rbs availiable for other UEs in TM5 continue; //to next user (there might be rbs availiable for other UEs in TM5
...@@ -1074,12 +1204,11 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -1074,12 +1204,11 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
// break; // break;
} }
if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { if (flexran_get_duplex_mode(mod_id, CC_id) ==
set_ue_dai (subframe, PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) {
set_ue_dai(subframe,
flexran_get_subframe_assignment(mod_id, CC_id), flexran_get_subframe_assignment(mod_id, CC_id),
UE_id, UE_id, CC_id, UE_list);
CC_id,
UE_list);
//TODO: update UL DAI after DLSCH scheduling //TODO: update UL DAI after DLSCH scheduling
//set_ul_DAI(mod_id, UE_id, CC_id, frame, subframe,frame_parms); //set_ul_DAI(mod_id, UE_id, CC_id, frame, subframe,frame_parms);
} }
...@@ -1087,7 +1216,9 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -1087,7 +1216,9 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
channels_added = 0; channels_added = 0;
// After this point all the UEs will be scheduled // After this point all the UEs will be scheduled
dl_data[num_ues_added] = (Protocol__FlexDlData *) malloc(sizeof(Protocol__FlexDlData)); dl_data[num_ues_added] =
(Protocol__FlexDlData *)
malloc(sizeof(Protocol__FlexDlData));
protocol__flex_dl_data__init(dl_data[num_ues_added]); protocol__flex_dl_data__init(dl_data[num_ues_added]);
dl_data[num_ues_added]->has_rnti = 1; dl_data[num_ues_added]->has_rnti = 1;
dl_data[num_ues_added]->rnti = rnti; dl_data[num_ues_added]->rnti = rnti;
...@@ -1096,23 +1227,25 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -1096,23 +1227,25 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
dl_data[num_ues_added]->serv_cell_index = CC_id; dl_data[num_ues_added]->serv_cell_index = CC_id;
nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id]; nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id];
flexran_get_harq(mod_id, CC_id, UE_id, frame, subframe, &harq_pid, &round); flexran_get_harq(mod_id, CC_id, UE_id, frame, subframe,
sdu_length_total=0; &harq_pid, &round);
sdu_length_total = 0;
mcs = cqi_to_mcs[flexran_get_ue_wcqi(mod_id, UE_id)]; mcs = cqi_to_mcs[flexran_get_ue_wcqi(mod_id, UE_id)];
// LOG_I(FLEXRAN_AGENT, "The MCS is %d\n", mcs); // LOG_I(FLEXRAN_AGENT, "The MCS is %d\n", mcs);
mcs = cmin(mcs,flexran_slice_maxmcs(slice_id)); mcs = cmin(mcs, flexran_slice_maxmcs(slice_id));
#ifdef EXMIMO #ifdef EXMIMO
if (mac_xface->get_transmission_mode(mod_id, CC_id, rnti) == 5) { if (mac_xface->get_transmission_mode(mod_id, CC_id, rnti) == 5) {
mcs = cqi_to_mcs[flexran_get_ue_wcqi(mod_id, UE_id)]; mcs = cqi_to_mcs[flexran_get_ue_wcqi(mod_id, UE_id)];
mcs = cmin(mcs,16); mcs = cmin(mcs, 16);
} }
#endif #endif
// initializing the rb allocation indicator for each UE // initializing the rb allocation indicator for each UE
for(j = 0; j < flexran_get_N_RBG(mod_id, CC_id); j++) { for (j = 0; j < flexran_get_N_RBG(mod_id, CC_id); j++) {
UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = 0; UE_list->
UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]
= 0;
rballoc_sub[j] = 0; rballoc_sub[j] = 0;
} }
...@@ -1121,7 +1254,9 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -1121,7 +1254,9 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
/* eNB_UE_stats->DL_cqi[0], mcs, */ /* eNB_UE_stats->DL_cqi[0], mcs, */
/* UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status); */ /* UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status); */
dl_dci = (Protocol__FlexDlDci*) malloc(sizeof(Protocol__FlexDlDci)); dl_dci =
(Protocol__FlexDlDci *)
malloc(sizeof(Protocol__FlexDlDci));
protocol__flex_dl_dci__init(dl_dci); protocol__flex_dl_dci__init(dl_dci);
dl_data[num_ues_added]->dl_dci = dl_dci; dl_data[num_ues_added]->dl_dci = dl_dci;
...@@ -1134,13 +1269,19 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -1134,13 +1269,19 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
/* process retransmission */ /* process retransmission */
if (round > 0) { if (round > 0) {
LOG_D(FLEXRAN_AGENT, "There was a retransmission just now and the round was %d\n", round); LOG_D(FLEXRAN_AGENT,
"There was a retransmission just now and the round was %d\n",
round);
if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { if (flexran_get_duplex_mode(mod_id, CC_id) ==
PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) {
UE_list->UE_template[CC_id][UE_id].DAI++; UE_list->UE_template[CC_id][UE_id].DAI++;
update_ul_dci(mod_id, CC_id, rnti, UE_list->UE_template[CC_id][UE_id].DAI); update_ul_dci(mod_id, CC_id, rnti,
LOG_D(MAC,"DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n", UE_list->UE_template[CC_id][UE_id].DAI);
CC_id, subframe,UE_id,UE_list->UE_template[CC_id][UE_id].DAI); LOG_D(MAC,
"DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n",
CC_id, subframe, UE_id,
UE_list->UE_template[CC_id][UE_id].DAI);
} }
mcs = UE_list->UE_template[CC_id][UE_id].mcs[harq_pid]; mcs = UE_list->UE_template[CC_id][UE_id].mcs[harq_pid];
...@@ -1153,24 +1294,38 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -1153,24 +1294,38 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
if (nb_rb <= nb_available_rb) { if (nb_rb <= nb_available_rb) {
if(nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) {
for(j = 0; j < flexran_get_N_RBG(mod_id, CC_id); j++) { // for indicating the rballoc for each sub-band for (j = 0; j < flexran_get_N_RBG(mod_id, CC_id); j++) { // for indicating the rballoc for each sub-band
UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; UE_list->UE_template[CC_id][UE_id].
rballoc_subband[harq_pid][j] =
ue_sched_ctl->rballoc_sub_UE[CC_id][j];
} }
} else { } else {
nb_rb_temp = nb_rb; nb_rb_temp = nb_rb;
j = 0; j = 0;
while((nb_rb_temp > 0) && (j < flexran_get_N_RBG(mod_id, CC_id))) { while ((nb_rb_temp > 0)
if(ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { && (j < flexran_get_N_RBG(mod_id, CC_id))) {
UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] ==
1) {
if((j == flexran_get_N_RBG(mod_id, CC_id) - 1) && UE_list->
((flexran_get_N_RB_DL(mod_id, CC_id) == 25)|| UE_template[CC_id]
(flexran_get_N_RB_DL(mod_id, CC_id) == 50))) { [UE_id].rballoc_subband[harq_pid][j] =
nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]+1; ue_sched_ctl->rballoc_sub_UE[CC_id][j];
if ((j ==
flexran_get_N_RBG(mod_id, CC_id) - 1)
&&
((flexran_get_N_RB_DL(mod_id, CC_id) ==
25)
|| (flexran_get_N_RB_DL(mod_id, CC_id)
== 50))) {
nb_rb_temp =
nb_rb_temp - min_rb_unit[CC_id] +
1;
} else { } else {
nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; nb_rb_temp =
nb_rb_temp - min_rb_unit[CC_id];
} }
} }
j = j + 1; j = j + 1;
...@@ -1178,23 +1333,38 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -1178,23 +1333,38 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
} }
nb_available_rb -= nb_rb; nb_available_rb -= nb_rb;
PHY_vars_eNB_g[mod_id][CC_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; PHY_vars_eNB_g[mod_id][CC_id]->
PHY_vars_eNB_g[mod_id][CC_id]->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id]; mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb;
PHY_vars_eNB_g[mod_id][CC_id]->
for(j=0; j < flexran_get_N_RBG(mod_id, CC_id); j++) { mu_mimo_mode[UE_id].dl_pow_off =
PHY_vars_eNB_g[mod_id][CC_id]->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; ue_sched_ctl->dl_pow_off[CC_id];
rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j];
for (j = 0; j < flexran_get_N_RBG(mod_id, CC_id); j++) {
PHY_vars_eNB_g[mod_id][CC_id]->
mu_mimo_mode[UE_id].rballoc_sub[j] =
UE_list->
UE_template[CC_id][UE_id].rballoc_subband
[harq_pid][j];
rballoc_sub[j] =
UE_list->
UE_template[CC_id][UE_id].rballoc_subband
[harq_pid][j];
} }
// Keep the old NDI, do not toggle // Keep the old NDI, do not toggle
ndi = UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; ndi =
tpc = UE_list->UE_template[CC_id][UE_id].oldTPC[harq_pid]; UE_list->UE_template[CC_id][UE_id].
oldNDI[harq_pid];
tpc =
UE_list->UE_template[CC_id][UE_id].
oldTPC[harq_pid];
UE_list->UE_template[CC_id][UE_id].mcs[harq_pid] = mcs; UE_list->UE_template[CC_id][UE_id].mcs[harq_pid] = mcs;
ue_has_transmission = 1; ue_has_transmission = 1;
num_ues_added++; num_ues_added++;
} else { } else {
LOG_D(MAC,"[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n", LOG_D(MAC,
"[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n",
mod_id, frame, CC_id, UE_id); mod_id, frame, CC_id, UE_id);
ue_has_transmission = 0; ue_has_transmission = 0;
} }
...@@ -1214,13 +1384,14 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -1214,13 +1384,14 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
ta_len = (ue_sched_ctl->ta_update != 0) ? 2 : 0; ta_len = (ue_sched_ctl->ta_update != 0) ? 2 : 0;
dl_data[num_ues_added]->n_ce_bitmap = 2; dl_data[num_ues_added]->n_ce_bitmap = 2;
dl_data[num_ues_added]->ce_bitmap = (uint32_t *) calloc(2, sizeof(uint32_t)); dl_data[num_ues_added]->ce_bitmap =
(uint32_t *) calloc(2, sizeof(uint32_t));
if (ta_len > 0) { if (ta_len > 0) {
ce_flags |= PROTOCOL__FLEX_CE_TYPE__FLPCET_TA; ce_flags |= PROTOCOL__FLEX_CE_TYPE__FLPCET_TA;
} }
/*TODO: Add other flags if DRX and other CE are required*/ /*TODO: Add other flags if DRX and other CE are required */
// Add the control element flags to the flexran message // Add the control element flags to the flexran message
dl_data[num_ues_added]->ce_bitmap[0] = ce_flags; dl_data[num_ues_added]->ce_bitmap[0] = ce_flags;
...@@ -1234,25 +1405,27 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -1234,25 +1405,27 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
for (j = 1; j < NB_RB_MAX; j++) { for (j = 1; j < NB_RB_MAX; j++) {
header_len += 3; header_len += 3;
// Need to see if we have space for data from this channel // Need to see if we have space for data from this channel
if (dci_tbs - ta_len - header_len - sdu_length_total > 0) { if (dci_tbs - ta_len - header_len - sdu_length_total >
LOG_D(MAC, "[TEST]Requested %d bytes from RLC buffer on channel %d during first call\n", dci_tbs-ta_len-header_len); 0) {
LOG_D(MAC,
"[TEST]Requested %d bytes from RLC buffer on channel %d during first call\n",
dci_tbs - ta_len - header_len);
//If we have space, we need to see how much data we can request at most (if any available) //If we have space, we need to see how much data we can request at most (if any available)
rlc_status = mac_rlc_status_ind(mod_id, rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, subframe, ENB_FLAG_YES, MBMS_FLAG_NO, j, (dci_tbs - ta_len - header_len - sdu_length_total)); // transport block set size
rnti,
mod_id,
frame,
subframe,
ENB_FLAG_YES,
MBMS_FLAG_NO,
j,
(dci_tbs - ta_len - header_len - sdu_length_total)); // transport block set size
//If data are available in channel j //If data are available in channel j
if (rlc_status.bytes_in_buffer > 0) { if (rlc_status.bytes_in_buffer > 0) {
LOG_D(MAC, "[TEST]Have %d bytes in DCCH buffer during first call\n", rlc_status.bytes_in_buffer); LOG_D(MAC,
"[TEST]Have %d bytes in DCCH buffer during first call\n",
rlc_status.bytes_in_buffer);
//Fill in as much as possible //Fill in as much as possible
data_to_request = cmin(dci_tbs - ta_len - header_len - sdu_length_total, rlc_status.bytes_in_buffer); data_to_request =
LOG_D(FLEXRAN_AGENT, "Will request %d bytes from channel %d\n", data_to_request, j); cmin(dci_tbs - ta_len - header_len -
sdu_length_total,
rlc_status.bytes_in_buffer);
LOG_D(FLEXRAN_AGENT,
"Will request %d bytes from channel %d\n",
data_to_request, j);
if (data_to_request < 128) { //The header will be one byte less if (data_to_request < 128) { //The header will be one byte less
header_len--; header_len--;
header_len_last = 2; header_len_last = 2;
...@@ -1262,23 +1435,47 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -1262,23 +1435,47 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
/* if (j == 1 || j == 2) { /* if (j == 1 || j == 2) {
data_to_request+=0; data_to_request+=0;
} */ } */
LOG_D(MAC, "[TEST]Will request %d from channel %d\n", data_to_request, j); LOG_D(MAC,
rlc_pdus[channels_added] = (Protocol__FlexRlcPdu *) malloc(sizeof(Protocol__FlexRlcPdu)); "[TEST]Will request %d from channel %d\n",
protocol__flex_rlc_pdu__init(rlc_pdus[channels_added]); data_to_request, j);
rlc_pdus[channels_added] =
(Protocol__FlexRlcPdu *)
malloc(sizeof(Protocol__FlexRlcPdu));
protocol__flex_rlc_pdu__init(rlc_pdus
[channels_added]);
rlc_pdus[channels_added]->n_rlc_pdu_tb = 2; rlc_pdus[channels_added]->n_rlc_pdu_tb = 2;
rlc_pdus[channels_added]->rlc_pdu_tb = (Protocol__FlexRlcPduTb **) malloc(sizeof(Protocol__FlexRlcPduTb *) * 2); rlc_pdus[channels_added]->rlc_pdu_tb =
rlc_pdus[channels_added]->rlc_pdu_tb[0] = (Protocol__FlexRlcPduTb *) malloc(sizeof(Protocol__FlexRlcPduTb)); (Protocol__FlexRlcPduTb **)
protocol__flex_rlc_pdu_tb__init(rlc_pdus[channels_added]->rlc_pdu_tb[0]); malloc(sizeof(Protocol__FlexRlcPduTb *) *
rlc_pdus[channels_added]->rlc_pdu_tb[0]->has_logical_channel_id = 1; 2);
rlc_pdus[channels_added]->rlc_pdu_tb[0]->logical_channel_id = j; rlc_pdus[channels_added]->rlc_pdu_tb[0] =
rlc_pdus[channels_added]->rlc_pdu_tb[0]->has_size = 1; (Protocol__FlexRlcPduTb *)
rlc_pdus[channels_added]->rlc_pdu_tb[0]->size = data_to_request; malloc(sizeof(Protocol__FlexRlcPduTb));
rlc_pdus[channels_added]->rlc_pdu_tb[1] = (Protocol__FlexRlcPduTb *) malloc(sizeof(Protocol__FlexRlcPduTb)); protocol__flex_rlc_pdu_tb__init(rlc_pdus
protocol__flex_rlc_pdu_tb__init(rlc_pdus[channels_added]->rlc_pdu_tb[1]); [channels_added]->rlc_pdu_tb
rlc_pdus[channels_added]->rlc_pdu_tb[1]->has_logical_channel_id = 1; [0]);
rlc_pdus[channels_added]->rlc_pdu_tb[1]->logical_channel_id = j; rlc_pdus[channels_added]->
rlc_pdus[channels_added]->rlc_pdu_tb[1]->has_size = 1; rlc_pdu_tb[0]->has_logical_channel_id = 1;
rlc_pdus[channels_added]->rlc_pdu_tb[1]->size = data_to_request; rlc_pdus[channels_added]->
rlc_pdu_tb[0]->logical_channel_id = j;
rlc_pdus[channels_added]->rlc_pdu_tb[0]->
has_size = 1;
rlc_pdus[channels_added]->rlc_pdu_tb[0]->size =
data_to_request;
rlc_pdus[channels_added]->rlc_pdu_tb[1] =
(Protocol__FlexRlcPduTb *)
malloc(sizeof(Protocol__FlexRlcPduTb));
protocol__flex_rlc_pdu_tb__init(rlc_pdus
[channels_added]->rlc_pdu_tb
[1]);
rlc_pdus[channels_added]->
rlc_pdu_tb[1]->has_logical_channel_id = 1;
rlc_pdus[channels_added]->
rlc_pdu_tb[1]->logical_channel_id = j;
rlc_pdus[channels_added]->rlc_pdu_tb[1]->
has_size = 1;
rlc_pdus[channels_added]->rlc_pdu_tb[1]->size =
data_to_request;
dl_data[num_ues_added]->n_rlc_pdu++; dl_data[num_ues_added]->n_rlc_pdu++;
channels_added++; channels_added++;
//Set this to the max value that we might request //Set this to the max value that we might request
...@@ -1291,7 +1488,8 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -1291,7 +1488,8 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
} // End of iterating the logical channels } // End of iterating the logical channels
// Add rlc_pdus to the dl_data message // Add rlc_pdus to the dl_data message
dl_data[num_ues_added]->rlc_pdu = (Protocol__FlexRlcPdu **) malloc(sizeof(Protocol__FlexRlcPdu *) * dl_data[num_ues_added]->rlc_pdu = (Protocol__FlexRlcPdu **)
malloc(sizeof(Protocol__FlexRlcPdu *) *
dl_data[num_ues_added]->n_rlc_pdu); dl_data[num_ues_added]->n_rlc_pdu);
for (i = 0; i < dl_data[num_ues_added]->n_rlc_pdu; i++) { for (i = 0; i < dl_data[num_ues_added]->n_rlc_pdu; i++) {
dl_data[num_ues_added]->rlc_pdu[i] = rlc_pdus[i]; dl_data[num_ues_added]->rlc_pdu[i] = rlc_pdus[i];
...@@ -1301,18 +1499,20 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -1301,18 +1499,20 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
LOG_D(FLEXRAN_AGENT, "Header was empty\n"); LOG_D(FLEXRAN_AGENT, "Header was empty\n");
header_len_last = 0; header_len_last = 0;
} }
// there is a payload // there is a payload
if ((dl_data[num_ues_added]->n_rlc_pdu > 0)) { if ((dl_data[num_ues_added]->n_rlc_pdu > 0)) {
// Now compute number of required RBs for total sdu length // Now compute number of required RBs for total sdu length
// Assume RAH format 2 // Assume RAH format 2
// adjust header lengths // adjust header lengths
LOG_D(FLEXRAN_AGENT, "We have %d bytes to transfer\n", sdu_length_total); LOG_D(FLEXRAN_AGENT, "We have %d bytes to transfer\n",
sdu_length_total);
if (header_len != 0) { if (header_len != 0) {
LOG_D(FLEXRAN_AGENT, "Header length was %d ", header_len); LOG_D(FLEXRAN_AGENT, "Header length was %d ",
header_len);
header_len_last--; header_len_last--;
header_len -= header_len_last; header_len -= header_len_last;
LOG_D(FLEXRAN_AGENT, "so we resized it to %d\n", header_len); LOG_D(FLEXRAN_AGENT, "so we resized it to %d\n",
header_len);
} }
/* if (header_len == 2 || header_len == 3) { //Only one SDU, remove length field */ /* if (header_len == 2 || header_len == 3) { //Only one SDU, remove length field */
...@@ -1325,21 +1525,28 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -1325,21 +1525,28 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
if (mcs_tmp == 0) { if (mcs_tmp == 0) {
nb_rb = 4; // don't let the TBS get too small nb_rb = 4; // don't let the TBS get too small
} else { } else {
nb_rb=min_rb_unit[CC_id]; nb_rb = min_rb_unit[CC_id];
} }
LOG_D(MAC,"[TEST]The initial number of resource blocks was %d\n", nb_rb); LOG_D(MAC,
LOG_D(MAC,"[TEST] The initial mcs was %d\n", mcs_tmp); "[TEST]The initial number of resource blocks was %d\n",
nb_rb);
LOG_D(MAC, "[TEST] The initial mcs was %d\n", mcs_tmp);
TBS = mac_xface->get_TBS_DL(mcs_tmp, nb_rb); TBS = mac_xface->get_TBS_DL(mcs_tmp, nb_rb);
LOG_D(MAC,"[TEST]The TBS during rate matching was %d\n", TBS); LOG_D(MAC,
"[TEST]The TBS during rate matching was %d\n",
TBS);
while (TBS < (sdu_length_total + header_len + ta_len)) { while (TBS < (sdu_length_total + header_len + ta_len)) {
nb_rb += min_rb_unit[CC_id]; // nb_rb += min_rb_unit[CC_id]; //
LOG_D(MAC, "[TEST]Had to increase the number of RBs\n"); LOG_D(MAC,
"[TEST]Had to increase the number of RBs\n");
if (nb_rb > nb_available_rb) { // if we've gone beyond the maximum number of RBs if (nb_rb > nb_available_rb) { // if we've gone beyond the maximum number of RBs
// (can happen if N_RB_DL is odd) // (can happen if N_RB_DL is odd)
TBS = mac_xface->get_TBS_DL(mcs_tmp, nb_available_rb); TBS =
mac_xface->get_TBS_DL(mcs_tmp,
nb_available_rb);
nb_rb = nb_available_rb; nb_rb = nb_available_rb;
break; break;
} }
...@@ -1347,46 +1554,73 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -1347,46 +1554,73 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
TBS = mac_xface->get_TBS_DL(mcs_tmp, nb_rb); TBS = mac_xface->get_TBS_DL(mcs_tmp, nb_rb);
} }
if(nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) {
LOG_D(MAC, "[TEST]We had the exact number of rbs. Time to fill the rballoc subband\n"); LOG_D(MAC,
for(j = 0; j < flexran_get_N_RBG(mod_id, CC_id); j++) { // for indicating the rballoc for each sub-band "[TEST]We had the exact number of rbs. Time to fill the rballoc subband\n");
UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; for (j = 0; j < flexran_get_N_RBG(mod_id, CC_id); j++) { // for indicating the rballoc for each sub-band
UE_list->UE_template[CC_id][UE_id].
rballoc_subband[harq_pid][j] =
ue_sched_ctl->rballoc_sub_UE[CC_id][j];
} }
} else { } else {
nb_rb_temp = nb_rb; nb_rb_temp = nb_rb;
j = 0; j = 0;
LOG_D(MAC, "[TEST]Will only partially fill the bitmap\n"); LOG_D(MAC,
while((nb_rb_temp > 0) && (j < flexran_get_N_RBG(mod_id, CC_id))) { "[TEST]Will only partially fill the bitmap\n");
if(ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { while ((nb_rb_temp > 0)
UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; && (j < flexran_get_N_RBG(mod_id, CC_id))) {
if ((j == flexran_get_N_RBG(mod_id, CC_id) - 1) && if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] ==
((flexran_get_N_RB_DL(mod_id, CC_id) == 25)|| 1) {
(flexran_get_N_RB_DL(mod_id, CC_id) == 50))) { UE_list->
nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1; UE_template[CC_id]
[UE_id].rballoc_subband[harq_pid][j] =
ue_sched_ctl->rballoc_sub_UE[CC_id][j];
if ((j ==
flexran_get_N_RBG(mod_id, CC_id) - 1)
&&
((flexran_get_N_RB_DL(mod_id, CC_id) ==
25)
|| (flexran_get_N_RB_DL(mod_id, CC_id)
== 50))) {
nb_rb_temp =
nb_rb_temp - min_rb_unit[CC_id] +
1;
} else { } else {
nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; nb_rb_temp =
nb_rb_temp - min_rb_unit[CC_id];
} }
} }
j = j+1; j = j + 1;
} }
} }
PHY_vars_eNB_g[mod_id][CC_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; PHY_vars_eNB_g[mod_id][CC_id]->
PHY_vars_eNB_g[mod_id][CC_id]->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id]; mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb;
PHY_vars_eNB_g[mod_id][CC_id]->
mu_mimo_mode[UE_id].dl_pow_off =
ue_sched_ctl->dl_pow_off[CC_id];
for(j = 0; j < flexran_get_N_RBG(mod_id, CC_id); j++) { for (j = 0; j < flexran_get_N_RBG(mod_id, CC_id); j++) {
PHY_vars_eNB_g[mod_id][CC_id]->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; PHY_vars_eNB_g[mod_id][CC_id]->
mu_mimo_mode[UE_id].rballoc_sub[j] =
UE_list->
UE_template[CC_id][UE_id].rballoc_subband
[harq_pid][j];
} }
// decrease mcs until TBS falls below required length // decrease mcs until TBS falls below required length
while ((TBS > (sdu_length_total + header_len + ta_len)) && (mcs_tmp > 0)) { while ((TBS > (sdu_length_total + header_len + ta_len))
&& (mcs_tmp > 0)) {
mcs_tmp--; mcs_tmp--;
TBS = mac_xface->get_TBS_DL(mcs_tmp, nb_rb); TBS = mac_xface->get_TBS_DL(mcs_tmp, nb_rb);
} }
// if we have decreased too much or we don't have enough RBs, increase MCS // if we have decreased too much or we don't have enough RBs, increase MCS
while ((TBS < (sdu_length_total + header_len + ta_len)) && while ((TBS < (sdu_length_total + header_len + ta_len))
((( ue_sched_ctl->dl_pow_off[CC_id] > 0) && (mcs_tmp < 28)) || ( (ue_sched_ctl->dl_pow_off[CC_id]==0) && (mcs_tmp <= 15)))) { && (((ue_sched_ctl->dl_pow_off[CC_id] > 0)
&& (mcs_tmp < 28))
|| ((ue_sched_ctl->dl_pow_off[CC_id] == 0)
&& (mcs_tmp <= 15)))) {
mcs_tmp++; mcs_tmp++;
TBS = mac_xface->get_TBS_DL(mcs_tmp, nb_rb); TBS = mac_xface->get_TBS_DL(mcs_tmp, nb_rb);
} }
...@@ -1398,42 +1632,58 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -1398,42 +1632,58 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
dl_dci->has_aggr_level = 1; dl_dci->has_aggr_level = 1;
dl_dci->aggr_level = aggregation; dl_dci->aggr_level = aggregation;
UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb; UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] =
nb_rb;
if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { if (flexran_get_duplex_mode(mod_id, CC_id) ==
PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) {
UE_list->UE_template[CC_id][UE_id].DAI++; UE_list->UE_template[CC_id][UE_id].DAI++;
// printf("DAI update: subframeP %d: UE %d, DAI %d\n",subframeP,UE_id,UE_list->UE_template[CC_id][UE_id].DAI); // printf("DAI update: subframeP %d: UE %d, DAI %d\n",subframeP,UE_id,UE_list->UE_template[CC_id][UE_id].DAI);
//#warning only for 5MHz channel //#warning only for 5MHz channel
update_ul_dci(mod_id, CC_id, rnti, UE_list->UE_template[CC_id][UE_id].DAI); update_ul_dci(mod_id, CC_id, rnti,
UE_list->UE_template[CC_id][UE_id].
DAI);
} }
// do PUCCH power control // do PUCCH power control
// this is the normalized RX power // this is the normalized RX power
normalized_rx_power = flexran_get_p0_pucch_dbm(mod_id,UE_id, CC_id); //eNB_UE_stats->Po_PUCCH_dBm; normalized_rx_power = flexran_get_p0_pucch_dbm(mod_id, UE_id, CC_id); //eNB_UE_stats->Po_PUCCH_dBm;
target_rx_power = flexran_get_p0_nominal_pucch(mod_id, CC_id) + 20; //mac_xface->get_target_pucch_rx_power(mod_id, CC_id) + 20; target_rx_power = flexran_get_p0_nominal_pucch(mod_id, CC_id) + 20; //mac_xface->get_target_pucch_rx_power(mod_id, CC_id) + 20;
// this assumes accumulated tpc // this assumes accumulated tpc
// make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out
int32_t framex10psubframe = UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame*10+UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe; int32_t framex10psubframe =
UE_list->UE_template[CC_id][UE_id].
if (((framex10psubframe+10)<=(frame*10+subframe)) || //normal case pucch_tpc_tx_frame * 10 +
((framex10psubframe>(frame*10+subframe)) && (((10240-framex10psubframe+frame*10+subframe)>=10)))) //frame wrap-around UE_list->UE_template[CC_id][UE_id].
if (flexran_get_p0_pucch_status(mod_id, UE_id, CC_id) == 1) { pucch_tpc_tx_subframe;
if (((framex10psubframe + 10) <= (frame * 10 + subframe)) || //normal case
((framex10psubframe > (frame * 10 + subframe)) && (((10240 - framex10psubframe + frame * 10 + subframe) >= 10)))) //frame wrap-around
if (flexran_get_p0_pucch_status
(mod_id, UE_id, CC_id) == 1) {
flexran_update_p0_pucch(mod_id, UE_id, CC_id); flexran_update_p0_pucch(mod_id, UE_id, CC_id);
UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame = frame; UE_list->
UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe = subframe; UE_template[CC_id]
if (normalized_rx_power>(target_rx_power+1)) { [UE_id].pucch_tpc_tx_frame = frame;
UE_list->
UE_template[CC_id]
[UE_id].pucch_tpc_tx_subframe = subframe;
if (normalized_rx_power >
(target_rx_power + 1)) {
tpc = 0; //-1 tpc = 0; //-1
tpc_accumulated--; tpc_accumulated--;
} else if (normalized_rx_power<(target_rx_power-1)) { } else if (normalized_rx_power <
(target_rx_power - 1)) {
tpc = 2; //+1 tpc = 2; //+1
tpc_accumulated++; tpc_accumulated++;
} else { } else {
tpc = 1; //0 tpc = 1; //0
} }
LOG_D(MAC,"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", LOG_D(MAC,
"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n",
mod_id, frame, subframe, harq_pid, tpc, mod_id, frame, subframe, harq_pid, tpc,
tpc_accumulated, normalized_rx_power, target_rx_power); tpc_accumulated, normalized_rx_power,
target_rx_power);
} // Po_PUCCH has been updated } // Po_PUCCH has been updated
else { else {
tpc = 1; //0 tpc = 1; //0
...@@ -1442,19 +1692,35 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -1442,19 +1692,35 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
tpc = 1; //0 tpc = 1; //0
} }
for(i=0; i<PHY_vars_eNB_g[mod_id][CC_id]->frame_parms.N_RBG; i++) { for (i = 0;
rballoc_sub[i] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][i]; i <
PHY_vars_eNB_g[mod_id][CC_id]->frame_parms.N_RBG;
i++) {
rballoc_sub[i] =
UE_list->
UE_template[CC_id][UE_id].rballoc_subband
[harq_pid][i];
} }
// Toggle NDI // Toggle NDI
LOG_D(MAC,"CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n", LOG_D(MAC,
"CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n",
CC_id, frame, subframe, UE_id, CC_id, frame, subframe, UE_id,
UE_list->UE_template[CC_id][UE_id].rnti,harq_pid, UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]); UE_list->UE_template[CC_id][UE_id].rnti,
UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]= 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; harq_pid,
ndi = UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; UE_list->UE_template[CC_id][UE_id].
oldNDI[harq_pid]);
UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid] =
1 -
UE_list->UE_template[CC_id][UE_id].
oldNDI[harq_pid];
ndi =
UE_list->UE_template[CC_id][UE_id].
oldNDI[harq_pid];
UE_list->UE_template[CC_id][UE_id].mcs[harq_pid] = mcs; UE_list->UE_template[CC_id][UE_id].mcs[harq_pid] = mcs;
UE_list->UE_template[CC_id][UE_id].oldTPC[harq_pid] = tpc; UE_list->UE_template[CC_id][UE_id].oldTPC[harq_pid] =
tpc;
// Increase the pointer for the number of scheduled UEs // Increase the pointer for the number of scheduled UEs
num_ues_added++; num_ues_added++;
...@@ -1466,142 +1732,194 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -1466,142 +1732,194 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
// If we has transmission or retransmission // If we has transmission or retransmission
if (ue_has_transmission) { if (ue_has_transmission) {
switch (mac_xface->get_transmission_mode(mod_id, CC_id, rnti)) { switch (mac_xface->
get_transmission_mode(mod_id, CC_id, rnti)) {
case 1: case 1:
case 2: case 2:
default: default:
dl_dci->has_res_alloc = 1; dl_dci->has_res_alloc = 1;
dl_dci->res_alloc = 0; dl_dci->res_alloc = 0;
dl_dci->has_vrb_format = 1; dl_dci->has_vrb_format = 1;
dl_dci->vrb_format = PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED; dl_dci->vrb_format =
PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED;
dl_dci->has_format = 1; dl_dci->has_format = 1;
dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1; dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1;
dl_dci->has_rb_bitmap = 1; dl_dci->has_rb_bitmap = 1;
dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, rballoc_sub); dl_dci->rb_bitmap =
allocate_prbs_sub(nb_rb, rballoc_sub);
dl_dci->has_rb_shift = 1; dl_dci->has_rb_shift = 1;
dl_dci->rb_shift = 0; dl_dci->rb_shift = 0;
dl_dci->n_ndi = 1; dl_dci->n_ndi = 1;
dl_dci->ndi = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_ndi); dl_dci->ndi =
(uint32_t *) malloc(sizeof(uint32_t) *
dl_dci->n_ndi);
dl_dci->ndi[0] = ndi; dl_dci->ndi[0] = ndi;
dl_dci->n_rv = 1; dl_dci->n_rv = 1;
dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); dl_dci->rv =
(uint32_t *) malloc(sizeof(uint32_t) *
dl_dci->n_rv);
dl_dci->rv[0] = round & 3; dl_dci->rv[0] = round & 3;
dl_dci->has_tpc = 1; dl_dci->has_tpc = 1;
dl_dci->tpc = tpc; dl_dci->tpc = tpc;
dl_dci->n_mcs = 1; dl_dci->n_mcs = 1;
dl_dci->mcs = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_mcs); dl_dci->mcs =
(uint32_t *) malloc(sizeof(uint32_t) *
dl_dci->n_mcs);
dl_dci->mcs[0] = mcs; dl_dci->mcs[0] = mcs;
dl_dci->n_tbs_size = 1; dl_dci->n_tbs_size = 1;
dl_dci->tbs_size = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_tbs_size); dl_dci->tbs_size =
(uint32_t *) malloc(sizeof(uint32_t) *
dl_dci->n_tbs_size);
dl_dci->tbs_size[0] = dci_tbs; dl_dci->tbs_size[0] = dci_tbs;
if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { if (flexran_get_duplex_mode(mod_id, CC_id) ==
PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) {
dl_dci->has_dai = 1; dl_dci->has_dai = 1;
dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; dl_dci->dai =
(UE_list->UE_template[CC_id][UE_id].DAI -
1) & 3;
} }
break; break;
case 3: case 3:
dl_dci->has_res_alloc = 1; dl_dci->has_res_alloc = 1;
dl_dci->res_alloc = 0; dl_dci->res_alloc = 0;
dl_dci->has_vrb_format = 1; dl_dci->has_vrb_format = 1;
dl_dci->vrb_format = PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED; dl_dci->vrb_format =
PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED;
dl_dci->has_format = 1; dl_dci->has_format = 1;
dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A; dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A;
dl_dci->has_rb_bitmap = 1; dl_dci->has_rb_bitmap = 1;
dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, rballoc_sub); dl_dci->rb_bitmap =
allocate_prbs_sub(nb_rb, rballoc_sub);
dl_dci->has_rb_shift = 1; dl_dci->has_rb_shift = 1;
dl_dci->rb_shift = 0; dl_dci->rb_shift = 0;
dl_dci->n_ndi = 2; dl_dci->n_ndi = 2;
dl_dci->ndi = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_ndi); dl_dci->ndi =
(uint32_t *) malloc(sizeof(uint32_t) *
dl_dci->n_ndi);
dl_dci->ndi[0] = ndi; dl_dci->ndi[0] = ndi;
dl_dci->ndi[1] = ndi; dl_dci->ndi[1] = ndi;
dl_dci->n_rv = 2; dl_dci->n_rv = 2;
dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); dl_dci->rv =
(uint32_t *) malloc(sizeof(uint32_t) *
dl_dci->n_rv);
dl_dci->rv[0] = round & 3; dl_dci->rv[0] = round & 3;
dl_dci->rv[1] = round & 3; dl_dci->rv[1] = round & 3;
dl_dci->has_tpc = 1; dl_dci->has_tpc = 1;
dl_dci->tpc = tpc; dl_dci->tpc = tpc;
dl_dci->n_mcs = 2; dl_dci->n_mcs = 2;
dl_dci->mcs = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_mcs); dl_dci->mcs =
(uint32_t *) malloc(sizeof(uint32_t) *
dl_dci->n_mcs);
dl_dci->mcs[0] = mcs; dl_dci->mcs[0] = mcs;
dl_dci->mcs[1] = mcs; dl_dci->mcs[1] = mcs;
dl_dci->n_tbs_size = 2; dl_dci->n_tbs_size = 2;
dl_dci->tbs_size = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_tbs_size); dl_dci->tbs_size =
(uint32_t *) malloc(sizeof(uint32_t) *
dl_dci->n_tbs_size);
dl_dci->tbs_size[0] = dci_tbs; dl_dci->tbs_size[0] = dci_tbs;
dl_dci->tbs_size[1] = dci_tbs; dl_dci->tbs_size[1] = dci_tbs;
if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { if (flexran_get_duplex_mode(mod_id, CC_id) ==
PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) {
dl_dci->has_dai = 1; dl_dci->has_dai = 1;
dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; dl_dci->dai =
(UE_list->UE_template[CC_id][UE_id].DAI -
1) & 3;
} }
break; break;
case 4: case 4:
dl_dci->has_res_alloc = 1; dl_dci->has_res_alloc = 1;
dl_dci->res_alloc = 0; dl_dci->res_alloc = 0;
dl_dci->has_vrb_format = 1; dl_dci->has_vrb_format = 1;
dl_dci->vrb_format = PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED; dl_dci->vrb_format =
PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED;
dl_dci->has_format = 1; dl_dci->has_format = 1;
dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A; dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A;
dl_dci->has_rb_bitmap = 1; dl_dci->has_rb_bitmap = 1;
dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, rballoc_sub); dl_dci->rb_bitmap =
allocate_prbs_sub(nb_rb, rballoc_sub);
dl_dci->has_rb_shift = 1; dl_dci->has_rb_shift = 1;
dl_dci->rb_shift = 0; dl_dci->rb_shift = 0;
dl_dci->n_ndi = 2; dl_dci->n_ndi = 2;
dl_dci->ndi = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_ndi); dl_dci->ndi =
(uint32_t *) malloc(sizeof(uint32_t) *
dl_dci->n_ndi);
dl_dci->ndi[0] = ndi; dl_dci->ndi[0] = ndi;
dl_dci->ndi[1] = ndi; dl_dci->ndi[1] = ndi;
dl_dci->n_rv = 2; dl_dci->n_rv = 2;
dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); dl_dci->rv =
(uint32_t *) malloc(sizeof(uint32_t) *
dl_dci->n_rv);
dl_dci->rv[0] = round & 3; dl_dci->rv[0] = round & 3;
dl_dci->rv[1] = round & 3; dl_dci->rv[1] = round & 3;
dl_dci->has_tpc = 1; dl_dci->has_tpc = 1;
dl_dci->tpc = tpc; dl_dci->tpc = tpc;
dl_dci->n_mcs = 2; dl_dci->n_mcs = 2;
dl_dci->mcs = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_mcs); dl_dci->mcs =
(uint32_t *) malloc(sizeof(uint32_t) *
dl_dci->n_mcs);
dl_dci->mcs[0] = mcs; dl_dci->mcs[0] = mcs;
dl_dci->mcs[1] = mcs; dl_dci->mcs[1] = mcs;
dl_dci->n_tbs_size = 2; dl_dci->n_tbs_size = 2;
dl_dci->tbs_size = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_tbs_size); dl_dci->tbs_size =
(uint32_t *) malloc(sizeof(uint32_t) *
dl_dci->n_tbs_size);
dl_dci->tbs_size[0] = dci_tbs; dl_dci->tbs_size[0] = dci_tbs;
dl_dci->tbs_size[1] = dci_tbs; dl_dci->tbs_size[1] = dci_tbs;
if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { if (flexran_get_duplex_mode(mod_id, CC_id) ==
PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) {
dl_dci->has_dai = 1; dl_dci->has_dai = 1;
dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; dl_dci->dai =
(UE_list->UE_template[CC_id][UE_id].DAI -
1) & 3;
} }
break; break;
case 5: case 5:
dl_dci->has_res_alloc = 1; dl_dci->has_res_alloc = 1;
dl_dci->res_alloc = 0; dl_dci->res_alloc = 0;
dl_dci->has_vrb_format = 1; dl_dci->has_vrb_format = 1;
dl_dci->vrb_format = PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED; dl_dci->vrb_format =
PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED;
dl_dci->has_format = 1; dl_dci->has_format = 1;
dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D; dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D;
dl_dci->has_rb_bitmap = 1; dl_dci->has_rb_bitmap = 1;
dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, rballoc_sub); dl_dci->rb_bitmap =
allocate_prbs_sub(nb_rb, rballoc_sub);
dl_dci->has_rb_shift = 1; dl_dci->has_rb_shift = 1;
dl_dci->rb_shift = 0; dl_dci->rb_shift = 0;
dl_dci->n_ndi = 1; dl_dci->n_ndi = 1;
dl_dci->ndi[0] = ndi; dl_dci->ndi[0] = ndi;
dl_dci->n_rv = 1; dl_dci->n_rv = 1;
dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); dl_dci->rv =
(uint32_t *) malloc(sizeof(uint32_t) *
dl_dci->n_rv);
dl_dci->rv[0] = round & 3; dl_dci->rv[0] = round & 3;
dl_dci->has_tpc = 1; dl_dci->has_tpc = 1;
dl_dci->tpc = tpc; dl_dci->tpc = tpc;
dl_dci->n_mcs = 1; dl_dci->n_mcs = 1;
dl_dci->mcs = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_mcs); dl_dci->mcs =
(uint32_t *) malloc(sizeof(uint32_t) *
dl_dci->n_mcs);
dl_dci->mcs[0] = mcs; dl_dci->mcs[0] = mcs;
dl_dci->n_tbs_size = 1; dl_dci->n_tbs_size = 1;
dl_dci->tbs_size = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_tbs_size); dl_dci->tbs_size =
(uint32_t *) malloc(sizeof(uint32_t) *
dl_dci->n_tbs_size);
dl_dci->tbs_size[0] = dci_tbs; dl_dci->tbs_size[0] = dci_tbs;
if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { if (flexran_get_duplex_mode(mod_id, CC_id) ==
PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) {
dl_dci->has_dai = 1; dl_dci->has_dai = 1;
dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; dl_dci->dai =
(UE_list->UE_template[CC_id][UE_id].DAI -
1) & 3;
} }
if(ue_sched_ctl->dl_pow_off[CC_id] == 2) { if (ue_sched_ctl->dl_pow_off[CC_id] == 2) {
ue_sched_ctl->dl_pow_off[CC_id] = 1; ue_sched_ctl->dl_pow_off[CC_id] = 1;
} }
dl_dci->has_dl_power_offset = 1; dl_dci->has_dl_power_offset = 1;
dl_dci->dl_power_offset = ue_sched_ctl->dl_pow_off[CC_id]; dl_dci->dl_power_offset =
ue_sched_ctl->dl_pow_off[CC_id];
dl_dci->has_precoding_info = 1; dl_dci->has_precoding_info = 1;
dl_dci->precoding_info = 5; // Is this right?? dl_dci->precoding_info = 5; // Is this right??
...@@ -1610,38 +1928,51 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -1610,38 +1928,51 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
dl_dci->has_res_alloc = 1; dl_dci->has_res_alloc = 1;
dl_dci->res_alloc = 0; dl_dci->res_alloc = 0;
dl_dci->has_vrb_format = 1; dl_dci->has_vrb_format = 1;
dl_dci->vrb_format = PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED; dl_dci->vrb_format =
PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED;
dl_dci->has_format = 1; dl_dci->has_format = 1;
dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D; dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D;
dl_dci->has_rb_bitmap = 1; dl_dci->has_rb_bitmap = 1;
dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, rballoc_sub); dl_dci->rb_bitmap =
allocate_prbs_sub(nb_rb, rballoc_sub);
dl_dci->has_rb_shift = 1; dl_dci->has_rb_shift = 1;
dl_dci->rb_shift = 0; dl_dci->rb_shift = 0;
dl_dci->n_ndi = 1; dl_dci->n_ndi = 1;
dl_dci->ndi = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_ndi); dl_dci->ndi =
(uint32_t *) malloc(sizeof(uint32_t) *
dl_dci->n_ndi);
dl_dci->ndi[0] = ndi; dl_dci->ndi[0] = ndi;
dl_dci->n_rv = 1; dl_dci->n_rv = 1;
dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); dl_dci->rv =
(uint32_t *) malloc(sizeof(uint32_t) *
dl_dci->n_rv);
dl_dci->rv[0] = round & 3; dl_dci->rv[0] = round & 3;
dl_dci->has_tpc = 1; dl_dci->has_tpc = 1;
dl_dci->tpc = tpc; dl_dci->tpc = tpc;
dl_dci->n_mcs = 1; dl_dci->n_mcs = 1;
dl_dci->mcs = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_mcs); dl_dci->mcs =
(uint32_t *) malloc(sizeof(uint32_t) *
dl_dci->n_mcs);
dl_dci->mcs[0] = mcs; dl_dci->mcs[0] = mcs;
if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { if (flexran_get_duplex_mode(mod_id, CC_id) ==
PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) {
dl_dci->has_dai = 1; dl_dci->has_dai = 1;
dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; dl_dci->dai =
(UE_list->UE_template[CC_id][UE_id].DAI -
1) & 3;
} }
dl_dci->has_dl_power_offset = 1; dl_dci->has_dl_power_offset = 1;
dl_dci->dl_power_offset = ue_sched_ctl->dl_pow_off[CC_id]; dl_dci->dl_power_offset =
ue_sched_ctl->dl_pow_off[CC_id];
dl_dci->has_precoding_info = 1; dl_dci->has_precoding_info = 1;
dl_dci->precoding_info = 5; // Is this right?? dl_dci->precoding_info = 5; // Is this right??
break; break;
} }
} }
if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { if (flexran_get_duplex_mode(mod_id, CC_id) ==
PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) {
/* TODO */ /* TODO */
//set_ul_DAI(mod_id, UE_id, CC_id, frame, subframe, frame_parms); //set_ul_DAI(mod_id, UE_id, CC_id, frame, subframe, frame_parms);
...@@ -1652,18 +1983,23 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -1652,18 +1983,23 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
// Add all the dl_data elements to the flexran message // Add all the dl_data elements to the flexran message
int offset = (*dl_info)->dl_mac_config_msg->n_dl_ue_data; int offset = (*dl_info)->dl_mac_config_msg->n_dl_ue_data;
(*dl_info)->dl_mac_config_msg->n_dl_ue_data += num_ues_added; (*dl_info)->dl_mac_config_msg->n_dl_ue_data += num_ues_added;
if ( num_ues_added > 0 ){ if (num_ues_added > 0) {
(*dl_info)->dl_mac_config_msg->dl_ue_data = (Protocol__FlexDlData **) realloc( (*dl_info)->dl_mac_config_msg->dl_ue_data, (*dl_info)->dl_mac_config_msg->dl_ue_data =
sizeof(Protocol__FlexDlData *) * ((*dl_info)->dl_mac_config_msg->n_dl_ue_data)); (Protocol__FlexDlData **)
if ((*dl_info)->dl_mac_config_msg->dl_ue_data == NULL ){ realloc((*dl_info)->dl_mac_config_msg->dl_ue_data,
sizeof(Protocol__FlexDlData *) *
((*dl_info)->dl_mac_config_msg->n_dl_ue_data));
if ((*dl_info)->dl_mac_config_msg->dl_ue_data == NULL) {
LOG_E(MAC, "Request for memory reallocation failed\n"); LOG_E(MAC, "Request for memory reallocation failed\n");
return; return;
} }
for (i = 0; i < num_ues_added; i++) { for (i = 0; i < num_ues_added; i++) {
(*dl_info)->dl_mac_config_msg->dl_ue_data[offset+i] = dl_data[i]; (*dl_info)->dl_mac_config_msg->dl_ue_data[offset + i] =
dl_data[i];
} }
} }
stop_meas(&eNB->schedule_dlsch); stop_meas(&eNB->schedule_dlsch);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH,VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT);
} }
...@@ -44,8 +44,11 @@ int queue_initialized = 0; ...@@ -44,8 +44,11 @@ int queue_initialized = 0;
//uint32_t period = 10; //uint32_t period = 10;
//uint32_t sched [] = {1, 2, 3}; //uint32_t sched [] = {1, 2, 3};
void flexran_schedule_ue_spec_remote(mid_t mod_id, uint32_t frame, uint32_t subframe, void
int *mbsfn_flag, Protocol__FlexranMessage **dl_info) { flexran_schedule_ue_spec_remote(mid_t mod_id, uint32_t frame,
uint32_t subframe, int *mbsfn_flag,
Protocol__FlexranMessage ** dl_info)
{
//if ((subframe == skip_subframe) && (frame % period == 0)) { //if ((subframe == skip_subframe) && (frame % period == 0)) {
...@@ -72,29 +75,36 @@ void flexran_schedule_ue_spec_remote(mid_t mod_id, uint32_t frame, uint32_t subf ...@@ -72,29 +75,36 @@ void flexran_schedule_ue_spec_remote(mid_t mod_id, uint32_t frame, uint32_t subf
dl_mac_config_element_t *dl_config_elem; dl_mac_config_element_t *dl_config_elem;
int diff; int diff;
LOG_D(MAC, "[TEST] Current frame and subframe %d, %d\n", frame, subframe); LOG_D(MAC, "[TEST] Current frame and subframe %d, %d\n", frame,
subframe);
// First we check to see if we have a scheduling decision for this sfn_sf already in our queue // First we check to see if we have a scheduling decision for this sfn_sf already in our queue
while(queue_head.tqh_first != NULL) { while (queue_head.tqh_first != NULL) {
dl_config_elem = queue_head.tqh_first; dl_config_elem = queue_head.tqh_first;
diff = get_sf_difference(mod_id, dl_config_elem->dl_info->dl_mac_config_msg->sfn_sf); diff =
get_sf_difference(mod_id,
dl_config_elem->dl_info->
dl_mac_config_msg->sfn_sf);
// Check if this decision is for now, for a later or a previous subframe // Check if this decision is for now, for a later or a previous subframe
if ( diff == 0) { // Now if (diff == 0) { // Now
LOG_D(MAC, "Found a decision for this subframe in the queue. Let's use it!\n"); LOG_D(MAC,
"Found a decision for this subframe in the queue. Let's use it!\n");
TAILQ_REMOVE(&queue_head, queue_head.tqh_first, configs); TAILQ_REMOVE(&queue_head, queue_head.tqh_first, configs);
*dl_info = dl_config_elem->dl_info; *dl_info = dl_config_elem->dl_info;
free(dl_config_elem); free(dl_config_elem);
eNB->eNB_stats[mod_id].sched_decisions++; eNB->eNB_stats[mod_id].sched_decisions++;
return; return;
} else if (diff < 0) { //previous subframe , delete message and free memory } else if (diff < 0) { //previous subframe , delete message and free memory
LOG_D(MAC, "Found a decision for a previous subframe in the queue. Let's get rid of it\n"); LOG_D(MAC,
"Found a decision for a previous subframe in the queue. Let's get rid of it\n");
TAILQ_REMOVE(&queue_head, queue_head.tqh_first, configs); TAILQ_REMOVE(&queue_head, queue_head.tqh_first, configs);
flexran_agent_mac_destroy_dl_config(dl_config_elem->dl_info); flexran_agent_mac_destroy_dl_config(dl_config_elem->dl_info);
free(dl_config_elem); free(dl_config_elem);
eNB->eNB_stats[mod_id].sched_decisions++; eNB->eNB_stats[mod_id].sched_decisions++;
eNB->eNB_stats[mod_id].missed_deadlines++; eNB->eNB_stats[mod_id].missed_deadlines++;
} else { // next subframe, nothing to do now } else { // next subframe, nothing to do now
LOG_D(MAC, "Found a decision for a future subframe in the queue. Nothing to do now\n"); LOG_D(MAC,
"Found a decision for a future subframe in the queue. Nothing to do now\n");
flexran_agent_mac_create_empty_dl_config(mod_id, dl_info); flexran_agent_mac_create_empty_dl_config(mod_id, dl_info);
return; return;
} }
...@@ -104,21 +114,27 @@ void flexran_schedule_ue_spec_remote(mid_t mod_id, uint32_t frame, uint32_t subf ...@@ -104,21 +114,27 @@ void flexran_schedule_ue_spec_remote(mid_t mod_id, uint32_t frame, uint32_t subf
flexran_agent_get_pending_dl_mac_config(mod_id, dl_info); flexran_agent_get_pending_dl_mac_config(mod_id, dl_info);
while (*dl_info != NULL) { while (*dl_info != NULL) {
diff = get_sf_difference(mod_id, (*dl_info)->dl_mac_config_msg->sfn_sf); diff =
get_sf_difference(mod_id,
(*dl_info)->dl_mac_config_msg->sfn_sf);
if (diff == 0) { // Got a command for this sfn_sf if (diff == 0) { // Got a command for this sfn_sf
LOG_D(MAC, "Found a decision for this subframe pending. Let's use it\n"); LOG_D(MAC,
"Found a decision for this subframe pending. Let's use it\n");
eNB->eNB_stats[mod_id].sched_decisions++; eNB->eNB_stats[mod_id].sched_decisions++;
return; return;
} else if (diff < 0) { } else if (diff < 0) {
LOG_D(MAC, "Found a decision for a previous subframe. Let's get rid of it\n"); LOG_D(MAC,
"Found a decision for a previous subframe. Let's get rid of it\n");
flexran_agent_mac_destroy_dl_config(*dl_info); flexran_agent_mac_destroy_dl_config(*dl_info);
*dl_info = NULL; *dl_info = NULL;
flexran_agent_get_pending_dl_mac_config(mod_id, dl_info); flexran_agent_get_pending_dl_mac_config(mod_id, dl_info);
eNB->eNB_stats[mod_id].sched_decisions++; eNB->eNB_stats[mod_id].sched_decisions++;
eNB->eNB_stats[mod_id].missed_deadlines++; eNB->eNB_stats[mod_id].missed_deadlines++;
} else { // Intended for future subframe. Store it in local cache } else { // Intended for future subframe. Store it in local cache
LOG_D(MAC, "Found a decision for a future subframe in the queue. Let's store it in the cache\n"); LOG_D(MAC,
dl_mac_config_element_t *e = malloc(sizeof(dl_mac_config_element_t)); "Found a decision for a future subframe in the queue. Let's store it in the cache\n");
dl_mac_config_element_t *e =
malloc(sizeof(dl_mac_config_element_t));
e->dl_info = *dl_info; e->dl_info = *dl_info;
TAILQ_INSERT_TAIL(&queue_head, e, configs); TAILQ_INSERT_TAIL(&queue_head, e, configs);
flexran_agent_mac_create_empty_dl_config(mod_id, dl_info); flexran_agent_mac_create_empty_dl_config(mod_id, dl_info);
...@@ -131,7 +147,8 @@ void flexran_schedule_ue_spec_remote(mid_t mod_id, uint32_t frame, uint32_t subf ...@@ -131,7 +147,8 @@ void flexran_schedule_ue_spec_remote(mid_t mod_id, uint32_t frame, uint32_t subf
flexran_agent_mac_create_empty_dl_config(mod_id, dl_info); flexran_agent_mac_create_empty_dl_config(mod_id, dl_info);
} }
int get_sf_difference(mid_t mod_id, uint32_t sfn_sf) { int get_sf_difference(mid_t mod_id, uint32_t sfn_sf)
{
int diff_in_subframes; int diff_in_subframes;
uint16_t current_frame = flexran_get_current_system_frame_num(mod_id); uint16_t current_frame = flexran_get_current_system_frame_num(mod_id);
...@@ -142,18 +159,21 @@ int get_sf_difference(mid_t mod_id, uint32_t sfn_sf) { ...@@ -142,18 +159,21 @@ int get_sf_difference(mid_t mod_id, uint32_t sfn_sf) {
return 0; return 0;
} }
uint16_t frame_mask = ((1<<12) - 1); uint16_t frame_mask = ((1 << 12) - 1);
uint16_t frame = (sfn_sf & (frame_mask << 4)) >> 4; uint16_t frame = (sfn_sf & (frame_mask << 4)) >> 4;
uint16_t sf_mask = ((1<<4) - 1); uint16_t sf_mask = ((1 << 4) - 1);
uint16_t subframe = (sfn_sf & sf_mask); uint16_t subframe = (sfn_sf & sf_mask);
LOG_D(MAC, "[TEST] Target frame and subframe %d, %d\n", frame, subframe); LOG_D(MAC, "[TEST] Target frame and subframe %d, %d\n", frame,
subframe);
if (frame == current_frame) { if (frame == current_frame) {
return subframe - current_subframe; return subframe - current_subframe;
} else if (frame > current_frame) { } else if (frame > current_frame) {
diff_in_subframes = ((frame*10)+subframe) - ((current_frame*10)+current_subframe); diff_in_subframes =
((frame * 10) + subframe) - ((current_frame * 10) +
current_subframe);
// diff_in_subframes = 9 - current_subframe; // diff_in_subframes = 9 - current_subframe;
//diff_in_subframes += (subframe + 1); //diff_in_subframes += (subframe + 1);
...@@ -170,7 +190,9 @@ int get_sf_difference(mid_t mod_id, uint32_t sfn_sf) { ...@@ -170,7 +190,9 @@ int get_sf_difference(mid_t mod_id, uint32_t sfn_sf) {
// diff_in_subframes += (frame - 1) * 10; // diff_in_subframes += (frame - 1) * 10;
//} //}
//diff_in_subframes += (1023 - current_frame) * 10; //diff_in_subframes += (1023 - current_frame) * 10;
diff_in_subframes = 10240 - ((current_frame*10)+current_subframe) + ((frame*10)+subframe); diff_in_subframes =
10240 - ((current_frame * 10) + current_subframe) +
((frame * 10) + subframe);
if (diff_in_subframes > SCHED_AHEAD_SUBFRAMES) { if (diff_in_subframes > SCHED_AHEAD_SUBFRAMES) {
return -1; return -1;
} else { } else {
......
...@@ -55,8 +55,9 @@ TAILQ_HEAD(DlMacConfigHead, dl_mac_config_element_s); ...@@ -55,8 +55,9 @@ TAILQ_HEAD(DlMacConfigHead, dl_mac_config_element_s);
/* /*
* Default scheduler used by the eNB agent * Default scheduler used by the eNB agent
*/ */
void flexran_schedule_ue_spec_remote(mid_t mod_id, uint32_t frame, uint32_t subframe, void flexran_schedule_ue_spec_remote(mid_t mod_id, uint32_t frame,
int *mbsfn_flag, Protocol__FlexranMessage **dl_info); uint32_t subframe, int *mbsfn_flag,
Protocol__FlexranMessage ** dl_info);
// Find the difference in subframes from the given subframe // Find the difference in subframes from the given subframe
......
...@@ -34,28 +34,36 @@ ...@@ -34,28 +34,36 @@
#include "UTIL/LOG/log.h" #include "UTIL/LOG/log.h"
#include "proto.h" #include "proto.h"
int8_t get_Po_NOMINAL_PUSCH(module_id_t module_idP,uint8_t CC_id) int8_t get_Po_NOMINAL_PUSCH(module_id_t module_idP, uint8_t CC_id)
{ {
RACH_ConfigCommon_t *rach_ConfigCommon = NULL; RACH_ConfigCommon_t *rach_ConfigCommon = NULL;
AssertFatal(CC_id==0, AssertFatal(CC_id == 0,
"Transmission on secondary CCs is not supported yet\n"); "Transmission on secondary CCs is not supported yet\n");
AssertFatal(UE_mac_inst[module_idP].radioResourceConfigCommon!=NULL, AssertFatal(UE_mac_inst[module_idP].radioResourceConfigCommon != NULL,
"[UE %d] CCid %d FATAL radioResourceConfigCommon is NULL !!!\n",module_idP,CC_id); "[UE %d] CCid %d FATAL radioResourceConfigCommon is NULL !!!\n",
module_idP, CC_id);
rach_ConfigCommon = &UE_mac_inst[module_idP].radioResourceConfigCommon->rach_ConfigCommon; rach_ConfigCommon =
&UE_mac_inst[module_idP].radioResourceConfigCommon->
rach_ConfigCommon;
return(-120 + (rach_ConfigCommon->powerRampingParameters.preambleInitialReceivedTargetPower<<1) + return (-120 +
get_DELTA_PREAMBLE(module_idP,CC_id)); (rach_ConfigCommon->
powerRampingParameters.preambleInitialReceivedTargetPower <<
1) + get_DELTA_PREAMBLE(module_idP, CC_id));
} }
int8_t get_deltaP_rampup(module_id_t module_idP,uint8_t CC_id) int8_t get_deltaP_rampup(module_id_t module_idP, uint8_t CC_id)
{ {
AssertFatal(CC_id==0, AssertFatal(CC_id == 0,
"Transmission on secondary CCs is not supported yet\n"); "Transmission on secondary CCs is not supported yet\n");
LOG_D(MAC,"[PUSCH]%d dB\n",UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER<<1); LOG_D(MAC, "[PUSCH]%d dB\n",
return((int8_t)(UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER<<1)); UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER << 1);
return ((int8_t)
(UE_mac_inst[module_idP].
RA_PREAMBLE_TRANSMISSION_COUNTER << 1));
} }
...@@ -48,52 +48,57 @@ ...@@ -48,52 +48,57 @@
extern RAN_CONTEXT_t RC; extern RAN_CONTEXT_t RC;
void dl_phy_sync_success(module_id_t module_idP, void dl_phy_sync_success(module_id_t module_idP, frame_t frameP, unsigned char eNB_index, uint8_t first_sync) //init as MR
frame_t frameP,
unsigned char eNB_index,
uint8_t first_sync) //init as MR
{ {
LOG_D(MAC,"[UE %d] Frame %d: PHY Sync to eNB_index %d successful \n", module_idP, frameP, eNB_index); LOG_D(MAC, "[UE %d] Frame %d: PHY Sync to eNB_index %d successful \n",
module_idP, frameP, eNB_index);
#if defined(ENABLE_USE_MME) #if defined(ENABLE_USE_MME)
int mme_enabled=1; int mme_enabled = 1;
#else #else
int mme_enabled=0; int mme_enabled = 0;
#endif #endif
if (first_sync==1 && !(mme_enabled==1)) { if (first_sync == 1 && !(mme_enabled == 1)) {
//layer2_init_UE(module_idP); //layer2_init_UE(module_idP);
openair_rrc_ue_init(module_idP,eNB_index); openair_rrc_ue_init(module_idP, eNB_index);
} else } else {
{ rrc_in_sync_ind(module_idP, frameP, eNB_index);
rrc_in_sync_ind(module_idP,frameP,eNB_index);
} }
} }
void mac_UE_out_of_sync_ind(module_id_t module_idP, frame_t frameP, uint16_t eNB_index) void
mac_UE_out_of_sync_ind(module_id_t module_idP, frame_t frameP,
uint16_t eNB_index)
{ {
// Mac_rlc_xface->mac_out_of_sync_ind(Mod_id, frameP, eNB_index); // Mac_rlc_xface->mac_out_of_sync_ind(Mod_id, frameP, eNB_index);
} }
int mac_top_init_ue(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, uint8_t HO_active) int
mac_top_init_ue(int eMBMS_active, char *uecap_xer,
uint8_t cba_group_active, uint8_t HO_active)
{ {
int i; int i;
LOG_I(MAC,"[MAIN] Init function start:Nb_UE_INST=%d\n",NB_UE_INST); LOG_I(MAC, "[MAIN] Init function start:Nb_UE_INST=%d\n", NB_UE_INST);
if (NB_UE_INST>0) { if (NB_UE_INST > 0) {
UE_mac_inst = (UE_MAC_INST*)malloc16(NB_UE_INST*sizeof(UE_MAC_INST)); UE_mac_inst =
(UE_MAC_INST *) malloc16(NB_UE_INST * sizeof(UE_MAC_INST));
AssertFatal(UE_mac_inst!=NULL, AssertFatal(UE_mac_inst != NULL,
"[MAIN] Can't ALLOCATE %zu Bytes for %d UE_MAC_INST with size %zu \n",NB_UE_INST*sizeof(UE_MAC_INST),NB_UE_INST,sizeof(UE_MAC_INST)); "[MAIN] Can't ALLOCATE %zu Bytes for %d UE_MAC_INST with size %zu \n",
NB_UE_INST * sizeof(UE_MAC_INST), NB_UE_INST,
sizeof(UE_MAC_INST));
LOG_D(MAC,"[MAIN] ALLOCATE %zu Bytes for %d UE_MAC_INST @ %p\n",NB_UE_INST*sizeof(UE_MAC_INST),NB_UE_INST,UE_mac_inst); LOG_D(MAC, "[MAIN] ALLOCATE %zu Bytes for %d UE_MAC_INST @ %p\n",
NB_UE_INST * sizeof(UE_MAC_INST), NB_UE_INST, UE_mac_inst);
bzero(UE_mac_inst,NB_UE_INST*sizeof(UE_MAC_INST)); bzero(UE_mac_inst, NB_UE_INST * sizeof(UE_MAC_INST));
for(i=0; i<NB_UE_INST; i++) { for (i = 0; i < NB_UE_INST; i++) {
ue_init_mac(i); ue_init_mac(i);
} }
} else { } else {
...@@ -101,13 +106,14 @@ int mac_top_init_ue(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, ...@@ -101,13 +106,14 @@ int mac_top_init_ue(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active,
} }
LOG_I(MAC,"[MAIN] calling RRC\n"); LOG_I(MAC, "[MAIN] calling RRC\n");
openair_rrc_top_init_ue(eMBMS_active, uecap_xer, cba_group_active,HO_active); openair_rrc_top_init_ue(eMBMS_active, uecap_xer, cba_group_active,
HO_active);
LOG_I(MAC,"[MAIN][INIT] Init function finished\n"); LOG_I(MAC, "[MAIN][INIT] Init function finished\n");
return(0); return (0);
} }
...@@ -115,41 +121,56 @@ int mac_top_init_ue(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, ...@@ -115,41 +121,56 @@ int mac_top_init_ue(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active,
void mac_top_init_eNB() void mac_top_init_eNB()
{ {
module_id_t i,j; module_id_t i, j;
int list_el; int list_el;
UE_list_t *UE_list; UE_list_t *UE_list;
eNB_MAC_INST *mac; eNB_MAC_INST *mac;
LOG_I(MAC,"[MAIN] Init function start:nb_macrlc_inst=%d\n",RC.nb_macrlc_inst); LOG_I(MAC, "[MAIN] Init function start:nb_macrlc_inst=%d\n",
RC.nb_macrlc_inst);
if (RC.nb_macrlc_inst>0) { if (RC.nb_macrlc_inst > 0) {
RC.mac = (eNB_MAC_INST**)malloc16(RC.nb_macrlc_inst*sizeof(eNB_MAC_INST*)); RC.mac =
AssertFatal(RC.mac != NULL,"can't ALLOCATE %zu Bytes for %d eNB_MAC_INST with size %zu \n", (eNB_MAC_INST **) malloc16(RC.nb_macrlc_inst *
RC.nb_macrlc_inst*sizeof(eNB_MAC_INST*), sizeof(eNB_MAC_INST *));
RC.nb_macrlc_inst, AssertFatal(RC.mac != NULL,
sizeof(eNB_MAC_INST)); "can't ALLOCATE %zu Bytes for %d eNB_MAC_INST with size %zu \n",
for (i=0;i<RC.nb_macrlc_inst;i++) { RC.nb_macrlc_inst * sizeof(eNB_MAC_INST *),
RC.mac[i] = (eNB_MAC_INST*)malloc16(sizeof(eNB_MAC_INST)); RC.nb_macrlc_inst, sizeof(eNB_MAC_INST));
for (i = 0; i < RC.nb_macrlc_inst; i++) {
RC.mac[i] = (eNB_MAC_INST *) malloc16(sizeof(eNB_MAC_INST));
AssertFatal(RC.mac != NULL, AssertFatal(RC.mac != NULL,
"can't ALLOCATE %zu Bytes for %d eNB_MAC_INST with size %zu \n", "can't ALLOCATE %zu Bytes for %d eNB_MAC_INST with size %zu \n",
RC.nb_macrlc_inst*sizeof(eNB_MAC_INST*),RC.nb_macrlc_inst,sizeof(eNB_MAC_INST)); RC.nb_macrlc_inst * sizeof(eNB_MAC_INST *),
LOG_D(MAC,"[MAIN] ALLOCATE %zu Bytes for %d eNB_MAC_INST @ %p\n",sizeof(eNB_MAC_INST),RC.nb_macrlc_inst,RC.mac); RC.nb_macrlc_inst, sizeof(eNB_MAC_INST));
bzero(RC.mac[i],sizeof(eNB_MAC_INST)); LOG_D(MAC,
"[MAIN] ALLOCATE %zu Bytes for %d eNB_MAC_INST @ %p\n",
sizeof(eNB_MAC_INST), RC.nb_macrlc_inst, RC.mac);
bzero(RC.mac[i], sizeof(eNB_MAC_INST));
RC.mac[i]->Mod_id = i; RC.mac[i]->Mod_id = i;
for (j=0;j<MAX_NUM_CCs;j++) { for (j = 0; j < MAX_NUM_CCs; j++) {
RC.mac[i]->DL_req[j].dl_config_request_body.dl_config_pdu_list = RC.mac[i]->dl_config_pdu_list[j]; RC.mac[i]->DL_req[j].dl_config_request_body.
RC.mac[i]->UL_req[j].ul_config_request_body.ul_config_pdu_list = RC.mac[i]->ul_config_pdu_list[j]; dl_config_pdu_list = RC.mac[i]->dl_config_pdu_list[j];
for (int k=0;k<10;k++) RC.mac[i]->UL_req_tmp[j][k].ul_config_request_body.ul_config_pdu_list = RC.mac[i]->ul_config_pdu_list_tmp[j][k]; RC.mac[i]->UL_req[j].ul_config_request_body.
RC.mac[i]->HI_DCI0_req[j].hi_dci0_request_body.hi_dci0_pdu_list = RC.mac[i]->hi_dci0_pdu_list[j]; ul_config_pdu_list = RC.mac[i]->ul_config_pdu_list[j];
RC.mac[i]->TX_req[j].tx_request_body.tx_pdu_list = RC.mac[i]->tx_request_pdu[j]; for (int k = 0; k < 10; k++)
RC.mac[i]->UL_req_tmp[j][k].
ul_config_request_body.ul_config_pdu_list =
RC.mac[i]->ul_config_pdu_list_tmp[j][k];
RC.mac[i]->HI_DCI0_req[j].
hi_dci0_request_body.hi_dci0_pdu_list =
RC.mac[i]->hi_dci0_pdu_list[j];
RC.mac[i]->TX_req[j].tx_request_body.tx_pdu_list =
RC.mac[i]->tx_request_pdu[j];
RC.mac[i]->ul_handle = 0; RC.mac[i]->ul_handle = 0;
} }
} }
AssertFatal(rlc_module_init()==0,"Could not initialize RLC layer\n"); AssertFatal(rlc_module_init() == 0,
"Could not initialize RLC layer\n");
// These should be out of here later // These should be out of here later
pdcp_layer_init (); pdcp_layer_init();
rrc_init_global_param(); rrc_init_global_param();
...@@ -158,7 +179,7 @@ void mac_top_init_eNB() ...@@ -158,7 +179,7 @@ void mac_top_init_eNB()
} }
// Initialize Linked-List for Active UEs // Initialize Linked-List for Active UEs
for(i=0; i<RC.nb_macrlc_inst; i++) { for (i = 0; i < RC.nb_macrlc_inst; i++) {
mac = RC.mac[i]; mac = RC.mac[i];
...@@ -166,131 +187,40 @@ void mac_top_init_eNB() ...@@ -166,131 +187,40 @@ void mac_top_init_eNB()
UE_list = &mac->UE_list; UE_list = &mac->UE_list;
UE_list->num_UEs=0; UE_list->num_UEs = 0;
UE_list->head=-1; UE_list->head = -1;
UE_list->head_ul=-1; UE_list->head_ul = -1;
UE_list->avail=0; UE_list->avail = 0;
for (list_el=0; list_el<NUMBER_OF_UE_MAX-1; list_el++) { 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] = list_el + 1;
UE_list->next_ul[list_el]=list_el+1; UE_list->next_ul[list_el] = list_el + 1;
} }
UE_list->next[list_el]=-1; UE_list->next[list_el] = -1;
UE_list->next_ul[list_el]=-1; UE_list->next_ul[list_el] = -1;
} }
} }
void mac_init_cell_params(int Mod_idP,int CC_idP) { void mac_init_cell_params(int Mod_idP, int CC_idP)
{
int j; int j;
RA_TEMPLATE *RA_template;
UE_TEMPLATE *UE_template; UE_TEMPLATE *UE_template;
int size_bytes1,size_bytes2,size_bits1,size_bits2;
LOG_D(MAC,"[MAIN][eNB %d] CC_id %d initializing RA_template\n",Mod_idP, CC_idP);
LOG_D(MAC, "[MSC_NEW][FRAME 00000][MAC_eNB][MOD %02d][]\n", Mod_idP); LOG_D(MAC, "[MSC_NEW][FRAME 00000][MAC_eNB][MOD %02d][]\n", Mod_idP);
COMMON_channels_t *cc = &RC.mac[Mod_idP]->common_channels[CC_idP]; COMMON_channels_t *cc = &RC.mac[Mod_idP]->common_channels[CC_idP];
RA_template = (RA_TEMPLATE *)&cc->RA_template[0]; memset(&RC.mac[Mod_idP]->eNB_stats, 0, sizeof(eNB_STATS));
UE_template =
for (j=0; j<NB_RA_PROC_MAX; j++) { (UE_TEMPLATE *) & RC.mac[Mod_idP]->UE_list.UE_template[CC_idP][0];
if ( cc->tdd_Config != NULL) {
switch (cc->mib->message.dl_Bandwidth) {
case MasterInformationBlock__dl_Bandwidth_n6:
size_bytes1 = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
size_bytes2 = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
size_bits1 = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
size_bits2 = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
break;
case MasterInformationBlock__dl_Bandwidth_n25:
size_bytes1 = sizeof(DCI1A_5MHz_TDD_1_6_t);
size_bytes2 = sizeof(DCI1A_5MHz_TDD_1_6_t);
size_bits1 = sizeof_DCI1A_5MHz_TDD_1_6_t;
size_bits2 = sizeof_DCI1A_5MHz_TDD_1_6_t;
break;
case MasterInformationBlock__dl_Bandwidth_n50:
size_bytes1 = sizeof(DCI1A_10MHz_TDD_1_6_t);
size_bytes2 = sizeof(DCI1A_10MHz_TDD_1_6_t);
size_bits1 = sizeof_DCI1A_10MHz_TDD_1_6_t;
size_bits2 = sizeof_DCI1A_10MHz_TDD_1_6_t;
break;
case MasterInformationBlock__dl_Bandwidth_n100:
size_bytes1 = sizeof(DCI1A_20MHz_TDD_1_6_t);
size_bytes2 = sizeof(DCI1A_20MHz_TDD_1_6_t);
size_bits1 = sizeof_DCI1A_20MHz_TDD_1_6_t;
size_bits2 = sizeof_DCI1A_20MHz_TDD_1_6_t;
break;
default:
size_bytes1 = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
size_bytes2 = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
size_bits1 = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
size_bits2 = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
break;
}
} else {
switch (cc->mib->message.dl_Bandwidth) {
case MasterInformationBlock__dl_Bandwidth_n6:
size_bytes1 = sizeof(DCI1A_1_5MHz_FDD_t);
size_bytes2 = sizeof(DCI1A_1_5MHz_FDD_t);
size_bits1 = sizeof_DCI1A_1_5MHz_FDD_t;
size_bits2 = sizeof_DCI1A_1_5MHz_FDD_t;
break;
case MasterInformationBlock__dl_Bandwidth_n25:
size_bytes1 = sizeof(DCI1A_5MHz_FDD_t);
size_bytes2 = sizeof(DCI1A_5MHz_FDD_t);
size_bits1 = sizeof_DCI1A_5MHz_FDD_t;
size_bits2 = sizeof_DCI1A_5MHz_FDD_t;
break;
case MasterInformationBlock__dl_Bandwidth_n50:
size_bytes1 = sizeof(DCI1A_10MHz_FDD_t);
size_bytes2 = sizeof(DCI1A_10MHz_FDD_t);
size_bits1 = sizeof_DCI1A_10MHz_FDD_t;
size_bits2 = sizeof_DCI1A_10MHz_FDD_t;
break;
case MasterInformationBlock__dl_Bandwidth_n100:
size_bytes1 = sizeof(DCI1A_20MHz_FDD_t);
size_bytes2 = sizeof(DCI1A_20MHz_FDD_t);
size_bits1 = sizeof_DCI1A_20MHz_FDD_t;
size_bits2 = sizeof_DCI1A_20MHz_FDD_t;
break;
default:
size_bytes1 = sizeof(DCI1A_1_5MHz_FDD_t);
size_bytes2 = sizeof(DCI1A_1_5MHz_FDD_t);
size_bits1 = sizeof_DCI1A_1_5MHz_FDD_t;
size_bits2 = sizeof_DCI1A_1_5MHz_FDD_t;
break;
}
}
memcpy((void *)&RA_template[j].RA_alloc_pdu1[0],(void *)&RA_alloc_pdu,size_bytes1);
memcpy((void *)&RA_template[j].RA_alloc_pdu2[0],(void *)&DLSCH_alloc_pdu1A,size_bytes2);
RA_template[j].RA_dci_size_bytes1 = size_bytes1;
RA_template[j].RA_dci_size_bytes2 = size_bytes2;
RA_template[j].RA_dci_size_bits1 = size_bits1;
RA_template[j].RA_dci_size_bits2 = size_bits2;
RA_template[j].RA_dci_fmt1 = format1A; for (j = 0; j < NUMBER_OF_UE_MAX; j++) {
RA_template[j].RA_dci_fmt2 = format1A; UE_template[j].rnti = 0;
}
memset (&RC.mac[Mod_idP]->eNB_stats,0,sizeof(eNB_STATS));
UE_template = (UE_TEMPLATE *)&RC.mac[Mod_idP]->UE_list.UE_template[CC_idP][0];
for (j=0; j<NUMBER_OF_UE_MAX; j++) {
UE_template[j].rnti=0;
// initiallize the eNB to UE statistics // initiallize the eNB to UE statistics
memset (&RC.mac[Mod_idP]->UE_list.eNB_UE_stats[CC_idP][j],0,sizeof(eNB_UE_STATS)); memset(&RC.mac[Mod_idP]->UE_list.eNB_UE_stats[CC_idP][j], 0,
sizeof(eNB_UE_STATS));
} }
} }
...@@ -300,15 +230,15 @@ int rlcmac_init_global_param(void) ...@@ -300,15 +230,15 @@ int rlcmac_init_global_param(void)
{ {
LOG_I(MAC,"[MAIN] CALLING RLC_MODULE_INIT...\n"); LOG_I(MAC, "[MAIN] CALLING RLC_MODULE_INIT...\n");
if (rlc_module_init()!=0) { if (rlc_module_init() != 0) {
return(-1); return (-1);
} }
pdcp_layer_init (); pdcp_layer_init();
LOG_I(MAC,"[MAIN] Init Global Param Done\n"); LOG_I(MAC, "[MAIN] Init Global Param Done\n");
return 0; return 0;
} }
...@@ -318,29 +248,31 @@ void mac_top_cleanup(void) ...@@ -318,29 +248,31 @@ void mac_top_cleanup(void)
{ {
#ifndef USER_MODE #ifndef USER_MODE
pdcp_module_cleanup (); pdcp_module_cleanup();
#endif #endif
if (NB_UE_INST>0) { if (NB_UE_INST > 0) {
free (UE_mac_inst); free(UE_mac_inst);
} }
if (RC.nb_macrlc_inst>0) { if (RC.nb_macrlc_inst > 0) {
free(RC.mac); free(RC.mac);
} }
} }
int l2_init_ue(int eMBMS_active, char *uecap_xer,uint8_t cba_group_active, uint8_t HO_active) int
l2_init_ue(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active,
uint8_t HO_active)
{ {
LOG_I(MAC,"[MAIN] MAC_INIT_GLOBAL_PARAM IN...\n"); LOG_I(MAC, "[MAIN] MAC_INIT_GLOBAL_PARAM IN...\n");
// NB_NODE=2; // NB_NODE=2;
// NB_INST=2; // NB_INST=2;
rlcmac_init_global_param(); rlcmac_init_global_param();
LOG_I(MAC,"[MAIN] init UE MAC functions \n"); LOG_I(MAC, "[MAIN] init UE MAC functions \n");
mac_top_init_ue(eMBMS_active,uecap_xer,cba_group_active,HO_active); mac_top_init_ue(eMBMS_active, uecap_xer, cba_group_active, HO_active);
return(1); return (1);
} }
int l2_init_eNB() int l2_init_eNB()
...@@ -348,13 +280,12 @@ int l2_init_eNB() ...@@ -348,13 +280,12 @@ int l2_init_eNB()
LOG_I(MAC,"[MAIN] MAC_INIT_GLOBAL_PARAM IN...\n"); LOG_I(MAC, "[MAIN] MAC_INIT_GLOBAL_PARAM IN...\n");
rlcmac_init_global_param(); rlcmac_init_global_param();
LOG_D(MAC,"[MAIN] ALL INIT OK\n"); LOG_D(MAC, "[MAIN] ALL INIT OK\n");
return(1); return (1);
} }
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/* \file openair2_proc.c
\brief MAC layer online statistics
\author Navid Nikaein
\date 2013 - 2014
\version 1.0
@ingroup _mac
*/
#ifndef USER_MODE
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#endif
#include "LAYER2/MAC/defs.h"
#include "LAYER2/MAC/extern.h"
//#include "RRC/LITE/extern.h"
//#include "LAYER2/PDCP/pdcp.h"
#include "proto.h"
extern RAN_CONTEXT_t RC;
int openair2_stats_read(char *buffer, char **my_buffer, off_t off, int length)
{
int len = 0,fg,Overhead, Sign;
unsigned int i,j,k,kk;
unsigned int ue_id, eNB_id;
unsigned int Mod_id = 0,CH_index;
unsigned int stat_tx_pdcp_sdu;
unsigned int stat_tx_pdcp_bytes;
unsigned int stat_tx_pdcp_sdu_discarded;
unsigned int stat_tx_pdcp_bytes_discarded;
unsigned int stat_tx_data_pdu;
unsigned int stat_tx_data_bytes;
unsigned int stat_tx_retransmit_pdu_by_status;
unsigned int stat_tx_retransmit_bytes_by_status;
unsigned int stat_tx_retransmit_pdu;
unsigned int stat_tx_retransmit_bytes;
unsigned int stat_tx_control_pdu;
unsigned int stat_tx_control_bytes;
unsigned int stat_rx_pdcp_sdu;
unsigned int stat_rx_pdcp_bytes;
unsigned int stat_rx_data_pdus_duplicate;
unsigned int stat_rx_data_bytes_duplicate;
unsigned int stat_rx_data_pdu;
unsigned int stat_rx_data_bytes;
unsigned int stat_rx_data_pdu_dropped;
unsigned int stat_rx_data_bytes_dropped;
unsigned int stat_rx_data_pdu_out_of_window;
unsigned int stat_rx_data_bytes_out_of_window;
unsigned int stat_rx_control_pdu;
unsigned int stat_rx_control_bytes;
unsigned int stat_timer_reordering_timed_out;
unsigned int stat_timer_poll_retransmit_timed_out;
unsigned int stat_timer_status_prohibit_timed_out;
// UE part
for (ue_id=0; ue_id<NUM_UE_INST; ue_id++) {
// mod_id used for PDCP and RLC
Mod_id = NB_eNB_INST + ue_id ;
len+=sprintf(&buffer[len],"UE RX TTI: %d\n",UE_mac_inst[ue_id].rxFrame);
for (enb_id= 0; enb_id <NB_SIG_CNX_UE; enb_id++) {
switch (mac_get_rrc_status(ue_id,0,enb_id) > RRC_CONNECTED) {
case RRC_RECONFIGURED :
case RRC_CONNECTED:
case RRC_SI_RECEIVED:
case RRC_IDLE:
break;
if (mac_get_rrc_status(ue_id,0,enb_id) > RRC_CONNECTED) {
// if (UE_mac_inst[ue_id].Dcch_lchan[CH_index].Active==1) {
len+=sprintf(&buffer[len],"eNB %d: Wideband SINR %d dB---\n",
CH_index,UE_mac_inst[Mod_id].Def_meas[CH_index].Wideband_sinr);
len+=sprintf(&buffer[len],"CH %d: Subband SINR (dB) :",
CH_index);
for (fg=0; fg<NUMBER_OF_MEASUREMENT_SUBBANDS; fg++) {
len+=sprintf(&buffer[len],"%d ",UE_mac_inst[Mod_id].Def_meas[CH_index].Sinr_meas[0][fg]);
}
len+=sprintf(&buffer[len],"\n");
len+=sprintf(&buffer[len],"BCCH %d, NB_RX_MAC = %d (%d errors)\n",
UE_mac_inst[Mod_id].Bcch_lchan[CH_index].Lchan_info.Lchan_id.Index,
UE_mac_inst[Mod_id].Bcch_lchan[CH_index].Lchan_info.NB_RX,
UE_mac_inst[Mod_id].Bcch_lchan[CH_index].Lchan_info.NB_RX_ERRORS);
len+=sprintf(&buffer[len],"CCCH %d, NB_RX_MAC = %d (%d errors)\n",
UE_mac_inst[Mod_id].Ccch_lchan[CH_index].Lchan_info.Lchan_id.Index,
UE_mac_inst[Mod_id].Ccch_lchan[CH_index].Lchan_info.NB_RX,
UE_mac_inst[Mod_id].Ccch_lchan[CH_index].Lchan_info.NB_RX_ERRORS);
len+=sprintf(&buffer[len],"LCHAN %d (DCCH), NB_TX_MAC = %d (%d bits/TTI, %d kbits/sec), NB_RX_MAC = %d (%d errors)\n",
UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.Lchan_id.Index,
UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.NB_TX,
UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.output_rate,
(10*UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.output_rate)>>5,
UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.NB_RX,
UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.NB_RX_ERRORS);
for(i=1; i<NB_RAB_MAX; i++) {
if (UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Active==1) {
Overhead=UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.output_rate - Pdcp_stats_tx_rate[k][CH_index][i];
if(Overhead<0) {
Overhead=-Overhead;
Sign=-1;
} else {
Sign=1;
}
len+=sprintf(&buffer[len],"[PDCP]LCHAN %d: NB_TX = %d ,Tx_rate =(%d bits/TTI ,%d Kbits/s), NB_RX = %d ,Rx_rate =(%d bits/TTI ,%d Kbits/s) , LAYER2 TX OVERHEAD: %d Kbits/s\n",
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index,
Pdcp_stats_tx[k][CH_index][i],
Pdcp_stats_tx_rate[k][CH_index][i],
(10*Pdcp_stats_tx_rate[k][CH_index][i])>>5,
Pdcp_stats_rx[k][CH_index][i],
Pdcp_stats_rx_rate[k][CH_index][i],
(10*Pdcp_stats_rx_rate[k][CH_index][i])>>5,
Sign*(10*Overhead)>>5);
int status = rlc_stat_req (k,
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index,
&stat_tx_pdcp_sdu,
&stat_tx_pdcp_bytes,
&stat_tx_pdcp_sdu_discarded,
&stat_tx_pdcp_bytes_discarded,
&stat_tx_data_pdu,
&stat_tx_data_bytes,
&stat_tx_retransmit_pdu_by_status,
&stat_tx_retransmit_bytes_by_status,
&stat_tx_retransmit_pdu,
&stat_tx_retransmit_bytes,
&stat_tx_control_pdu,
&stat_tx_control_bytes,
&stat_rx_pdcp_sdu,
&stat_rx_pdcp_bytes,
&stat_rx_data_pdus_duplicate,
&stat_rx_data_bytes_duplicate,
&stat_rx_data_pdu,
&stat_rx_data_bytes,
&stat_rx_data_pdu_dropped,
&stat_rx_data_bytes_dropped,
&stat_rx_data_pdu_out_of_window,
&stat_rx_data_bytes_out_of_window,
&stat_rx_control_pdu,
&stat_rx_control_bytes,
&stat_timer_reordering_timed_out,
&stat_timer_poll_retransmit_timed_out,
&stat_timer_status_prohibit_timed_out) ;
if (status == RLC_OP_STATUS_OK) {
len+=sprintf(&buffer[len],"RLC LCHAN %d, NB_SDU_TO_TX = %d\tNB_SDU_DISC %d\tNB_RX_SDU %d\n",
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index,
tx_pdcp_sdu,
tx_pdcp_sdu_discarded,
rx_sdu);
len+=sprintf(&buffer[len],"RLC LCHAN %d, NB_TB_TX_DATA = %d\tNB_TB_TX_CONTROL %d\tNB_TX_TB_RETRANS %d",
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index,
tx_data_pdu,
tx_control_pdu,
tx_retransmit_pdu);
len+=sprintf(&buffer[len],"\tRLC LCHAN %d, NB_TX_TB_RETRANS_BY_STATUS = %d\tNB_TX_TB_RETRANS_PADD %d\n",
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index,
tx_retransmit_pdu_by_status,
tx_retransmit_pdu_unblock);
len+=sprintf(&buffer[len],"RLC LCHAN %d, NB_RX_DATA = %d\tNB_RX_TB_OUT_WIN %d\tNB_RX_TB_CORRUPT %d\n",
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index,
rx_data_pdu,
rx_data_pdu_out_of_window,
rx_error_pdu);
}
len+=sprintf(&buffer[len],"[MAC]: LCHAN %d, NB_TX_MAC = %d (%d bits/TTI, %d kbits/s), NB_RX_MAC = %d (%d errors)\n",
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index,
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_TX,
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.output_rate,
(10*UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.output_rate)>>5,
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_RX,
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_RX_ERRORS);
len+=sprintf(&buffer[len]," TX per TB: ");
for(kk=0; kk<MAX_NUMBER_TB_PER_LCHAN/2; kk++) {
len+=sprintf(&buffer[len],"%d . ",UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_TX_TB[kk]);
}
len+=sprintf(&buffer[len],"\n");
len+=sprintf(&buffer[len]," RXerr per TB: ");
for(kk=0; kk<MAX_NUMBER_TB_PER_LCHAN/2; kk++)
len+=sprintf(&buffer[len],"%d/%d . ",UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_RX_ERRORS_TB[kk],
UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_RX_TB[kk]);
len+=sprintf(&buffer[len],"\n");
}
}
}
}
#endif //PHY_EMUL_ONE_MACHINE
}
else if(Mac_rlc_xface->Is_cluster_head[k] ==1) {
Mod_id=k;
len+=sprintf(&buffer[len],
"-------------------------------------------------------------------CH %d: TTI: %d------------------------------------------------------------------\n",
NODE_ID[Mod_id],Mac_rlc_xface->frame);
for(i=1; i<=NB_CNX_CH; i++) {
if (CH_mac_inst[Mod_id].Dcch_lchan[i].Active==1) {
len+=sprintf(&buffer[len],"\nMR index %d: DL SINR (feedback) %d dB, CQI: %s\n\n",
i,//CH_rrc_inst[Mod_id].Info.UE_list[i].L2_id[0],
CH_mac_inst[Mod_id].Def_meas[i].Wideband_sinr);
//print_cqi(CH_mac_inst[Mod_id].Def_meas[i].cqi));
len+=sprintf(&buffer[len],
"[MAC] LCHAN %d (DCCH), NB_TX_MAC= %d (%d bits/TTI, %d kbits/s), NB_RX_MAC= %d (errors %d, sacch errors %d, sach errors %d, sach_missing %d)\n\n",
CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.Lchan_id.Index,
CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_TX,
CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.output_rate,
(10*CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.output_rate)>>5,
CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX,
CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX_ERRORS,
CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX_SACCH_ERRORS,
CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX_SACH_ERRORS,
CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX_SACH_MISSING);
for(j=0; j<NB_RAB_MAX; j++) {
if (CH_mac_inst[Mod_id].Dtch_lchan[j][i].Active==1) {
Overhead=CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.output_rate - Pdcp_stats_tx_rate[k][i][j];
if(Overhead<0) {
Overhead=-Overhead;
Sign=-1;
} else {
Sign=1;
}
len+=sprintf(&buffer[len],
"[PDCP]LCHAN %d: NB_TX = %d ,Tx_rate =(%d bits/TTI ,%d Kbits/s), NB_RX = %d ,Rx_rate =(%d bits/TTI ,%d Kbits/s), LAYER2 TX OVERHEAD= %d Kbits/s\n",
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index,
Pdcp_stats_tx[k][i][j],
Pdcp_stats_tx_rate[k][i][j],
(10*Pdcp_stats_tx_rate[k][i][j])>>5,
Pdcp_stats_rx[k][i][j],
Pdcp_stats_rx_rate[k][i][j],
(10*Pdcp_stats_rx_rate[k][i][j])>>5,
Sign*(10*Overhead)>>5);
int status = rlc_stat_req (k,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index,
&tx_pdcp_sdu,
&tx_pdcp_sdu_discarded,
&tx_retransmit_pdu_unblock,
&tx_retransmit_pdu_by_status,
&tx_retransmit_pdu,
&tx_data_pdu,
&tx_control_pdu,
&rx_sdu,
&rx_error_pdu,
&rx_data_pdu,
&rx_data_pdu_out_of_window,
&rx_control_pdu) ;
/*
if (status == RLC_OP_STATUS_OK) {
len+=sprintf(&buffer[len],"\t[RLC] LCHAN %d, NB_SDU_TO_TX = %d\tNB_SDU_DISC %d\tNB_RX_SDU %d\n",
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index,
tx_pdcp_sdu,
tx_pdcp_sdu_discarded,
rx_sdu);
len+=sprintf(&buffer[len],"\t[RLC] LCHAN %d, NB_TB_TX_DATA = %d\tNB_TB_TX_CONTROL %d\tNB_TX_TB_RETRANS %\n",
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index,
tx_data_pdu,
tx_control_pdu,
tx_retransmit_pdu);
len+=sprintf(&buffer[len],"\t[RLC] LCHAN %d, NB_TX_TB_RETRANS_BY_STATUS = %d\tNB_TX_TB_RETRANS_PADD %d\n",
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index,
tx_retransmit_pdu_by_status,
tx_retransmit_pdu_unblock);
len+=sprintf(&buffer[len],"\t[RLC] LCHAN %d, NB_RX_DATA = %d\tNB_RX_TB_OUT_WIN %d\tNB_RX_TB_CORRUPT %d\n",
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index,
rx_data_pdu,
rx_data_pdu_out_of_window,
rx_error_pdu);
}
*/
len+=sprintf(&buffer[len],
"[MAC]LCHAN %d (CNX %d,RAB %d), NB_TX_MAC= %d (%d bits/TTI, %d kbit/s), NB_RX_MAC= %d (errors %d, sacch_errors %d, sach_errors %d, sach_missing %d)\n",
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index,
i,j,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_TX,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.output_rate,
(10*CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.output_rate)>>5,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_ERRORS,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_SACCH_ERRORS,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_SACH_ERRORS,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_SACH_MISSING);
len+=sprintf(&buffer[len],"[MAC][SCHEDULER] TX Arrival Rate %d, TX Service Rate %d, RX Arrival rate %d, RX Service rate %d, NB_BW_REQ_RX %d\n\n",
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Arrival_rate,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Tx_rate,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Req_rate,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Rx_rate,
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_BW_REQ_RX);
/*
len+=sprintf(&buffer[len]," TX per TB: ");
for(kk=0;kk<MAX_NUMBER_TB_PER_LCHAN/2;kk++)
len+=sprintf(&buffer[len],"%d.",CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_TX_TB[kk]);
len+=sprintf(&buffer[len],"\n");
len+=sprintf(&buffer[len]," RXerr per TB: ");
for(kk=0;kk<MAX_NUMBER_TB_PER_LCHAN/2;kk++)
len+=sprintf(&buffer[len],"%d/%d . ",CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_ERRORS_TB[kk],
CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_TB[kk]);
len+=sprintf(&buffer[len],"\n");
*/
}
}
}
}
}
}
return len;
}
#ifndef USER_MODE
static struct proc_dir_entry *proc_openair2_root;
/*
* Initialize the module and add the /proc file.
*/
int add_openair2_stats()
{
//#ifdef KERNEL_VERSION_GREATER_THAN_2629
struct proc_dir_entry *pde;
//#endif
proc_openair2_root = proc_mkdir("openair2",0);
//#ifdef KERNEL_VERSION_GREATER_THAN_2629
// pde = proc_create_entry("lchan_stats", S_IFREG | S_IRUGO, proc_openair2_root);
pde = create_proc_read_entry("lchan_stats", S_IFREG | S_IRUGO, proc_openair2_root, (read_proc_t*)&openair2_stats_read, NULL);
if (!pde) {
printk("[OPENAIR][ERROR] can't create proc entry !\n");
}
//#else
//create_proc_info_entry("lchan_stats", S_IFREG | S_IRUGO, proc_openair2_root, openair2_stats_read);
//#endif
return 0;
}
/*
* Unregister the file when the module is closed.
*/
void remove_openair2_stats()
{
if (proc_openair2_root) {
printk("[OPENAIR][CLEANUP] Removing openair proc entry\n");
remove_proc_entry("lchan_stats", proc_openair2_root);
//#ifdef KERNEL_VERSION_GREATER_THAN_2629
//#else
remove_proc_entry("openair2",NULL);
//#endif;
}
}
#endif
...@@ -95,74 +95,84 @@ int phy_stats_exist(module_id_t Mod_id, int rnti) ...@@ -95,74 +95,84 @@ int phy_stats_exist(module_id_t Mod_id, int rnti)
*/ */
// This function stores the downlink buffer for all the logical channels // This function stores the downlink buffer for all the logical channels
void store_dlsch_buffer (module_id_t Mod_id, void
frame_t frameP, store_dlsch_buffer(module_id_t Mod_id, frame_t frameP,
sub_frame_t subframeP) sub_frame_t subframeP)
{ {
int UE_id,i; int UE_id, i;
rnti_t rnti; rnti_t rnti;
mac_rlc_status_resp_t rlc_status; mac_rlc_status_resp_t rlc_status;
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
UE_TEMPLATE *UE_template; UE_TEMPLATE *UE_template;
for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
if (UE_list->active[UE_id] != TRUE) continue; if (UE_list->active[UE_id] != TRUE)
continue;
UE_template = &UE_list->UE_template[UE_PCCID(Mod_id,UE_id)][UE_id]; UE_template =
&UE_list->UE_template[UE_PCCID(Mod_id, UE_id)][UE_id];
// clear logical channel interface variables // clear logical channel interface variables
UE_template->dl_buffer_total = 0; UE_template->dl_buffer_total = 0;
UE_template->dl_pdus_total = 0; UE_template->dl_pdus_total = 0;
for(i=0; i< MAX_NUM_LCID; i++) { for (i = 0; i < MAX_NUM_LCID; i++) {
UE_template->dl_buffer_info[i]=0; UE_template->dl_buffer_info[i] = 0;
UE_template->dl_pdus_in_buffer[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_creation_time[i] = 0;
UE_template->dl_buffer_head_sdu_remaining_size_to_send[i]=0; UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = 0;
} }
rnti = UE_RNTI(Mod_id,UE_id); rnti = UE_RNTI(Mod_id, UE_id);
for(i=0; i< MAX_NUM_LCID; i++) { // loop over all the logical channels for (i = 0; i < MAX_NUM_LCID; i++) { // loop over all the logical channels
rlc_status = mac_rlc_status_ind(Mod_id,rnti, Mod_id,frameP,subframeP,ENB_FLAG_YES,MBMS_FLAG_NO,i,0 ); rlc_status =
mac_rlc_status_ind(Mod_id, rnti, Mod_id, frameP, subframeP,
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_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_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_creation_time[i] =
UE_template->dl_buffer_head_sdu_creation_time_max = cmax(UE_template->dl_buffer_head_sdu_creation_time_max, rlc_status.head_sdu_creation_time;
rlc_status.head_sdu_creation_time ); UE_template->dl_buffer_head_sdu_creation_time_max =
UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = rlc_status.head_sdu_remaining_size_to_send; cmax(UE_template->dl_buffer_head_sdu_creation_time_max,
UE_template->dl_buffer_head_sdu_is_segmented[i] = rlc_status.head_sdu_is_segmented; rlc_status.head_sdu_creation_time);
UE_template->dl_buffer_total += UE_template->dl_buffer_info[i];//storing the total dlsch buffer UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] =
UE_template->dl_pdus_total += UE_template->dl_pdus_in_buffer[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_info[i]; //storing the total dlsch buffer
UE_template->dl_pdus_total +=
UE_template->dl_pdus_in_buffer[i];
#ifdef DEBUG_eNB_SCHEDULER #ifdef DEBUG_eNB_SCHEDULER
/* note for dl_buffer_head_sdu_remaining_size_to_send[i] : /* note for dl_buffer_head_sdu_remaining_size_to_send[i] :
* 0 if head SDU has not been segmented (yet), else remaining size not already segmented and sent * 0 if head SDU has not been segmented (yet), else remaining size not already segmented and sent
*/ */
if (UE_template->dl_buffer_info[i]>0) if (UE_template->dl_buffer_info[i] > 0)
LOG_D(MAC, 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", "[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, Mod_id, frameP, subframeP, UE_id,
i, UE_template->dl_pdus_in_buffer[i],UE_template->dl_buffer_info[i], 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_creation_time[i],
UE_template->dl_buffer_head_sdu_remaining_size_to_send[i], UE_template->
UE_template->dl_buffer_head_sdu_is_segmented[i] dl_buffer_head_sdu_remaining_size_to_send[i],
); UE_template->dl_buffer_head_sdu_is_segmented[i]);
#endif #endif
} }
//#ifdef DEBUG_eNB_SCHEDULER //#ifdef DEBUG_eNB_SCHEDULER
if ( UE_template->dl_buffer_total>0) if (UE_template->dl_buffer_total > 0)
LOG_D(MAC,"[eNB %d] Frame %d Subframe %d : RLC status for UE %d : total DL buffer size %d and total number of pdu %d \n", LOG_D(MAC,
"[eNB %d] Frame %d Subframe %d : RLC status for UE %d : total DL buffer size %d and total number of pdu %d \n",
Mod_id, frameP, subframeP, UE_id, Mod_id, frameP, subframeP, UE_id,
UE_template->dl_buffer_total, UE_template->dl_buffer_total,
UE_template->dl_pdus_total UE_template->dl_pdus_total);
);
//#endif //#endif
} }
...@@ -170,87 +180,111 @@ void store_dlsch_buffer (module_id_t Mod_id, ...@@ -170,87 +180,111 @@ void store_dlsch_buffer (module_id_t Mod_id,
// This function returns the estimated number of RBs required by each UE for downlink scheduling // This function returns the estimated number of RBs required by each UE for downlink scheduling
void assign_rbs_required (module_id_t Mod_id, void
assign_rbs_required(module_id_t Mod_id,
frame_t frameP, frame_t frameP,
sub_frame_t subframe, sub_frame_t subframe,
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], uint16_t
nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
int min_rb_unit[MAX_NUM_CCs]) int min_rb_unit[MAX_NUM_CCs])
{ {
uint16_t TBS = 0; uint16_t TBS = 0;
int UE_id,n,i,j,CC_id,pCCid,tmp; int UE_id, n, i, j, CC_id, pCCid, tmp;
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
eNB_UE_STATS *eNB_UE_stats,*eNB_UE_stats_i,*eNB_UE_stats_j; eNB_UE_STATS *eNB_UE_stats, *eNB_UE_stats_i, *eNB_UE_stats_j;
int N_RB_DL; int N_RB_DL;
// clear rb allocations across all CC_id // clear rb allocations across all CC_id
for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
if (UE_list->active[UE_id] != TRUE) continue; if (UE_list->active[UE_id] != TRUE)
continue;
pCCid = UE_PCCID(Mod_id,UE_id); pCCid = UE_PCCID(Mod_id, UE_id);
//update CQI information across component carriers //update CQI information across component carriers
for (n=0; n<UE_list->numactiveCCs[UE_id]; n++) { for (n = 0; n < UE_list->numactiveCCs[UE_id]; n++) {
CC_id = UE_list->ordered_CCids[n][UE_id]; CC_id = UE_list->ordered_CCids[n][UE_id];
eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
eNB_UE_stats->dlsch_mcs1=cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]]; eNB_UE_stats->dlsch_mcs1 =
cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]];
} }
// provide the list of CCs sorted according to MCS // provide the list of CCs sorted according to MCS
for (i=0; i<UE_list->numactiveCCs[UE_id]; i++) { for (i = 0; i < UE_list->numactiveCCs[UE_id]; i++) {
eNB_UE_stats_i = &UE_list->eNB_UE_stats[UE_list->ordered_CCids[i][UE_id]][UE_id]; eNB_UE_stats_i =
for (j=i+1; j<UE_list->numactiveCCs[UE_id]; j++) { &UE_list->eNB_UE_stats[UE_list->
DevAssert( j < MAX_NUM_CCs ); ordered_CCids[i][UE_id]][UE_id];
eNB_UE_stats_j = &UE_list->eNB_UE_stats[UE_list->ordered_CCids[j][UE_id]][UE_id]; for (j = i + 1; j < UE_list->numactiveCCs[UE_id]; j++) {
DevAssert(j < MAX_NUM_CCs);
eNB_UE_stats_j =
&UE_list->
eNB_UE_stats[UE_list->ordered_CCids[j][UE_id]][UE_id];
if (eNB_UE_stats_j->dlsch_mcs1 > if (eNB_UE_stats_j->dlsch_mcs1 >
eNB_UE_stats_i->dlsch_mcs1) { eNB_UE_stats_i->dlsch_mcs1) {
tmp = UE_list->ordered_CCids[i][UE_id]; 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[i][UE_id] =
UE_list->ordered_CCids[j][UE_id];
UE_list->ordered_CCids[j][UE_id] = tmp; UE_list->ordered_CCids[j][UE_id] = tmp;
} }
} }
} }
if (UE_list->UE_template[pCCid][UE_id].dl_buffer_total> 0) { if (UE_list->UE_template[pCCid][UE_id].dl_buffer_total > 0) {
LOG_D(MAC,"[preprocessor] assign RB for UE %d\n",UE_id); LOG_D(MAC, "[preprocessor] assign RB for UE %d\n", UE_id);
for (i=0; i<UE_list->numactiveCCs[UE_id]; i++) { for (i = 0; i < UE_list->numactiveCCs[UE_id]; i++) {
CC_id = UE_list->ordered_CCids[i][UE_id]; CC_id = UE_list->ordered_CCids[i][UE_id];
eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
if (eNB_UE_stats->dlsch_mcs1==0) { if (eNB_UE_stats->dlsch_mcs1 == 0) {
nb_rbs_required[CC_id][UE_id] = 4; // don't let the TBS get too small nb_rbs_required[CC_id][UE_id] = 4; // don't let the TBS get too small
} else { } else {
nb_rbs_required[CC_id][UE_id] = min_rb_unit[CC_id]; nb_rbs_required[CC_id][UE_id] = min_rb_unit[CC_id];
} }
TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_rbs_required[CC_id][UE_id]); TBS =
get_TBS_DL(eNB_UE_stats->dlsch_mcs1,
nb_rbs_required[CC_id][UE_id]);
LOG_D(MAC,"[preprocessor] start RB assignement for UE %d CC_id %d dl buffer %d (RB unit %d, MCS %d, TBS %d) \n", LOG_D(MAC,
UE_id, CC_id, UE_list->UE_template[pCCid][UE_id].dl_buffer_total, "[preprocessor] start RB assignement for UE %d CC_id %d dl buffer %d (RB unit %d, MCS %d, TBS %d) \n",
nb_rbs_required[CC_id][UE_id],eNB_UE_stats->dlsch_mcs1,TBS); UE_id, CC_id,
UE_list->UE_template[pCCid][UE_id].dl_buffer_total,
nb_rbs_required[CC_id][UE_id],
eNB_UE_stats->dlsch_mcs1, TBS);
N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); N_RB_DL =
to_prb(RC.mac[Mod_id]->common_channels[CC_id].
mib->message.dl_Bandwidth);
/* calculating required number of RBs for each UE */ /* calculating required number of RBs for each UE */
while (TBS < UE_list->UE_template[pCCid][UE_id].dl_buffer_total) { while (TBS <
UE_list->UE_template[pCCid][UE_id].
dl_buffer_total) {
nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id]; nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id];
if (nb_rbs_required[CC_id][UE_id] > N_RB_DL) { if (nb_rbs_required[CC_id][UE_id] > N_RB_DL) {
TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1,N_RB_DL); TBS =
get_TBS_DL(eNB_UE_stats->dlsch_mcs1, N_RB_DL);
nb_rbs_required[CC_id][UE_id] = N_RB_DL; nb_rbs_required[CC_id][UE_id] = N_RB_DL;
break; break;
} }
TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_rbs_required[CC_id][UE_id]); TBS =
get_TBS_DL(eNB_UE_stats->dlsch_mcs1,
nb_rbs_required[CC_id][UE_id]);
} // end of while } // end of while
LOG_D(MAC,"[eNB %d] Frame %d: UE %d on CC %d: RB unit %d, nb_required RB %d (TBS %d, mcs %d)\n", LOG_D(MAC,
Mod_id, frameP,UE_id, CC_id, min_rb_unit[CC_id], nb_rbs_required[CC_id][UE_id], TBS, eNB_UE_stats->dlsch_mcs1); "[eNB %d] Frame %d: UE %d on CC %d: RB unit %d, nb_required RB %d (TBS %d, mcs %d)\n",
Mod_id, frameP, UE_id, CC_id, min_rb_unit[CC_id],
nb_rbs_required[CC_id][UE_id], TBS,
eNB_UE_stats->dlsch_mcs1);
} }
} }
} }
...@@ -259,21 +293,25 @@ void assign_rbs_required (module_id_t Mod_id, ...@@ -259,21 +293,25 @@ void assign_rbs_required (module_id_t Mod_id,
// This function scans all CC_ids for a particular UE to find the maximum round index of its HARQ processes // This function scans all CC_ids for a particular UE to find the maximum round index of its HARQ processes
int maxround(module_id_t Mod_id,uint16_t rnti,int frame,sub_frame_t subframe,uint8_t ul_flag ) int
maxround(module_id_t Mod_id, uint16_t rnti, int frame,
sub_frame_t subframe, uint8_t ul_flag)
{ {
uint8_t round,round_max=0,UE_id; uint8_t round, round_max = 0, UE_id;
int CC_id,harq_pid; int CC_id, harq_pid;
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
COMMON_channels_t *cc; COMMON_channels_t *cc;
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
cc = &RC.mac[Mod_id]->common_channels[CC_id]; cc = &RC.mac[Mod_id]->common_channels[CC_id];
UE_id = find_UE_id(Mod_id,rnti); UE_id = find_UE_id(Mod_id, rnti);
if (cc->tdd_Config) harq_pid = ((frame*10)+subframe)%10; if (cc->tdd_Config)
else harq_pid = ((frame*10)+subframe)&7; harq_pid = ((frame * 10) + subframe) % 10;
else
harq_pid = ((frame * 10) + subframe) & 7;
round = UE_list->UE_sched_ctrl[UE_id].round[CC_id][harq_pid]; round = UE_list->UE_sched_ctrl[UE_id].round[CC_id][harq_pid];
if (round > round_max) { if (round > round_max) {
...@@ -286,13 +324,13 @@ int maxround(module_id_t Mod_id,uint16_t rnti,int frame,sub_frame_t subframe,uin ...@@ -286,13 +324,13 @@ int maxround(module_id_t Mod_id,uint16_t rnti,int frame,sub_frame_t subframe,uin
// This function scans all CC_ids for a particular UE to find the maximum DL CQI // This function scans all CC_ids for a particular UE to find the maximum DL CQI
// it returns -1 if the UE is not found in PHY layer (get_eNB_UE_stats gives NULL) // it returns -1 if the UE is not found in PHY layer (get_eNB_UE_stats gives NULL)
int maxcqi(module_id_t Mod_id,int32_t UE_id) int maxcqi(module_id_t Mod_id, int32_t UE_id)
{ {
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
int CC_id,n; int CC_id, n;
int CQI = 0; int CQI = 0;
for (n=0; n<UE_list->numactiveCCs[UE_id]; n++) { for (n = 0; n < UE_list->numactiveCCs[UE_id]; n++) {
CC_id = UE_list->ordered_CCids[n][UE_id]; CC_id = UE_list->ordered_CCids[n][UE_id];
if (UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id] > CQI) { if (UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id] > CQI) {
...@@ -314,35 +352,49 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params) ...@@ -314,35 +352,49 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params)
struct sort_ue_dl_params *params = _params; struct sort_ue_dl_params *params = _params;
UE_list_t *UE_list = &RC.mac[params->Mod_idP]->UE_list; UE_list_t *UE_list = &RC.mac[params->Mod_idP]->UE_list;
int UE_id1 = *(const int *)_a; int UE_id1 = *(const int *) _a;
int UE_id2 = *(const int *)_b; int UE_id2 = *(const int *) _b;
int rnti1 = UE_RNTI(params->Mod_idP, UE_id1); int rnti1 = UE_RNTI(params->Mod_idP, UE_id1);
int pCC_id1 = UE_PCCID(params->Mod_idP, UE_id1); int pCC_id1 = UE_PCCID(params->Mod_idP, UE_id1);
int round1 = maxround(params->Mod_idP, rnti1, params->frameP, params->subframeP, 1); int round1 =
maxround(params->Mod_idP, rnti1, params->frameP, params->subframeP,
1);
int rnti2 = UE_RNTI(params->Mod_idP, UE_id2); int rnti2 = UE_RNTI(params->Mod_idP, UE_id2);
int pCC_id2 = UE_PCCID(params->Mod_idP, UE_id2); int pCC_id2 = UE_PCCID(params->Mod_idP, UE_id2);
int round2 = maxround(params->Mod_idP, rnti2, params->frameP, params->subframeP, 1); int round2 =
maxround(params->Mod_idP, rnti2, params->frameP, params->subframeP,
1);
int cqi1 = maxcqi(params->Mod_idP, UE_id1); int cqi1 = maxcqi(params->Mod_idP, UE_id1);
int cqi2 = maxcqi(params->Mod_idP, UE_id2); int cqi2 = maxcqi(params->Mod_idP, UE_id2);
if (round1 > round2) return -1; if (round1 > round2)
if (round1 < round2) return 1; return -1;
if (round1 < round2)
return 1;
if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[1] + UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[2] > if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[1] +
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] + UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2]) UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[2] >
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] +
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2])
return -1; return -1;
if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[1] + UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[2] < if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[1] +
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] + UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2]) UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[2] <
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] +
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2])
return 1; return 1;
if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_head_sdu_creation_time_max > if (UE_list->
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_head_sdu_creation_time_max) UE_template[pCC_id1][UE_id1].dl_buffer_head_sdu_creation_time_max >
UE_list->
UE_template[pCC_id2][UE_id2].dl_buffer_head_sdu_creation_time_max)
return -1; return -1;
if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_head_sdu_creation_time_max < if (UE_list->
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_head_sdu_creation_time_max) UE_template[pCC_id1][UE_id1].dl_buffer_head_sdu_creation_time_max <
UE_list->
UE_template[pCC_id2][UE_id2].dl_buffer_head_sdu_creation_time_max)
return 1; return 1;
if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total > if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total >
...@@ -352,14 +404,16 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params) ...@@ -352,14 +404,16 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params)
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total) UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total)
return 1; return 1;
if (cqi1 > cqi2) return -1; if (cqi1 > cqi2)
if (cqi1 < cqi2) return 1; return -1;
if (cqi1 < cqi2)
return 1;
return 0; return 0;
#if 0 #if 0
/* The above order derives from the following. */ /* The above order derives from the following. */
if(round2 > round1) { // Check first if one of the UEs has an active HARQ process which needs service and swap order 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,0); swap_UEs(UE_list, UE_id1, UE_id2, 0);
} else if (round2 == round1) { } else if (round2 == round1) {
// RK->NN : I guess this is for fairness in the scheduling. This doesn't make sense unless all UEs have the same configuration of logical channels. This should be done on the sum of all information that has to be sent. And still it wouldn't ensure fairness. It should be based on throughput seen by each UE or maybe using the head_sdu_creation_time, i.e. swap UEs if one is waiting longer for service. // 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++){ // for(j=0;j<MAX_NUM_LCID;j++){
...@@ -368,26 +422,28 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params) ...@@ -368,26 +422,28 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params)
// first check the buffer status for SRB1 and SRB2 // first check the buffer status for SRB1 and SRB2
if ( (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[1] + UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[2]) < if ((UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[1] +
(UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] + UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2]) ) { UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[2]) <
swap_UEs(UE_list,UE_id1,UE_id2,0); (UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] +
} else if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_head_sdu_creation_time_max < UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2])) {
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_head_sdu_creation_time_max ) { swap_UEs(UE_list, UE_id1, UE_id2, 0);
swap_UEs(UE_list,UE_id1,UE_id2,0); } else if (UE_list->UE_template[pCC_id1]
[UE_id1].dl_buffer_head_sdu_creation_time_max <
UE_list->UE_template[pCC_id2]
[UE_id2].dl_buffer_head_sdu_creation_time_max) {
swap_UEs(UE_list, UE_id1, UE_id2, 0);
} else if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total < } else if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total <
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total ) { UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total) {
swap_UEs(UE_list,UE_id1,UE_id2,0); swap_UEs(UE_list, UE_id1, UE_id2, 0);
} else if (cqi1 < cqi2) { } else if (cqi1 < cqi2) {
swap_UEs(UE_list,UE_id1,UE_id2,0); swap_UEs(UE_list, UE_id1, UE_id2, 0);
} }
} }
#endif #endif
} }
// This fuction sorts the UE in order their dlsch buffer and CQI // This fuction sorts the UE in order their dlsch buffer and CQI
void sort_UEs (module_id_t Mod_idP, void sort_UEs(module_id_t Mod_idP, int frameP, sub_frame_t subframeP)
int frameP,
sub_frame_t subframeP)
{ {
int i; int i;
int list[NUMBER_OF_UE_MAX]; int list[NUMBER_OF_UE_MAX];
...@@ -399,9 +455,12 @@ void sort_UEs (module_id_t Mod_idP, ...@@ -399,9 +455,12 @@ void sort_UEs (module_id_t Mod_idP,
for (i = 0; i < NUMBER_OF_UE_MAX; i++) { for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
if (UE_list->active[i]==FALSE) continue; if (UE_list->active[i] == FALSE)
if ((rnti = UE_RNTI(Mod_idP, i)) == NOT_A_RNTI) continue; continue;
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; if ((rnti = UE_RNTI(Mod_idP, i)) == NOT_A_RNTI)
continue;
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
continue;
list[list_size] = i; list[list_size] = i;
list_size++; list_size++;
...@@ -410,9 +469,9 @@ void sort_UEs (module_id_t Mod_idP, ...@@ -410,9 +469,9 @@ void sort_UEs (module_id_t Mod_idP,
qsort_r(list, list_size, sizeof(int), ue_dl_compare, &params); qsort_r(list, list_size, sizeof(int), ue_dl_compare, &params);
if (list_size) { if (list_size) {
for (i = 0; i < list_size-1; i++) for (i = 0; i < list_size - 1; i++)
UE_list->next[list[i]] = list[i+1]; UE_list->next[list[i]] = list[i + 1];
UE_list->next[list[list_size-1]] = -1; UE_list->next[list[list_size - 1]] = -1;
UE_list->head = list[0]; UE_list->head = list[0];
} else { } else {
UE_list->head = -1; UE_list->head = -1;
...@@ -421,40 +480,40 @@ void sort_UEs (module_id_t Mod_idP, ...@@ -421,40 +480,40 @@ void sort_UEs (module_id_t Mod_idP,
#if 0 #if 0
int UE_id1,UE_id2; int UE_id1, UE_id2;
int pCC_id1,pCC_id2; int pCC_id1, pCC_id2;
int cqi1,cqi2,round1,round2; int cqi1, cqi2, round1, round2;
int i=0,ii=0;//,j=0; int i = 0, ii = 0; //,j=0;
rnti_t rnti1,rnti2; rnti_t rnti1, rnti2;
UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list; UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list;
for (i=UE_list->head; i>=0; i=UE_list->next[i]) { for (i = UE_list->head; i >= 0; i = UE_list->next[i]) {
for(ii=UE_list->next[i]; ii>=0; ii=UE_list->next[ii]) { for (ii = UE_list->next[i]; ii >= 0; ii = UE_list->next[ii]) {
UE_id1 = i; UE_id1 = i;
rnti1 = UE_RNTI(Mod_idP,UE_id1); rnti1 = UE_RNTI(Mod_idP, UE_id1);
if(rnti1 == NOT_A_RNTI) if (rnti1 == NOT_A_RNTI)
continue; continue;
if (UE_list->UE_sched_ctrl[UE_id1].ul_out_of_sync == 1) if (UE_list->UE_sched_ctrl[UE_id1].ul_out_of_sync == 1)
continue; continue;
pCC_id1 = UE_PCCID(Mod_idP,UE_id1); pCC_id1 = UE_PCCID(Mod_idP, UE_id1);
cqi1 = maxcqi(Mod_idP,UE_id1); // cqi1 = maxcqi(Mod_idP, UE_id1); //
round1 = maxround(Mod_idP,rnti1,frameP,subframeP,0); round1 = maxround(Mod_idP, rnti1, frameP, subframeP, 0);
UE_id2 = ii; UE_id2 = ii;
rnti2 = UE_RNTI(Mod_idP,UE_id2); rnti2 = UE_RNTI(Mod_idP, UE_id2);
if(rnti2 == NOT_A_RNTI) if (rnti2 == NOT_A_RNTI)
continue; continue;
if (UE_list->UE_sched_ctrl[UE_id2].ul_out_of_sync == 1) if (UE_list->UE_sched_ctrl[UE_id2].ul_out_of_sync == 1)
continue; continue;
cqi2 = maxcqi(Mod_idP,UE_id2); cqi2 = maxcqi(Mod_idP, UE_id2);
round2 = maxround(Mod_idP,rnti2,frameP,subframeP,0); //mac_xface->get_ue_active_harq_pid(Mod_id,rnti2,subframe,&harq_pid2,&round2,0); round2 = maxround(Mod_idP, rnti2, frameP, subframeP, 0); //mac_xface->get_ue_active_harq_pid(Mod_id,rnti2,subframe,&harq_pid2,&round2,0);
pCC_id2 = UE_PCCID(Mod_idP,UE_id2); pCC_id2 = UE_PCCID(Mod_idP, UE_id2);
if(round2 > round1) { // Check first if one of the UEs has an active HARQ process which needs service and swap order 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,0); swap_UEs(UE_list, UE_id1, UE_id2, 0);
} else if (round2 == round1) { } else if (round2 == round1) {
// RK->NN : I guess this is for fairness in the scheduling. This doesn't make sense unless all UEs have the same configuration of logical channels. This should be done on the sum of all information that has to be sent. And still it wouldn't ensure fairness. It should be based on throughput seen by each UE or maybe using the head_sdu_creation_time, i.e. swap UEs if one is waiting longer for service. // 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++){ // for(j=0;j<MAX_NUM_LCID;j++){
...@@ -463,17 +522,27 @@ void sort_UEs (module_id_t Mod_idP, ...@@ -463,17 +522,27 @@ void sort_UEs (module_id_t Mod_idP,
// first check the buffer status for SRB1 and SRB2 // first check the buffer status for SRB1 and SRB2
if ( (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[1] + UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[2]) < if ((UE_list->UE_template[pCC_id1][UE_id1].
(UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] + UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2]) ) { dl_buffer_info[1] +
swap_UEs(UE_list,UE_id1,UE_id2,0); UE_list->UE_template[pCC_id1][UE_id1].
} else if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_head_sdu_creation_time_max < dl_buffer_info[2]) <
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_head_sdu_creation_time_max ) { (UE_list->UE_template[pCC_id2][UE_id2].
swap_UEs(UE_list,UE_id1,UE_id2,0); dl_buffer_info[1] +
} else if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total < UE_list->UE_template[pCC_id2][UE_id2].
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total ) { dl_buffer_info[2])) {
swap_UEs(UE_list,UE_id1,UE_id2,0); swap_UEs(UE_list, UE_id1, UE_id2, 0);
} else if (UE_list->UE_template[pCC_id1]
[UE_id1].dl_buffer_head_sdu_creation_time_max <
UE_list->UE_template[pCC_id2]
[UE_id2].dl_buffer_head_sdu_creation_time_max) {
swap_UEs(UE_list, UE_id1, UE_id2, 0);
} else 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, 0);
} else if (cqi1 < cqi2) { } else if (cqi1 < cqi2) {
swap_UEs(UE_list,UE_id1,UE_id2,0); swap_UEs(UE_list, UE_id1, UE_id2, 0);
} }
} }
} }
...@@ -485,24 +554,25 @@ void sort_UEs (module_id_t Mod_idP, ...@@ -485,24 +554,25 @@ void sort_UEs (module_id_t Mod_idP,
// This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done // This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done
void dlsch_scheduler_pre_processor (module_id_t Mod_id, void
dlsch_scheduler_pre_processor(module_id_t Mod_id,
frame_t frameP, frame_t frameP,
sub_frame_t subframeP, sub_frame_t subframeP,
int N_RBG[MAX_NUM_CCs], int N_RBG[MAX_NUM_CCs], int *mbsfn_flag)
int *mbsfn_flag)
{ {
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],harq_pid=0,round=0,total_ue_count; unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX], harq_pid =
0, round = 0, total_ue_count;
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]; unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX];
int UE_id, i; int UE_id, i;
uint16_t ii,j; uint16_t ii, j;
uint16_t nb_rbs_required[MAX_NUM_CCs][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[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
uint16_t nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; uint16_t nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
uint16_t average_rbs_per_user[MAX_NUM_CCs] = {0}; uint16_t average_rbs_per_user[MAX_NUM_CCs] = { 0 };
rnti_t rnti; rnti_t rnti;
int min_rb_unit[MAX_NUM_CCs]; int min_rb_unit[MAX_NUM_CCs];
uint16_t r1=0; uint16_t r1 = 0;
uint8_t CC_id; uint8_t CC_id;
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
...@@ -513,27 +583,28 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id, ...@@ -513,27 +583,28 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id,
COMMON_channels_t *cc; COMMON_channels_t *cc;
#ifdef TM5 #ifdef TM5
int harq_pid1=0; int harq_pid1 = 0;
int round1=0,round2=0; int round1 = 0, round2 = 0;
int UE_id2; int UE_id2;
uint16_t i1,i2,i3; uint16_t i1, i2, i3;
rnti_t rnti1,rnti2; rnti_t rnti1, rnti2;
LTE_eNB_UE_stats *eNB_UE_stats1 = NULL; LTE_eNB_UE_stats *eNB_UE_stats1 = NULL;
LTE_eNB_UE_stats *eNB_UE_stats2 = NULL; LTE_eNB_UE_stats *eNB_UE_stats2 = NULL;
UE_sched_ctrl *ue_sched_ctl1,*ue_sched_ctl2; UE_sched_ctrl *ue_sched_ctl1, *ue_sched_ctl2;
#endif #endif
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { 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 if (mbsfn_flag[CC_id] > 0) // If this CC is allocated for MBSFN skip it here
continue; continue;
min_rb_unit[CC_id]=get_min_rb_unit(Mod_id,CC_id); min_rb_unit[CC_id] = get_min_rb_unit(Mod_id, CC_id);
for (i = 0; i < NUMBER_OF_UE_MAX; i++) { for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
if (UE_list->active[i] != TRUE) continue; if (UE_list->active[i] != TRUE)
continue;
UE_id = i; UE_id = i;
// Initialize scheduling information for all active UEs // Initialize scheduling information for all active UEs
...@@ -556,53 +627,54 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id, ...@@ -556,53 +627,54 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id,
// Store the DLSCH buffer for each logical channel // Store the DLSCH buffer for each logical channel
store_dlsch_buffer (Mod_id,frameP,subframeP); store_dlsch_buffer(Mod_id, frameP, subframeP);
// Calculate the number of RBs required by each UE on the basis of logical channel's buffer // Calculate the number of RBs required by each UE on the basis of logical channel's buffer
assign_rbs_required (Mod_id,frameP,subframeP,nb_rbs_required,min_rb_unit); assign_rbs_required(Mod_id, frameP, subframeP, nb_rbs_required,
min_rb_unit);
// Sorts the user on the basis of dlsch logical channel buffer and CQI // Sorts the user on the basis of dlsch logical channel buffer and CQI
sort_UEs (Mod_id,frameP,subframeP); sort_UEs(Mod_id, frameP, subframeP);
total_ue_count =0; total_ue_count = 0;
// loop over all active UEs // loop over all active UEs
for (i=UE_list->head; i>=0; i=UE_list->next[i]) { for (i = UE_list->head; i >= 0; i = UE_list->next[i]) {
rnti = UE_RNTI(Mod_id,i); rnti = UE_RNTI(Mod_id, i);
if(rnti == NOT_A_RNTI) if (rnti == NOT_A_RNTI)
continue; continue;
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
continue; continue;
UE_id = i; UE_id = i;
for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) { for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) {
CC_id = UE_list->ordered_CCids[ii][UE_id]; CC_id = UE_list->ordered_CCids[ii][UE_id];
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
cc=&RC.mac[Mod_id]->common_channels[ii]; cc = &RC.mac[Mod_id]->common_channels[ii];
if (cc->tdd_Config) harq_pid = ((frameP*10)+subframeP)%10; if (cc->tdd_Config)
else harq_pid = ((frameP*10)+subframeP)&7; harq_pid = ((frameP * 10) + subframeP) % 10;
else
harq_pid = ((frameP * 10) + subframeP) & 7;
round = ue_sched_ctl->round[CC_id][harq_pid]; round = ue_sched_ctl->round[CC_id][harq_pid];
average_rbs_per_user[CC_id]=0; average_rbs_per_user[CC_id] = 0;
if(round != 8) { if (round != 8) {
nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; nb_rbs_required[CC_id][UE_id] =
UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
} }
//nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id]; //nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id];
if (nb_rbs_required[CC_id][UE_id] > 0) { if (nb_rbs_required[CC_id][UE_id] > 0) {
total_ue_count = total_ue_count + 1; total_ue_count = total_ue_count + 1;
} }
// hypothetical assignment // hypothetical assignment
/* /*
* If schedule is enabled and if the priority of the UEs is modified * If schedule is enabled and if the priority of the UEs is modified
...@@ -613,12 +685,15 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id, ...@@ -613,12 +685,15 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id,
* per user by a coefficient which represents the degree of priority. * per user by a coefficient which represents the degree of priority.
*/ */
N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); N_RB_DL =
to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->
message.dl_Bandwidth);
if (total_ue_count == 0) { if (total_ue_count == 0) {
average_rbs_per_user[CC_id] = 0; average_rbs_per_user[CC_id] = 0;
} else if( (min_rb_unit[CC_id] * total_ue_count) <= (N_RB_DL) ) { } else if ((min_rb_unit[CC_id] * total_ue_count) <= (N_RB_DL)) {
average_rbs_per_user[CC_id] = (uint16_t) floor(N_RB_DL/total_ue_count); average_rbs_per_user[CC_id] =
(uint16_t) floor(N_RB_DL / total_ue_count);
} else { } else {
average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; // consider the total number of use that can be scheduled UE average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; // consider the total number of use that can be scheduled UE
} }
...@@ -627,25 +702,29 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id, ...@@ -627,25 +702,29 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id,
// note: nb_rbs_required is assigned according to total_buffer_dl // note: nb_rbs_required is assigned according to total_buffer_dl
// extend nb_rbs_required to capture per LCID RB required // extend nb_rbs_required to capture per LCID RB required
for(i=UE_list->head; i>=0; i=UE_list->next[i]) { for (i = UE_list->head; i >= 0; i = UE_list->next[i]) {
rnti = UE_RNTI(Mod_id,i); rnti = UE_RNTI(Mod_id, i);
if(rnti == NOT_A_RNTI) if (rnti == NOT_A_RNTI)
continue; continue;
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
continue; continue;
for (ii=0; ii<UE_num_active_CC(UE_list,i); ii++) { for (ii = 0; ii < UE_num_active_CC(UE_list, i); ii++) {
CC_id = UE_list->ordered_CCids[ii][i]; CC_id = UE_list->ordered_CCids[ii][i];
ue_sched_ctl = &UE_list->UE_sched_ctrl[i]; ue_sched_ctl = &UE_list->UE_sched_ctrl[i];
round = ue_sched_ctl->round[CC_id][harq_pid]; round = ue_sched_ctl->round[CC_id][harq_pid];
// control channel or retransmission // control channel or retransmission
/* TODO: do we have to check for retransmission? */ /* TODO: do we have to check for retransmission? */
if (mac_eNB_get_rrc_status(Mod_id,rnti) < RRC_RECONFIGURED || round > 0) { if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_RECONFIGURED
nb_rbs_required_remaining_1[CC_id][i] = nb_rbs_required[CC_id][i]; || round > 0) {
nb_rbs_required_remaining_1[CC_id][i] =
nb_rbs_required[CC_id][i];
} else { } else {
nb_rbs_required_remaining_1[CC_id][i] = cmin(average_rbs_per_user[CC_id],nb_rbs_required[CC_id][i]); nb_rbs_required_remaining_1[CC_id][i] =
cmin(average_rbs_per_user[CC_id],
nb_rbs_required[CC_id][i]);
} }
} }
...@@ -654,50 +733,56 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id, ...@@ -654,50 +733,56 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id,
//Allocation to UEs is done in 2 rounds, //Allocation to UEs is done in 2 rounds,
// 1st stage: average number of RBs allocated to each UE // 1st stage: average number of RBs allocated to each UE
// 2nd stage: remaining RBs are allocated to high priority UEs // 2nd stage: remaining RBs are allocated to high priority UEs
for(r1=0; r1<2; r1++) { for (r1 = 0; r1 < 2; r1++) {
for(i=UE_list->head; i>=0; i=UE_list->next[i]) { for (i = UE_list->head; i >= 0; i = UE_list->next[i]) {
for (ii=0; ii<UE_num_active_CC(UE_list,i); ii++) { for (ii = 0; ii < UE_num_active_CC(UE_list, i); ii++) {
CC_id = UE_list->ordered_CCids[ii][i]; CC_id = UE_list->ordered_CCids[ii][i];
if(r1 == 0) { if (r1 == 0) {
nb_rbs_required_remaining[CC_id][i] = nb_rbs_required_remaining_1[CC_id][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 } else { // rb required based only on the buffer - rb allloctaed in the 1st round + extra reaming rb form the 1st round
nb_rbs_required_remaining[CC_id][i] = nb_rbs_required[CC_id][i]-nb_rbs_required_remaining_1[CC_id][i]+nb_rbs_required_remaining[CC_id][i]; nb_rbs_required_remaining[CC_id][i] =
if (nb_rbs_required_remaining[CC_id][i]<0) abort(); nb_rbs_required[CC_id][i] -
nb_rbs_required_remaining_1[CC_id][i] +
nb_rbs_required_remaining[CC_id][i];
if (nb_rbs_required_remaining[CC_id][i] < 0)
abort();
} }
if (nb_rbs_required[CC_id][i]> 0 ) if (nb_rbs_required[CC_id][i] > 0)
LOG_D(MAC,"round %d : nb_rbs_required_remaining[%d][%d]= %d (remaining_1 %d, required %d, pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n", LOG_D(MAC,
"round %d : nb_rbs_required_remaining[%d][%d]= %d (remaining_1 %d, required %d, pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n",
r1, CC_id, i, r1, CC_id, i,
nb_rbs_required_remaining[CC_id][i], nb_rbs_required_remaining[CC_id][i],
nb_rbs_required_remaining_1[CC_id][i], nb_rbs_required_remaining_1[CC_id][i],
nb_rbs_required[CC_id][i], nb_rbs_required[CC_id][i],
UE_list->UE_sched_ctrl[i].pre_nb_available_rbs[CC_id], UE_list->UE_sched_ctrl[i].
N_RBG[CC_id], pre_nb_available_rbs[CC_id], N_RBG[CC_id],
min_rb_unit[CC_id]); min_rb_unit[CC_id]);
} }
} }
if (total_ue_count > 0 ) { if (total_ue_count > 0) {
for(i=UE_list->head; i>=0; i=UE_list->next[i]) { for (i = UE_list->head; i >= 0; i = UE_list->next[i]) {
UE_id = i; UE_id = i;
for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) { for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) {
CC_id = UE_list->ordered_CCids[ii][UE_id]; CC_id = UE_list->ordered_CCids[ii][UE_id];
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
round = ue_sched_ctl->round[CC_id][harq_pid]; round = ue_sched_ctl->round[CC_id][harq_pid];
rnti = UE_RNTI(Mod_id,UE_id); rnti = UE_RNTI(Mod_id, UE_id);
// LOG_D(MAC,"UE %d rnti 0x\n", UE_id, rnti ); // LOG_D(MAC,"UE %d rnti 0x\n", UE_id, rnti );
if(rnti == NOT_A_RNTI) if (rnti == NOT_A_RNTI)
continue; continue;
if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1)
continue; continue;
transmission_mode = get_tmode(Mod_id,CC_id,UE_id); transmission_mode = get_tmode(Mod_id, CC_id, UE_id);
// mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frameP,subframeP,&harq_pid,&round,0); // mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frameP,subframeP,&harq_pid,&round,0);
//rrc_status = mac_eNB_get_rrc_status(Mod_id,rnti); //rrc_status = mac_eNB_get_rrc_status(Mod_id,rnti);
/* 1st allocate for the retx */ /* 1st allocate for the retx */
...@@ -705,14 +790,17 @@ if (nb_rbs_required_remaining[CC_id][i]<0) abort(); ...@@ -705,14 +790,17 @@ if (nb_rbs_required_remaining[CC_id][i]<0) abort();
// retransmission in data channels // retransmission in data channels
// control channel in the 1st transmission // control channel in the 1st transmission
// data channel for all TM // data channel for all TM
LOG_T(MAC,"calling dlsch_scheduler_pre_processor_allocate .. \n "); LOG_T(MAC,
dlsch_scheduler_pre_processor_allocate (Mod_id, "calling dlsch_scheduler_pre_processor_allocate .. \n ");
UE_id, dlsch_scheduler_pre_processor_allocate(Mod_id, UE_id,
CC_id, CC_id,
N_RBG[CC_id], N_RBG[CC_id],
transmission_mode, transmission_mode,
min_rb_unit[CC_id], min_rb_unit
to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth), [CC_id],
to_prb(RC.mac
[Mod_id]->common_channels
[CC_id].mib->message.dl_Bandwidth),
nb_rbs_required, nb_rbs_required,
nb_rbs_required_remaining, nb_rbs_required_remaining,
rballoc_sub, rballoc_sub,
...@@ -721,71 +809,155 @@ if (nb_rbs_required_remaining[CC_id][i]<0) abort(); ...@@ -721,71 +809,155 @@ if (nb_rbs_required_remaining[CC_id][i]<0) abort();
#ifdef TM5 #ifdef TM5
// data chanel TM5: to be revisted // data chanel TM5: to be revisted
if ((round == 0 ) && if ((round == 0) &&
(transmission_mode == 5) && (transmission_mode == 5) &&
(ue_sched_ctl->dl_pow_off[CC_id] != 1)) { (ue_sched_ctl->dl_pow_off[CC_id] != 1)) {
for(j=0; j<N_RBG[CC_id]; j+=2) { for (j = 0; j < N_RBG[CC_id]; j += 2) {
if( (((j == (N_RBG[CC_id]-1))&& (rballoc_sub[CC_id][j] == 0) && (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 0)) || if ((((j == (N_RBG[CC_id] - 1))
((j < (N_RBG[CC_id]-1)) && (rballoc_sub[CC_id][j+1] == 0) && (ue_sched_ctl->rballoc_sub_UE[CC_id][j+1] == 0)) ) && && (rballoc_sub[CC_id][j] == 0)
(nb_rbs_required_remaining[CC_id][UE_id]>0)) { && (ue_sched_ctl->
rballoc_sub_UE[CC_id][j] == 0))
|| ((j < (N_RBG[CC_id] - 1))
&& (rballoc_sub[CC_id][j + 1] == 0)
&&
(ue_sched_ctl->rballoc_sub_UE
[CC_id][j + 1] == 0)))
&& (nb_rbs_required_remaining[CC_id][UE_id]
> 0)) {
for (ii = UE_list->next[i+1]; ii >=0; ii=UE_list->next[ii]) { for (ii = UE_list->next[i + 1]; ii >= 0;
ii = UE_list->next[ii]) {
UE_id2 = ii; UE_id2 = ii;
rnti2 = UE_RNTI(Mod_id,UE_id2); rnti2 = UE_RNTI(Mod_id, UE_id2);
ue_sched_ctl2 = &UE_list->UE_sched_ctrl[UE_id2]; ue_sched_ctl2 =
&UE_list->UE_sched_ctrl[UE_id2];
round2 = ue_sched_ctl2->round[CC_id]; round2 = ue_sched_ctl2->round[CC_id];
if(rnti2 == NOT_A_RNTI) if (rnti2 == NOT_A_RNTI)
continue; continue;
if (UE_list->UE_sched_ctrl[UE_id2].ul_out_of_sync == 1) if (UE_list->
UE_sched_ctrl
[UE_id2].ul_out_of_sync == 1)
continue; continue;
eNB_UE_stats2 = UE_list->eNB_UE_stats[CC_id][UE_id2]; eNB_UE_stats2 =
UE_list->
eNB_UE_stats[CC_id][UE_id2];
//mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,frameP,subframeP,&harq_pid2,&round2,0); //mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,frameP,subframeP,&harq_pid2,&round2,0);
if ((mac_eNB_get_rrc_status(Mod_id,rnti2) >= RRC_RECONFIGURED) && if ((mac_eNB_get_rrc_status
(round2==0) && (Mod_id,
(get_tmode(Mod_id,CC_id,UE_id2)==5) && rnti2) >= RRC_RECONFIGURED)
(ue_sched_ctl->dl_pow_off[CC_id] != 1)) { && (round2 == 0)
&&
if( (((j == (N_RBG[CC_id]-1)) && (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 0)) || (get_tmode(Mod_id, CC_id, UE_id2)
((j < (N_RBG[CC_id]-1)) && (ue_sched_ctl->rballoc_sub_UE[CC_id][j+1] == 0)) ) && == 5)
(nb_rbs_required_remaining[CC_id][UE_id2]>0)) { && (ue_sched_ctl->
dl_pow_off[CC_id] != 1)) {
if((((eNB_UE_stats2->DL_pmi_single^eNB_UE_stats1->DL_pmi_single)<<(14-j))&0xc000)== 0x4000) { //MU-MIMO only for 25 RBs configuration
if ((((j == (N_RBG[CC_id] - 1))
&&
(ue_sched_ctl->rballoc_sub_UE
[CC_id][j] == 0))
|| ((j < (N_RBG[CC_id] - 1))
&&
(ue_sched_ctl->
rballoc_sub_UE[CC_id][j +
1]
== 0)))
&&
(nb_rbs_required_remaining
[CC_id]
[UE_id2] > 0)) {
if ((((eNB_UE_stats2->
DL_pmi_single ^
eNB_UE_stats1->
DL_pmi_single)
<< (14 - j)) & 0xc000) == 0x4000) { //MU-MIMO only for 25 RBs configuration
rballoc_sub[CC_id][j] = 1; rballoc_sub[CC_id][j] = 1;
ue_sched_ctl->rballoc_sub_UE[CC_id][j] = 1; ue_sched_ctl->
ue_sched_ctl2->rballoc_sub_UE[CC_id][j] = 1; rballoc_sub_UE[CC_id]
MIMO_mode_indicator[CC_id][j] = 0; [j] = 1;
ue_sched_ctl2->
if (j< N_RBG[CC_id]-1) { rballoc_sub_UE[CC_id]
rballoc_sub[CC_id][j+1] = 1; [j] = 1;
ue_sched_ctl->rballoc_sub_UE[CC_id][j+1] = 1; MIMO_mode_indicator[CC_id]
ue_sched_ctl2->rballoc_sub_UE[CC_id][j+1] = 1; [j] = 0;
MIMO_mode_indicator[CC_id][j+1] = 0;
} if (j < N_RBG[CC_id] - 1) {
rballoc_sub[CC_id][j +
ue_sched_ctl->dl_pow_off[CC_id] = 0; 1] =
ue_sched_ctl2->dl_pow_off[CC_id] = 0; 1;
ue_sched_ctl->
rballoc_sub_UE
if ((j == N_RBG[CC_id]-1) && [CC_id][j + 1] = 1;
((N_RB_DL == 25) || ue_sched_ctl2->rballoc_sub_UE
(N_RB_DL == 50))) { [CC_id][j + 1] = 1;
MIMO_mode_indicator
nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id]+1; [CC_id][j + 1]
ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit[CC_id]-1; = 0;
nb_rbs_required_remaining[CC_id][UE_id2] = nb_rbs_required_remaining[CC_id][UE_id2] - min_rb_unit[CC_id]+1; }
ue_sched_ctl2->pre_nb_available_rbs[CC_id] = ue_sched_ctl2->pre_nb_available_rbs[CC_id] + min_rb_unit[CC_id]-1;
ue_sched_ctl->
dl_pow_off[CC_id]
= 0;
ue_sched_ctl2->
dl_pow_off[CC_id]
= 0;
if ((j == N_RBG[CC_id] - 1)
&& ((N_RB_DL == 25)
|| (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;
ue_sched_ctl->pre_nb_available_rbs
[CC_id] =
ue_sched_ctl->pre_nb_available_rbs
[CC_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;
ue_sched_ctl2->pre_nb_available_rbs
[CC_id] =
ue_sched_ctl2->pre_nb_available_rbs
[CC_id] +
min_rb_unit[CC_id]
- 1;
} else { } else {
nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - 4; nb_rbs_required_remaining
ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + 4; [CC_id][UE_id] =
nb_rbs_required_remaining[CC_id][UE_id2] = nb_rbs_required_remaining[CC_id][UE_id2] - 4; nb_rbs_required_remaining
ue_sched_ctl2->pre_nb_available_rbs[CC_id] = ue_sched_ctl2->pre_nb_available_rbs[CC_id] + 4; [CC_id][UE_id] - 4;
ue_sched_ctl->pre_nb_available_rbs
[CC_id] =
ue_sched_ctl->pre_nb_available_rbs
[CC_id] + 4;
nb_rbs_required_remaining
[CC_id][UE_id2] =
nb_rbs_required_remaining
[CC_id][UE_id2] -
4;
ue_sched_ctl2->pre_nb_available_rbs
[CC_id] =
ue_sched_ctl2->pre_nb_available_rbs
[CC_id] + 4;
} }
break; break;
...@@ -796,7 +968,6 @@ if (nb_rbs_required_remaining[CC_id][i]<0) abort(); ...@@ -796,7 +968,6 @@ if (nb_rbs_required_remaining[CC_id][i]<0) abort();
} }
} }
} }
#endif #endif
} }
} }
...@@ -806,59 +977,75 @@ if (nb_rbs_required_remaining[CC_id][i]<0) abort(); ...@@ -806,59 +977,75 @@ if (nb_rbs_required_remaining[CC_id][i]<0) abort();
#ifdef TM5 #ifdef TM5
// This has to be revisited!!!! // This has to be revisited!!!!
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
i1=0; i1 = 0;
i2=0; i2 = 0;
i3=0; i3 = 0;
for (j=0; j<N_RBG[CC_id]; j++) { for (j = 0; j < N_RBG[CC_id]; j++) {
if(MIMO_mode_indicator[CC_id][j] == 2) { if (MIMO_mode_indicator[CC_id][j] == 2) {
i1 = i1+1; i1 = i1 + 1;
} else if(MIMO_mode_indicator[CC_id][j] == 1) { } else if (MIMO_mode_indicator[CC_id][j] == 1) {
i2 = i2+1; i2 = i2 + 1;
} else if(MIMO_mode_indicator[CC_id][j] == 0) { } else if (MIMO_mode_indicator[CC_id][j] == 0) {
i3 = i3+1; i3 = i3 + 1;
} }
} }
if((i1 < N_RBG[CC_id]) && (i2>0) && (i3==0)) { if ((i1 < N_RBG[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; 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_RBG[CC_id] && i1==0 && i2==0) { if (i3 == N_RBG[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; 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_RBG[CC_id]) && (i3 > 0)) { if ((i1 < N_RBG[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_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; 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;
} }
#endif #endif
for(i=UE_list->head; i>=0; i=UE_list->next[i]) { for (i = UE_list->head; i >= 0; i = UE_list->next[i]) {
UE_id = i; UE_id = i;
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) { for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) {
CC_id = UE_list->ordered_CCids[ii][UE_id]; CC_id = UE_list->ordered_CCids[ii][UE_id];
//PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id]; //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id];
if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0 ) { if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0) {
LOG_D(MAC,"******************DL Scheduling Information for UE%d ************************\n",UE_id); LOG_D(MAC,
LOG_D(MAC,"dl power offset UE%d = %d \n",UE_id,ue_sched_ctl->dl_pow_off[CC_id]); "******************DL Scheduling Information for UE%d ************************\n",
LOG_D(MAC,"***********RB Alloc for every subband for UE%d ***********\n",UE_id); UE_id);
LOG_D(MAC, "dl power offset UE%d = %d \n", UE_id,
ue_sched_ctl->dl_pow_off[CC_id]);
LOG_D(MAC,
"***********RB Alloc for every subband for UE%d ***********\n",
UE_id);
for(j=0; j<N_RBG[CC_id]; j++) { for (j = 0; j < N_RBG[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]; //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,ue_sched_ctl->rballoc_sub_UE[CC_id][j]); LOG_D(MAC, "RB Alloc for UE%d and Subband%d = %d\n",
UE_id, j,
ue_sched_ctl->rballoc_sub_UE[CC_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]; //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,ue_sched_ctl->pre_nb_available_rbs[CC_id]); LOG_D(MAC, "Total RBs allocated for UE%d = %d\n", UE_id,
ue_sched_ctl->pre_nb_available_rbs[CC_id]);
} }
} }
} }
...@@ -866,35 +1053,44 @@ if (nb_rbs_required_remaining[CC_id][i]<0) abort(); ...@@ -866,35 +1053,44 @@ if (nb_rbs_required_remaining[CC_id][i]<0) abort();
#define SF0_LIMIT 1 #define SF0_LIMIT 1
void dlsch_scheduler_pre_processor_reset (int module_idP, void
dlsch_scheduler_pre_processor_reset(int module_idP,
int UE_id, int UE_id,
uint8_t CC_id, uint8_t CC_id,
int frameP, int frameP,
int subframeP, int subframeP,
int N_RBG, int N_RBG,
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], uint16_t nb_rbs_required[MAX_NUM_CCs]
uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX], [NUMBER_OF_UE_MAX],
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX], uint16_t
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]) nb_rbs_required_remaining
[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
unsigned char
rballoc_sub[MAX_NUM_CCs]
[N_RBG_MAX], unsigned char
MIMO_mode_indicator[MAX_NUM_CCs]
[N_RBG_MAX])
{ {
int i,j; int i, j;
UE_list_t *UE_list=&RC.mac[module_idP]->UE_list; UE_list_t *UE_list = &RC.mac[module_idP]->UE_list;
UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
rnti_t rnti = UE_RNTI(module_idP,UE_id); rnti_t rnti = UE_RNTI(module_idP, UE_id);
uint8_t *vrb_map = RC.mac[module_idP]->common_channels[CC_id].vrb_map; uint8_t *vrb_map = RC.mac[module_idP]->common_channels[CC_id].vrb_map;
int N_RB_DL = to_prb(RC.mac[module_idP]->common_channels[CC_id].mib->message.dl_Bandwidth); int N_RB_DL =
int RBGsize = N_RB_DL/N_RBG,RBGsize_last; to_prb(RC.mac[module_idP]->common_channels[CC_id].mib->
message.dl_Bandwidth);
int RBGsize = N_RB_DL / N_RBG, RBGsize_last;
#ifdef SF0_LIMIT #ifdef SF0_LIMIT
int sf0_upper=-1,sf0_lower=-1; int sf0_upper = -1, sf0_lower = -1;
#endif #endif
LOG_D(MAC,"Running preprocessor for UE %d (%x)\n",UE_id,rnti); LOG_D(MAC, "Running preprocessor for UE %d (%x)\n", UE_id, rnti);
// initialize harq_pid and round // initialize harq_pid and round
if (ue_sched_ctl->ta_timer) ue_sched_ctl->ta_timer--; if (ue_sched_ctl->ta_timer)
ue_sched_ctl->ta_timer--;
/* /*
eNB_UE_stats *eNB_UE_stats; eNB_UE_stats *eNB_UE_stats;
...@@ -954,49 +1150,69 @@ void dlsch_scheduler_pre_processor_reset (int module_idP, ...@@ -954,49 +1150,69 @@ void dlsch_scheduler_pre_processor_reset (int module_idP,
} }
*/ */
nb_rbs_required[CC_id][UE_id]=0; nb_rbs_required[CC_id][UE_id] = 0;
ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0; ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0;
ue_sched_ctl->dl_pow_off[CC_id] = 2; ue_sched_ctl->dl_pow_off[CC_id] = 2;
nb_rbs_required_remaining[CC_id][UE_id] = 0; nb_rbs_required_remaining[CC_id][UE_id] = 0;
switch (N_RB_DL) { switch (N_RB_DL) {
case 6: RBGsize = 1; RBGsize_last = 1; break; case 6:
case 15: RBGsize = 2; RBGsize_last = 1; break; RBGsize = 1;
case 25: RBGsize = 2; RBGsize_last = 1; break; RBGsize_last = 1;
case 50: RBGsize = 3; RBGsize_last = 2; break; break;
case 75: RBGsize = 4; RBGsize_last = 3; break; case 15:
case 100: RBGsize = 4; RBGsize_last = 4; break; RBGsize = 2;
default: AssertFatal(1==0,"unsupported RBs (%d)\n", N_RB_DL); RBGsize_last = 1;
break;
case 25:
RBGsize = 2;
RBGsize_last = 1;
break;
case 50:
RBGsize = 3;
RBGsize_last = 2;
break;
case 75:
RBGsize = 4;
RBGsize_last = 3;
break;
case 100:
RBGsize = 4;
RBGsize_last = 4;
break;
default:
AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL);
} }
#ifdef SF0_LIMIT #ifdef SF0_LIMIT
switch (N_RBG) { switch (N_RBG) {
case 6: case 6:
sf0_lower=0; sf0_lower = 0;
sf0_upper=5; sf0_upper = 5;
break; break;
case 8: case 8:
sf0_lower=2; sf0_lower = 2;
sf0_upper=5; sf0_upper = 5;
break; break;
case 13: case 13:
sf0_lower=4; sf0_lower = 4;
sf0_upper=7; sf0_upper = 7;
break; break;
case 17: case 17:
sf0_lower=7; sf0_lower = 7;
sf0_upper=9; sf0_upper = 9;
break; break;
case 25: case 25:
sf0_lower=11; sf0_lower = 11;
sf0_upper=13; sf0_upper = 13;
break; break;
default: AssertFatal(1==0,"unsupported RBs (%d)\n", N_RB_DL); default:
AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL);
} }
#endif #endif
// Initialize Subbands according to VRB map // Initialize Subbands according to VRB map
for (i=0; i<N_RBG; i++) { for (i = 0; i < N_RBG; i++) {
int rb_size = i==N_RBG-1 ? RBGsize_last : RBGsize; int rb_size = i == N_RBG - 1 ? RBGsize_last : RBGsize;
ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0; ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0;
rballoc_sub[CC_id][i] = 0; rballoc_sub[CC_id][i] = 0;
...@@ -1006,72 +1222,93 @@ void dlsch_scheduler_pre_processor_reset (int module_idP, ...@@ -1006,72 +1222,93 @@ void dlsch_scheduler_pre_processor_reset (int module_idP,
* compute number of available REs and limit MCS according to the * compute number of available REs and limit MCS according to the
* TBS table 36.213 7.1.7.2.1-1 (can be done after pre-processor) * TBS table 36.213 7.1.7.2.1-1 (can be done after pre-processor)
*/ */
if (subframeP==0 && if (subframeP == 0 && i >= sf0_lower && i <= sf0_upper)
i >= sf0_lower && i <= sf0_upper) rballoc_sub[CC_id][i] = 1;
rballoc_sub[CC_id][i]=1;
#endif #endif
// for SI-RNTI,RA-RNTI and P-RNTI allocations // for SI-RNTI,RA-RNTI and P-RNTI allocations
for (j = 0; j < rb_size; j++) { for (j = 0; j < rb_size; j++) {
if (vrb_map[j+(i*RBGsize)] != 0) { if (vrb_map[j + (i * RBGsize)] != 0) {
rballoc_sub[CC_id][i] = 1; rballoc_sub[CC_id][i] = 1;
LOG_D(MAC,"Frame %d, subframe %d : vrb %d allocated\n",frameP,subframeP,j+(i*RBGsize)); LOG_D(MAC, "Frame %d, subframe %d : vrb %d allocated\n",
frameP, subframeP, j + (i * RBGsize));
break; break;
} }
} }
LOG_D(MAC,"Frame %d Subframe %d CC_id %d RBG %i : rb_alloc %d\n",frameP,subframeP,CC_id,i,rballoc_sub[CC_id][i]); LOG_D(MAC, "Frame %d Subframe %d CC_id %d RBG %i : rb_alloc %d\n",
frameP, subframeP, CC_id, i, rballoc_sub[CC_id][i]);
MIMO_mode_indicator[CC_id][i] = 2; MIMO_mode_indicator[CC_id][i] = 2;
} }
} }
void dlsch_scheduler_pre_processor_allocate (module_id_t Mod_id, void
dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id,
int UE_id, int UE_id,
uint8_t CC_id, uint8_t CC_id,
int N_RBG, int N_RBG,
int transmission_mode, int transmission_mode,
int min_rb_unit, int min_rb_unit,
uint8_t N_RB_DL, uint8_t N_RB_DL,
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], uint16_t
uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX], nb_rbs_required[MAX_NUM_CCs]
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX], [NUMBER_OF_UE_MAX],
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]) uint16_t
nb_rbs_required_remaining
[MAX_NUM_CCs]
[NUMBER_OF_UE_MAX], unsigned char
rballoc_sub[MAX_NUM_CCs]
[N_RBG_MAX], unsigned char
MIMO_mode_indicator
[MAX_NUM_CCs][N_RBG_MAX])
{ {
int i; int i;
UE_list_t *UE_list=&RC.mac[Mod_id]->UE_list; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
for(i=0; i<N_RBG; i++) { for (i = 0; i < N_RBG; i++) {
if((rballoc_sub[CC_id][i] == 0) && if ((rballoc_sub[CC_id][i] == 0) &&
(ue_sched_ctl->rballoc_sub_UE[CC_id][i] == 0) && (ue_sched_ctl->rballoc_sub_UE[CC_id][i] == 0) &&
(nb_rbs_required_remaining[CC_id][UE_id]>0) && (nb_rbs_required_remaining[CC_id][UE_id] > 0) &&
(ue_sched_ctl->pre_nb_available_rbs[CC_id] < nb_rbs_required[CC_id][UE_id])) { (ue_sched_ctl->pre_nb_available_rbs[CC_id] <
nb_rbs_required[CC_id][UE_id])) {
// if this UE is not scheduled for TM5 // if this UE is not scheduled for TM5
if (ue_sched_ctl->dl_pow_off[CC_id] != 0 ) { if (ue_sched_ctl->dl_pow_off[CC_id] != 0) {
if ((i == N_RBG-1) && ((N_RB_DL == 25) || (N_RB_DL == 50))) { if ((i == N_RBG - 1)
if (nb_rbs_required_remaining[CC_id][UE_id] >= min_rb_unit-1){ && ((N_RB_DL == 25) || (N_RB_DL == 50))) {
if (nb_rbs_required_remaining[CC_id][UE_id] >=
min_rb_unit - 1) {
rballoc_sub[CC_id][i] = 1; rballoc_sub[CC_id][i] = 1;
ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1; ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1;
MIMO_mode_indicator[CC_id][i] = 1; MIMO_mode_indicator[CC_id][i] = 1;
if (transmission_mode == 5 ) { if (transmission_mode == 5) {
ue_sched_ctl->dl_pow_off[CC_id] = 1; ue_sched_ctl->dl_pow_off[CC_id] = 1;
} }
nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit+1; nb_rbs_required_remaining[CC_id][UE_id] =
ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit - 1; nb_rbs_required_remaining[CC_id][UE_id] -
min_rb_unit + 1;
ue_sched_ctl->pre_nb_available_rbs[CC_id] =
ue_sched_ctl->pre_nb_available_rbs[CC_id] +
min_rb_unit - 1;
} }
} else { } else {
if (nb_rbs_required_remaining[CC_id][UE_id] >= min_rb_unit){ if (nb_rbs_required_remaining[CC_id][UE_id] >=
min_rb_unit) {
rballoc_sub[CC_id][i] = 1; rballoc_sub[CC_id][i] = 1;
ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1; ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1;
MIMO_mode_indicator[CC_id][i] = 1; MIMO_mode_indicator[CC_id][i] = 1;
if (transmission_mode == 5 ) { if (transmission_mode == 5) {
ue_sched_ctl->dl_pow_off[CC_id] = 1; ue_sched_ctl->dl_pow_off[CC_id] = 1;
} }
nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit; nb_rbs_required_remaining[CC_id][UE_id] =
ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit; nb_rbs_required_remaining[CC_id][UE_id] -
min_rb_unit;
ue_sched_ctl->pre_nb_available_rbs[CC_id] =
ue_sched_ctl->pre_nb_available_rbs[CC_id] +
min_rb_unit;
} }
} }
} // dl_pow_off[CC_id][UE_id] ! = 0 } // dl_pow_off[CC_id][UE_id] ! = 0
...@@ -1083,16 +1320,18 @@ void dlsch_scheduler_pre_processor_allocate (module_id_t Mod_id, ...@@ -1083,16 +1320,18 @@ void dlsch_scheduler_pre_processor_allocate (module_id_t Mod_id,
/// ULSCH PRE_PROCESSOR /// ULSCH PRE_PROCESSOR
void ulsch_scheduler_pre_processor(module_id_t module_idP, void
ulsch_scheduler_pre_processor(module_id_t module_idP,
int frameP, int frameP,
sub_frame_t subframeP, sub_frame_t subframeP, uint16_t * first_rb)
uint16_t *first_rb)
{ {
int16_t i; int16_t i;
uint16_t UE_id,n,r; uint16_t UE_id, n, r;
uint8_t CC_id, harq_pid; uint8_t CC_id, harq_pid;
uint16_t nb_allocated_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX],total_allocated_rbs[MAX_NUM_CCs],average_rbs_per_user[MAX_NUM_CCs]; uint16_t nb_allocated_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
total_allocated_rbs[MAX_NUM_CCs],
average_rbs_per_user[MAX_NUM_CCs];
int16_t total_remaining_rbs[MAX_NUM_CCs]; int16_t total_remaining_rbs[MAX_NUM_CCs];
uint16_t max_num_ue_to_be_scheduled = 0; uint16_t max_num_ue_to_be_scheduled = 0;
uint16_t total_ue_count = 0; uint16_t total_ue_count = 0;
...@@ -1101,39 +1340,43 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, ...@@ -1101,39 +1340,43 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
UE_TEMPLATE *UE_template = 0; UE_TEMPLATE *UE_template = 0;
int N_RB_DL; int N_RB_DL;
int N_RB_UL; int N_RB_UL;
LOG_D(MAC,"In ulsch_preprocessor: assign max mcs min rb\n"); LOG_D(MAC, "In ulsch_preprocessor: assign max mcs min rb\n");
// maximize MCS and then allocate required RB according to the buffer occupancy with the limit of max available UL RB // maximize MCS and then allocate required RB according to the buffer occupancy with the limit of max available UL RB
assign_max_mcs_min_rb(module_idP,frameP, subframeP, first_rb); assign_max_mcs_min_rb(module_idP, frameP, subframeP, first_rb);
LOG_D(MAC,"In ulsch_preprocessor: sort ue \n"); LOG_D(MAC, "In ulsch_preprocessor: sort ue \n");
// sort ues // sort ues
sort_ue_ul (module_idP,frameP, subframeP); sort_ue_ul(module_idP, frameP, subframeP);
// we need to distribute RBs among UEs // we need to distribute RBs among UEs
// step1: reset the vars // step1: reset the vars
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
N_RB_DL = to_prb(RC.mac[module_idP]->common_channels[CC_id].mib->message.dl_Bandwidth); N_RB_DL =
N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth); to_prb(RC.mac[module_idP]->common_channels[CC_id].mib->
message.dl_Bandwidth);
N_RB_UL =
to_prb(RC.mac[module_idP]->common_channels[CC_id].
ul_Bandwidth);
total_allocated_rbs[CC_id] = 0; total_allocated_rbs[CC_id] = 0;
total_remaining_rbs[CC_id] = 0; total_remaining_rbs[CC_id] = 0;
average_rbs_per_user[CC_id] = 0; average_rbs_per_user[CC_id] = 0;
for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) { for (i = UE_list->head_ul; i >= 0; i = UE_list->next_ul[i]) {
nb_allocated_rbs[CC_id][i]=0; nb_allocated_rbs[CC_id][i] = 0;
} }
} }
LOG_D(MAC,"In ulsch_preprocessor: step2 \n"); LOG_D(MAC, "In ulsch_preprocessor: step2 \n");
// step 2: calculate the average rb per UE // step 2: calculate the average rb per UE
total_ue_count =0; total_ue_count = 0;
max_num_ue_to_be_scheduled=0; max_num_ue_to_be_scheduled = 0;
for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) { for (i = UE_list->head_ul; i >= 0; i = UE_list->next_ul[i]) {
rnti = UE_RNTI(module_idP,i); rnti = UE_RNTI(module_idP, i);
if (rnti==NOT_A_RNTI) if (rnti == NOT_A_RNTI)
continue; continue;
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
...@@ -1142,134 +1385,169 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, ...@@ -1142,134 +1385,169 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
UE_id = i; UE_id = i;
LOG_D(MAC,"In ulsch_preprocessor: handling UE %d/%x\n",UE_id,rnti); LOG_D(MAC, "In ulsch_preprocessor: handling UE %d/%x\n", UE_id,
for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) { rnti);
for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) {
// This is the actual CC_id in the list // This is the actual CC_id in the list
CC_id = UE_list->ordered_ULCCids[n][UE_id]; CC_id = UE_list->ordered_ULCCids[n][UE_id];
LOG_D(MAC,"In ulsch_preprocessor: handling UE %d/%x CCid %d\n",UE_id,rnti,CC_id); LOG_D(MAC,
"In ulsch_preprocessor: handling UE %d/%x CCid %d\n",
UE_id, rnti, CC_id);
UE_template = &UE_list->UE_template[CC_id][UE_id]; UE_template = &UE_list->UE_template[CC_id][UE_id];
average_rbs_per_user[CC_id]=0; average_rbs_per_user[CC_id] = 0;
if (UE_template->pre_allocated_nb_rb_ul > 0) { if (UE_template->pre_allocated_nb_rb_ul > 0) {
total_ue_count+=1; total_ue_count += 1;
} }
/* /*
if((mac_xface->get_nCCE_max(module_idP,CC_id,3,subframeP) - nCCE_to_be_used[CC_id]) > (1<<aggregation)) { if((mac_xface->get_nCCE_max(module_idP,CC_id,3,subframeP) - nCCE_to_be_used[CC_id]) > (1<<aggregation)) {
nCCE_to_be_used[CC_id] = nCCE_to_be_used[CC_id] + (1<<aggregation); nCCE_to_be_used[CC_id] = nCCE_to_be_used[CC_id] + (1<<aggregation);
max_num_ue_to_be_scheduled+=1; max_num_ue_to_be_scheduled+=1;
}*/ } */
max_num_ue_to_be_scheduled+=1; max_num_ue_to_be_scheduled += 1;
if (total_ue_count == 0) { if (total_ue_count == 0) {
average_rbs_per_user[CC_id] = 0; average_rbs_per_user[CC_id] = 0;
} else if (total_ue_count == 1 ) { // increase the available RBs, special case, } else if (total_ue_count == 1) { // increase the available RBs, special case,
average_rbs_per_user[CC_id] = N_RB_UL-first_rb[CC_id]+1; average_rbs_per_user[CC_id] =
} else if( (total_ue_count <= (N_RB_DL-first_rb[CC_id])) && N_RB_UL - first_rb[CC_id] + 1;
(total_ue_count <= max_num_ue_to_be_scheduled)) { } else if ((total_ue_count <= (N_RB_DL - first_rb[CC_id]))
average_rbs_per_user[CC_id] = (uint16_t) floor((N_RB_UL-first_rb[CC_id])/total_ue_count); && (total_ue_count <= max_num_ue_to_be_scheduled)) {
} else if (max_num_ue_to_be_scheduled > 0 ) { average_rbs_per_user[CC_id] =
average_rbs_per_user[CC_id] = (uint16_t) floor((N_RB_UL-first_rb[CC_id])/max_num_ue_to_be_scheduled); (uint16_t) floor((N_RB_UL - first_rb[CC_id]) /
total_ue_count);
} else if (max_num_ue_to_be_scheduled > 0) {
average_rbs_per_user[CC_id] =
(uint16_t) floor((N_RB_UL - first_rb[CC_id]) /
max_num_ue_to_be_scheduled);
} else { } else {
average_rbs_per_user[CC_id]=1; average_rbs_per_user[CC_id] = 1;
LOG_W(MAC,"[eNB %d] frame %d subframe %d: UE %d CC %d: can't get average rb per user (should not be here)\n", LOG_W(MAC,
module_idP,frameP,subframeP,UE_id,CC_id); "[eNB %d] frame %d subframe %d: UE %d CC %d: can't get average rb per user (should not be here)\n",
module_idP, frameP, subframeP, UE_id, CC_id);
} }
} }
} }
if (total_ue_count > 0) if (total_ue_count > 0)
LOG_D(MAC,"[eNB %d] Frame %d subframe %d: total ue to be scheduled %d/%d\n", LOG_D(MAC,
module_idP, frameP, subframeP,total_ue_count, max_num_ue_to_be_scheduled); "[eNB %d] Frame %d subframe %d: total ue to be scheduled %d/%d\n",
module_idP, frameP, subframeP, total_ue_count,
max_num_ue_to_be_scheduled);
//LOG_D(MAC,"step3\n"); //LOG_D(MAC,"step3\n");
// step 3: assigne RBS // step 3: assigne RBS
for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) { for (i = UE_list->head_ul; i >= 0; i = UE_list->next_ul[i]) {
rnti = UE_RNTI(module_idP,i); rnti = UE_RNTI(module_idP, i);
if (rnti==NOT_A_RNTI) if (rnti == NOT_A_RNTI)
continue; continue;
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
continue; continue;
UE_id = i; UE_id = i;
for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) { for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) {
// This is the actual CC_id in the list // This is the actual CC_id in the list
CC_id = UE_list->ordered_ULCCids[n][UE_id]; CC_id = UE_list->ordered_ULCCids[n][UE_id];
harq_pid = subframe2harqpid(&RC.mac[module_idP]->common_channels[CC_id],frameP,subframeP); harq_pid =
subframe2harqpid(&RC.mac[module_idP]->
common_channels[CC_id], frameP,
subframeP);
// mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL); // mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL);
if(UE_list->UE_sched_ctrl[UE_id].round_UL[CC_id]>0) { if (UE_list->UE_sched_ctrl[UE_id].round_UL[CC_id] > 0) {
nb_allocated_rbs[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb_ul[harq_pid]; nb_allocated_rbs[CC_id][UE_id] =
UE_list->UE_template[CC_id][UE_id].nb_rb_ul[harq_pid];
} else { } else {
nb_allocated_rbs[CC_id][UE_id] = cmin(UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul, average_rbs_per_user[CC_id]); nb_allocated_rbs[CC_id][UE_id] =
cmin(UE_list->
UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul,
average_rbs_per_user[CC_id]);
} }
total_allocated_rbs[CC_id]+= nb_allocated_rbs[CC_id][UE_id]; total_allocated_rbs[CC_id] += nb_allocated_rbs[CC_id][UE_id];
LOG_D(MAC,"In ulsch_preprocessor: assigning %d RBs for UE %d/%x CCid %d, harq_pid %d\n",nb_allocated_rbs[CC_id][UE_id],UE_id,rnti,CC_id,harq_pid); LOG_D(MAC,
"In ulsch_preprocessor: assigning %d RBs for UE %d/%x CCid %d, harq_pid %d\n",
nb_allocated_rbs[CC_id][UE_id], UE_id, rnti, CC_id,
harq_pid);
} }
} }
// step 4: assigne the remaining RBs and set the pre_allocated rbs accordingly // step 4: assigne the remaining RBs and set the pre_allocated rbs accordingly
for(r=0; r<2; r++) { for (r = 0; r < 2; r++) {
for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) { for (i = UE_list->head_ul; i >= 0; i = UE_list->next_ul[i]) {
rnti = UE_RNTI(module_idP,i); rnti = UE_RNTI(module_idP, i);
if (rnti==NOT_A_RNTI) if (rnti == NOT_A_RNTI)
continue; continue;
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
continue; continue;
UE_id = i; UE_id = i;
for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) { for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) {
// This is the actual CC_id in the list // This is the actual CC_id in the list
CC_id = UE_list->ordered_ULCCids[n][UE_id]; CC_id = UE_list->ordered_ULCCids[n][UE_id];
UE_template = &UE_list->UE_template[CC_id][UE_id]; UE_template = &UE_list->UE_template[CC_id][UE_id];
total_remaining_rbs[CC_id]=N_RB_UL - first_rb[CC_id] - total_allocated_rbs[CC_id]; total_remaining_rbs[CC_id] =
N_RB_UL - first_rb[CC_id] - total_allocated_rbs[CC_id];
if (total_ue_count == 1 ) { if (total_ue_count == 1) {
total_remaining_rbs[CC_id]+=1; total_remaining_rbs[CC_id] += 1;
} }
if ( r == 0 ) { if (r == 0) {
while ( (UE_template->pre_allocated_nb_rb_ul > 0 ) && while ((UE_template->pre_allocated_nb_rb_ul > 0) &&
(nb_allocated_rbs[CC_id][UE_id] < UE_template->pre_allocated_nb_rb_ul) && (nb_allocated_rbs[CC_id][UE_id] <
(total_remaining_rbs[CC_id] > 0)) { UE_template->pre_allocated_nb_rb_ul)
nb_allocated_rbs[CC_id][UE_id] = cmin(nb_allocated_rbs[CC_id][UE_id]+1,UE_template->pre_allocated_nb_rb_ul); && (total_remaining_rbs[CC_id] > 0)) {
nb_allocated_rbs[CC_id][UE_id] =
cmin(nb_allocated_rbs[CC_id][UE_id] + 1,
UE_template->pre_allocated_nb_rb_ul);
total_remaining_rbs[CC_id]--; total_remaining_rbs[CC_id]--;
total_allocated_rbs[CC_id]++; total_allocated_rbs[CC_id]++;
} }
} else { } else {
UE_template->pre_allocated_nb_rb_ul= nb_allocated_rbs[CC_id][UE_id]; UE_template->pre_allocated_nb_rb_ul =
LOG_D(MAC,"******************UL Scheduling Information for UE%d CC_id %d ************************\n",UE_id, CC_id); nb_allocated_rbs[CC_id][UE_id];
LOG_D(MAC,"[eNB %d] total RB allocated for UE%d CC_id %d = %d\n", module_idP, UE_id, CC_id, UE_template->pre_allocated_nb_rb_ul); LOG_D(MAC,
"******************UL Scheduling Information for UE%d CC_id %d ************************\n",
UE_id, CC_id);
LOG_D(MAC,
"[eNB %d] total RB allocated for UE%d CC_id %d = %d\n",
module_idP, UE_id, CC_id,
UE_template->pre_allocated_nb_rb_ul);
} }
} }
} }
} }
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
if (total_allocated_rbs[CC_id]>0) { if (total_allocated_rbs[CC_id] > 0) {
LOG_D(MAC,"[eNB %d] total RB allocated for all UEs = %d/%d\n", module_idP, total_allocated_rbs[CC_id], N_RB_UL - first_rb[CC_id]); LOG_D(MAC, "[eNB %d] total RB allocated for all UEs = %d/%d\n",
module_idP, total_allocated_rbs[CC_id],
N_RB_UL - first_rb[CC_id]);
} }
} }
} }
void assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subframeP, uint16_t *first_rb) void
assign_max_mcs_min_rb(module_id_t module_idP, int frameP,
sub_frame_t subframeP, uint16_t * first_rb)
{ {
int i; int i;
uint16_t n,UE_id; uint16_t n, UE_id;
uint8_t CC_id; uint8_t CC_id;
rnti_t rnti = -1; rnti_t rnti = -1;
int mcs; int mcs;
int rb_table_index=0,tbs,tx_power; int rb_table_index = 0, tbs, tx_power;
eNB_MAC_INST *eNB = RC.mac[module_idP]; eNB_MAC_INST *eNB = RC.mac[module_idP];
UE_list_t *UE_list = &eNB->UE_list; UE_list_t *UE_list = &eNB->UE_list;
...@@ -1278,11 +1556,12 @@ void assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subfra ...@@ -1278,11 +1556,12 @@ void assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subfra
int N_RB_UL; int N_RB_UL;
for (i = 0; i < NUMBER_OF_UE_MAX; i++) { for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
if (UE_list->active[i] != TRUE) continue; if (UE_list->active[i] != TRUE)
continue;
rnti = UE_RNTI(module_idP,i); rnti = UE_RNTI(module_idP, i);
if (rnti==NOT_A_RNTI) if (rnti == NOT_A_RNTI)
continue; continue;
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
continue; continue;
...@@ -1294,78 +1573,85 @@ void assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subfra ...@@ -1294,78 +1573,85 @@ void assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subfra
UE_id = i; UE_id = i;
for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) { for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) {
// This is the actual CC_id in the list // This is the actual CC_id in the list
CC_id = UE_list->ordered_ULCCids[n][UE_id]; CC_id = UE_list->ordered_ULCCids[n][UE_id];
if (CC_id >= MAX_NUM_CCs) { if (CC_id >= MAX_NUM_CCs) {
LOG_E( MAC, "CC_id %u should be < %u, loop n=%u < numactiveULCCs[%u]=%u", LOG_E(MAC,
CC_id, "CC_id %u should be < %u, loop n=%u < numactiveULCCs[%u]=%u",
MAX_NUM_CCs, CC_id, MAX_NUM_CCs, n, UE_id,
n,
UE_id,
UE_list->numactiveULCCs[UE_id]); UE_list->numactiveULCCs[UE_id]);
} }
AssertFatal( CC_id < MAX_NUM_CCs, "CC_id %u should be < %u, loop n=%u < numactiveULCCs[%u]=%u", AssertFatal(CC_id < MAX_NUM_CCs,
CC_id, "CC_id %u should be < %u, loop n=%u < numactiveULCCs[%u]=%u",
MAX_NUM_CCs, CC_id, MAX_NUM_CCs, n, UE_id,
n,
UE_id,
UE_list->numactiveULCCs[UE_id]); UE_list->numactiveULCCs[UE_id]);
UE_template = &UE_list->UE_template[CC_id][UE_id]; UE_template = &UE_list->UE_template[CC_id][UE_id];
Ncp = RC.mac[module_idP]->common_channels[CC_id].Ncp; Ncp = RC.mac[module_idP]->common_channels[CC_id].Ncp;
N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth); N_RB_UL =
to_prb(RC.mac[module_idP]->common_channels[CC_id].
ul_Bandwidth);
// if this UE has UL traffic // if this UE has UL traffic
if (UE_template->ul_total_buffer > 0 ) { if (UE_template->ul_total_buffer > 0) {
tbs = get_TBS_UL(mcs,3)<<3; // 1 or 2 PRB with cqi enabled does not work well! tbs = get_TBS_UL(mcs, 3) << 3; // 1 or 2 PRB with cqi enabled does not work well!
rb_table_index = 2; rb_table_index = 2;
// fixme: set use_srs flag // fixme: set use_srs flag
tx_power= estimate_ue_tx_power(tbs,rb_table[rb_table_index],0,Ncp,0); tx_power =
estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0,
Ncp, 0);
while ((((UE_template->phr_info - tx_power) < 0 ) || (tbs > UE_template->ul_total_buffer))&& while ((((UE_template->phr_info - tx_power) < 0)
(mcs > 3)) { || (tbs > UE_template->ul_total_buffer))
&& (mcs > 3)) {
// LOG_I(MAC,"UE_template->phr_info %d tx_power %d mcs %d\n", UE_template->phr_info,tx_power, mcs); // LOG_I(MAC,"UE_template->phr_info %d tx_power %d mcs %d\n", UE_template->phr_info,tx_power, mcs);
mcs--; mcs--;
tbs = get_TBS_UL(mcs,rb_table[rb_table_index])<<3; tbs = get_TBS_UL(mcs, rb_table[rb_table_index]) << 3;
tx_power = estimate_ue_tx_power(tbs,rb_table[rb_table_index],0,Ncp,0); // fixme: set use_srs tx_power = estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0, Ncp, 0); // fixme: set use_srs
} }
while ((tbs < UE_template->ul_total_buffer) && while ((tbs < UE_template->ul_total_buffer) &&
(rb_table[rb_table_index]<(N_RB_UL-first_rb[CC_id])) && (rb_table[rb_table_index] <
((UE_template->phr_info - tx_power) > 0) && (N_RB_UL - first_rb[CC_id]))
(rb_table_index < 32 )) { && ((UE_template->phr_info - tx_power) > 0)
&& (rb_table_index < 32)) {
rb_table_index++; rb_table_index++;
tbs = get_TBS_UL(mcs,rb_table[rb_table_index])<<3; tbs = get_TBS_UL(mcs, rb_table[rb_table_index]) << 3;
tx_power = estimate_ue_tx_power(tbs,rb_table[rb_table_index],0,Ncp,0); tx_power =
estimate_ue_tx_power(tbs, rb_table[rb_table_index],
0, Ncp, 0);
} }
UE_template->ue_tx_power = tx_power; UE_template->ue_tx_power = tx_power;
if (rb_table[rb_table_index]>(N_RB_UL-first_rb[CC_id]-1)) { if (rb_table[rb_table_index] >
(N_RB_UL - first_rb[CC_id] - 1)) {
rb_table_index--; rb_table_index--;
} }
// 1 or 2 PRB with cqi enabled does not work well // 1 or 2 PRB with cqi enabled does not work well
if (rb_table[rb_table_index]<3) { if (rb_table[rb_table_index] < 3) {
rb_table_index=2; //3PRB rb_table_index = 2; //3PRB
} }
UE_template->pre_assigned_mcs_ul=mcs; UE_template->pre_assigned_mcs_ul = mcs;
UE_template->pre_allocated_rb_table_index_ul=rb_table_index; UE_template->pre_allocated_rb_table_index_ul =
UE_template->pre_allocated_nb_rb_ul= rb_table[rb_table_index]; rb_table_index;
LOG_D(MAC,"[eNB %d] frame %d subframe %d: for UE %d CC %d: pre-assigned mcs %d, pre-allocated rb_table[%d]=%d RBs (phr %d, tx power %d)\n", UE_template->pre_allocated_nb_rb_ul =
rb_table[rb_table_index];
LOG_D(MAC,
"[eNB %d] frame %d subframe %d: for UE %d CC %d: pre-assigned mcs %d, pre-allocated rb_table[%d]=%d RBs (phr %d, tx power %d)\n",
module_idP, frameP, subframeP, UE_id, CC_id, module_idP, frameP, subframeP, UE_id, CC_id,
UE_template->pre_assigned_mcs_ul, UE_template->pre_assigned_mcs_ul,
UE_template->pre_allocated_rb_table_index_ul, UE_template->pre_allocated_rb_table_index_ul,
UE_template->pre_allocated_nb_rb_ul, UE_template->pre_allocated_nb_rb_ul,
UE_template->phr_info,tx_power); UE_template->phr_info, tx_power);
} else { } else {
/* if UE has pending scheduling request then pre-allocate 3 RBs */ /* if UE has pending scheduling request then pre-allocate 3 RBs */
//if (UE_template->ul_active == 1 && UE_template->ul_SR == 1) { //if (UE_template->ul_active == 1 && UE_template->ul_SR == 1) {
...@@ -1395,33 +1681,43 @@ static int ue_ul_compare(const void *_a, const void *_b, void *_params) ...@@ -1395,33 +1681,43 @@ static int ue_ul_compare(const void *_a, const void *_b, void *_params)
struct sort_ue_ul_params *params = _params; struct sort_ue_ul_params *params = _params;
UE_list_t *UE_list = &RC.mac[params->module_idP]->UE_list; UE_list_t *UE_list = &RC.mac[params->module_idP]->UE_list;
int UE_id1 = *(const int *)_a; int UE_id1 = *(const int *) _a;
int UE_id2 = *(const int *)_b; int UE_id2 = *(const int *) _b;
int rnti1 = UE_RNTI(params->module_idP, UE_id1); int rnti1 = UE_RNTI(params->module_idP, UE_id1);
int pCCid1 = UE_PCCID(params->module_idP, UE_id1); int pCCid1 = UE_PCCID(params->module_idP, UE_id1);
int round1 = maxround(params->module_idP, rnti1, params->frameP, params->subframeP, 1); int round1 = maxround(params->module_idP, rnti1, params->frameP,
params->subframeP, 1);
int rnti2 = UE_RNTI(params->module_idP, UE_id2); int rnti2 = UE_RNTI(params->module_idP, UE_id2);
int pCCid2 = UE_PCCID(params->module_idP, UE_id2); int pCCid2 = UE_PCCID(params->module_idP, UE_id2);
int round2 = maxround(params->module_idP, rnti2, params->frameP, params->subframeP, 1); int round2 = maxround(params->module_idP, rnti2, params->frameP,
params->subframeP, 1);
if (round1 > round2) return -1; if (round1 > round2)
if (round1 < round2) return 1; return -1;
if (round1 < round2)
return 1;
if (UE_list->UE_template[pCCid1][UE_id1].ul_buffer_info[LCGID0] > UE_list->UE_template[pCCid2][UE_id2].ul_buffer_info[LCGID0]) if (UE_list->UE_template[pCCid1][UE_id1].ul_buffer_info[LCGID0] >
UE_list->UE_template[pCCid2][UE_id2].ul_buffer_info[LCGID0])
return -1; return -1;
if (UE_list->UE_template[pCCid1][UE_id1].ul_buffer_info[LCGID0] < UE_list->UE_template[pCCid2][UE_id2].ul_buffer_info[LCGID0]) if (UE_list->UE_template[pCCid1][UE_id1].ul_buffer_info[LCGID0] <
UE_list->UE_template[pCCid2][UE_id2].ul_buffer_info[LCGID0])
return 1; return 1;
if (UE_list->UE_template[pCCid1][UE_id1].ul_total_buffer > UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer) if (UE_list->UE_template[pCCid1][UE_id1].ul_total_buffer >
UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer)
return -1; return -1;
if (UE_list->UE_template[pCCid1][UE_id1].ul_total_buffer < UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer) if (UE_list->UE_template[pCCid1][UE_id1].ul_total_buffer <
UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer)
return 1; return 1;
if (UE_list->UE_template[pCCid1][UE_id1].pre_assigned_mcs_ul > UE_list->UE_template[pCCid2][UE_id2].pre_assigned_mcs_ul) if (UE_list->UE_template[pCCid1][UE_id1].pre_assigned_mcs_ul >
UE_list->UE_template[pCCid2][UE_id2].pre_assigned_mcs_ul)
return -1; return -1;
if (UE_list->UE_template[pCCid1][UE_id1].pre_assigned_mcs_ul < UE_list->UE_template[pCCid2][UE_id2].pre_assigned_mcs_ul) if (UE_list->UE_template[pCCid1][UE_id1].pre_assigned_mcs_ul <
UE_list->UE_template[pCCid2][UE_id2].pre_assigned_mcs_ul)
return 1; return 1;
return 0; return 0;
...@@ -1431,23 +1727,28 @@ static int ue_ul_compare(const void *_a, const void *_b, void *_params) ...@@ -1431,23 +1727,28 @@ static int ue_ul_compare(const void *_a, const void *_b, void *_params)
* The last case is not handled: "if (UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer > 0 )" * The last case is not handled: "if (UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer > 0 )"
* I don't think it makes a big difference. * I don't think it makes a big difference.
*/ */
if(round2 > round1) { if (round2 > round1) {
swap_UEs(UE_list,UE_id1,UE_id2,1); swap_UEs(UE_list, UE_id1, UE_id2, 1);
} else if (round2 == round1) { } else if (round2 == round1) {
if (UE_list->UE_template[pCCid1][UE_id1].ul_buffer_info[LCGID0] < UE_list->UE_template[pCCid2][UE_id2].ul_buffer_info[LCGID0]) { if (UE_list->UE_template[pCCid1][UE_id1].ul_buffer_info[LCGID0] <
swap_UEs(UE_list,UE_id1,UE_id2,1); UE_list->UE_template[pCCid2][UE_id2].ul_buffer_info[LCGID0]) {
} else if (UE_list->UE_template[pCCid1][UE_id1].ul_total_buffer < UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer) { swap_UEs(UE_list, UE_id1, UE_id2, 1);
swap_UEs(UE_list,UE_id1,UE_id2,1); } else if (UE_list->UE_template[pCCid1][UE_id1].ul_total_buffer <
} else if (UE_list->UE_template[pCCid1][UE_id1].pre_assigned_mcs_ul < UE_list->UE_template[pCCid2][UE_id2].pre_assigned_mcs_ul) { UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer) {
if (UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer > 0 ) { swap_UEs(UE_list, UE_id1, UE_id2, 1);
swap_UEs(UE_list,UE_id1,UE_id2,1); } else if (UE_list->UE_template[pCCid1][UE_id1].
pre_assigned_mcs_ul <
UE_list->UE_template[pCCid2][UE_id2].
pre_assigned_mcs_ul) {
if (UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer > 0) {
swap_UEs(UE_list, UE_id1, UE_id2, 1);
} }
} }
} }
#endif #endif
} }
void sort_ue_ul (module_id_t module_idP,int frameP, sub_frame_t subframeP) void sort_ue_ul(module_id_t module_idP, int frameP, sub_frame_t subframeP)
{ {
int i; int i;
int list[NUMBER_OF_UE_MAX]; int list[NUMBER_OF_UE_MAX];
...@@ -1458,9 +1759,12 @@ void sort_ue_ul (module_id_t module_idP,int frameP, sub_frame_t subframeP) ...@@ -1458,9 +1759,12 @@ void sort_ue_ul (module_id_t module_idP,int frameP, sub_frame_t subframeP)
UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; UE_list_t *UE_list = &RC.mac[module_idP]->UE_list;
for (i = 0; i < NUMBER_OF_UE_MAX; i++) { for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
if (UE_list->active[i] == FALSE) continue; if (UE_list->active[i] == FALSE)
if ((rnti = UE_RNTI(module_idP, i)) == NOT_A_RNTI) continue; continue;
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; if ((rnti = UE_RNTI(module_idP, i)) == NOT_A_RNTI)
continue;
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
continue;
list[list_size] = i; list[list_size] = i;
list_size++; list_size++;
...@@ -1469,62 +1773,74 @@ void sort_ue_ul (module_id_t module_idP,int frameP, sub_frame_t subframeP) ...@@ -1469,62 +1773,74 @@ void sort_ue_ul (module_id_t module_idP,int frameP, sub_frame_t subframeP)
qsort_r(list, list_size, sizeof(int), ue_ul_compare, &params); qsort_r(list, list_size, sizeof(int), ue_ul_compare, &params);
if (list_size) { if (list_size) {
for (i = 0; i < list_size-1; i++) for (i = 0; i < list_size - 1; i++)
UE_list->next_ul[list[i]] = list[i+1]; UE_list->next_ul[list[i]] = list[i + 1];
UE_list->next_ul[list[list_size-1]] = -1; UE_list->next_ul[list[list_size - 1]] = -1;
UE_list->head_ul = list[0]; UE_list->head_ul = list[0];
} else { } else {
UE_list->head_ul = -1; UE_list->head_ul = -1;
} }
#if 0 #if 0
int UE_id1,UE_id2; int UE_id1, UE_id2;
int pCCid1,pCCid2; int pCCid1, pCCid2;
int round1,round2; int round1, round2;
int i=0,ii=0; int i = 0, ii = 0;
rnti_t rnti1,rnti2; rnti_t rnti1, rnti2;
UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; UE_list_t *UE_list = &RC.mac[module_idP]->UE_list;
for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) { for (i = UE_list->head_ul; i >= 0; i = UE_list->next_ul[i]) {
//LOG_I(MAC,"sort ue ul i %d\n",i); //LOG_I(MAC,"sort ue ul i %d\n",i);
for (ii=UE_list->next_ul[i]; ii>=0; ii=UE_list->next_ul[ii]) { for (ii = UE_list->next_ul[i]; ii >= 0; ii = UE_list->next_ul[ii]) {
//LOG_I(MAC,"sort ul ue 2 ii %d\n",ii); //LOG_I(MAC,"sort ul ue 2 ii %d\n",ii);
UE_id1 = i; UE_id1 = i;
rnti1 = UE_RNTI(module_idP,UE_id1); rnti1 = UE_RNTI(module_idP, UE_id1);
if(rnti1 == NOT_A_RNTI) if (rnti1 == NOT_A_RNTI)
continue; continue;
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
continue; continue;
pCCid1 = UE_PCCID(module_idP,UE_id1); pCCid1 = UE_PCCID(module_idP, UE_id1);
round1 = maxround(module_idP,rnti1,frameP,subframeP,1); round1 = maxround(module_idP, rnti1, frameP, subframeP, 1);
UE_id2 = ii; UE_id2 = ii;
rnti2 = UE_RNTI(module_idP,UE_id2); rnti2 = UE_RNTI(module_idP, UE_id2);
if(rnti2 == NOT_A_RNTI) if (rnti2 == NOT_A_RNTI)
continue; continue;
if (UE_list->UE_sched_ctrl[UE_id2].ul_out_of_sync == 1) if (UE_list->UE_sched_ctrl[UE_id2].ul_out_of_sync == 1)
continue; continue;
pCCid2 = UE_PCCID(module_idP,UE_id2); pCCid2 = UE_PCCID(module_idP, UE_id2);
round2 = maxround(module_idP,rnti2,frameP,subframeP,1); round2 = maxround(module_idP, rnti2, frameP, subframeP, 1);
if(round2 > round1) { if (round2 > round1) {
swap_UEs(UE_list,UE_id1,UE_id2,1); swap_UEs(UE_list, UE_id1, UE_id2, 1);
} else if (round2 == round1) { } else if (round2 == round1) {
if (UE_list->UE_template[pCCid1][UE_id1].ul_buffer_info[LCGID0] < UE_list->UE_template[pCCid2][UE_id2].ul_buffer_info[LCGID0]) { if (UE_list->
swap_UEs(UE_list,UE_id1,UE_id2,1); UE_template[pCCid1][UE_id1].ul_buffer_info[LCGID0] <
} else if (UE_list->UE_template[pCCid1][UE_id1].ul_total_buffer < UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer) { UE_list->UE_template[pCCid2][UE_id2].
swap_UEs(UE_list,UE_id1,UE_id2,1); ul_buffer_info[LCGID0]) {
} else if (UE_list->UE_template[pCCid1][UE_id1].pre_assigned_mcs_ul < UE_list->UE_template[pCCid2][UE_id2].pre_assigned_mcs_ul) { swap_UEs(UE_list, UE_id1, UE_id2, 1);
if (UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer > 0 ) { } else if (UE_list->UE_template[pCCid1][UE_id1].
swap_UEs(UE_list,UE_id1,UE_id2,1); ul_total_buffer <
UE_list->UE_template[pCCid2][UE_id2].
ul_total_buffer) {
swap_UEs(UE_list, UE_id1, UE_id2, 1);
} else if (UE_list->
UE_template[pCCid1][UE_id1].pre_assigned_mcs_ul
<
UE_list->
UE_template[pCCid2][UE_id2].pre_assigned_mcs_ul)
{
if (UE_list->UE_template[pCCid2][UE_id2].
ul_total_buffer > 0) {
swap_UEs(UE_list, UE_id1, UE_id2, 1);
} }
} }
} }
......
...@@ -44,11 +44,10 @@ ...@@ -44,11 +44,10 @@
*/ */
void schedule_mib(module_id_t module_idP, void schedule_mib(module_id_t module_idP,
frame_t frameP, frame_t frameP, sub_frame_t subframeP);
sub_frame_t subframeP);
/** \fn void schedule_RA(module_id_t module_idP,frame_t frameP,sub_frame_t subframe); /** \fn void schedule_RA(module_id_t module_idP,frame_t frameP,sub_frame_t subframe);
\brief First stage of Random-Access Scheduling. Loops over the RA_templates and checks if RAR, Msg3 or its retransmission are to be scheduled in the subframe. It returns the total number of PRB used for RA SDUs. For Msg3 it retrieves the L3msg from RRC and fills the appropriate buffers. For the others it just computes the number of PRBs. Each DCI uses 3 PRBs (format 1A) \brief First stage of Random-Access Scheduling. Loops over the ras and checks if RAR, Msg3 or its retransmission are to be scheduled in the subframe. It returns the total number of PRB used for RA SDUs. For Msg3 it retrieves the L3msg from RRC and fills the appropriate buffers. For the others it just computes the number of PRBs. Each DCI uses 3 PRBs (format 1A)
for the message. for the message.
@param Mod_id Instance ID of eNB @param Mod_id Instance ID of eNB
@param frame Frame index @param frame Frame index
...@@ -56,28 +55,32 @@ for the message. ...@@ -56,28 +55,32 @@ for the message.
*/ */
void schedule_RA(module_id_t module_idP,frame_t frameP,sub_frame_t subframe); void schedule_RA(module_id_t module_idP, frame_t frameP,
sub_frame_t subframe);
/** \brief First stage of SI Scheduling. Gets a SI SDU from RRC if available and computes the MCS required to transport it as a function of the SDU length. It assumes a length less than or equal to 64 bytes (MCS 6, 3 PRBs). /** \brief First stage of SI Scheduling. Gets a SI SDU from RRC if available and computes the MCS required to transport it as a function of the SDU length. It assumes a length less than or equal to 64 bytes (MCS 6, 3 PRBs).
@param Mod_id Instance ID of eNB @param Mod_id Instance ID of eNB
@param frame Frame index @param frame Frame index
@param subframe Subframe number on which to act @param subframe Subframe number on which to act
*/ */
void schedule_SI(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP); void schedule_SI(module_id_t module_idP, frame_t frameP,
sub_frame_t subframeP);
/** \brief MBMS scheduling: Checking the position for MBSFN subframes. Create MSI, transfer MCCH from RRC to MAC, transfer MTCHs from RLC to MAC. Multiplexing MSI,MCCH&MTCHs. Return 1 if there are MBSFN data being allocated, otherwise return 0; /** \brief MBMS scheduling: Checking the position for MBSFN subframes. Create MSI, transfer MCCH from RRC to MAC, transfer MTCHs from RLC to MAC. Multiplexing MSI,MCCH&MTCHs. Return 1 if there are MBSFN data being allocated, otherwise return 0;
@param Mod_id Instance ID of eNB @param Mod_id Instance ID of eNB
@param frame Frame index @param frame Frame index
@param subframe Subframe number on which to act @param subframe Subframe number on which to act
*/ */
int schedule_MBMS(module_id_t module_idP,uint8_t CC_id, frame_t frameP, sub_frame_t subframe); int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
sub_frame_t subframe);
/** \brief check the mapping between sf allocation and sync area, Currently only supports 1:1 mapping /** \brief check the mapping between sf allocation and sync area, Currently only supports 1:1 mapping
@param Mod_id Instance ID of eNB @param Mod_id Instance ID of eNB
@param mbsfn_sync_area index of mbsfn sync area @param mbsfn_sync_area index of mbsfn sync area
@param[out] index of sf pattern @param[out] index of sf pattern
*/ */
int8_t get_mbsfn_sf_alloction (module_id_t module_idP, uint8_t CC_id, uint8_t mbsfn_sync_area); int8_t get_mbsfn_sf_alloction(module_id_t module_idP, uint8_t CC_id,
uint8_t mbsfn_sync_area);
/** \brief check the mapping between sf allocation and sync area, Currently only supports 1:1 mapping /** \brief check the mapping between sf allocation and sync area, Currently only supports 1:1 mapping
@param Mod_id Instance ID of eNB @param Mod_id Instance ID of eNB
...@@ -85,14 +88,17 @@ int8_t get_mbsfn_sf_alloction (module_id_t module_idP, uint8_t CC_id, uint8_t mb ...@@ -85,14 +88,17 @@ int8_t get_mbsfn_sf_alloction (module_id_t module_idP, uint8_t CC_id, uint8_t mb
@param eNB_index index of eNB @param eNB_index index of eNB
@param[out] index of sf pattern @param[out] index of sf pattern
*/ */
int8_t ue_get_mbsfn_sf_alloction (module_id_t module_idP, uint8_t mbsfn_sync_area, unsigned char eNB_index); int8_t ue_get_mbsfn_sf_alloction(module_id_t module_idP,
uint8_t mbsfn_sync_area,
unsigned char eNB_index);
/** \brief top ULSCH Scheduling for TDD (config 1-6). /** \brief top ULSCH Scheduling for TDD (config 1-6).
@param Mod_id Instance ID of eNB @param Mod_id Instance ID of eNB
@param frame Frame index @param frame Frame index
@param subframe Subframe number on which to act @param subframe Subframe number on which to act
*/ */
void schedule_ulsch(module_id_t module_idP,frame_t frameP,sub_frame_t subframe); void schedule_ulsch(module_id_t module_idP, frame_t frameP,
sub_frame_t subframe);
/** \brief ULSCH Scheduling per RNTI /** \brief ULSCH Scheduling per RNTI
@param Mod_id Instance ID of eNB @param Mod_id Instance ID of eNB
...@@ -100,7 +106,10 @@ void schedule_ulsch(module_id_t module_idP,frame_t frameP,sub_frame_t subframe); ...@@ -100,7 +106,10 @@ void schedule_ulsch(module_id_t module_idP,frame_t frameP,sub_frame_t subframe);
@param subframe Subframe number on which to act @param subframe Subframe number on which to act
@param sched_subframe Subframe number where PUSCH is transmitted (for DAI lookup) @param sched_subframe Subframe number where PUSCH is transmitted (for DAI lookup)
*/ */
void schedule_ulsch_rnti(module_id_t module_idP, frame_t frameP, sub_frame_t subframe, unsigned char sched_subframe, uint16_t *first_rb); void schedule_ulsch_rnti(module_id_t module_idP, frame_t frameP,
sub_frame_t subframe,
unsigned char sched_subframe,
uint16_t * first_rb);
/** \brief Second stage of DLSCH scheduling, after schedule_SI, schedule_RA and schedule_dlsch have been called. This routine first allocates random frequency assignments for SI and RA SDUs using distributed VRB allocations and adds the corresponding DCI SDU to the DCI buffer for PHY. It then loops over the UE specific DCIs previously allocated and fills in the remaining DCI fields related to frequency allocation. It assumes localized allocation of type 0 (DCI.rah=0). The allocation is done for tranmission modes 1,2,4. /** \brief Second stage of DLSCH scheduling, after schedule_SI, schedule_RA and schedule_dlsch have been called. This routine first allocates random frequency assignments for SI and RA SDUs using distributed VRB allocations and adds the corresponding DCI SDU to the DCI buffer for PHY. It then loops over the UE specific DCIs previously allocated and fills in the remaining DCI fields related to frequency allocation. It assumes localized allocation of type 0 (DCI.rah=0). The allocation is done for tranmission modes 1,2,4.
@param Mod_id Instance of eNB @param Mod_id Instance of eNB
...@@ -108,7 +117,8 @@ void schedule_ulsch_rnti(module_id_t module_idP, frame_t frameP, sub_frame_t sub ...@@ -108,7 +117,8 @@ void schedule_ulsch_rnti(module_id_t module_idP, frame_t frameP, sub_frame_t sub
@param subframe Index of subframe @param subframe Index of subframe
@param mbsfn_flag Indicates that this subframe is for MCH/MCCH @param mbsfn_flag Indicates that this subframe is for MCH/MCCH
*/ */
void fill_DLSCH_dci(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,int *mbsfn_flag); void fill_DLSCH_dci(module_id_t module_idP, frame_t frameP,
sub_frame_t subframe, int *mbsfn_flag);
/** \brief UE specific DLSCH scheduling. Retrieves next ue to be schduled from round-robin scheduler and gets the appropriate harq_pid for the subframe from PHY. If the process is active and requires a retransmission, it schedules the retransmission with the same PRB count and MCS as the first transmission. Otherwise it consults RLC for DCCH/DTCH SDUs (status with maximum number of available PRBS), builds the MAC header (timing advance sent by default) and copies /** \brief UE specific DLSCH scheduling. Retrieves next ue to be schduled from round-robin scheduler and gets the appropriate harq_pid for the subframe from PHY. If the process is active and requires a retransmission, it schedules the retransmission with the same PRB count and MCS as the first transmission. Otherwise it consults RLC for DCCH/DTCH SDUs (status with maximum number of available PRBS), builds the MAC header (timing advance sent by default) and copies
@param Mod_id Instance ID of eNB @param Mod_id Instance ID of eNB
...@@ -117,39 +127,43 @@ void fill_DLSCH_dci(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,i ...@@ -117,39 +127,43 @@ void fill_DLSCH_dci(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,i
@param mbsfn_flag Indicates that MCH/MCCH is in this subframe @param mbsfn_flag Indicates that MCH/MCCH is in this subframe
*/ */
void schedule_ue_spec(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,int *mbsfn_flag); void schedule_ue_spec(module_id_t module_idP, frame_t frameP,
sub_frame_t subframe, int *mbsfn_flag);
/** \brief Function for UE/PHY to compute PUSCH transmit power in power-control procedure. /** \brief Function for UE/PHY to compute PUSCH transmit power in power-control procedure.
@param Mod_id Module id of UE @param Mod_id Module id of UE
@returns Po_NOMINAL_PUSCH (PREAMBLE_RECEIVED_TARGET_POWER+DELTA_PREAMBLE @returns Po_NOMINAL_PUSCH (PREAMBLE_RECEIVED_TARGET_POWER+DELTA_PREAMBLE
*/ */
int8_t get_Po_NOMINAL_PUSCH(module_id_t module_idP,uint8_t CC_id); int8_t get_Po_NOMINAL_PUSCH(module_id_t module_idP, uint8_t CC_id);
/** \brief Function to compute DELTA_PREAMBLE from 36.321 (for RA power ramping procedure and Msg3 PUSCH power control policy) /** \brief Function to compute DELTA_PREAMBLE from 36.321 (for RA power ramping procedure and Msg3 PUSCH power control policy)
@param Mod_id Module id of UE @param Mod_id Module id of UE
@returns DELTA_PREAMBLE @returns DELTA_PREAMBLE
*/ */
int8_t get_DELTA_PREAMBLE(module_id_t module_idP,int CC_id); int8_t get_DELTA_PREAMBLE(module_id_t module_idP, int CC_id);
/** \brief Function for compute deltaP_rampup from 36.321 (for RA power ramping procedure and Msg3 PUSCH power control policy) /** \brief Function for compute deltaP_rampup from 36.321 (for RA power ramping procedure and Msg3 PUSCH power control policy)
@param Mod_id Module id of UE @param Mod_id Module id of UE
@param CC_id carrier component id of UE @param CC_id carrier component id of UE
@returns deltaP_rampup @returns deltaP_rampup
*/ */
int8_t get_deltaP_rampup(module_id_t module_idP,uint8_t CC_id); int8_t get_deltaP_rampup(module_id_t module_idP, uint8_t CC_id);
uint16_t mac_computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs); uint16_t mac_computeRIV(uint16_t N_RB_DL, uint16_t RBstart,
uint16_t Lcrbs);
void add_msg3(module_id_t module_idP,int CC_id, RA_TEMPLATE *RA_template, frame_t frameP, sub_frame_t subframeP); void add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP,
sub_frame_t subframeP);
//main.c //main.c
int mac_top_init(int eMBMS_active, char *uecap_xer,uint8_t cba_group_active, uint8_t HO_active); int mac_top_init(int eMBMS_active, char *uecap_xer,
uint8_t cba_group_active, uint8_t HO_active);
void mac_top_init_eNB(void); void mac_top_init_eNB(void);
void mac_init_cell_params(int Mod_idP,int CC_idP); void mac_init_cell_params(int Mod_idP, int CC_idP);
char layer2_init_UE(module_id_t module_idP); char layer2_init_UE(module_id_t module_idP);
...@@ -161,19 +175,29 @@ int mac_init_global_param(void); ...@@ -161,19 +175,29 @@ int mac_init_global_param(void);
void mac_top_cleanup(void); void mac_top_cleanup(void);
void mac_UE_out_of_sync_ind(module_id_t module_idP,frame_t frameP, uint16_t eNB_index); void mac_UE_out_of_sync_ind(module_id_t module_idP, frame_t frameP,
uint16_t eNB_index);
void clear_nfapi_information(eNB_MAC_INST *eNB,int CC_idP,frame_t frameP,sub_frame_t subframeP); void clear_nfapi_information(eNB_MAC_INST * eNB, int CC_idP,
frame_t frameP, sub_frame_t subframeP);
void dlsch_scheduler_pre_processor_reset (int module_idP,int UE_id, void dlsch_scheduler_pre_processor_reset(int module_idP, int UE_id,
uint8_t CC_id, uint8_t CC_id,
int frameP, int frameP,
int subframeP, int subframeP,
int N_RBG, int N_RBG,
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], uint16_t
uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX], nb_rbs_required[MAX_NUM_CCs]
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX], [NUMBER_OF_UE_MAX],
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]); uint16_t
nb_rbs_required_remaining
[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
unsigned char
rballoc_sub[MAX_NUM_CCs]
[N_RBG_MAX],
unsigned char
MIMO_mode_indicator[MAX_NUM_CCs]
[N_RBG_MAX]);
// eNB functions // eNB functions
/* \brief This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done /* \brief This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done
...@@ -184,24 +208,33 @@ void dlsch_scheduler_pre_processor_reset (int module_idP,int UE_id, ...@@ -184,24 +208,33 @@ void dlsch_scheduler_pre_processor_reset (int module_idP,int UE_id,
*/ */
void dlsch_scheduler_pre_processor (module_id_t module_idP, void dlsch_scheduler_pre_processor(module_id_t module_idP,
frame_t frameP, frame_t frameP,
sub_frame_t subframe, sub_frame_t subframe,
int N_RBG[MAX_NUM_CCs], int N_RBG[MAX_NUM_CCs],
int *mbsfn_flag); int *mbsfn_flag);
void dlsch_scheduler_pre_processor_allocate (module_id_t Mod_id, void dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id,
int UE_id, int UE_id,
uint8_t CC_id, uint8_t CC_id,
int N_RBG, int N_RBG,
int transmission_mode, int transmission_mode,
int min_rb_unit, int min_rb_unit,
uint8_t N_RB_DL, uint8_t N_RB_DL,
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], uint16_t
uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX], nb_rbs_required[MAX_NUM_CCs]
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX], [NUMBER_OF_UE_MAX],
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]); uint16_t
nb_rbs_required_remaining
[MAX_NUM_CCs]
[NUMBER_OF_UE_MAX],
unsigned char
rballoc_sub[MAX_NUM_CCs]
[N_RBG_MAX],
unsigned char
MIMO_mode_indicator
[MAX_NUM_CCs][N_RBG_MAX]);
/* \brief Function to trigger the eNB scheduling procedure. It is called by PHY at the beginning of each subframe, \f$n$\f /* \brief Function to trigger the eNB scheduling procedure. It is called by PHY at the beginning of each subframe, \f$n$\f
and generates all DLSCH allocations for subframe \f$n\f$ and ULSCH allocations for subframe \f$n+k$\f. and generates all DLSCH allocations for subframe \f$n\f$ and ULSCH allocations for subframe \f$n+k$\f.
...@@ -209,7 +242,7 @@ void dlsch_scheduler_pre_processor_allocate (module_id_t Mod_id, ...@@ -209,7 +242,7 @@ void dlsch_scheduler_pre_processor_allocate (module_id_t Mod_id,
@param subframe Index of current subframe @param subframe Index of current subframe
@param calibration_flag Flag to indicate that eNB scheduler should schedule TDD auto-calibration PUSCH. @param calibration_flag Flag to indicate that eNB scheduler should schedule TDD auto-calibration PUSCH.
*/ */
void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP);//, int calibration_flag); void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP); //, int calibration_flag);
/* \brief Function to indicate a received preamble on PRACH. It initiates the RA procedure. /* \brief Function to indicate a received preamble on PRACH. It initiates the RA procedure.
@param Mod_id Instance ID of eNB @param Mod_id Instance ID of eNB
...@@ -218,10 +251,11 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame ...@@ -218,10 +251,11 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame
@param rnti RA rnti corresponding to this PRACH preamble @param rnti RA rnti corresponding to this PRACH preamble
@param rach_resource type (0=non BL/CE,1 CE level 0,2 CE level 1, 3 CE level 2,4 CE level 3) @param rach_resource type (0=non BL/CE,1 CE level 0,2 CE level 1, 3 CE level 2,4 CE level 3)
*/ */
void initiate_ra_proc(module_id_t module_idP,int CC_id,frame_t frameP, sub_frame_t subframeP, uint16_t preamble_index,int16_t timing_offset,uint16_t rnti void initiate_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP,
sub_frame_t subframeP, uint16_t preamble_index,
int16_t timing_offset, uint16_t rnti
#ifdef Rel14 #ifdef Rel14
, , uint8_t rach_resource_type
uint8_t rach_resource_type
#endif #endif
); );
...@@ -231,31 +265,30 @@ void initiate_ra_proc(module_id_t module_idP,int CC_id,frame_t frameP, sub_frame ...@@ -231,31 +265,30 @@ void initiate_ra_proc(module_id_t module_idP,int CC_id,frame_t frameP, sub_frame
@param N_RB_UL Number of UL resource blocks @param N_RB_UL Number of UL resource blocks
@returns t_CRNTI @returns t_CRNTI
*/ */
unsigned short fill_rar( unsigned short fill_rar(const module_id_t module_idP,
const module_id_t module_idP,
const int CC_id, const int CC_id,
RA_t *ra,
const frame_t frameP, const frame_t frameP,
uint8_t * const dlsch_buffer, uint8_t * const dlsch_buffer,
const uint16_t N_RB_UL, const uint16_t N_RB_UL,
const uint8_t input_buffer_length const uint8_t input_buffer_length);
);
#ifdef Rel14 #ifdef Rel14
unsigned short fill_rar_br(eNB_MAC_INST *eNB, unsigned short fill_rar_br(eNB_MAC_INST * eNB,
int CC_id, int CC_id,
RA_TEMPLATE *RA_template, RA_t * ra,
const frame_t frameP, const frame_t frameP,
const sub_frame_t subframeP, const sub_frame_t subframeP,
uint8_t* const dlsch_buffer, uint8_t * const dlsch_buffer,
const uint8_t ce_level const uint8_t ce_level);
);
#endif #endif
/* \brief Function to indicate a failed RA response. It removes all temporary variables related to the initial connection of a UE /* \brief Function to indicate a failed RA response. It removes all temporary variables related to the initial connection of a UE
@param Mod_id Instance ID of eNB @param Mod_id Instance ID of eNB
@param preamble_index index of the received RA request. @param preamble_index index of the received RA request.
*/ */
void cancel_ra_proc(module_id_t module_idP,int CC_id,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 used by PHY to inform MAC that an uplink is scheduled /* \brief Function used by PHY to inform MAC that an uplink is scheduled
for Msg3 in given subframe. This is used so that the MAC for Msg3 in given subframe. This is used so that the MAC
...@@ -272,9 +305,7 @@ void set_msg3_subframe(module_id_t Mod_id, ...@@ -272,9 +305,7 @@ void set_msg3_subframe(module_id_t Mod_id,
int CC_id, int CC_id,
int frame, int frame,
int subframe, int subframe,
int rnti, int rnti, int Msg3_frame, int Msg3_subframe);
int Msg3_frame,
int Msg3_subframe);
/* \brief Function to indicate a received SDU on ULSCH. /* \brief Function to indicate a received SDU on ULSCH.
@param Mod_id Instance ID of eNB @param Mod_id Instance ID of eNB
...@@ -290,10 +321,9 @@ void rx_sdu(const module_id_t enb_mod_idP, ...@@ -290,10 +321,9 @@ void rx_sdu(const module_id_t enb_mod_idP,
const frame_t frameP, const frame_t frameP,
const sub_frame_t subframeP, const sub_frame_t subframeP,
const rnti_t rntiP, const rnti_t rntiP,
uint8_t *sduP, uint8_t * sduP,
const uint16_t sdu_lenP, const uint16_t sdu_lenP,
const uint16_t timing_advance, const uint16_t timing_advance, const uint8_t ul_cqi);
const uint8_t ul_cqi);
/* \brief Function to indicate a scheduled schduling request (SR) was received by eNB. /* \brief Function to indicate a scheduled schduling request (SR) was received by eNB.
...@@ -304,7 +334,8 @@ void rx_sdu(const module_id_t enb_mod_idP, ...@@ -304,7 +334,8 @@ void rx_sdu(const module_id_t enb_mod_idP,
@param rnti RNTI of UE transmitting the SR @param rnti RNTI of UE transmitting the SR
@param ul_cqi SNR measurement of PUCCH (SNR quantized to 8 bits, -64 ... 63.5 dB in .5dB steps) @param ul_cqi SNR measurement of PUCCH (SNR quantized to 8 bits, -64 ... 63.5 dB in .5dB steps)
*/ */
void SR_indication(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subframe,rnti_t rnti,uint8_t ul_cqi); void SR_indication(module_id_t module_idP, int CC_id, frame_t frameP,
sub_frame_t subframe, rnti_t rnti, uint8_t ul_cqi);
/* \brief Function to indicate a UL failure was detected by eNB PHY. /* \brief Function to indicate a UL failure was detected by eNB PHY.
@param Mod_id Instance ID of eNB @param Mod_id Instance ID of eNB
...@@ -313,7 +344,8 @@ void SR_indication(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t s ...@@ -313,7 +344,8 @@ void SR_indication(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t s
@param rnti RNTI of UE transmitting the SR @param rnti RNTI of UE transmitting the SR
@param subframe Index of subframe where SR was received @param subframe Index of subframe where SR was received
*/ */
void UL_failure_indication(module_id_t Mod_id,int CC_id,frame_t frameP,rnti_t rnti,sub_frame_t subframe); void UL_failure_indication(module_id_t Mod_id, int CC_id, frame_t frameP,
rnti_t rnti, sub_frame_t subframe);
/* \brief Function to indicate an HARQ ACK/NAK. /* \brief Function to indicate an HARQ ACK/NAK.
@param Mod_id Instance ID of eNB @param Mod_id Instance ID of eNB
...@@ -322,7 +354,9 @@ void UL_failure_indication(module_id_t Mod_id,int CC_id,frame_t frameP,rnti_t rn ...@@ -322,7 +354,9 @@ void UL_failure_indication(module_id_t Mod_id,int CC_id,frame_t frameP,rnti_t rn
@param subframeP subframe index @param subframeP subframe index
@param harq_pdu NFAPI HARQ PDU descriptor @param harq_pdu NFAPI HARQ PDU descriptor
*/ */
void harq_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, sub_frame_t subframeP, nfapi_harq_indication_pdu_t *harq_pdu); void harq_indication(module_id_t mod_idP, int CC_idP, frame_t frameP,
sub_frame_t subframeP,
nfapi_harq_indication_pdu_t * harq_pdu);
/* \brief Function to indicate a received CQI pdu /* \brief Function to indicate a received CQI pdu
@param Mod_id Instance ID of eNB @param Mod_id Instance ID of eNB
...@@ -332,11 +366,13 @@ void harq_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, sub_frame_ ...@@ -332,11 +366,13 @@ void harq_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, sub_frame_
@param rntiP RNTI of incoming CQI information @param rntiP RNTI of incoming CQI information
@param ul_cqi_information NFAPI UL CQI measurement @param ul_cqi_information NFAPI UL CQI measurement
*/ */
void cqi_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, sub_frame_t subframeP, rnti_t rntiP, void cqi_indication(module_id_t mod_idP, int CC_idP, frame_t frameP,
nfapi_cqi_indication_rel9_t *rel9,uint8_t *pdu, sub_frame_t subframeP, rnti_t rntiP,
nfapi_ul_cqi_information_t *ul_cqi_information); nfapi_cqi_indication_rel9_t * rel9, uint8_t * pdu,
nfapi_ul_cqi_information_t * ul_cqi_information);
uint8_t *get_dlsch_sdu(module_id_t module_idP,int CC_id,frame_t frameP,rnti_t rnti,uint8_t TBindex); uint8_t *get_dlsch_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
rnti_t rnti, uint8_t TBindex);
/* \brief Function to retrieve MCH transport block and MCS used for MCH in this MBSFN subframe. Returns null if no MCH is to be transmitted /* \brief Function to retrieve MCH transport block and MCS used for MCH in this MBSFN subframe. Returns null if no MCH is to be transmitted
@param Mod_id Instance ID of eNB @param Mod_id Instance ID of eNB
...@@ -345,28 +381,31 @@ uint8_t *get_dlsch_sdu(module_id_t module_idP,int CC_id,frame_t frameP,rnti_t rn ...@@ -345,28 +381,31 @@ uint8_t *get_dlsch_sdu(module_id_t module_idP,int CC_id,frame_t frameP,rnti_t rn
@param mcs Pointer to mcs used by PHY (to be filled by MAC) @param mcs Pointer to mcs used by PHY (to be filled by MAC)
@returns Pointer to MCH transport block and mcs for subframe @returns Pointer to MCH transport block and mcs for subframe
*/ */
MCH_PDU *get_mch_sdu( module_id_t Mod_id, int CC_id, frame_t frame, sub_frame_t subframe); MCH_PDU *get_mch_sdu(module_id_t Mod_id, int CC_id, frame_t frame,
sub_frame_t subframe);
void ue_mac_reset (module_id_t module_idP,uint8_t eNB_index); void ue_mac_reset(module_id_t module_idP, uint8_t eNB_index);
void ue_init_mac (module_id_t module_idP); void ue_init_mac(module_id_t module_idP);
void init_ue_sched_info(void); void init_ue_sched_info(void);
void add_ue_ulsch_info (module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframe,UE_ULSCH_STATUS status); void add_ue_ulsch_info(module_id_t module_idP, int CC_id, int UE_id,
void add_ue_dlsch_info (module_id_t module_idP, int CC_id,int UE_id, sub_frame_t subframe,UE_DLSCH_STATUS status); sub_frame_t subframe, UE_ULSCH_STATUS status);
int find_UE_id (module_id_t module_idP, rnti_t rnti) ; void add_ue_dlsch_info(module_id_t module_idP, int CC_id, int UE_id,
int find_RA_id (module_id_t mod_idP, int CC_idP, rnti_t rntiP); sub_frame_t subframe, UE_DLSCH_STATUS status);
rnti_t UE_RNTI (module_id_t module_idP, int UE_id); int find_UE_id(module_id_t module_idP, rnti_t rnti);
int UE_PCCID (module_id_t module_idP, int UE_id); int find_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP);
uint8_t find_active_UEs (module_id_t module_idP); rnti_t UE_RNTI(module_id_t module_idP, int UE_id);
boolean_t is_UE_active (module_id_t module_idP, int UE_id); int UE_PCCID(module_id_t module_idP, int UE_id);
uint8_t get_aggregation (uint8_t bw_index, uint8_t cqi, uint8_t dci_fmt); uint8_t find_active_UEs(module_id_t module_idP);
boolean_t is_UE_active(module_id_t module_idP, int UE_id);
uint8_t get_aggregation(uint8_t bw_index, uint8_t cqi, uint8_t dci_fmt);
int8_t find_active_UEs_with_traffic(module_id_t module_idP); int8_t find_active_UEs_with_traffic(module_id_t module_idP);
void init_CCE_table(int module_idP,int CC_idP); void init_CCE_table(int module_idP, int CC_idP);
int get_nCCE_offset(int *CCE_table, int get_nCCE_offset(int *CCE_table,
const unsigned char L, const unsigned char L,
...@@ -375,39 +414,37 @@ int get_nCCE_offset(int *CCE_table, ...@@ -375,39 +414,37 @@ int get_nCCE_offset(int *CCE_table,
const unsigned short rnti, const unsigned short rnti,
const unsigned char subframe); const unsigned char subframe);
int allocate_CCEs(int module_idP, int allocate_CCEs(int module_idP, int CC_idP, int subframe, int test_only);
int CC_idP,
int subframe,
int test_only);
boolean_t CCE_allocation_infeasible(int module_idP, boolean_t CCE_allocation_infeasible(int module_idP,
int CC_idP, int CC_idP,
int common_flag, int common_flag,
int subframe, int subframe,
int aggregation, int aggregation, int rnti);
int rnti);
void set_ue_dai(sub_frame_t subframeP, void set_ue_dai(sub_frame_t subframeP,
int UE_id, int UE_id,
uint8_t CC_id, uint8_t CC_id, uint8_t tdd_config, UE_list_t * UE_list);
uint8_t tdd_config,
UE_list_t *UE_list);
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,
uint8_t UE_is_to_be_scheduled(module_id_t module_idP,int CC_id,uint8_t UE_id); unsigned char group_id);
uint8_t UE_is_to_be_scheduled(module_id_t module_idP, int CC_id,
uint8_t UE_id);
/** \brief Round-robin scheduler for ULSCH traffic. /** \brief Round-robin scheduler for ULSCH traffic.
@param Mod_id Instance ID for eNB @param Mod_id Instance ID for eNB
@param subframe Subframe number on which to act @param subframe Subframe number on which to act
@returns UE index that is to be scheduled if needed/room @returns UE index that is to be scheduled if needed/room
*/ */
module_id_t schedule_next_ulue(module_id_t module_idP, int UE_id,sub_frame_t subframe); module_id_t schedule_next_ulue(module_id_t module_idP, int UE_id,
sub_frame_t subframe);
/** \brief Round-robin scheduler for DLSCH traffic. /** \brief Round-robin scheduler for DLSCH traffic.
@param Mod_id Instance ID for eNB @param Mod_id Instance ID for eNB
@param subframe Subframe number on which to act @param subframe Subframe number on which to act
@returns UE index that is to be scheduled if needed/room @returns UE index that is to be scheduled if needed/room
*/ */
int schedule_next_dlue(module_id_t module_idP, int CC_id, sub_frame_t subframe); int schedule_next_dlue(module_id_t module_idP, int CC_id,
sub_frame_t subframe);
/* \brief Allocates a set of PRBS for a particular UE. This is a simple function for the moment, later it should process frequency-domain CQI information and/or PMI information. Currently it just returns the first PRBS that are available in the subframe based on the number requested. /* \brief Allocates a set of PRBS for a particular UE. This is a simple function for the moment, later it should process frequency-domain CQI information and/or PMI information. Currently it just returns the first PRBS that are available in the subframe based on the number requested.
@param UE_id Index of UE on which to act @param UE_id Index of UE on which to act
...@@ -416,7 +453,8 @@ int schedule_next_dlue(module_id_t module_idP, int CC_id, sub_frame_t subframe); ...@@ -416,7 +453,8 @@ int schedule_next_dlue(module_id_t module_idP, int CC_id, sub_frame_t subframe);
@param rballoc Pointer to bit-map of current PRB allocation given to previous users/control channels. This is updated for subsequent calls to the routine. @param rballoc Pointer to bit-map of current PRB allocation given to previous users/control channels. This is updated for subsequent calls to the routine.
@returns an rballoc bitmap for resource type 0 allocation (DCI). @returns an rballoc bitmap for resource type 0 allocation (DCI).
*/ */
uint32_t allocate_prbs(int UE_id,uint8_t nb_rb, int N_RB_DL, uint32_t *rballoc); uint32_t allocate_prbs(int UE_id, uint8_t nb_rb, int N_RB_DL,
uint32_t * rballoc);
/* \fn uint32_t req_new_ulsch(module_id_t module_idP) /* \fn uint32_t req_new_ulsch(module_id_t module_idP)
\brief check for a new transmission in any drb \brief check for a new transmission in any drb
...@@ -433,19 +471,25 @@ uint32_t req_new_ulsch(module_id_t module_idP); ...@@ -433,19 +471,25 @@ uint32_t req_new_ulsch(module_id_t module_idP);
@param subframe subframe number @param subframe subframe number
@returns 0 for no SR, 1 for SR @returns 0 for no SR, 1 for SR
*/ */
uint32_t ue_get_SR(module_id_t module_idP, int CC_id,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, int CC_id, int UE_id); uint8_t get_ue_weight(module_id_t module_idP, int CC_id, int UE_id);
// UE functions // UE functions
void mac_out_of_sync_ind(module_id_t module_idP, frame_t frameP, uint16_t CH_index); void mac_out_of_sync_ind(module_id_t module_idP, frame_t frameP,
uint16_t CH_index);
void ue_decode_si(module_id_t module_idP, int CC_id,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_decode_p(module_id_t module_idP, int CC_id,frame_t frame, uint8_t CH_index, void *pdu, uint16_t len); void ue_decode_p(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, uint8_t CC_id,frame_t frame, sub_frame_t subframe, uint8_t *sdu,uint16_t sdu_len,uint8_t CH_index); void ue_send_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frame,
sub_frame_t subframe, uint8_t * sdu, uint16_t sdu_len,
uint8_t CH_index);
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
...@@ -457,7 +501,9 @@ void ue_send_sdu(module_id_t module_idP, uint8_t CC_id,frame_t frame, sub_frame_ ...@@ -457,7 +501,9 @@ void ue_send_sdu(module_id_t module_idP, uint8_t CC_id,frame_t frame, sub_frame_
@param eNB_index Index of attached eNB @param eNB_index Index of attached eNB
@param sync_area the index of MBSFN sync area @param sync_area the index of MBSFN sync area
*/ */
void ue_send_mch_sdu(module_id_t module_idP,uint8_t CC_id, frame_t frameP,uint8_t *sdu,uint16_t sdu_len,uint8_t eNB_index,uint8_t sync_area) ; void ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
uint8_t * sdu, uint16_t sdu_len, uint8_t eNB_index,
uint8_t sync_area);
/*\brief Function to check if UE PHY needs to decode MCH for MAC. /*\brief Function to check if UE PHY needs to decode MCH for MAC.
@param Mod_id Index of protocol instance @param Mod_id Index of protocol instance
...@@ -467,7 +513,9 @@ void ue_send_mch_sdu(module_id_t module_idP,uint8_t CC_id, frame_t frameP,uint8_ ...@@ -467,7 +513,9 @@ void ue_send_mch_sdu(module_id_t module_idP,uint8_t CC_id, frame_t frameP,uint8_
@param[out] sync_area return the sync area @param[out] sync_area return the sync area
@param[out] mcch_active flag indicating whether this MCCH is active in this SF @param[out] mcch_active flag indicating whether this MCCH is active in this SF
*/ */
int ue_query_mch(uint8_t Mod_id,uint8_t CC_id, uint32_t frame,sub_frame_t subframe, uint8_t eNB_index, uint8_t *sync_area, uint8_t *mcch_active); int ue_query_mch(uint8_t Mod_id, uint8_t CC_id, uint32_t frame,
sub_frame_t subframe, uint8_t eNB_index,
uint8_t * sync_area, uint8_t * mcch_active);
#endif #endif
...@@ -478,7 +526,10 @@ int ue_query_mch(uint8_t Mod_id,uint8_t CC_id, uint32_t frame,sub_frame_t subfra ...@@ -478,7 +526,10 @@ int ue_query_mch(uint8_t Mod_id,uint8_t CC_id, uint32_t frame,sub_frame_t subfra
@param subframe subframe number @param subframe subframe number
@returns 0 for no SR, 1 for SR @returns 0 for no SR, 1 for SR
*/ */
void ue_get_sdu(module_id_t module_idP, 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); void ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
sub_frame_t subframe, uint8_t eNB_index,
uint8_t * ulsch_buffer, uint16_t buflen,
uint8_t * access_mode);
/* \brief Function called by PHY to retrieve information to be transmitted using the RA procedure. If the UE is not in PUSCH mode for a particular eNB index, this is assumed to be an Msg3 and MAC attempts to retrieves the CCCH message from RRC. If the UE is in PUSCH mode for a particular eNB index and PUCCH format 0 (Scheduling Request) is not activated, the MAC may use this resource for random-access to transmit a BSR along with the C-RNTI control element (see 5.1.4 from 36.321) /* \brief Function called by PHY to retrieve information to be transmitted using the RA procedure. If the UE is not in PUSCH mode for a particular eNB index, this is assumed to be an Msg3 and MAC attempts to retrieves the CCCH message from RRC. If the UE is in PUSCH mode for a particular eNB index and PUCCH format 0 (Scheduling Request) is not activated, the MAC may use this resource for random-access to transmit a BSR along with the C-RNTI control element (see 5.1.4 from 36.321)
@param Mod_id Index of UE instance @param Mod_id Index of UE instance
...@@ -486,7 +537,9 @@ void ue_get_sdu(module_id_t module_idP, int CC_id,frame_t frameP, sub_frame_t su ...@@ -486,7 +537,9 @@ void ue_get_sdu(module_id_t module_idP, int CC_id,frame_t frameP, sub_frame_t su
@param New_Msg3 Flag to indicate this call is for a new Msg3 @param New_Msg3 Flag to indicate this call is for a new Msg3
@param subframe Index of subframe for PRACH transmission (0 ... 9) @param subframe Index of subframe for PRACH transmission (0 ... 9)
@returns A pointer to a PRACH_RESOURCES_t */ @returns A pointer to a PRACH_RESOURCES_t */
PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP,uint8_t new_Msg3,sub_frame_t subframe); PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id,
frame_t frameP, uint8_t new_Msg3,
sub_frame_t subframe);
/* \brief Function called by PHY to process the received RAR. It checks that the preamble matches what was sent by the eNB and provides the timing advance and t-CRNTI. /* \brief Function called by PHY to process the received RAR. It checks that the preamble matches what was sent by the eNB and provides the timing advance and t-CRNTI.
@param Mod_id Index of UE instance @param Mod_id Index of UE instance
...@@ -501,16 +554,14 @@ random-access procedure ...@@ -501,16 +554,14 @@ random-access procedure
@returns timing advance or 0xffff if preamble doesn't match @returns timing advance or 0xffff if preamble doesn't match
*/ */
uint16_t uint16_t
ue_process_rar( ue_process_rar(const module_id_t module_idP,
const module_id_t module_idP,
const int CC_id, const int CC_id,
const frame_t frameP, const frame_t frameP,
const rnti_t ra_rnti, const rnti_t ra_rnti,
uint8_t * const dlsch_buffer, uint8_t * const dlsch_buffer,
rnti_t * const t_crnti, rnti_t * const t_crnti,
const uint8_t preamble_index, const uint8_t preamble_index,
uint8_t* selected_rar_buffer uint8_t * selected_rar_buffer);
);
/* \brief Generate header for UL-SCH. This function parses the desired control elements and sdus and generates the header as described /* \brief Generate header for UL-SCH. This function parses the desired control elements and sdus and generates the header as described
...@@ -529,16 +580,16 @@ in the ULSCH buffer. ...@@ -529,16 +580,16 @@ in the ULSCH buffer.
@param post_padding Number of bytes for padding at the end of MAC PDU @param post_padding Number of bytes for padding at the end of MAC PDU
@returns Number of bytes used for header @returns Number of bytes used for header
*/ */
unsigned char generate_ulsch_header(uint8_t *mac_header, unsigned char generate_ulsch_header(uint8_t * mac_header,
uint8_t num_sdus, uint8_t num_sdus,
uint8_t short_padding, uint8_t short_padding,
uint16_t *sdu_lengths, uint16_t * sdu_lengths,
uint8_t *sdu_lcids, uint8_t * sdu_lcids,
POWER_HEADROOM_CMD *power_headroom, POWER_HEADROOM_CMD * power_headroom,
uint16_t *crnti, uint16_t * crnti,
BSR_SHORT *truncated_bsr, BSR_SHORT * truncated_bsr,
BSR_SHORT *short_bsr, BSR_SHORT * short_bsr,
BSR_LONG *long_bsr, BSR_LONG * long_bsr,
unsigned short post_padding); unsigned short post_padding);
/* \brief Parse header for UL-SCH. This function parses the received UL-SCH header as described /* \brief Parse header for UL-SCH. This function parses the received UL-SCH header as described
...@@ -552,40 +603,46 @@ in the ULSCH buffer. ...@@ -552,40 +603,46 @@ in the ULSCH buffer.
@param rx_lengths Pointer to array of SDU lengths @param rx_lengths Pointer to array of SDU lengths
@returns Pointer to payload following header @returns Pointer to payload following header
*/ */
uint8_t *parse_ulsch_header(uint8_t *mac_header, uint8_t *parse_ulsch_header(uint8_t * mac_header,
uint8_t *num_ce, uint8_t * num_ce,
uint8_t *num_sdu, uint8_t * num_sdu,
uint8_t *rx_ces, uint8_t * rx_ces,
uint8_t *rx_lcids, uint8_t * rx_lcids,
uint16_t *rx_lengths, uint16_t * rx_lengths, uint16_t tx_lenght);
uint16_t tx_lenght);
int to_prb(int); int to_prb(int);
int to_rbg(int); int to_rbg(int);
int l2_init(LTE_DL_FRAME_PARMS *frame_parms,int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, uint8_t HO_active); int l2_init(LTE_DL_FRAME_PARMS * frame_parms, int eMBMS_active,
char *uecap_xer, uint8_t cba_group_active, uint8_t HO_active);
int mac_init(void); int mac_init(void);
int add_new_ue(module_id_t Mod_id, int CC_id, rnti_t rnti,int harq_pid int add_new_ue(module_id_t Mod_id, int CC_id, rnti_t rnti, int harq_pid
#ifdef Rel14 #ifdef Rel14
,uint8_t rach_resource_type , uint8_t rach_resource_type
#endif #endif
); );
int rrc_mac_remove_ue(module_id_t Mod_id, rnti_t rntiP); int rrc_mac_remove_ue(module_id_t Mod_id, rnti_t rntiP);
int maxround(module_id_t Mod_id,uint16_t rnti,int frame,sub_frame_t subframe,uint8_t ul_flag); int maxround(module_id_t Mod_id, uint16_t rnti, int frame,
void swap_UEs(UE_list_t *listP,int nodeiP, int nodejP, int ul_flag); sub_frame_t subframe, uint8_t ul_flag);
int prev(UE_list_t *listP, int nodeP, int ul_flag); void swap_UEs(UE_list_t * listP, int nodeiP, int nodejP, int ul_flag);
void dump_ue_list(UE_list_t *listP, int ul_flag); int prev(UE_list_t * listP, int nodeP, int ul_flag);
int UE_num_active_CC(UE_list_t *listP,int ue_idP); void dump_ue_list(UE_list_t * listP, int ul_flag);
int UE_PCCID(module_id_t mod_idP,int ue_idP); int UE_num_active_CC(UE_list_t * listP, int ue_idP);
int UE_PCCID(module_id_t mod_idP, int ue_idP);
rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP); rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP);
void ulsch_scheduler_pre_processor(module_id_t module_idP, int frameP, sub_frame_t subframeP, uint16_t *first_rb); void ulsch_scheduler_pre_processor(module_id_t module_idP, int frameP,
void store_ulsch_buffer(module_id_t module_idP, int frameP, sub_frame_t subframeP); sub_frame_t subframeP,
void sort_ue_ul (module_id_t module_idP,int frameP, sub_frame_t subframeP); uint16_t * first_rb);
void assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subframeP,uint16_t *first_rb); void store_ulsch_buffer(module_id_t module_idP, int frameP,
void adjust_bsr_info(int buffer_occupancy, uint16_t TBS, UE_TEMPLATE *UE_template); sub_frame_t subframeP);
void sort_ue_ul(module_id_t module_idP, int frameP, sub_frame_t subframeP);
void assign_max_mcs_min_rb(module_id_t module_idP, int frameP,
sub_frame_t subframeP, uint16_t * first_rb);
void adjust_bsr_info(int buffer_occupancy, uint16_t TBS,
UE_TEMPLATE * UE_template);
int phy_stats_exist(module_id_t Mod_id, int rnti); int phy_stats_exist(module_id_t Mod_id, int rnti);
/*! \fn UE_L2_state_t ue_scheduler(const module_id_t module_idP,const frame_t frameP, const sub_frame_t subframe, const lte_subframe_t direction,const uint8_t eNB_index) /*! \fn UE_L2_state_t ue_scheduler(const module_id_t module_idP,const frame_t frameP, const sub_frame_t subframe, const lte_subframe_t direction,const uint8_t eNB_index)
...@@ -599,15 +656,13 @@ int phy_stats_exist(module_id_t Mod_id, int rnti); ...@@ -599,15 +656,13 @@ int phy_stats_exist(module_id_t Mod_id, int rnti);
\param[in] eNB_index instance of eNB \param[in] eNB_index instance of eNB
@returns L2 state (CONNETION_OK or CONNECTION_LOST or PHY_RESYNCH) @returns L2 state (CONNETION_OK or CONNECTION_LOST or PHY_RESYNCH)
*/ */
UE_L2_STATE_t ue_scheduler( UE_L2_STATE_t ue_scheduler(const module_id_t module_idP,
const module_id_t module_idP,
const frame_t rxFrameP, const frame_t rxFrameP,
const sub_frame_t rxSubframe, const sub_frame_t rxSubframe,
const frame_t txFrameP, const frame_t txFrameP,
const sub_frame_t txSubframe, const sub_frame_t txSubframe,
const lte_subframe_t direction, const lte_subframe_t direction,
const uint8_t eNB_index, const uint8_t eNB_index, const int CC_id);
const int CC_id);
/*! \fn int cba_access(module_id_t module_idP,frame_t frameP,sub_frame_t subframe, uint8_t eNB_index,uint16_t buflen); /*! \fn int cba_access(module_id_t module_idP,frame_t frameP,sub_frame_t subframe, uint8_t eNB_index,uint16_t buflen);
\brief determine whether to use cba resource to transmit or not \brief determine whether to use cba resource to transmit or not
...@@ -617,7 +672,8 @@ UE_L2_STATE_t ue_scheduler( ...@@ -617,7 +672,8 @@ UE_L2_STATE_t ue_scheduler(
\param[in] eNB_index instance of eNB \param[in] eNB_index instance of eNB
\param[out] access(1) or postpone (0) \param[out] access(1) or postpone (0)
*/ */
int cba_access(module_id_t module_idP,frame_t frameP,sub_frame_t subframe, uint8_t eNB_index,uint16_t buflen); int cba_access(module_id_t module_idP, frame_t frameP,
sub_frame_t subframe, uint8_t eNB_index, uint16_t buflen);
/*! \fn BSR_SHORT * get_bsr_short(module_id_t module_idP, uint8_t bsr_len) /*! \fn BSR_SHORT * get_bsr_short(module_id_t module_idP, uint8_t bsr_len)
\brief get short bsr level \brief get short bsr level
...@@ -633,14 +689,15 @@ BSR_SHORT *get_bsr_short(module_id_t module_idP, uint8_t bsr_len); ...@@ -633,14 +689,15 @@ BSR_SHORT *get_bsr_short(module_id_t module_idP, uint8_t bsr_len);
\param[in] bsr_len indicator for no, short, or long bsr \param[in] bsr_len indicator for no, short, or long bsr
\param[out] bsr_l pointer to long bsr \param[out] bsr_l pointer to long bsr
*/ */
BSR_LONG * get_bsr_long(module_id_t module_idP, uint8_t bsr_len); BSR_LONG *get_bsr_long(module_id_t module_idP, uint8_t bsr_len);
/*! \fn boolean_t update_bsr(module_id_t module_idP, frame_t frameP,sub_frame_t subframeP) /*! \fn boolean_t update_bsr(module_id_t module_idP, frame_t frameP,sub_frame_t subframeP)
\brief get the rlc stats and update the bsr level for each lcid \brief get the rlc stats and update the bsr level for each lcid
\param[in] Mod_id instance of the UE \param[in] Mod_id instance of the UE
\param[in] frame Frame index \param[in] frame Frame index
*/ */
boolean_t update_bsr(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP,eNB_index_t eNB_index); boolean_t update_bsr(module_id_t module_idP, frame_t frameP,
sub_frame_t subframeP, eNB_index_t eNB_index);
/*! \fn locate_BsrIndexByBufferSize (int *table, int size, int value) /*! \fn locate_BsrIndexByBufferSize (int *table, int size, int value)
\brief locate the BSR level in the table as defined in 36.321. This function requires that he values in table to be monotonic, either increasing or decreasing. The returned value is not less than 0, nor greater than n-1, where n is the size of table. \brief locate the BSR level in the table as defined in 36.321. This function requires that he values in table to be monotonic, either increasing or decreasing. The returned value is not less than 0, nor greater than n-1, where n is the size of table.
...@@ -649,7 +706,8 @@ boolean_t update_bsr(module_id_t module_idP, frame_t frameP, sub_frame_t subfram ...@@ -649,7 +706,8 @@ boolean_t update_bsr(module_id_t module_idP, frame_t frameP, sub_frame_t subfram
\param[in] value Value of the buffer \param[in] value Value of the buffer
\return the index in the BSR_LEVEL table \return the index in the BSR_LEVEL table
*/ */
uint8_t locate_BsrIndexByBufferSize (const uint32_t *table, int size, int value); uint8_t locate_BsrIndexByBufferSize(const uint32_t * table, int size,
int value);
/*! \fn int get_sf_periodicBSRTimer(uint8_t periodicBSR_Timer) /*! \fn int get_sf_periodicBSRTimer(uint8_t periodicBSR_Timer)
...@@ -700,7 +758,8 @@ int get_db_dl_PathlossChange(uint8_t dl_PathlossChange); ...@@ -700,7 +758,8 @@ int get_db_dl_PathlossChange(uint8_t dl_PathlossChange);
\param[in] CC_id Component Carrier Index \param[in] CC_id Component Carrier Index
\return phr mapping \return phr mapping
*/ */
uint8_t get_phr_mapping (module_id_t module_idP, int CC_id, uint8_t eNB_index); uint8_t get_phr_mapping(module_id_t module_idP, int CC_id,
uint8_t eNB_index);
/*! \fn void update_phr (module_id_t module_idP) /*! \fn void update_phr (module_id_t module_idP)
\brief update/reset the phr timers \brief update/reset the phr timers
...@@ -708,13 +767,14 @@ uint8_t get_phr_mapping (module_id_t module_idP, int CC_id, uint8_t eNB_index); ...@@ -708,13 +767,14 @@ uint8_t get_phr_mapping (module_id_t module_idP, int CC_id, uint8_t eNB_index);
\param[in] CC_id Component carrier index \param[in] CC_id Component carrier index
\return void \return void
*/ */
void update_phr (module_id_t module_idP,int CC_id); void update_phr(module_id_t module_idP, int CC_id);
/*! \brief Function to indicate Msg3 transmission/retransmission which initiates/reset Contention Resolution Timer /*! \brief Function to indicate Msg3 transmission/retransmission which initiates/reset Contention Resolution Timer
\param[in] Mod_id Instance index of UE \param[in] Mod_id Instance index of UE
\param[in] eNB_id Index of eNB \param[in] eNB_id Index of eNB
*/ */
void Msg3_tx(module_id_t module_idP,uint8_t CC_id,frame_t frameP,uint8_t eNB_id); void Msg3_tx(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
uint8_t eNB_id);
/*! \brief Function to indicate the transmission of msg1/rach /*! \brief Function to indicate the transmission of msg1/rach
...@@ -722,12 +782,12 @@ void Msg3_tx(module_id_t module_idP,uint8_t CC_id,frame_t frameP,uint8_t eNB_id) ...@@ -722,12 +782,12 @@ void Msg3_tx(module_id_t module_idP,uint8_t CC_id,frame_t frameP,uint8_t eNB_id)
\param[in] eNB_id Index of eNB \param[in] eNB_id Index of eNB
*/ */
void Msg1_tx(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id); void Msg1_tx(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
uint8_t eNB_id);
void dl_phy_sync_success(module_id_t module_idP, void dl_phy_sync_success(module_id_t module_idP,
frame_t frameP, frame_t frameP,
unsigned char eNB_index, unsigned char eNB_index, uint8_t first_sync);
uint8_t first_sync);
int dump_eNB_l2_stats(char *buffer, int length); int dump_eNB_l2_stats(char *buffer, int length);
...@@ -744,9 +804,11 @@ void add_common_dci(DCI_PDU *DCI_pdu, ...@@ -744,9 +804,11 @@ void add_common_dci(DCI_PDU *DCI_pdu,
uint8_t ra_flag); uint8_t ra_flag);
*/ */
uint32_t allocate_prbs_sub(int nb_rb, int N_RB_DL, int N_RBG, uint8_t *rballoc); uint32_t allocate_prbs_sub(int nb_rb, int N_RB_DL, int N_RBG,
uint8_t * rballoc);
void update_ul_dci(module_id_t module_idP,uint8_t CC_id,rnti_t rnti,uint8_t dai); void update_ul_dci(module_id_t module_idP, uint8_t CC_id, rnti_t rnti,
uint8_t dai);
int get_bw_index(module_id_t module_id, uint8_t CC_id); int get_bw_index(module_id_t module_id, uint8_t CC_id);
...@@ -803,44 +865,48 @@ int rrc_mac_config_req_eNB(module_id_t module_idP, ...@@ -803,44 +865,48 @@ int rrc_mac_config_req_eNB(module_id_t module_idP,
int physCellId, int physCellId,
int p_eNB, int p_eNB,
int Ncp, int Ncp,
int eutra_band, int eutra_band, uint32_t dl_CarrierFreq,
uint32_t dl_CarrierFreq,
#ifdef Rel14 #ifdef Rel14
int pbch_repetition, int pbch_repetition,
#endif #endif
rnti_t rntiP, rnti_t rntiP,
BCCH_BCH_Message_t *mib, BCCH_BCH_Message_t * mib,
RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, RadioResourceConfigCommonSIB_t *
radioResourceConfigCommon,
#ifdef Rel14 #ifdef Rel14
RadioResourceConfigCommonSIB_t *radioResourceConfigCommon_BR, RadioResourceConfigCommonSIB_t *
radioResourceConfigCommon_BR,
#endif #endif
struct PhysicalConfigDedicated *physicalConfigDedicated, struct PhysicalConfigDedicated
*physicalConfigDedicated,
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
SCellToAddMod_r10_t *sCellToAddMod_r10, SCellToAddMod_r10_t * sCellToAddMod_r10,
//struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10,
#endif #endif
MeasObjectToAddMod_t **measObj, MeasObjectToAddMod_t ** measObj,
MAC_MainConfig_t *mac_MainConfig, MAC_MainConfig_t * mac_MainConfig,
long logicalChannelIdentity, long logicalChannelIdentity,
LogicalChannelConfig_t *logicalChannelConfig, LogicalChannelConfig_t * logicalChannelConfig,
MeasGapConfig_t *measGapConfig, MeasGapConfig_t * measGapConfig,
TDD_Config_t *tdd_Config, TDD_Config_t * tdd_Config,
MobilityControlInfo_t *mobilityControlInfo, MobilityControlInfo_t * mobilityControlInfo,
SchedulingInfoList_t *schedulingInfoList, SchedulingInfoList_t * schedulingInfoList,
uint32_t ul_CarrierFreq, uint32_t ul_CarrierFreq,
long *ul_Bandwidth, long *ul_Bandwidth,
AdditionalSpectrumEmission_t *additionalSpectrumEmission, AdditionalSpectrumEmission_t *
struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList additionalSpectrumEmission,
struct MBSFN_SubframeConfigList
*mbsfn_SubframeConfigList
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
, ,
uint8_t MBMS_Flag, uint8_t MBMS_Flag,
MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList, MBSFN_AreaInfoList_r9_t * mbsfn_AreaInfoList,
PMCH_InfoList_r9_t *pmch_InfoList PMCH_InfoList_r9_t * pmch_InfoList
#endif #endif
#ifdef Rel14 #ifdef Rel14
, ,
SystemInformationBlockType1_v1310_IEs_t *sib1_ext_r13 SystemInformationBlockType1_v1310_IEs_t *
sib1_ext_r13
#endif #endif
); );
...@@ -867,129 +933,151 @@ int rrc_mac_config_req_eNB(module_id_t module_idP, ...@@ -867,129 +933,151 @@ int rrc_mac_config_req_eNB(module_id_t module_idP,
int rrc_mac_config_req_ue(module_id_t module_idP, int rrc_mac_config_req_ue(module_id_t module_idP,
int CC_id, int CC_id,
uint8_t eNB_index, uint8_t eNB_index,
RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, RadioResourceConfigCommonSIB_t *
struct PhysicalConfigDedicated *physicalConfigDedicated, radioResourceConfigCommon,
struct PhysicalConfigDedicated
*physicalConfigDedicated,
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
SCellToAddMod_r10_t *sCellToAddMod_r10, SCellToAddMod_r10_t * sCellToAddMod_r10,
//struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10,
#endif #endif
MeasObjectToAddMod_t **measObj, MeasObjectToAddMod_t ** measObj,
MAC_MainConfig_t *mac_MainConfig, MAC_MainConfig_t * mac_MainConfig,
long logicalChannelIdentity, long logicalChannelIdentity,
LogicalChannelConfig_t *logicalChannelConfig, LogicalChannelConfig_t * logicalChannelConfig,
MeasGapConfig_t *measGapConfig, MeasGapConfig_t * measGapConfig,
TDD_Config_t *tdd_Config, TDD_Config_t * tdd_Config,
MobilityControlInfo_t *mobilityControlInfo, MobilityControlInfo_t * mobilityControlInfo,
uint8_t *SIwindowsize, uint8_t * SIwindowsize,
uint16_t *SIperiod, uint16_t * SIperiod,
ARFCN_ValueEUTRA_t *ul_CarrierFreq, ARFCN_ValueEUTRA_t * ul_CarrierFreq,
long *ul_Bandwidth, long *ul_Bandwidth,
AdditionalSpectrumEmission_t *additionalSpectrumEmission, AdditionalSpectrumEmission_t *
struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList additionalSpectrumEmission,
struct MBSFN_SubframeConfigList
*mbsfn_SubframeConfigList
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
, ,
uint8_t MBMS_Flag, uint8_t MBMS_Flag,
MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList, MBSFN_AreaInfoList_r9_t * mbsfn_AreaInfoList,
PMCH_InfoList_r9_t *pmch_InfoList PMCH_InfoList_r9_t * pmch_InfoList
#endif #endif
#ifdef CBA #ifdef CBA
, ,
uint8_t num_active_cba_groups, uint8_t num_active_cba_groups, uint16_t cba_rnti
uint16_t cba_rnti
#endif #endif
); );
uint16_t getRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs); uint16_t getRIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs);
int get_subbandsize(uint8_t dl_bandwidth); int get_subbandsize(uint8_t dl_bandwidth);
void get_Msg3allocret(COMMON_channels_t *cc, void get_Msg3allocret(COMMON_channels_t * cc,
sub_frame_t current_subframe, sub_frame_t current_subframe,
frame_t current_frame, frame_t current_frame,
frame_t *frame, frame_t * frame, sub_frame_t * subframe);
sub_frame_t *subframe);
void get_Msg3alloc(COMMON_channels_t *cc, void get_Msg3alloc(COMMON_channels_t * cc,
sub_frame_t current_subframe, sub_frame_t current_subframe,
frame_t current_frame, frame_t current_frame,
frame_t *frame, frame_t * frame, sub_frame_t * subframe);
sub_frame_t *subframe);
uint16_t mac_computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs); uint16_t mac_computeRIV(uint16_t N_RB_DL, uint16_t RBstart,
uint16_t Lcrbs);
int get_phich_resource_times6(COMMON_channels_t *cc); int get_phich_resource_times6(COMMON_channels_t * cc);
int to_rbg(int dl_Bandwidth); int to_rbg(int dl_Bandwidth);
int to_prb(int dl_Bandwidth); int to_prb(int dl_Bandwidth);
uint8_t get_Msg3harqpid(COMMON_channels_t *cc, uint8_t get_Msg3harqpid(COMMON_channels_t * cc,
frame_t frame, frame_t frame, sub_frame_t current_subframe);
sub_frame_t current_subframe);
uint32_t pdcchalloc2ulframe(COMMON_channels_t *ccP,uint32_t frame, uint8_t n); uint32_t pdcchalloc2ulframe(COMMON_channels_t * ccP, uint32_t frame,
uint8_t n);
uint8_t pdcchalloc2ulsubframe(COMMON_channels_t *ccP,uint8_t n); uint8_t pdcchalloc2ulsubframe(COMMON_channels_t * ccP, uint8_t n);
int is_UL_sf(COMMON_channels_t *ccP,sub_frame_t subframeP); int is_UL_sf(COMMON_channels_t * ccP, sub_frame_t subframeP);
uint8_t getQm(uint8_t mcs); uint8_t getQm(uint8_t mcs);
uint8_t subframe2harqpid(COMMON_channels_t *cc,frame_t frame,sub_frame_t subframe); uint8_t subframe2harqpid(COMMON_channels_t * cc, frame_t frame,
sub_frame_t subframe);
void get_srs_pos(COMMON_channels_t *cc,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset);
void get_srs_pos(COMMON_channels_t * cc, uint16_t isrs,
void get_csi_params(COMMON_channels_t *cc,struct CQI_ReportPeriodic *cqi_PMI_ConfigIndex,uint16_t *Npd,uint16_t *N_OFFSET_CQI,int *H); uint16_t * psrsPeriodicity, uint16_t * psrsOffset);
uint8_t get_rel8_dl_cqi_pmi_size(UE_sched_ctrl *sched_ctl,int CC_idP,COMMON_channels_t *cc,uint8_t tmode, struct CQI_ReportPeriodic *cqi_ReportPeriodic); void get_csi_params(COMMON_channels_t * cc,
struct CQI_ReportPeriodic *cqi_PMI_ConfigIndex,
uint8_t get_dl_cqi_pmi_size_pusch(COMMON_channels_t *cc,uint8_t tmode, uint8_t ri, CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic); uint16_t * Npd, uint16_t * N_OFFSET_CQI, int *H);
void extract_pucch_csi(module_id_t mod_idP,int CC_idP,int UE_id, frame_t frameP,sub_frame_t subframeP, uint8_t *pdu, uint8_t length);
uint8_t get_rel8_dl_cqi_pmi_size(UE_sched_ctrl * sched_ctl, int CC_idP,
void extract_pusch_csi(module_id_t mod_idP,int CC_idP,int UE_id, frame_t frameP,sub_frame_t subframeP,uint8_t *pdu, uint8_t length); COMMON_channels_t * cc, uint8_t tmode,
struct CQI_ReportPeriodic
uint16_t fill_nfapi_tx_req(nfapi_tx_request_body_t *tx_req_body,uint16_t absSF,uint16_t pdu_length, uint16_t pdu_index, uint8_t *pdu ); *cqi_ReportPeriodic);
void fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t *ul_config_pdu, uint8_t get_dl_cqi_pmi_size_pusch(COMMON_channels_t * cc, uint8_t tmode,
uint8_t cqi_req, uint8_t ri,
COMMON_channels_t *cc, CQI_ReportModeAperiodic_t *
struct PhysicalConfigDedicated *physicalConfigDedicated, cqi_ReportModeAperiodic);
uint8_t tmode, void extract_pucch_csi(module_id_t mod_idP, int CC_idP, int UE_id,
uint32_t handle, frame_t frameP, sub_frame_t subframeP,
uint8_t * pdu, uint8_t length);
void extract_pusch_csi(module_id_t mod_idP, int CC_idP, int UE_id,
frame_t frameP, sub_frame_t subframeP,
uint8_t * pdu, uint8_t length);
uint16_t fill_nfapi_tx_req(nfapi_tx_request_body_t * tx_req_body,
uint16_t absSF, uint16_t pdu_length,
uint16_t pdu_index, uint8_t * pdu);
void fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t *
ul_config_pdu, uint8_t cqi_req,
COMMON_channels_t * cc,
struct PhysicalConfigDedicated
*physicalConfigDedicated,
uint8_t tmode, uint32_t handle,
uint16_t rnti, uint16_t rnti,
uint8_t resource_block_start, uint8_t resource_block_start,
uint8_t number_of_resource_blocks, uint8_t
number_of_resource_blocks,
uint8_t mcs, uint8_t mcs,
uint8_t cyclic_shift_2_for_drms, uint8_t cyclic_shift_2_for_drms,
uint8_t frequency_hopping_enabled_flag, uint8_t
frequency_hopping_enabled_flag,
uint8_t frequency_hopping_bits, uint8_t frequency_hopping_bits,
uint8_t new_data_indication, uint8_t new_data_indication,
uint8_t redundancy_version, uint8_t redundancy_version,
uint8_t harq_process_number, uint8_t harq_process_number,
uint8_t ul_tx_mode, uint8_t ul_tx_mode,
uint8_t current_tx_nb, uint8_t current_tx_nb,
uint8_t n_srs, uint8_t n_srs, uint16_t size);
uint16_t size
);
#ifdef Rel14 #ifdef Rel14
void fill_nfapi_ulsch_config_request_emtc(nfapi_ul_config_request_pdu_t *ul_config_pdu, void fill_nfapi_ulsch_config_request_emtc(nfapi_ul_config_request_pdu_t *
uint8_t ue_type, ul_config_pdu, uint8_t ue_type,
uint16_t total_number_of_repetitions, uint16_t
total_number_of_repetitions,
uint16_t repetition_number, uint16_t repetition_number,
uint16_t initial_transmission_sf_io); uint16_t
initial_transmission_sf_io);
#endif #endif
void program_dlsch_acknak(module_id_t module_idP, int CC_idP,int UE_idP, frame_t frameP, sub_frame_t subframeP,uint8_t cce_idx); void program_dlsch_acknak(module_id_t module_idP, int CC_idP, int UE_idP,
frame_t frameP, sub_frame_t subframeP,
uint8_t cce_idx);
void fill_nfapi_dlsch_config(eNB_MAC_INST *eNB, nfapi_dl_config_request_body_t *dl_req, void fill_nfapi_dlsch_config(eNB_MAC_INST * eNB,
uint16_t length, nfapi_dl_config_request_body_t * dl_req,
uint16_t pdu_index, uint16_t length, uint16_t pdu_index,
uint16_t rnti, uint16_t rnti,
uint8_t resource_allocation_type, uint8_t resource_allocation_type,
uint8_t virtual_resource_block_assignment_flag, uint8_t
virtual_resource_block_assignment_flag,
uint16_t resource_block_coding, uint16_t resource_block_coding,
uint8_t modulation, uint8_t modulation,
uint8_t redundancy_version, uint8_t redundancy_version,
...@@ -1006,28 +1094,27 @@ void fill_nfapi_dlsch_config(eNB_MAC_INST *eNB, nfapi_dl_config_request_body_t * ...@@ -1006,28 +1094,27 @@ void fill_nfapi_dlsch_config(eNB_MAC_INST *eNB, nfapi_dl_config_request_body_t *
uint8_t nprb, uint8_t nprb,
uint8_t transmission_mode, uint8_t transmission_mode,
uint8_t num_bf_prb_per_subband, uint8_t num_bf_prb_per_subband,
uint8_t num_bf_vector uint8_t num_bf_vector);
);
void fill_nfapi_harq_information(module_id_t module_idP, void fill_nfapi_harq_information(module_id_t module_idP,
int CC_idP, int CC_idP,
uint16_t rntiP, uint16_t rntiP,
uint16_t absSFP, uint16_t absSFP,
nfapi_ul_config_harq_information *harq_information, nfapi_ul_config_harq_information *
uint8_t cce_idxP); harq_information, uint8_t cce_idxP);
void fill_nfapi_ulsch_harq_information(module_id_t module_idP, void fill_nfapi_ulsch_harq_information(module_id_t module_idP,
int CC_idP, int CC_idP,
uint16_t rntiP, uint16_t rntiP,
nfapi_ul_config_ulsch_harq_information *harq_information); nfapi_ul_config_ulsch_harq_information
* harq_information);
uint16_t fill_nfapi_uci_acknak(module_id_t module_idP, uint16_t fill_nfapi_uci_acknak(module_id_t module_idP,
int CC_idP, int CC_idP,
uint16_t rntiP, uint16_t rntiP,
uint16_t absSFP, uint16_t absSFP, uint8_t cce_idxP);
uint8_t cce_idxP);
void fill_nfapi_dl_dci_1A(nfapi_dl_config_request_pdu_t *dl_config_pdu, void fill_nfapi_dl_dci_1A(nfapi_dl_config_request_pdu_t * dl_config_pdu,
uint8_t aggregation_level, uint8_t aggregation_level,
uint16_t rnti, uint16_t rnti,
uint8_t rnti_type, uint8_t rnti_type,
...@@ -1035,34 +1122,40 @@ void fill_nfapi_dl_dci_1A(nfapi_dl_config_request_pdu_t *dl_config_pdu, ...@@ -1035,34 +1122,40 @@ void fill_nfapi_dl_dci_1A(nfapi_dl_config_request_pdu_t *dl_config_pdu,
uint8_t tpc, uint8_t tpc,
uint16_t resource_block_coding, uint16_t resource_block_coding,
uint8_t mcs, uint8_t mcs,
uint8_t ndi, uint8_t ndi, uint8_t rv, uint8_t vrb_flag);
uint8_t rv,
uint8_t vrb_flag);
nfapi_ul_config_request_pdu_t* has_ul_grant(module_id_t module_idP,int CC_idP,uint16_t subframeP,uint16_t rnti); nfapi_ul_config_request_pdu_t *has_ul_grant(module_id_t module_idP,
int CC_idP, uint16_t subframeP,
uint16_t rnti);
uint8_t get_tmode(module_id_t module_idP,int CC_idP,int UE_idP); uint8_t get_tmode(module_id_t module_idP, int CC_idP, int UE_idP);
uint8_t get_ul_req_index(module_id_t module_idP, int CC_idP, sub_frame_t subframeP); uint8_t get_ul_req_index(module_id_t module_idP, int CC_idP,
sub_frame_t subframeP);
#ifdef Rel14 #ifdef Rel14
int get_numnarrowbandbits(long dl_Bandwidth); int get_numnarrowbandbits(long dl_Bandwidth);
int mpdcch_sf_condition(eNB_MAC_INST *eNB,int CC_id, frame_t frameP,sub_frame_t subframeP,int rmax,MPDCCH_TYPES_t mpdcch_type,int UE_id); int mpdcch_sf_condition(eNB_MAC_INST * eNB, int CC_id, frame_t frameP,
sub_frame_t subframeP, int rmax,
MPDCCH_TYPES_t mpdcch_type, int UE_id);
int get_numnarrowbands(long dl_Bandwidth); int get_numnarrowbands(long dl_Bandwidth);
int narrowband_to_first_rb(COMMON_channels_t *cc, int nb_index); int narrowband_to_first_rb(COMMON_channels_t * cc, int nb_index);
#endif #endif
int l2_init_eNB(void); int l2_init_eNB(void);
void Msg1_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id); void Msg1_transmitted(module_id_t module_idP, uint8_t CC_id,
void Msg3_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id); frame_t frameP, uint8_t eNB_id);
uint32_t from_earfcn(int eutra_bandP,uint32_t dl_earfcn); void Msg3_transmitted(module_id_t module_idP, uint8_t CC_id,
frame_t frameP, uint8_t eNB_id);
uint32_t from_earfcn(int eutra_bandP, uint32_t dl_earfcn);
int32_t get_uldl_offset(int eutra_bandP); int32_t get_uldl_offset(int eutra_bandP);
int l2_init_ue(int eMBMS_active, char *uecap_xer,uint8_t cba_group_active, uint8_t HO_active); int l2_init_ue(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active,
uint8_t HO_active);
#endif #endif
/** @}*/ /** @}*/
...@@ -49,12 +49,14 @@ ...@@ -49,12 +49,14 @@
#include "SIMULATION/TOOLS/defs.h" // for taus #include "SIMULATION/TOOLS/defs.h" // for taus
int8_t get_DELTA_PREAMBLE(module_id_t module_idP,int CC_id) int8_t get_DELTA_PREAMBLE(module_id_t module_idP, int CC_id)
{ {
AssertFatal(CC_id==0, AssertFatal(CC_id == 0,
"Transmission on secondary CCs is not supported yet\n"); "Transmission on secondary CCs is not supported yet\n");
uint8_t prachConfigIndex = UE_mac_inst[module_idP].radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_ConfigIndex; uint8_t prachConfigIndex =
UE_mac_inst[module_idP].radioResourceConfigCommon->
prach_Config.prach_ConfigInfo.prach_ConfigIndex;
uint8_t preambleformat; uint8_t preambleformat;
if (UE_mac_inst[module_idP].tdd_Config) { // TDD if (UE_mac_inst[module_idP].tdd_Config) { // TDD
...@@ -70,62 +72,70 @@ int8_t get_DELTA_PREAMBLE(module_id_t module_idP,int CC_id) ...@@ -70,62 +72,70 @@ int8_t get_DELTA_PREAMBLE(module_id_t module_idP,int CC_id)
preambleformat = 4; preambleformat = 4;
} }
} else { // FDD } else { // FDD
preambleformat = prachConfigIndex>>2; preambleformat = prachConfigIndex >> 2;
} }
switch (preambleformat) { switch (preambleformat) {
case 0: case 0:
case 1: case 1:
return(0); return (0);
case 2: case 2:
case 3: case 3:
return(-3); return (-3);
case 4: case 4:
return(8); return (8);
default: default:
AssertFatal(1==0,"[UE %d] ue_procedures.c: FATAL, Illegal preambleformat %d, prachConfigIndex %d\n", AssertFatal(1 == 0,
module_idP, "[UE %d] ue_procedures.c: FATAL, Illegal preambleformat %d, prachConfigIndex %d\n",
preambleformat,prachConfigIndex); module_idP, preambleformat, prachConfigIndex);
} }
} }
/// This routine implements Section 5.1.2 (UE Random Access Resource Selection) from 36.321 /// This routine implements Section 5.1.2 (UE Random Access Resource Selection) from 36.321
void get_prach_resources(module_id_t module_idP, void
get_prach_resources(module_id_t module_idP,
int CC_id, int CC_id,
uint8_t eNB_index, uint8_t eNB_index,
uint8_t t_id, uint8_t t_id,
uint8_t first_Msg3, uint8_t first_Msg3,
RACH_ConfigDedicated_t *rach_ConfigDedicated) RACH_ConfigDedicated_t * rach_ConfigDedicated)
{ {
uint8_t Msg3_size = UE_mac_inst[module_idP].RA_Msg3_size; uint8_t Msg3_size = UE_mac_inst[module_idP].RA_Msg3_size;
PRACH_RESOURCES_t *prach_resources = &UE_mac_inst[module_idP].RA_prach_resources; PRACH_RESOURCES_t *prach_resources =
&UE_mac_inst[module_idP].RA_prach_resources;
RACH_ConfigCommon_t *rach_ConfigCommon = NULL; RACH_ConfigCommon_t *rach_ConfigCommon = NULL;
uint8_t noGroupB = 0; uint8_t noGroupB = 0;
uint8_t f_id = 0,num_prach=0; uint8_t f_id = 0, num_prach = 0;
int numberOfRA_Preambles; int numberOfRA_Preambles;
int messageSizeGroupA; int messageSizeGroupA;
int sizeOfRA_PreamblesGroupA; int sizeOfRA_PreamblesGroupA;
int messagePowerOffsetGroupB; int messagePowerOffsetGroupB;
int PLThreshold; int PLThreshold;
AssertFatal(CC_id==0, AssertFatal(CC_id == 0,
"Transmission on secondary CCs is not supported yet\n"); "Transmission on secondary CCs is not supported yet\n");
AssertFatal(UE_mac_inst[module_idP].radioResourceConfigCommon!=NULL, AssertFatal(UE_mac_inst[module_idP].radioResourceConfigCommon != NULL,
"[UE %d] FATAL radioResourceConfigCommon is NULL !!!\n",module_idP); "[UE %d] FATAL radioResourceConfigCommon is NULL !!!\n",
module_idP);
rach_ConfigCommon = &UE_mac_inst[module_idP].radioResourceConfigCommon->rach_ConfigCommon; rach_ConfigCommon =
numberOfRA_Preambles = (1+rach_ConfigCommon->preambleInfo.numberOfRA_Preambles)<<2; &UE_mac_inst[module_idP].radioResourceConfigCommon->
rach_ConfigCommon;
numberOfRA_Preambles =
(1 + rach_ConfigCommon->preambleInfo.numberOfRA_Preambles) << 2;
if (rach_ConfigDedicated) { // This is for network controlled Mobility, later if (rach_ConfigDedicated) { // This is for network controlled Mobility, later
if (rach_ConfigDedicated->ra_PRACH_MaskIndex != 0) { if (rach_ConfigDedicated->ra_PRACH_MaskIndex != 0) {
prach_resources->ra_PreambleIndex = rach_ConfigDedicated->ra_PreambleIndex; prach_resources->ra_PreambleIndex =
prach_resources->ra_RACH_MaskIndex = rach_ConfigDedicated->ra_PRACH_MaskIndex; rach_ConfigDedicated->ra_PreambleIndex;
prach_resources->ra_RACH_MaskIndex =
rach_ConfigDedicated->ra_PRACH_MaskIndex;
return; return;
} }
} }
...@@ -136,8 +146,11 @@ void get_prach_resources(module_id_t module_idP, ...@@ -136,8 +146,11 @@ void get_prach_resources(module_id_t module_idP,
if (!rach_ConfigCommon->preambleInfo.preamblesGroupAConfig) { if (!rach_ConfigCommon->preambleInfo.preamblesGroupAConfig) {
noGroupB = 1; noGroupB = 1;
} else { } else {
sizeOfRA_PreamblesGroupA = (rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA+1)<<2; sizeOfRA_PreamblesGroupA =
switch (rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->messageSizeGroupA) { (rach_ConfigCommon->preambleInfo.
preamblesGroupAConfig->sizeOfRA_PreamblesGroupA + 1) << 2;
switch (rach_ConfigCommon->preambleInfo.
preamblesGroupAConfig->messageSizeGroupA) {
case 0: case 0:
messageSizeGroupA = 56; messageSizeGroupA = 56;
break; break;
...@@ -154,7 +167,8 @@ void get_prach_resources(module_id_t module_idP, ...@@ -154,7 +167,8 @@ void get_prach_resources(module_id_t module_idP,
/* TODO: what value to use as default? */ /* TODO: what value to use as default? */
messagePowerOffsetGroupB = -9999; messagePowerOffsetGroupB = -9999;
switch (rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->messagePowerOffsetGroupB) { switch (rach_ConfigCommon->preambleInfo.
preamblesGroupAConfig->messagePowerOffsetGroupB) {
case 0: case 0:
messagePowerOffsetGroupB = -9999; messagePowerOffsetGroupB = -9999;
break; break;
...@@ -181,7 +195,11 @@ void get_prach_resources(module_id_t module_idP, ...@@ -181,7 +195,11 @@ void get_prach_resources(module_id_t module_idP,
break; break;
} }
PLThreshold = 0 - get_DELTA_PREAMBLE(module_idP,CC_id) - get_Po_NOMINAL_PUSCH(module_idP,CC_id) - messagePowerOffsetGroupB; PLThreshold =
0 - get_DELTA_PREAMBLE(module_idP,
CC_id) -
get_Po_NOMINAL_PUSCH(module_idP,
CC_id) - messagePowerOffsetGroupB;
// Note Pcmax is set to 0 here, we have to fix this // Note Pcmax is set to 0 here, we have to fix this
if (sizeOfRA_PreamblesGroupA == numberOfRA_Preambles) { if (sizeOfRA_PreamblesGroupA == numberOfRA_Preambles) {
...@@ -192,39 +210,58 @@ void get_prach_resources(module_id_t module_idP, ...@@ -192,39 +210,58 @@ void get_prach_resources(module_id_t module_idP,
if (first_Msg3 == 1) { if (first_Msg3 == 1) {
if (noGroupB == 1) { if (noGroupB == 1) {
// use Group A procedure // use Group A procedure
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = (taus())%numberOfRA_Preambles; UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex =
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0; (taus()) % numberOfRA_Preambles;
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex =
0;
UE_mac_inst[module_idP].RA_usedGroupA = 1; UE_mac_inst[module_idP].RA_usedGroupA = 1;
} else if ((Msg3_size <messageSizeGroupA) || } else if ((Msg3_size < messageSizeGroupA) ||
(get_PL(module_idP,0,eNB_index) > PLThreshold)) { (get_PL(module_idP, 0, eNB_index) > PLThreshold)) {
// use Group A procedure // use Group A procedure
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = (taus())%sizeOfRA_PreamblesGroupA; UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex =
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0; (taus()) % sizeOfRA_PreamblesGroupA;
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex =
0;
UE_mac_inst[module_idP].RA_usedGroupA = 1; UE_mac_inst[module_idP].RA_usedGroupA = 1;
} else { // use Group B } else { // use Group B
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = sizeOfRA_PreamblesGroupA + UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex =
(taus())%(numberOfRA_Preambles - sizeOfRA_PreamblesGroupA); sizeOfRA_PreamblesGroupA +
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0; (taus()) % (numberOfRA_Preambles -
sizeOfRA_PreamblesGroupA);
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex =
0;
UE_mac_inst[module_idP].RA_usedGroupA = 0; UE_mac_inst[module_idP].RA_usedGroupA = 0;
} }
UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER = get_Po_NOMINAL_PUSCH(module_idP,CC_id); UE_mac_inst[module_idP].
RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER =
get_Po_NOMINAL_PUSCH(module_idP, CC_id);
} else { // Msg3 is being retransmitted } else { // Msg3 is being retransmitted
if (UE_mac_inst[module_idP].RA_usedGroupA == 1) { if (UE_mac_inst[module_idP].RA_usedGroupA == 1) {
if (rach_ConfigCommon->preambleInfo.preamblesGroupAConfig) { if (rach_ConfigCommon->preambleInfo.preamblesGroupAConfig) {
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = (taus())%rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA; UE_mac_inst[module_idP].RA_prach_resources.
ra_PreambleIndex =
(taus()) %
rach_ConfigCommon->preambleInfo.
preamblesGroupAConfig->sizeOfRA_PreamblesGroupA;
} else { } else {
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = (taus())&0x3f; UE_mac_inst[module_idP].RA_prach_resources.
ra_PreambleIndex = (taus()) & 0x3f;
} }
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0; UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex =
0;
} else { } else {
// FIXME rach_ConfigCommon->preambleInfo.preamblesGroupAConfig may be zero // FIXME rach_ConfigCommon->preambleInfo.preamblesGroupAConfig may be zero
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex =
rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA + rach_ConfigCommon->preambleInfo.
(taus())%(rach_ConfigCommon->preambleInfo.numberOfRA_Preambles - preamblesGroupAConfig->sizeOfRA_PreamblesGroupA +
rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA); (taus()) %
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0; (rach_ConfigCommon->preambleInfo.numberOfRA_Preambles -
rach_ConfigCommon->preambleInfo.
preamblesGroupAConfig->sizeOfRA_PreamblesGroupA);
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex =
0;
} }
} }
...@@ -232,111 +269,148 @@ void get_prach_resources(module_id_t module_idP, ...@@ -232,111 +269,148 @@ void get_prach_resources(module_id_t module_idP,
if (UE_mac_inst[module_idP].tdd_Config) { if (UE_mac_inst[module_idP].tdd_Config) {
num_prach = get_num_prach_tdd(module_idP); num_prach = get_num_prach_tdd(module_idP);
if ((num_prach>0) && (num_prach<6)) { if ((num_prach > 0) && (num_prach < 6)) {
UE_mac_inst[module_idP].RA_prach_resources.ra_TDD_map_index = (taus()%num_prach); UE_mac_inst[module_idP].RA_prach_resources.ra_TDD_map_index =
(taus() % num_prach);
} }
f_id = get_fid_prach_tdd(module_idP, f_id = get_fid_prach_tdd(module_idP,
UE_mac_inst[module_idP].RA_prach_resources.ra_TDD_map_index); UE_mac_inst
[module_idP].RA_prach_resources.
ra_TDD_map_index);
} }
// choose RA-RNTI // choose RA-RNTI
UE_mac_inst[module_idP].RA_prach_resources.ra_RNTI = 1 + t_id + 10*f_id; UE_mac_inst[module_idP].RA_prach_resources.ra_RNTI =
1 + t_id + 10 * f_id;
} }
void Msg1_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id) void
Msg1_transmitted(module_id_t module_idP, uint8_t CC_id,
frame_t frameP, uint8_t eNB_id)
{ {
AssertFatal(CC_id==0, AssertFatal(CC_id == 0,
"Transmission on secondary CCs is not supported yet\n"); "Transmission on secondary CCs is not supported yet\n");
// start contention resolution timer // start contention resolution timer
UE_mac_inst[module_idP].RA_attempt_number++; UE_mac_inst[module_idP].RA_attempt_number++;
if (opt_enabled) { if (opt_enabled) {
trace_pdu(0, NULL, 0, module_idP, 0 , UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex, trace_pdu(0, NULL, 0, module_idP, 0,
UE_mac_inst[module_idP].txFrame, UE_mac_inst[module_idP].txSubframe, 0, UE_mac_inst[module_idP].RA_attempt_number); UE_mac_inst[module_idP].RA_prach_resources.
LOG_D(OPT,"[UE %d][RAPROC] TX MSG1 Frame %d trace pdu for rnti %x with size %d\n", ra_PreambleIndex, UE_mac_inst[module_idP].txFrame,
UE_mac_inst[module_idP].txSubframe, 0,
UE_mac_inst[module_idP].RA_attempt_number);
LOG_D(OPT,
"[UE %d][RAPROC] TX MSG1 Frame %d trace pdu for rnti %x with size %d\n",
module_idP, frameP, 1, UE_mac_inst[module_idP].RA_Msg3_size); module_idP, frameP, 1, UE_mac_inst[module_idP].RA_Msg3_size);
} }
} }
void Msg3_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id) void
Msg3_transmitted(module_id_t module_idP, uint8_t CC_id,
frame_t frameP, uint8_t eNB_id)
{ {
AssertFatal(CC_id==0, AssertFatal(CC_id == 0,
"Transmission on secondary CCs is not supported yet\n"); "Transmission on secondary CCs is not supported yet\n");
// start contention resolution timer // start contention resolution timer
LOG_D(MAC,"[UE %d][RAPROC] Frame %d : Msg3_tx: Setting contention resolution timer\n",module_idP,frameP); LOG_D(MAC,
"[UE %d][RAPROC] Frame %d : Msg3_tx: Setting contention resolution timer\n",
module_idP, frameP);
UE_mac_inst[module_idP].RA_contention_resolution_cnt = 0; UE_mac_inst[module_idP].RA_contention_resolution_cnt = 0;
UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 1; UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 1;
if (opt_enabled) { // msg3 if (opt_enabled) { // msg3
trace_pdu(0, &UE_mac_inst[module_idP].CCCH_pdu.payload[0], UE_mac_inst[module_idP].RA_Msg3_size, trace_pdu(0, &UE_mac_inst[module_idP].CCCH_pdu.payload[0],
module_idP, 3, UE_mac_inst[module_idP].crnti, UE_mac_inst[module_idP].txFrame, UE_mac_inst[module_idP].txSubframe, 0, 0); UE_mac_inst[module_idP].RA_Msg3_size, module_idP, 3,
LOG_D(OPT,"[UE %d][RAPROC] MSG3 Frame %d trace pdu Preamble %d with size %d\n", UE_mac_inst[module_idP].crnti,
module_idP, frameP, UE_mac_inst[module_idP].crnti /*UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex*/, UE_mac_inst[module_idP].RA_Msg3_size); UE_mac_inst[module_idP].txFrame,
UE_mac_inst[module_idP].txSubframe, 0, 0);
LOG_D(OPT,
"[UE %d][RAPROC] MSG3 Frame %d trace pdu Preamble %d with size %d\n",
module_idP, frameP, UE_mac_inst[module_idP].crnti
/*UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex */
, UE_mac_inst[module_idP].RA_Msg3_size);
} }
} }
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) PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id,
frame_t frameP, uint8_t eNB_indexP,
sub_frame_t subframeP)
{ {
uint8_t Size = 0; uint8_t Size = 0;
UE_MODE_t UE_mode = get_ue_mode(module_idP,0,eNB_indexP); UE_MODE_t UE_mode = get_ue_mode(module_idP, 0, eNB_indexP);
uint8_t lcid = CCCH; uint8_t lcid = CCCH;
uint16_t Size16; uint16_t Size16;
struct RACH_ConfigCommon *rach_ConfigCommon = (struct RACH_ConfigCommon *)NULL; struct RACH_ConfigCommon *rach_ConfigCommon =
(struct RACH_ConfigCommon *) NULL;
int32_t frame_diff = 0; int32_t frame_diff = 0;
mac_rlc_status_resp_t rlc_status; mac_rlc_status_resp_t rlc_status;
uint8_t dcch_header_len = 0; uint8_t dcch_header_len = 0;
uint16_t sdu_lengths[8]; uint16_t sdu_lengths[8];
uint8_t ulsch_buff[MAX_ULSCH_PAYLOAD_BYTES]; uint8_t ulsch_buff[MAX_ULSCH_PAYLOAD_BYTES];
AssertFatal(CC_id==0, AssertFatal(CC_id == 0,
"Transmission on secondary CCs is not supported yet\n"); "Transmission on secondary CCs is not supported yet\n");
if (UE_mode == PRACH) { if (UE_mode == PRACH) {
if (UE_mac_inst[module_idP].radioResourceConfigCommon) { if (UE_mac_inst[module_idP].radioResourceConfigCommon) {
rach_ConfigCommon = &UE_mac_inst[module_idP].radioResourceConfigCommon->rach_ConfigCommon; rach_ConfigCommon =
&UE_mac_inst[module_idP].
radioResourceConfigCommon->rach_ConfigCommon;
} else { } else {
return(NULL); return (NULL);
} }
if (UE_mac_inst[module_idP].RA_active == 0) { if (UE_mac_inst[module_idP].RA_active == 0) {
LOG_I(MAC,"RA not active\n"); LOG_I(MAC, "RA not active\n");
// check if RRC is ready to initiate the RA procedure // check if RRC is ready to initiate the RA procedure
Size = mac_rrc_data_req(module_idP, Size = mac_rrc_data_req(module_idP,
CC_id, CC_id,
frameP, frameP,
CCCH,1, CCCH, 1,
&UE_mac_inst[module_idP].CCCH_pdu.payload[sizeof(SCH_SUBHEADER_SHORT)+1],0, &UE_mac_inst[module_idP].
eNB_indexP, CCCH_pdu.payload[sizeof
(SCH_SUBHEADER_SHORT)
+ 1], 0, eNB_indexP,
0); 0);
Size16 = (uint16_t)Size; Size16 = (uint16_t) Size;
// LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n",module_idP,frameP,Size); // LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n",module_idP,frameP,Size);
LOG_I(RRC, "[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- MAC_DATA_REQ (RRCConnectionRequest eNB %d) --->][MAC_UE][MOD %02d][]\n", LOG_I(RRC,
"[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- MAC_DATA_REQ (RRCConnectionRequest eNB %d) --->][MAC_UE][MOD %02d][]\n",
frameP, module_idP, eNB_indexP, module_idP); frameP, module_idP, eNB_indexP, module_idP);
LOG_I(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n",module_idP,frameP,Size); LOG_I(MAC,
"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n",
module_idP, frameP, Size);
if (Size>0) { if (Size > 0) {
UE_mac_inst[module_idP].RA_active = 1; UE_mac_inst[module_idP].RA_active = 1;
UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER = 1; UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER =
UE_mac_inst[module_idP].RA_Msg3_size = Size+sizeof(SCH_SUBHEADER_SHORT)+sizeof(SCH_SUBHEADER_SHORT); 1;
UE_mac_inst[module_idP].RA_Msg3_size =
Size + sizeof(SCH_SUBHEADER_SHORT) +
sizeof(SCH_SUBHEADER_SHORT);
UE_mac_inst[module_idP].RA_prachMaskIndex = 0; UE_mac_inst[module_idP].RA_prachMaskIndex = 0;
UE_mac_inst[module_idP].RA_prach_resources.Msg3 = UE_mac_inst[module_idP].CCCH_pdu.payload; UE_mac_inst[module_idP].RA_prach_resources.Msg3 =
UE_mac_inst[module_idP].CCCH_pdu.payload;
UE_mac_inst[module_idP].RA_backoff_cnt = 0; // add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator) UE_mac_inst[module_idP].RA_backoff_cnt = 0; // add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator)
AssertFatal(rach_ConfigCommon!=NULL, AssertFatal(rach_ConfigCommon != NULL,
"[UE %d] FATAL Frame %d: rach_ConfigCommon is NULL !!!\n",module_idP,frameP); "[UE %d] FATAL Frame %d: rach_ConfigCommon is NULL !!!\n",
UE_mac_inst[module_idP].RA_window_cnt = 2+ rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize; module_idP, frameP);
UE_mac_inst[module_idP].RA_window_cnt =
2 +
rach_ConfigCommon->ra_SupervisionInfo.
ra_ResponseWindowSize;
if (UE_mac_inst[module_idP].RA_window_cnt == 9) { if (UE_mac_inst[module_idP].RA_window_cnt == 9) {
UE_mac_inst[module_idP].RA_window_cnt = 10; // Note: 9 subframe window doesn't exist, after 8 is 10! UE_mac_inst[module_idP].RA_window_cnt = 10; // Note: 9 subframe window doesn't exist, after 8 is 10!
...@@ -347,9 +421,10 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP, ...@@ -347,9 +421,10 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP,
UE_mac_inst[module_idP].RA_backoff_frame = frameP; UE_mac_inst[module_idP].RA_backoff_frame = frameP;
UE_mac_inst[module_idP].RA_backoff_subframe = subframeP; UE_mac_inst[module_idP].RA_backoff_subframe = subframeP;
// Fill in preamble and PRACH resource // Fill in preamble and PRACH resource
get_prach_resources(module_idP,CC_id,eNB_indexP,subframeP,1,NULL); get_prach_resources(module_idP, CC_id, eNB_indexP,
subframeP, 1, NULL);
generate_ulsch_header((uint8_t*)&UE_mac_inst[module_idP].CCCH_pdu.payload[0], // mac header generate_ulsch_header((uint8_t *) & UE_mac_inst[module_idP].CCCH_pdu.payload[0], // mac header
1, // num sdus 1, // num sdus
0, // short pading 0, // short pading
&Size16, // sdu length &Size16, // sdu length
...@@ -360,47 +435,69 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP, ...@@ -360,47 +435,69 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP,
NULL, // short bsr NULL, // short bsr
NULL, // long_bsr NULL, // long_bsr
1); //post_padding 1); //post_padding
return(&UE_mac_inst[module_idP].RA_prach_resources); return (&UE_mac_inst[module_idP].RA_prach_resources);
} else if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[DCCH]] > 0) { } else if (UE_mac_inst[module_idP].
scheduling_info.BSR_bytes[UE_mac_inst[module_idP].
scheduling_info.LCGID
[DCCH]] > 0) {
// This is for triggering a transmission on DCCH using PRACH (during handover, or sending SR for example) // This is for triggering a transmission on DCCH using PRACH (during handover, or sending SR for example)
dcch_header_len = 2 + 2; /// SHORT Subheader + C-RNTI control element dcch_header_len = 2 + 2; /// SHORT Subheader + C-RNTI control element
rlc_status = mac_rlc_status_ind(module_idP,UE_mac_inst[module_idP].crnti, eNB_indexP,frameP,subframeP,ENB_FLAG_NO,MBMS_FLAG_NO, rlc_status =
DCCH, mac_rlc_status_ind(module_idP,
6); UE_mac_inst[module_idP].crnti,
eNB_indexP, frameP, subframeP,
ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 6);
if (UE_mac_inst[module_idP].crnti_before_ho) if (UE_mac_inst[module_idP].crnti_before_ho)
LOG_D(MAC, LOG_D(MAC,
"[UE %d] Frame %d : UL-DCCH -> ULSCH, HO RRCConnectionReconfigurationComplete (%x, %x), RRC message has %d bytes to send throug PRACH (mac header len %d)\n", "[UE %d] Frame %d : UL-DCCH -> ULSCH, HO RRCConnectionReconfigurationComplete (%x, %x), RRC message has %d bytes to send throug PRACH (mac header len %d)\n",
module_idP,frameP, UE_mac_inst[module_idP].crnti,UE_mac_inst[module_idP].crnti_before_ho, rlc_status.bytes_in_buffer,dcch_header_len); module_idP, frameP,
UE_mac_inst[module_idP].crnti,
UE_mac_inst[module_idP].crnti_before_ho,
rlc_status.bytes_in_buffer, dcch_header_len);
else else
LOG_D(MAC,"[UE %d] Frame %d : UL-DCCH -> ULSCH, RRC message has %d bytes to send through PRACH(mac header len %d)\n", LOG_D(MAC,
module_idP,frameP, rlc_status.bytes_in_buffer,dcch_header_len); "[UE %d] Frame %d : UL-DCCH -> ULSCH, RRC message has %d bytes to send through PRACH(mac header len %d)\n",
module_idP, frameP, rlc_status.bytes_in_buffer,
sdu_lengths[0] = mac_rlc_data_req(module_idP, UE_mac_inst[module_idP].crnti, dcch_header_len);
eNB_indexP, frameP,ENB_FLAG_NO, MBMS_FLAG_NO,
DCCH, sdu_lengths[0] = mac_rlc_data_req(module_idP, UE_mac_inst[module_idP].crnti, eNB_indexP, frameP, ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 6, //not used
6, //not used (char *) &ulsch_buff[0]);
(char *)&ulsch_buff[0]);
LOG_D(MAC, "[UE %d] TX Got %d bytes for DCCH\n",
LOG_D(MAC,"[UE %d] TX Got %d bytes for DCCH\n",module_idP,sdu_lengths[0]); module_idP, sdu_lengths[0]);
update_bsr(module_idP, frameP, subframeP,eNB_indexP); update_bsr(module_idP, frameP, subframeP, eNB_indexP);
UE_mac_inst[module_idP].scheduling_info.BSR[UE_mac_inst[module_idP].scheduling_info.LCGID[DCCH]] = UE_mac_inst[module_idP].
locate_BsrIndexByBufferSize(BSR_TABLE, BSR_TABLE_SIZE, UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[DCCH]]); scheduling_info.BSR[UE_mac_inst[module_idP].
scheduling_info.LCGID[DCCH]] =
locate_BsrIndexByBufferSize(BSR_TABLE, BSR_TABLE_SIZE,
UE_mac_inst
[module_idP].scheduling_info.BSR_bytes
[UE_mac_inst
[module_idP].scheduling_info.LCGID
[DCCH]]);
//TO DO: fill BSR infos in UL TBS //TO DO: fill BSR infos in UL TBS
//header_len +=2; //header_len +=2;
UE_mac_inst[module_idP].RA_active = 1; UE_mac_inst[module_idP].RA_active = 1;
UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER = 1; UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER =
UE_mac_inst[module_idP].RA_Msg3_size = Size+dcch_header_len; 1;
UE_mac_inst[module_idP].RA_Msg3_size =
Size + dcch_header_len;
UE_mac_inst[module_idP].RA_prachMaskIndex = 0; UE_mac_inst[module_idP].RA_prachMaskIndex = 0;
UE_mac_inst[module_idP].RA_prach_resources.Msg3 = ulsch_buff; UE_mac_inst[module_idP].RA_prach_resources.Msg3 =
ulsch_buff;
UE_mac_inst[module_idP].RA_backoff_cnt = 0; // add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator) UE_mac_inst[module_idP].RA_backoff_cnt = 0; // add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator)
AssertFatal(rach_ConfigCommon!=NULL, AssertFatal(rach_ConfigCommon != NULL,
"[UE %d] FATAL Frame %d: rach_ConfigCommon is NULL !!!\n",module_idP,frameP); "[UE %d] FATAL Frame %d: rach_ConfigCommon is NULL !!!\n",
UE_mac_inst[module_idP].RA_window_cnt = 2+ rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize; module_idP, frameP);
UE_mac_inst[module_idP].RA_window_cnt =
2 +
rach_ConfigCommon->ra_SupervisionInfo.
ra_ResponseWindowSize;
if (UE_mac_inst[module_idP].RA_window_cnt == 9) { if (UE_mac_inst[module_idP].RA_window_cnt == 9) {
UE_mac_inst[module_idP].RA_window_cnt = 10; // Note: 9 subframe window doesn't exist, after 8 is 10! UE_mac_inst[module_idP].RA_window_cnt = 10; // Note: 9 subframe window doesn't exist, after 8 is 10!
...@@ -412,8 +509,9 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP, ...@@ -412,8 +509,9 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP,
UE_mac_inst[module_idP].RA_backoff_frame = frameP; UE_mac_inst[module_idP].RA_backoff_frame = frameP;
UE_mac_inst[module_idP].RA_backoff_subframe = subframeP; UE_mac_inst[module_idP].RA_backoff_subframe = subframeP;
// Fill in preamble and PRACH resource // Fill in preamble and PRACH resource
get_prach_resources(module_idP,CC_id,eNB_indexP,subframeP,1,NULL); get_prach_resources(module_idP, CC_id, eNB_indexP,
generate_ulsch_header((uint8_t*)ulsch_buff, // mac header subframeP, 1, NULL);
generate_ulsch_header((uint8_t *) ulsch_buff, // mac header
1, // num sdus 1, // num sdus
0, // short pading 0, // short pading
&Size16, // sdu length &Size16, // sdu length
...@@ -425,50 +523,62 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP, ...@@ -425,50 +523,62 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP,
NULL, // long_bsr NULL, // long_bsr
0); //post_padding 0); //post_padding
return(&UE_mac_inst[module_idP].RA_prach_resources); return (&UE_mac_inst[module_idP].RA_prach_resources);
} }
} else { // RACH is active } else { // RACH is active
LOG_D(MAC,"[MAC][UE %d][RAPROC] frameP %d, subframe %d: RA Active, window cnt %d (RA_tx_frame %d, RA_tx_subframe %d)\n",module_idP, LOG_D(MAC,
frameP,subframeP,UE_mac_inst[module_idP].RA_window_cnt, "[MAC][UE %d][RAPROC] frameP %d, subframe %d: RA Active, window cnt %d (RA_tx_frame %d, RA_tx_subframe %d)\n",
UE_mac_inst[module_idP].RA_tx_frame,UE_mac_inst[module_idP].RA_tx_subframe); module_idP, frameP, subframeP,
UE_mac_inst[module_idP].RA_window_cnt,
UE_mac_inst[module_idP].RA_tx_frame,
UE_mac_inst[module_idP].RA_tx_subframe);
// compute backoff parameters // compute backoff parameters
if (UE_mac_inst[module_idP].RA_backoff_cnt>0) { if (UE_mac_inst[module_idP].RA_backoff_cnt > 0) {
frame_diff = (sframe_t)frameP - UE_mac_inst[module_idP].RA_backoff_frame; frame_diff =
(sframe_t) frameP -
UE_mac_inst[module_idP].RA_backoff_frame;
if (frame_diff < 0) { if (frame_diff < 0) {
frame_diff = -frame_diff; frame_diff = -frame_diff;
} }
UE_mac_inst[module_idP].RA_backoff_cnt -= ((10*frame_diff) + (subframeP-UE_mac_inst[module_idP].RA_backoff_subframe)); UE_mac_inst[module_idP].RA_backoff_cnt -=
((10 * frame_diff) +
(subframeP -
UE_mac_inst[module_idP].RA_backoff_subframe));
UE_mac_inst[module_idP].RA_backoff_frame = frameP; UE_mac_inst[module_idP].RA_backoff_frame = frameP;
UE_mac_inst[module_idP].RA_backoff_subframe = subframeP; UE_mac_inst[module_idP].RA_backoff_subframe = subframeP;
} }
// compute RA window parameters // compute RA window parameters
if (UE_mac_inst[module_idP].RA_window_cnt>0) { if (UE_mac_inst[module_idP].RA_window_cnt > 0) {
frame_diff = (frame_t)frameP - UE_mac_inst[module_idP].RA_tx_frame; frame_diff =
(frame_t) frameP - UE_mac_inst[module_idP].RA_tx_frame;
if (frame_diff < 0) { if (frame_diff < 0) {
frame_diff = -frame_diff; frame_diff = -frame_diff;
} }
UE_mac_inst[module_idP].RA_window_cnt -= ((10*frame_diff) + (subframeP-UE_mac_inst[module_idP].RA_tx_subframe)); UE_mac_inst[module_idP].RA_window_cnt -=
LOG_D(MAC,"[MAC][UE %d][RAPROC] frameP %d, subframe %d: RA Active, adjusted window cnt %d\n",module_idP, ((10 * frame_diff) +
frameP,subframeP,UE_mac_inst[module_idP].RA_window_cnt); (subframeP - UE_mac_inst[module_idP].RA_tx_subframe));
LOG_D(MAC,
"[MAC][UE %d][RAPROC] frameP %d, subframe %d: RA Active, adjusted window cnt %d\n",
module_idP, frameP, subframeP,
UE_mac_inst[module_idP].RA_window_cnt);
} }
if ((UE_mac_inst[module_idP].RA_window_cnt<=0) && if ((UE_mac_inst[module_idP].RA_window_cnt <= 0) &&
(UE_mac_inst[module_idP].RA_backoff_cnt<=0)) { (UE_mac_inst[module_idP].RA_backoff_cnt <= 0)) {
UE_mac_inst[module_idP].RA_tx_frame = frameP; UE_mac_inst[module_idP].RA_tx_frame = frameP;
UE_mac_inst[module_idP].RA_tx_subframe = subframeP; UE_mac_inst[module_idP].RA_tx_subframe = subframeP;
UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER++; UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER++;
UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER += UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER += (rach_ConfigCommon->powerRampingParameters.powerRampingStep << 1); // 2dB increments in ASN.1 definition
(rach_ConfigCommon->powerRampingParameters.powerRampingStep<<1); // 2dB increments in ASN.1 definition
int preambleTransMax = -1; int preambleTransMax = -1;
switch (rach_ConfigCommon->ra_SupervisionInfo.preambleTransMax) { switch (rach_ConfigCommon->ra_SupervisionInfo.
preambleTransMax) {
case PreambleTransMax_n3: case PreambleTransMax_n3:
preambleTransMax = 3; preambleTransMax = 3;
break; break;
...@@ -504,25 +614,37 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP, ...@@ -504,25 +614,37 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP,
break; break;
} }
if (UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER == preambleTransMax) { if (UE_mac_inst[module_idP].
LOG_D(MAC,"[UE %d] Frame %d: Maximum number of RACH attempts (%d)\n",module_idP,frameP,preambleTransMax); RA_PREAMBLE_TRANSMISSION_COUNTER == preambleTransMax) {
LOG_D(MAC,
"[UE %d] Frame %d: Maximum number of RACH attempts (%d)\n",
module_idP, frameP, preambleTransMax);
// send message to RRC // send message to RRC
UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER=1; UE_mac_inst[module_idP].
UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER = get_Po_NOMINAL_PUSCH(module_idP,CC_id); RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
UE_mac_inst[module_idP].
RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER
= get_Po_NOMINAL_PUSCH(module_idP, CC_id);
} }
UE_mac_inst[module_idP].RA_window_cnt = 2+ rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize; UE_mac_inst[module_idP].RA_window_cnt =
2 +
rach_ConfigCommon->ra_SupervisionInfo.
ra_ResponseWindowSize;
UE_mac_inst[module_idP].RA_backoff_cnt = 0; UE_mac_inst[module_idP].RA_backoff_cnt = 0;
// Fill in preamble and PRACH resource // Fill in preamble and PRACH resource
get_prach_resources(module_idP,CC_id,eNB_indexP,subframeP,0,NULL); get_prach_resources(module_idP, CC_id, eNB_indexP,
return(&UE_mac_inst[module_idP].RA_prach_resources); subframeP, 0, NULL);
return (&UE_mac_inst[module_idP].RA_prach_resources);
} }
} }
} else if (UE_mode == PUSCH) { } else if (UE_mode == PUSCH) {
LOG_D(MAC,"[UE %d] FATAL: Should not have checked for RACH in PUSCH yet ...",module_idP); LOG_D(MAC,
AssertFatal(1==0,""); "[UE %d] FATAL: Should not have checked for RACH in PUSCH yet ...",
module_idP);
AssertFatal(1 == 0, "");
} }
return(NULL); return (NULL);
} }
...@@ -47,185 +47,151 @@ extern unsigned short RIV2first_rb_LUT25[512]; ...@@ -47,185 +47,151 @@ extern unsigned short RIV2first_rb_LUT25[512];
extern RAN_CONTEXT_t RC; extern RAN_CONTEXT_t RC;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
unsigned short fill_rar( unsigned short
const module_id_t module_idP, fill_rar(const module_id_t module_idP,
const int CC_id, const int CC_id,
RA_t * ra,
const frame_t frameP, const frame_t frameP,
uint8_t* const dlsch_buffer, uint8_t * const dlsch_buffer,
const uint16_t N_RB_UL, const uint16_t N_RB_UL, const uint8_t input_buffer_length)
const uint8_t input_buffer_length
)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *)dlsch_buffer; RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *) dlsch_buffer;
// RAR_PDU *rar = (RAR_PDU *)(dlsch_buffer+1); uint8_t *rar = (uint8_t *) (dlsch_buffer + 1);
uint8_t *rar = (uint8_t *)(dlsch_buffer+1);
int i,ra_idx = -1;
RA_TEMPLATE *RA_template;
AssertFatal(CC_id < MAX_NUM_CCs, "CC_id %u < MAX_NUM_CCs %u", CC_id, MAX_NUM_CCs);
for (i=0; i<NB_RA_PROC_MAX; i++) {
if (RC.mac[module_idP]->common_channels[CC_id].RA_template[i].generate_rar == 1) {
ra_idx=i;
RC.mac[module_idP]->common_channels[CC_id].RA_template[i].generate_rar = 0;
break;
}
}
RA_template = &RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx];
//DevAssert( ra_idx != -1 );
if (ra_idx==-1)
return(0);
// subheader fixed // subheader fixed
rarh->E = 0; // First and last RAR rarh->E = 0; // First and last RAR
rarh->T = 1; // 0 for E/T/R/R/BI subheader, 1 for E/T/RAPID subheader rarh->T = 1; // 0 for E/T/R/R/BI subheader, 1 for E/T/RAPID subheader
rarh->RAPID = RA_template->preamble_index; // Respond to Preamble 0 only for the moment rarh->RAPID = ra->preamble_index; // Respond to Preamble 0 only for the moment
rar[4] = (uint8_t)(RA_template->rnti>>8); rar[4] = (uint8_t) (ra->rnti >> 8);
rar[5] = (uint8_t)(RA_template->rnti&0xff); rar[5] = (uint8_t) (ra->rnti & 0xff);
//RA_template->timing_offset = 0; //ra->timing_offset = 0;
RA_template->timing_offset /= 16; //T_A = N_TA/16, where N_TA should be on a 30.72Msps ra->timing_offset /= 16; //T_A = N_TA/16, where N_TA should be on a 30.72Msps
rar[0] = (uint8_t)(RA_template->timing_offset>>(2+4)); // 7 MSBs of timing advance + divide by 4 rar[0] = (uint8_t) (ra->timing_offset >> (2 + 4)); // 7 MSBs of timing advance + divide by 4
rar[1] = (uint8_t)(RA_template->timing_offset<<(4-2))&0xf0; // 4 LSBs of timing advance + divide by 4 rar[1] = (uint8_t) (ra->timing_offset << (4 - 2)) & 0xf0; // 4 LSBs of timing advance + divide by 4
RA_template->msg3_first_rb=6; ra->msg3_first_rb = 6;
RA_template->msg3_nb_rb=1; ra->msg3_nb_rb = 1;
uint16_t rballoc = mac_computeRIV(N_RB_UL,RA_template->msg3_first_rb,RA_template->msg3_nb_rb); // first PRB only for UL Grant uint16_t rballoc = mac_computeRIV(N_RB_UL, ra->msg3_first_rb, ra->msg3_nb_rb); // first PRB only for UL Grant
rar[1] |= (rballoc>>7)&7; // Hopping = 0 (bit 3), 3 MSBs of rballoc rar[1] |= (rballoc >> 7) & 7; // Hopping = 0 (bit 3), 3 MSBs of rballoc
rar[2] = ((uint8_t)(rballoc&0xff))<<1; // 7 LSBs of rballoc rar[2] = ((uint8_t) (rballoc & 0xff)) << 1; // 7 LSBs of rballoc
RA_template->msg3_mcs = 10; ra->msg3_mcs = 10;
RA_template->msg3_TPC = 3; ra->msg3_TPC = 3;
RA_template->msg3_ULdelay = 0; ra->msg3_ULdelay = 0;
RA_template->msg3_cqireq = 0; ra->msg3_cqireq = 0;
rar[2] |= ((RA_template->msg3_mcs&0x8)>>3); // mcs 10 rar[2] |= ((ra->msg3_mcs & 0x8) >> 3); // mcs 10
rar[3] = (((RA_template->msg3_mcs&0x7)<<5)) | ((RA_template->msg3_TPC&7)<<2) | ((RA_template->msg3_ULdelay&1)<<1) | (RA_template->msg3_cqireq&1); rar[3] =
(((ra->msg3_mcs & 0x7) << 5)) | ((ra->msg3_TPC & 7) << 2) |
LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Generating RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for ra_idx %d, CRNTI %x,preamble %d/%d,TIMING OFFSET %d\n", ((ra->msg3_ULdelay & 1) << 1) | (ra->msg3_cqireq & 1);
module_idP, CC_id,
frameP,
*(uint8_t*)rarh,rar[0],rar[1],rar[2],rar[3],rar[4],rar[5],
ra_idx,
RA_template->rnti,
rarh->RAPID,RC.mac[module_idP]->common_channels[CC_id].RA_template[0].preamble_index,
RA_template->timing_offset);
if (opt_enabled) { if (opt_enabled) {
trace_pdu(1, dlsch_buffer, input_buffer_length, module_idP, 2, 1, trace_pdu(1, dlsch_buffer, input_buffer_length, module_idP, 2, 1,
RC.mac[module_idP]->frame, RC.mac[module_idP]->subframe, 0, 0); RC.mac[module_idP]->frame, RC.mac[module_idP]->subframe,
LOG_D(OPT,"[eNB %d][RAPROC] CC_id %d RAR Frame %d trace pdu for rnti %x and rapid %d size %d\n", 0, 0);
module_idP, CC_id, frameP, RA_template->rnti, LOG_D(OPT,
rarh->RAPID, input_buffer_length); "[eNB %d][RAPROC] CC_id %d RAR Frame %d trace pdu for rnti %x and rapid %d size %d\n",
module_idP, CC_id, frameP, ra->rnti, rarh->RAPID,
input_buffer_length);
} }
return(RA_template->rnti); return (ra->rnti);
} }
#ifdef Rel14 #ifdef Rel14
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
unsigned short fill_rar_br(eNB_MAC_INST *eNB, unsigned short
fill_rar_br(eNB_MAC_INST * eNB,
int CC_id, int CC_id,
RA_TEMPLATE *RA_template, RA_t * ra,
const frame_t frameP, const frame_t frameP,
const sub_frame_t subframeP, const sub_frame_t subframeP,
uint8_t* const dlsch_buffer, uint8_t * const dlsch_buffer, const uint8_t ce_level)
const uint8_t ce_level
)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *)dlsch_buffer; RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *) dlsch_buffer;
COMMON_channels_t *cc = &eNB->common_channels[CC_id]; COMMON_channels_t *cc = &eNB->common_channels[CC_id];
uint8_t *rar = (uint8_t *)(dlsch_buffer+1); uint8_t *rar = (uint8_t *) (dlsch_buffer + 1);
// uint8_t nb,reps; // uint8_t nb,reps;
uint8_t rballoc; uint8_t rballoc;
uint8_t mcs,TPC,ULdelay,cqireq; uint8_t mcs, TPC, ULdelay, cqireq;
int input_buffer_length; int input_buffer_length;
AssertFatal(RA_template != NULL, "RA is null \n"); AssertFatal(ra != NULL, "RA is null \n");
// subheader fixed // subheader fixed
rarh->E = 0; // First and last RAR rarh->E = 0; // First and last RAR
rarh->T = 1; // 0 for E/T/R/R/BI subheader, 1 for E/T/RAPID subheader rarh->T = 1; // 0 for E/T/R/R/BI subheader, 1 for E/T/RAPID subheader
rarh->RAPID = RA_template->preamble_index; // Respond to Preamble 0 only for the moment rarh->RAPID = ra->preamble_index; // Respond to Preamble 0 only for the moment
RA_template->timing_offset /= 16; //T_A = N_TA/16, where N_TA should be on a 30.72Msps ra->timing_offset /= 16; //T_A = N_TA/16, where N_TA should be on a 30.72Msps
rar[0] = (uint8_t)(RA_template->timing_offset>>(2+4)); // 7 MSBs of timing advance + divide by 4 rar[0] = (uint8_t) (ra->timing_offset >> (2 + 4)); // 7 MSBs of timing advance + divide by 4
rar[1] = (uint8_t)(RA_template->timing_offset<<(4-2))&0xf0; // 4 LSBs of timing advance + divide by 4 rar[1] = (uint8_t) (ra->timing_offset << (4 - 2)) & 0xf0; // 4 LSBs of timing advance + divide by 4
int N_NB_index; int N_NB_index;
AssertFatal(1==0,"RAR for BL/CE Still to be finished ...\n"); AssertFatal(1 == 0, "RAR for BL/CE Still to be finished ...\n");
// Copy the Msg2 narrowband // Copy the Msg2 narrowband
RA_template->msg34_narrowband = RA_template->msg2_narrowband; ra->msg34_narrowband = ra->msg2_narrowband;
if (ce_level<2) { //CE Level 0,1, CEmodeA if (ce_level < 2) { //CE Level 0,1, CEmodeA
input_buffer_length =6; input_buffer_length = 6;
N_NB_index = get_numnarrowbandbits(cc->mib->message.dl_Bandwidth); N_NB_index = get_numnarrowbandbits(cc->mib->message.dl_Bandwidth);
rar[4] = (uint8_t)(RA_template->rnti>>8); rar[4] = (uint8_t) (ra->rnti >> 8);
rar[5] = (uint8_t)(RA_template->rnti&0xff); rar[5] = (uint8_t) (ra->rnti & 0xff);
//cc->RA_template[ra_idx].timing_offset = 0; //cc->ra[ra_idx].timing_offset = 0;
// nb = 0; // nb = 0;
rballoc = mac_computeRIV(6,1+ce_level,1); // one PRB only for UL Grant in position 1+ce_level within Narrowband rballoc = mac_computeRIV(6, 1 + ce_level, 1); // one PRB only for UL Grant in position 1+ce_level within Narrowband
rar[1] |= (rballoc&15)<<(4-N_NB_index); // Hopping = 0 (bit 3), 3 MSBs of rballoc rar[1] |= (rballoc & 15) << (4 - N_NB_index); // Hopping = 0 (bit 3), 3 MSBs of rballoc
// reps = 4; // reps = 4;
mcs = 7; mcs = 7;
TPC = 3; // no power increase TPC = 3; // no power increase
ULdelay = 0; ULdelay = 0;
cqireq = 0; cqireq = 0;
rar[2] |= ((mcs&0x8)>>3); // mcs 10 rar[2] |= ((mcs & 0x8) >> 3); // mcs 10
rar[3] = (((mcs&0x7)<<5)) | ((TPC&7)<<2) | ((ULdelay&1)<<1) | (cqireq&1); rar[3] =
} (((mcs & 0x7) << 5)) | ((TPC & 7) << 2) | ((ULdelay & 1) << 1)
else { // CE level 2,3 => CEModeB | (cqireq & 1);
} else { // CE level 2,3 => CEModeB
input_buffer_length =5; input_buffer_length = 5;
rar[3] = (uint8_t)(RA_template->rnti>>8); rar[3] = (uint8_t) (ra->rnti >> 8);
rar[4] = (uint8_t)(RA_template->rnti&0xff); rar[4] = (uint8_t) (ra->rnti & 0xff);
} }
LOG_D(MAC,"[RAPROC] Frame %d Generating RAR BR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for ce_level %d, CRNTI %x,preamble %d/%d,TIMING OFFSET %d\n", LOG_D(MAC,
frameP, "[RAPROC] Frame %d Generating RAR BR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for ce_level %d, CRNTI %x,preamble %d/%d,TIMING OFFSET %d\n",
*(uint8_t*)rarh,rar[0],rar[1],rar[2],rar[3],rar[4],rar[5], frameP, *(uint8_t *) rarh, rar[0], rar[1], rar[2], rar[3],
ce_level, rar[4], rar[5], ce_level, ra->rnti, rarh->RAPID,
RA_template->rnti, ra->preamble_index, ra->timing_offset);
rarh->RAPID,RA_template->preamble_index,
RA_template->timing_offset);
if (opt_enabled) { if (opt_enabled) {
trace_pdu(1, dlsch_buffer, input_buffer_length, eNB->Mod_id, 2, 1, trace_pdu(1, dlsch_buffer, input_buffer_length, eNB->Mod_id, 2, 1,
eNB->frame, eNB->subframe, 0, 0); eNB->frame, eNB->subframe, 0, 0);
LOG_D(OPT,"[RAPROC] RAR Frame %d trace pdu for rnti %x and rapid %d size %d\n", LOG_D(OPT,
frameP, RA_template->rnti, "[RAPROC] RAR Frame %d trace pdu for rnti %x and rapid %d size %d\n",
rarh->RAPID, input_buffer_length); frameP, ra->rnti, rarh->RAPID, input_buffer_length);
} }
return(RA_template->rnti); return (ra->rnti);
} }
#endif #endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
uint16_t uint16_t ue_process_rar(const module_id_t module_idP, const int CC_id, const frame_t frameP, const rnti_t ra_rnti, uint8_t * const dlsch_buffer, rnti_t * const t_crnti, const uint8_t preamble_index, uint8_t * selected_rar_buffer // output argument for storing the selected RAR header and RAR payload
ue_process_rar( )
const module_id_t module_idP,
const int CC_id,
const frame_t frameP,
const rnti_t ra_rnti,
uint8_t* const dlsch_buffer,
rnti_t* const t_crnti,
const uint8_t preamble_index,
uint8_t* selected_rar_buffer // output argument for storing the selected RAR header and RAR payload
)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
uint16_t ret = 0; // return value uint16_t ret = 0; // return value
RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *)dlsch_buffer; RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *) dlsch_buffer;
// RAR_PDU *rar = (RAR_PDU *)(dlsch_buffer+1); // RAR_PDU *rar = (RAR_PDU *)(dlsch_buffer+1);
uint8_t *rar = (uint8_t *)(dlsch_buffer+1); uint8_t *rar = (uint8_t *) (dlsch_buffer + 1);
// get the last RAR payload for working with CMW500 // get the last RAR payload for working with CMW500
uint8_t n_rarpy = 0; // number of RAR payloads uint8_t n_rarpy = 0; // number of RAR payloads
...@@ -239,69 +205,80 @@ ue_process_rar( ...@@ -239,69 +205,80 @@ ue_process_rar(
} }
if (rarh->RAPID == preamble_index) { if (rarh->RAPID == preamble_index) {
LOG_D(PHY, "Found RAR with the intended RAPID %d\n", rarh->RAPID); LOG_D(PHY, "Found RAR with the intended RAPID %d\n",
rar = (uint8_t *)(dlsch_buffer+n_rarh + (n_rarpy-1)*6); rarh->RAPID);
rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6);
break; break;
} }
if (abs((int)rarh->RAPID - (int)preamble_index) < abs((int)best_rx_rapid - (int)preamble_index)) { if (abs((int) rarh->RAPID - (int) preamble_index) <
abs((int) best_rx_rapid - (int) preamble_index)) {
best_rx_rapid = rarh->RAPID; best_rx_rapid = rarh->RAPID;
rar = (uint8_t *)(dlsch_buffer+n_rarh + (n_rarpy-1)*6); rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6);
} }
if (rarh->E == 0) { if (rarh->E == 0) {
LOG_I(PHY, "No RAR found with the intended RAPID. The closest RAPID in all RARs is %d\n", best_rx_rapid); LOG_I(PHY,
"No RAR found with the intended RAPID. The closest RAPID in all RARs is %d\n",
best_rx_rapid);
break; break;
} else { } else {
rarh++; rarh++;
} }
}; };
LOG_D(MAC, "number of RAR subheader %d; number of RAR pyloads %d\n", n_rarh, n_rarpy); LOG_D(MAC, "number of RAR subheader %d; number of RAR pyloads %d\n",
n_rarh, n_rarpy);
if (CC_id>0) { if (CC_id > 0) {
LOG_W(MAC,"Should not have received RAR on secondary CCs! \n"); LOG_W(MAC, "Should not have received RAR on secondary CCs! \n");
return(0xffff); return (0xffff);
} }
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n",module_idP,frameP, LOG_I(MAC,
*(uint8_t*)rarh,rar[0],rar[1],rar[2],rar[3],rar[4],rar[5], "[eNB %d][RAPROC] Frame %d Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n",
rarh->RAPID,preamble_index); module_idP, frameP, *(uint8_t *) rarh, rar[0], rar[1], rar[2],
rar[3], rar[4], rar[5], rarh->RAPID, preamble_index);
#ifdef DEBUG_RAR #ifdef DEBUG_RAR
LOG_D(MAC,"[UE %d][RAPROC] rarh->E %d\n",module_idP,rarh->E); LOG_D(MAC, "[UE %d][RAPROC] rarh->E %d\n", module_idP, rarh->E);
LOG_D(MAC,"[UE %d][RAPROC] rarh->T %d\n",module_idP,rarh->T); LOG_D(MAC, "[UE %d][RAPROC] rarh->T %d\n", module_idP, rarh->T);
LOG_D(MAC,"[UE %d][RAPROC] rarh->RAPID %d\n",module_idP,rarh->RAPID); LOG_D(MAC, "[UE %d][RAPROC] rarh->RAPID %d\n", module_idP,
rarh->RAPID);
// LOG_I(MAC,"[UE %d][RAPROC] rar->R %d\n",module_idP,rar->R); // LOG_I(MAC,"[UE %d][RAPROC] rar->R %d\n",module_idP,rar->R);
LOG_D(MAC,"[UE %d][RAPROC] rar->Timing_Advance_Command %d\n",module_idP,(((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4)); LOG_D(MAC, "[UE %d][RAPROC] rar->Timing_Advance_Command %d\n",
module_idP, (((uint16_t) (rar[0] & 0x7f)) << 4) + (rar[1] >> 4));
// LOG_I(MAC,"[UE %d][RAPROC] rar->hopping_flag %d\n",module_idP,rar->hopping_flag); // LOG_I(MAC,"[UE %d][RAPROC] rar->hopping_flag %d\n",module_idP,rar->hopping_flag);
// LOG_I(MAC,"[UE %d][RAPROC] rar->rb_alloc %d\n",module_idP,rar->rb_alloc); // LOG_I(MAC,"[UE %d][RAPROC] rar->rb_alloc %d\n",module_idP,rar->rb_alloc);
// LOG_I(MAC,"[UE %d][RAPROC] rar->mcs %d\n",module_idP,rar->mcs); // LOG_I(MAC,"[UE %d][RAPROC] rar->mcs %d\n",module_idP,rar->mcs);
// LOG_I(MAC,"[UE %d][RAPROC] rar->TPC %d\n",module_idP,rar->TPC); // LOG_I(MAC,"[UE %d][RAPROC] rar->TPC %d\n",module_idP,rar->TPC);
// LOG_I(MAC,"[UE %d][RAPROC] rar->UL_delay %d\n",module_idP,rar->UL_delay); // LOG_I(MAC,"[UE %d][RAPROC] rar->UL_delay %d\n",module_idP,rar->UL_delay);
// LOG_I(MAC,"[UE %d][RAPROC] rar->cqi_req %d\n",module_idP,rar->cqi_req); // LOG_I(MAC,"[UE %d][RAPROC] rar->cqi_req %d\n",module_idP,rar->cqi_req);
LOG_D(MAC,"[UE %d][RAPROC] rar->t_crnti %x\n",module_idP,(uint16_t)rar[5]+(rar[4]<<8)); LOG_D(MAC, "[UE %d][RAPROC] rar->t_crnti %x\n", module_idP,
(uint16_t) rar[5] + (rar[4] << 8));
#endif #endif
if (opt_enabled) { if (opt_enabled) {
LOG_D(OPT,"[UE %d][RAPROC] CC_id %d RAR Frame %d trace pdu for ra-RNTI %x\n", LOG_D(OPT,
"[UE %d][RAPROC] CC_id %d RAR Frame %d trace pdu for ra-RNTI %x\n",
module_idP, CC_id, frameP, ra_rnti); module_idP, CC_id, frameP, ra_rnti);
trace_pdu(1, (uint8_t*)dlsch_buffer, n_rarh + n_rarpy*6, module_idP, 2, ra_rnti, trace_pdu(1, (uint8_t *) dlsch_buffer, n_rarh + n_rarpy * 6,
UE_mac_inst[module_idP].rxFrame, UE_mac_inst[module_idP].rxSubframe, 0, 0); module_idP, 2, ra_rnti, UE_mac_inst[module_idP].rxFrame,
UE_mac_inst[module_idP].rxSubframe, 0, 0);
} }
if (preamble_index == rarh->RAPID) { if (preamble_index == rarh->RAPID) {
*t_crnti = (uint16_t)rar[5]+(rar[4]<<8);//rar->t_crnti; *t_crnti = (uint16_t) rar[5] + (rar[4] << 8); //rar->t_crnti;
UE_mac_inst[module_idP].crnti = *t_crnti;//rar->t_crnti; UE_mac_inst[module_idP].crnti = *t_crnti; //rar->t_crnti;
//return(rar->Timing_Advance_Command); //return(rar->Timing_Advance_Command);
ret = ((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4)); ret = ((((uint16_t) (rar[0] & 0x7f)) << 4) + (rar[1] >> 4));
} else { } else {
UE_mac_inst[module_idP].crnti=0; UE_mac_inst[module_idP].crnti = 0;
ret = (0xffff); ret = (0xffff);
} }
// move the selected RAR to the front of the RA_PDSCH buffer // move the selected RAR to the front of the RA_PDSCH buffer
memcpy(selected_rar_buffer+0, (uint8_t*)rarh, 1); memcpy(selected_rar_buffer + 0, (uint8_t *) rarh, 1);
memcpy(selected_rar_buffer+1, (uint8_t*)rar , 6); memcpy(selected_rar_buffer + 1, (uint8_t *) rar, 6);
return ret; return ret;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -39,20 +39,27 @@ ...@@ -39,20 +39,27 @@
#include "defs.h" #include "defs.h"
#include "COMMON/mac_rrc_primitives.h" #include "COMMON/mac_rrc_primitives.h"
const uint32_t BSR_TABLE[BSR_TABLE_SIZE]= {0,10,12,14,17,19,22,26,31,36,42,49,57,67,78,91, const uint32_t BSR_TABLE[BSR_TABLE_SIZE] =
105,125,146,171,200,234,274,321,376,440,515,603,706,826,967,1132, { 0, 10, 12, 14, 17, 19, 22, 26, 31, 36, 42, 49, 57, 67, 78, 91,
1326,1552,1817,2127,2490,2915,3413,3995,4677,5467,6411,7505,8787,10287,12043,14099, 105, 125, 146, 171, 200, 234, 274, 321, 376, 440, 515, 603, 706, 826,
16507,19325,22624,26487,31009,36304,42502,49759,58255,68201,79846,93479,109439, 128125,150000, 300000 967, 1132,
}; 1326, 1552, 1817, 2127, 2490, 2915, 3413, 3995, 4677, 5467, 6411, 7505,
8787, 10287, 12043, 14099,
16507, 19325, 22624, 26487, 31009, 36304, 42502, 49759, 58255, 68201,
79846, 93479, 109439, 128125, 150000, 300000
};
// extended bsr table--currently not used // extended bsr table--currently not used
const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE] = {0,10,13,16,19,23,29,35,43,53,65,80,98,120,147, const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE] =
181,223,274,337,414,509,625,769,945,1162,1429, { 0, 10, 13, 16, 19, 23, 29, 35, 43, 53, 65, 80, 98, 120, 147,
1757,2161,2657,3267,4017,4940,6074,7469,9185, 181, 223, 274, 337, 414, 509, 625, 769, 945, 1162, 1429,
11294,13888,17077,20999,25822,31752,39045,48012, 1757, 2161, 2657, 3267, 4017, 4940, 6074, 7469, 9185,
59039,72598,89272,109774,134986,165989,204111, 11294, 13888, 17077, 20999, 25822, 31752, 39045, 48012,
250990,308634,379519,466683,573866,705666,867737, 59039, 72598, 89272, 109774, 134986, 165989, 204111,
1067031,1312097,1613447,1984009,2439678,3000000, 250990, 308634, 379519, 466683, 573866, 705666, 867737,
6000000}; 1067031, 1312097, 1613447, 1984009, 2439678, 3000000,
6000000
};
//#define MAX_SIZE_OF_AGG3 576 //#define MAX_SIZE_OF_AGG3 576
//#define MAX_SIZE_OF_AGG2 288 //#define MAX_SIZE_OF_AGG2 288
...@@ -64,20 +71,22 @@ const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE] = {0,10,13,16,19,23,29,35,43,5 ...@@ -64,20 +71,22 @@ const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE] = {0,10,13,16,19,23,29,35,43,5
* this is also dependent to transmission mode, where an offset could be defined * this is also dependent to transmission mode, where an offset could be defined
*/ */
// the follwoing three tables are calibrated for TXMODE 1 and 2 // the follwoing three tables are calibrated for TXMODE 1 and 2
const uint8_t cqi2fmt0_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE]= { const uint8_t cqi2fmt0_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE] = {
{3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}, // 1.4_DCI0_CRC_Size= 37 bits {3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}, // 1.4_DCI0_CRC_Size= 37 bits
//{3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0}, // 5_DCI0_CRC_SIZE = 41 //{3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0}, // 5_DCI0_CRC_SIZE = 41
{3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, // 5_DCI0_CRC_SIZE = 41 {3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, // 5_DCI0_CRC_SIZE = 41
{3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0}, // 10_DCI0_CRC_SIZE = 43 {3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0}, // 10_DCI0_CRC_SIZE = 43
{3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0} // 20_DCI0_CRC_SIZE = 44 {3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0} // 20_DCI0_CRC_SIZE = 44
}; };
const uint8_t cqi2fmt1x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE]= {
const uint8_t cqi2fmt1x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE] = {
{3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}, // 1.4_DCI0_CRC_Size < 38 bits {3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}, // 1.4_DCI0_CRC_Size < 38 bits
{3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, // 5_DCI0_CRC_SIZE < 43 {3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, // 5_DCI0_CRC_SIZE < 43
{3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0}, // 10_DCI0_CRC_SIZE < 47 {3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0}, // 10_DCI0_CRC_SIZE < 47
{3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0} // 20_DCI0_CRC_SIZE < 55 {3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0} // 20_DCI0_CRC_SIZE < 55
}; };
const uint8_t cqi2fmt2x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE]= {
const uint8_t cqi2fmt2x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE] = {
{3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}, // 1.4_DCI0_CRC_Size= 47 bits {3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}, // 1.4_DCI0_CRC_Size= 47 bits
{3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, // 5_DCI0_CRC_SIZE = 55 {3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, // 5_DCI0_CRC_SIZE = 55
{3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0}, // 10_DCI0_CRC_SIZE = 59 {3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0}, // 10_DCI0_CRC_SIZE = 59
...@@ -102,10 +111,10 @@ eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; ...@@ -102,10 +111,10 @@ eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX];
#ifdef OPENAIR2 #ifdef OPENAIR2
unsigned char NB_eNB_INST=0; unsigned char NB_eNB_INST = 0;
unsigned char NB_UE_INST=0; unsigned char NB_UE_INST = 0;
unsigned char NB_RN_INST=0; unsigned char NB_RN_INST = 0;
unsigned char NB_INST=0; unsigned char NB_INST = 0;
#endif #endif
...@@ -137,5 +146,3 @@ DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu2; ...@@ -137,5 +146,3 @@ DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu2;
DCI1E_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu1E; DCI1E_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu1E;
#endif #endif
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