Commit e190c4e2 authored by Cedric Roux's avatar Cedric Roux

Merge remote-tracking branch 'origin/RA-notation' into develop_integration_w46

parents 4a348988 d01aa2d0
...@@ -60,37 +60,37 @@ ...@@ -60,37 +60,37 @@
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
UE_mac_inst[module_idP].scheduling_info.Bj[0] = 0; UE_mac_inst[module_idP].scheduling_info.Bj[0] = 0;
UE_mac_inst[module_idP].scheduling_info.Bj[1] = 0; UE_mac_inst[module_idP].scheduling_info.Bj[1] = 0;
UE_mac_inst[module_idP].scheduling_info.Bj[2] = 0; UE_mac_inst[module_idP].scheduling_info.Bj[2] = 0;
//Stopping all timers //Stopping all timers
//timeAlignmentTimer expires //timeAlignmentTimer expires
// 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;
// stop ongoing RACH procedure // stop ongoing RACH procedure
// discard explicitly signaled ra_PreambleIndex and ra_RACH_MaskIndex, if any // discard explicitly signaled ra_PreambleIndex and ra_RACH_MaskIndex, if any
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = 0; // check! UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = 0; // check!
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0; UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0;
ue_init_mac(module_idP); //This will hopefully do the rest of the MAC reset procedure ue_init_mac(module_idP); //This will hopefully do the rest of the MAC reset procedure
} }
...@@ -115,912 +115,1236 @@ typedef struct band_info_s { ...@@ -115,912 +115,1236 @@ 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},
{13, 7770, 7870, 7460, 7560, 51800}, {13, 7770, 7870, 7460, 7560, 51800},
{14, 7880, 7980, 7580, 7680, 52800}, {14, 7880, 7980, 7580, 7680, 52800},
{17, 7040, 7160, 7340, 7460, 57300}, {17, 7040, 7160, 7340, 7460, 57300},
{18, 8150, 9650, 8600, 10100, 58500}, {18, 8150, 9650, 8600, 10100, 58500},
{19, 8300, 8450, 8750, 8900, 60000}, {19, 8300, 8450, 8750, 8900, 60000},
{20, 8320, 8620, 7910, 8210, 61500}, {20, 8320, 8620, 7910, 8210, 61500},
{21, 14479, 14629, 14959, 15109, 64500}, {21, 14479, 14629, 14959, 15109, 64500},
{22, 34100, 34900, 35100, 35900, 66000}, {22, 34100, 34900, 35100, 35900, 66000},
{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},
{36, 19300, 19900, 19300, 19900, 36950}, {36, 19300, 19900, 19300, 19900, 36950},
{37, 19100, 19300, 19100, 19300, 37550}, {37, 19100, 19300, 19100, 19300, 37550},
{38, 25700, 26200, 25700, 26300, 37750}, {38, 25700, 26200, 25700, 26300, 37750},
{39, 18800, 19200, 18800, 19200, 38250}, {39, 18800, 19200, 18800, 19200, 38250},
{40, 23000, 24000, 23000, 24000, 38650}, {40, 23000, 24000, 23000, 24000, 38650},
{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; {
int bw_by_100 = bw/100;
uint32_t dl_CarrierFreq_by_100k = dl_CarrierFreq / 100000;
int i; int bw_by_100 = bw / 100;
AssertFatal(eutra_bandP < 69,"eutra_band %d > 68\n",eutra_bandP); int i;
for (i=0;i<69 && eutra_bandtable[i].band!=eutra_bandP;i++);
AssertFatal(eutra_bandP < 69, "eutra_band %d > 68\n", eutra_bandP);
AssertFatal(dl_CarrierFreq_by_100k>=eutra_bandtable[i].dl_min, for (i = 0; i < 69 && eutra_bandtable[i].band != eutra_bandP; i++);
"Band %d, bw %u : DL carrier frequency %u Hz < %u\n",
eutra_bandP,bw,dl_CarrierFreq,eutra_bandtable[i].dl_min); AssertFatal(dl_CarrierFreq_by_100k >= 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 < %u\n",
"Band %d, bw %u: DL carrier frequency %u Hz > %d\n", eutra_bandP, bw, dl_CarrierFreq,
eutra_bandP,bw,dl_CarrierFreq,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),
return(dl_CarrierFreq_by_100k - eutra_bandtable[i].dl_min + (eutra_bandtable[i].N_OFFs_DL/10)); "Band %d, bw %u: DL carrier frequency %u Hz > %d\n",
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));
} }
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,
int CC_idP, void
int eutra_bandP, config_mib(int Mod_idP,
int dl_BandwidthP, int CC_idP,
PHICH_Config_t *phich_configP, int eutra_bandP,
int Nid_cellP, int dl_BandwidthP,
int NcpP, PHICH_Config_t * phich_configP,
int p_eNBP, int Nid_cellP,
uint32_t dl_CarrierFreqP, int NcpP,
uint32_t ul_CarrierFreqP, int p_eNBP,
uint32_t pbch_repetitionP) { uint32_t dl_CarrierFreqP,
uint32_t ul_CarrierFreqP, uint32_t pbch_repetitionP)
nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; {
cfg->subframe_config.pcfich_power_offset.value = 6000; // 0dB nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP];
cfg->subframe_config.dl_cyclic_prefix_type.value = NcpP;
cfg->subframe_config.ul_cyclic_prefix_type.value = NcpP; cfg->subframe_config.pcfich_power_offset.value = 6000; // 0dB
cfg->subframe_config.dl_cyclic_prefix_type.value = NcpP;
LOG_I(MAC,"Ncp %d,p_eNB %d\n",NcpP,p_eNBP); cfg->subframe_config.ul_cyclic_prefix_type.value = NcpP;
cfg->rf_config.dl_channel_bandwidth.value = dl_BandwidthP; LOG_I(MAC, "Ncp %d,p_eNB %d\n", NcpP, p_eNBP);
cfg->rf_config.ul_channel_bandwidth.value = dl_BandwidthP;
cfg->rf_config.tx_antenna_ports.value = p_eNBP; cfg->rf_config.dl_channel_bandwidth.value = dl_BandwidthP;
cfg->rf_config.rx_antenna_ports.value = 2; cfg->rf_config.ul_channel_bandwidth.value = dl_BandwidthP;
cfg->rf_config.tx_antenna_ports.value = p_eNBP;
cfg->nfapi_config.earfcn.value = to_earfcn(eutra_bandP,dl_CarrierFreqP,bw_table[dl_BandwidthP]/100); cfg->rf_config.rx_antenna_ports.value = 2;
cfg->nfapi_config.rf_bands.number_rf_bands = 1;
cfg->nfapi_config.rf_bands.rf_band[0] = eutra_bandP; cfg->nfapi_config.earfcn.value =
cfg->phich_config.phich_resource.value = phich_configP->phich_Resource; to_earfcn(eutra_bandP, dl_CarrierFreqP,
cfg->phich_config.phich_duration.value = phich_configP->phich_Duration; bw_table[dl_BandwidthP] / 100);
cfg->phich_config.phich_power_offset.value = 6000; // 0dB cfg->nfapi_config.rf_bands.number_rf_bands = 1;
cfg->nfapi_config.rf_bands.rf_band[0] = eutra_bandP;
cfg->sch_config.primary_synchronization_signal_epre_eprers.value = 6000; // 0dB cfg->phich_config.phich_resource.value = phich_configP->phich_Resource;
cfg->sch_config.secondary_synchronization_signal_epre_eprers.value = 6000; // 0dB cfg->phich_config.phich_duration.value = phich_configP->phich_Duration;
cfg->sch_config.physical_cell_id.value = Nid_cellP; cfg->phich_config.phich_power_offset.value = 6000; // 0dB
cfg->sch_config.primary_synchronization_signal_epre_eprers.value = 6000; // 0dB
cfg->sch_config.secondary_synchronization_signal_epre_eprers.value = 6000; // 0dB
cfg->sch_config.physical_cell_id.value = Nid_cellP;
#ifdef Rel14 #ifdef Rel14
cfg->emtc_config.pbch_repetitions_enable_r13.value = pbch_repetitionP; cfg->emtc_config.pbch_repetitions_enable_r13.value = pbch_repetitionP;
#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
cfg->subframe_config.duplex_mode.value = 0;
cfg->tdd_frame_structure_config.subframe_assignment.value =
tdd_ConfigP->subframeAssignment;
cfg->tdd_frame_structure_config.special_subframe_patterns.value =
tdd_ConfigP->specialSubframePatterns;
} else { // FDD
cfg->subframe_config.duplex_mode.value = 1;
// Note no half-duplex here
}
if (tdd_ConfigP) { //TDD
cfg->subframe_config.duplex_mode.value = 0;
cfg->tdd_frame_structure_config.subframe_assignment.value = tdd_ConfigP->subframeAssignment;
cfg->tdd_frame_structure_config.special_subframe_patterns.value = tdd_ConfigP->specialSubframePatterns;
}
else { // FDD
cfg->subframe_config.duplex_mode.value = 1;
// Note no half-duplex here
}
} }
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
int CC_idP, config_sib2(int Mod_idP,
RadioResourceConfigCommonSIB_t *radioResourceConfigCommonP, int CC_idP,
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]; {
cfg->subframe_config.pb.value = radioResourceConfigCommonP->pdsch_ConfigCommon.p_b;
cfg->rf_config.reference_signal_power.value = radioResourceConfigCommonP->pdsch_ConfigCommon.referenceSignalPower;
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->prach_config.configuration_index.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.prach_ConfigIndex;
cfg->prach_config.root_sequence_index.value = radioResourceConfigCommonP->prach_Config.rootSequenceIndex;
cfg->prach_config.zero_correlation_zone_configuration.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig;
cfg->prach_config.high_speed_flag.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.highSpeedFlag;
cfg->prach_config.frequency_offset.value = 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;
else if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled == true)
cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 2;
else // No hopping
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.cyclic_shift_1_for_drms.value = radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift;
// how to enable/disable SRS?
if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.present==SoundingRS_UL_ConfigCommon_PR_setup) {
cfg->srs_config.bandwidth_configuration.value = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig;
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;
else
cfg->srs_config.max_up_pts.value = 0;
}
#ifdef Rel14
if (RC.mac[Mod_idP]->common_channels[CC_idP].mib->message.schedulingInfoSIB1_BR_r13>0) {
AssertFatal(radioResourceConfigCommon_BRP!=NULL,"radioResource rou is missing\n");
AssertFatal(radioResourceConfigCommon_BRP->ext4!=NULL,"ext4 is missing\n");
cfg->emtc_config.prach_catm_root_sequence_index.value = radioResourceConfigCommon_BRP->prach_Config.rootSequenceIndex;
cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.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;
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_2_enable.value=0;
cfg->emtc_config.prach_ce_level_3_enable.value=0;
switch (prach_ParametersListCE_r13->list.count) {
case 4:
p=prach_ParametersListCE_r13->list.array[3];
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_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)
cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.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:
p=prach_ParametersListCE_r13->list.array[2];
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_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)
cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.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:
p=prach_ParametersListCE_r13->list.array[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_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)
cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.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:
p=prach_ParametersListCE_r13->list.array[0];
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_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)
cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.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; nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP];
if ((ext4_freqHoppingParameters) &&
(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13)){ cfg->subframe_config.pb.value =
switch(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->present) { radioResourceConfigCommonP->pdsch_ConfigCommon.p_b;
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_NOTHING: /* No components present */ cfg->rf_config.reference_signal_power.value =
break; radioResourceConfigCommonP->pdsch_ConfigCommon.
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_FDD_r13: referenceSignalPower;
cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_FDD_r13; cfg->nfapi_config.max_transmit_power.value =
break; cfg->rf_config.reference_signal_power.value +
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_TDD_r13: power_off_dB[cfg->rf_config.dl_channel_bandwidth.value];
cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_TDD_r13;
break; cfg->prach_config.configuration_index.value =
} radioResourceConfigCommonP->prach_Config.
prach_ConfigInfo.prach_ConfigIndex;
cfg->prach_config.root_sequence_index.value =
radioResourceConfigCommonP->prach_Config.rootSequenceIndex;
cfg->prach_config.zero_correlation_zone_configuration.value =
radioResourceConfigCommonP->prach_Config.
prach_ConfigInfo.zeroCorrelationZoneConfig;
cfg->prach_config.high_speed_flag.value =
radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.
highSpeedFlag;
cfg->prach_config.frequency_offset.value =
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;
else if (radioResourceConfigCommonP->
pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.
sequenceHoppingEnabled == true)
cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 2;
else // No hopping
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.cyclic_shift_1_for_drms.value =
radioResourceConfigCommonP->
pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift;
// how to enable/disable SRS?
if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.present ==
SoundingRS_UL_ConfigCommon_PR_setup) {
cfg->srs_config.bandwidth_configuration.value =
radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.
choice.setup.srs_BandwidthConfig;
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;
else
cfg->srs_config.max_up_pts.value = 0;
} }
if ((ext4_freqHoppingParameters) && #ifdef Rel14
(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13)){ if (RC.mac[Mod_idP]->common_channels[CC_idP].mib->
switch(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->present) { message.schedulingInfoSIB1_BR_r13 > 0) {
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_NOTHING: /* No components present */ AssertFatal(radioResourceConfigCommon_BRP != NULL,
break; "radioResource rou is missing\n");
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_FDD_r13: AssertFatal(radioResourceConfigCommon_BRP->ext4 != NULL,
cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_FDD_r13; "ext4 is missing\n");
break; cfg->emtc_config.prach_catm_root_sequence_index.value =
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_TDD_r13: radioResourceConfigCommon_BRP->prach_Config.rootSequenceIndex;
cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_TDD_r13; cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.
break; 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;
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_2_enable.value = 0;
cfg->emtc_config.prach_ce_level_3_enable.value = 0;
switch (prach_ParametersListCE_r13->list.count) {
case 4:
p = prach_ParametersListCE_r13->list.array[3];
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_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)
cfg->
emtc_config.prach_ce_level_3_starting_subframe_periodicity.
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:
p = prach_ParametersListCE_r13->list.array[2];
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_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)
cfg->
emtc_config.prach_ce_level_2_starting_subframe_periodicity.
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:
p = prach_ParametersListCE_r13->list.array[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_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)
cfg->
emtc_config.prach_ce_level_1_starting_subframe_periodicity.
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:
p = prach_ParametersListCE_r13->list.array[0];
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_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)
cfg->
emtc_config.prach_ce_level_0_starting_subframe_periodicity.
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;
if ((ext4_freqHoppingParameters)
&&
(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13))
{
switch
(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->
present) {
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_NOTHING: /* No components present */
break;
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;
break;
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;
break;
}
}
if ((ext4_freqHoppingParameters) &&
(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13))
{
switch
(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->
present) {
case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_NOTHING: /* No components present */
break;
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;
break;
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;
break;
}
}
} }
}
#endif #endif
} }
void config_dedicated(int Mod_idP, void
int CC_idP, config_dedicated(int Mod_idP,
uint16_t rnti, int CC_idP,
struct PhysicalConfigDedicated *physicalConfigDedicated) { uint16_t rnti,
struct PhysicalConfigDedicated *physicalConfigDedicated)
{
} }
void config_dedicated_scell(int Mod_idP, void
uint16_t rnti, config_dedicated_scell(int Mod_idP,
SCellToAddMod_r10_t *sCellToAddMod_r10) { uint16_t rnti,
SCellToAddMod_r10_t * sCellToAddMod_r10)
{
} }
int rrc_mac_config_req_eNB(module_id_t Mod_idP, int
int CC_idP, rrc_mac_config_req_eNB(module_id_t Mod_idP,
int physCellId, int CC_idP,
int p_eNB, int physCellId,
int Ncp, int p_eNB,
int eutra_band, int Ncp, 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_v13ext SystemInformationBlockType1_v1310_IEs_t *
sib1_v13ext
#endif #endif
) { )
{
int i;
int i;
int UE_id = -1;
eNB_MAC_INST *eNB = RC.mac[Mod_idP]; int UE_id = -1;
UE_list_t *UE_list= &eNB->UE_list; eNB_MAC_INST *eNB = RC.mac[Mod_idP];
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 (RC.mac == NULL) l2_init_eNB();
if (mib != NULL) {
mac_top_init_eNB(); if (RC.mac == NULL)
l2_init_eNB();
RC.mac[Mod_idP]->common_channels[CC_idP].mib = mib;
RC.mac[Mod_idP]->common_channels[CC_idP].physCellId = physCellId; mac_top_init_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].mib = mib;
RC.mac[Mod_idP]->common_channels[CC_idP].eutra_band = eutra_band; RC.mac[Mod_idP]->common_channels[CC_idP].physCellId = physCellId;
RC.mac[Mod_idP]->common_channels[CC_idP].dl_CarrierFreq = dl_CarrierFreq; RC.mac[Mod_idP]->common_channels[CC_idP].p_eNB = p_eNB;
RC.mac[Mod_idP]->common_channels[CC_idP].Ncp = Ncp;
LOG_I(MAC, RC.mac[Mod_idP]->common_channels[CC_idP].eutra_band = eutra_band;
"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", RC.mac[Mod_idP]->common_channels[CC_idP].dl_CarrierFreq =
Mod_idP, dl_CarrierFreq;
CC_idP,
eutra_band, LOG_I(MAC,
to_prb((int)mib->message.dl_Bandwidth), "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",
physCellId, Mod_idP,
p_eNB, CC_idP,
dl_CarrierFreq, eutra_band,
(int)mib->message.phich_Config.phich_Resource, to_prb((int) mib->message.dl_Bandwidth),
(int)mib->message.phich_Config.phich_Duration); physCellId,
p_eNB,
config_mib(Mod_idP,CC_idP, dl_CarrierFreq,
eutra_band, (int) mib->message.phich_Config.phich_Resource,
mib->message.dl_Bandwidth, (int) mib->message.phich_Config.phich_Duration);
&mib->message.phich_Config,
physCellId, config_mib(Mod_idP, CC_idP,
Ncp, eutra_band,
p_eNB, mib->message.dl_Bandwidth,
dl_CarrierFreq, &mib->message.phich_Config,
ul_CarrierFreq physCellId, 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);
"radioResourceconfigCommon %d == 0\n", LOG_I(MAC, "[CONFIG]pusch_config_common.enable64QAM = %d\n",
(int)radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx); radioResourceConfigCommon->
pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM);
RC.mac[Mod_idP]->common_channels[CC_idP].radioResourceConfigCommon = radioResourceConfigCommon; LOG_I(MAC,
if (ul_CarrierFreq>0) RC.mac[Mod_idP]->common_channels[CC_idP].ul_CarrierFreq = ul_CarrierFreq; "[CONFIG]pusch_config_common.groupHoppingEnabled = %d\n",
if (ul_Bandwidth) RC.mac[Mod_idP]->common_channels[CC_idP].ul_Bandwidth = *ul_Bandwidth; radioResourceConfigCommon->
else RC.mac[Mod_idP]->common_channels[CC_idP].ul_Bandwidth = RC.mac[Mod_idP]->common_channels[CC_idP].mib->message.dl_Bandwidth; pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.
groupHoppingEnabled);
config_sib2(Mod_idP, CC_idP, LOG_I(MAC,
radioResourceConfigCommon, "[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",
(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;
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, 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
if (logicalChannelConfig!= NULL) { // check for eMTC specific things
UE_id = find_UE_id(Mod_idP, rntiP);
if (UE_id == -1) {
LOG_E(MAC,"%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, __LINE__, __FUNCTION__);
} else {
if (logicalChannelConfig)
UE_list->UE_template[CC_idP][UE_id].lcgidmap[logicalChannelIdentity] = *logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup;
else
UE_list->UE_template[CC_idP][UE_id].lcgidmap[logicalChannelIdentity] = 0;
} }
} // SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters->logicalChannelGroup
if (logicalChannelConfig != NULL) { // check for eMTC specific things
UE_id = find_UE_id(Mod_idP, rntiP);
if (physicalConfigDedicated != NULL) {
UE_id = find_UE_id(Mod_idP, rntiP); if (UE_id == -1) {
LOG_E(MAC, "%s:%d:%s: ERROR, UE_id == -1\n", __FILE__,
__LINE__, __FUNCTION__);
} else {
if (logicalChannelConfig)
UE_list->
UE_template[CC_idP][UE_id].lcgidmap
[logicalChannelIdentity] =
*logicalChannelConfig->
ul_SpecificParameters->logicalChannelGroup;
else
UE_list->
UE_template[CC_idP][UE_id].lcgidmap
[logicalChannelIdentity] = 0;
}
}
if (UE_id == -1)
LOG_E(MAC,"%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, __LINE__, __FUNCTION__);
else
UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated=physicalConfigDedicated;
}
if (physicalConfigDedicated != NULL) {
UE_id = find_UE_id(Mod_idP, rntiP);
if (UE_id == -1)
LOG_E(MAC, "%s:%d:%s: ERROR, UE_id == -1\n", __FILE__,
__LINE__, __FUNCTION__);
else
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__,
else __LINE__, __FUNCTION__);
config_dedicated_scell(Mod_idP,rntiP,sCellToAddMod_r10); else
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] =
// config_sib13(Mod_idP,0,i,RC.mac[Mod_idP]->common_channels[0].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9); mbsfn_AreaInfoList->list.array[i];
} LOG_I(MAC,
} "[eNB %d][CONFIG] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n",
Mod_idP, i,
if (pmch_InfoList != NULL) { RC.mac[Mod_idP]->common_channels[0].
mbsfn_AreaInfo[i]->mcch_Config_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)); mcch_RepetitionPeriod_r9);
// config_sib13(Mod_idP,0,i,RC.mac[Mod_idP]->common_channels[0].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9);
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++) {
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,
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,
RC.mac[Mod_idP]->common_channels[0].pmch_Config[i]->dataMCS_r9);
// 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;
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);
} }
}
if (pmch_InfoList != NULL) {
// LOG_I(MAC,"DUY: lcid when entering rrc_mac config_req is %02d\n",(pmch_InfoList->list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9));
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++) {
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,
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,
RC.mac[Mod_idP]->common_channels[0].
pmch_Config[i]->dataMCS_r9);
// 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;
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,
PHY_Config_t phycfg; "if_inst->phy_config_request is null\n");
phycfg.Mod_id = Mod_idP; PHY_Config_t phycfg;
phycfg.CC_id = CC_idP; phycfg.Mod_id = Mod_idP;
phycfg.cfg = &RC.mac[Mod_idP]->config[CC_idP]; phycfg.CC_id = 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)
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT); RC.mac[Mod_idP]->if_inst->PHY_config_req(&phycfg);
}
return(0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT);
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 *
RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, radioResourceConfigCommon,
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,
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",
if (tdd_Config != NULL) { Mod_idP, eNB_index);
UE_mac_inst[Mod_idP].tdd_Config = tdd_Config;
} if (tdd_Config != NULL) {
UE_mac_inst[Mod_idP].tdd_Config = tdd_Config;
if (tdd_Config && SIwindowsize && SIperiod) {
phy_config_sib1_ue(Mod_idP,0,eNB_index,tdd_Config,*SIwindowsize,*SIperiod);
}
if (radioResourceConfigCommon!=NULL) {
UE_mac_inst[Mod_idP].radioResourceConfigCommon = 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
if (logicalChannelConfig!= NULL) {
LOG_I(MAC,"[CONFIG][UE %d] Applying RRC logicalChannelConfig from eNB%d\n",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,
"[UE %d] LCID %ld NULL ul_SpecificParameters\n",
Mod_idP,logicalChannelIdentity);
UE_mac_inst[Mod_idP].scheduling_info.bucket_size[logicalChannelIdentity]=logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate *
logicalChannelConfig->ul_SpecificParameters->bucketSizeDuration; // set the max bucket size
if (logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup != NULL) {
UE_mac_inst[Mod_idP].scheduling_info.LCGID[logicalChannelIdentity]=*logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup;
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;
if (tdd_Config && SIwindowsize && SIperiod) {
phy_config_sib1_ue(Mod_idP, 0, eNB_index, tdd_Config,
*SIwindowsize, *SIperiod);
} }
UE_mac_inst[Mod_idP].scheduling_info.LCID_buffer_remain[logicalChannelIdentity] = 0;
} if (radioResourceConfigCommon != NULL) {
UE_mac_inst[Mod_idP].radioResourceConfigCommon =
if (mac_MainConfig != NULL) { radioResourceConfigCommon;
LOG_I(MAC,"[CONFIG][UE%d] Applying RRC macMainConfig from eNB%d\n",Mod_idP,eNB_index); phy_config_sib2_ue(Mod_idP, 0, eNB_index,
UE_mac_inst[Mod_idP].macConfig=mac_MainConfig; radioResourceConfigCommon, ul_CarrierFreq,
UE_mac_inst[Mod_idP].measGapConfig=measGapConfig; ul_Bandwidth, additionalSpectrumEmission,
mbsfn_SubframeConfigList);
if (mac_MainConfig->ul_SCH_Config) { }
// SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters->logicalChannelGroup
if (mac_MainConfig->ul_SCH_Config->periodicBSR_Timer) { if (logicalChannelConfig != NULL) {
UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_Timer = (uint16_t) *mac_MainConfig->ul_SCH_Config->periodicBSR_Timer; LOG_I(MAC,
} else { "[CONFIG][UE %d] Applying RRC logicalChannelConfig from eNB%d\n",
UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_Timer = 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,
"[UE %d] LCID %ld NULL ul_SpecificParameters\n",
Mod_idP, logicalChannelIdentity);
UE_mac_inst[Mod_idP].scheduling_info.bucket_size[logicalChannelIdentity] = logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate * logicalChannelConfig->ul_SpecificParameters->bucketSizeDuration; // set the max bucket size
if (logicalChannelConfig->ul_SpecificParameters->
logicalChannelGroup != NULL) {
UE_mac_inst[Mod_idP].scheduling_info.
LCGID[logicalChannelIdentity] =
*logicalChannelConfig->ul_SpecificParameters->
logicalChannelGroup;
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;
}
if (mac_MainConfig != NULL) {
LOG_I(MAC,
"[CONFIG][UE%d] Applying RRC macMainConfig from eNB%d\n",
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->periodicBSR_Timer) {
UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_Timer =
(uint16_t) *
mac_MainConfig->ul_SCH_Config->periodicBSR_Timer;
} else {
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
; ;
} }
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 =
} else { (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_n5; } else {
} 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); (uint16_t)
MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5;
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; phy_config_harq_ue(Mod_idP, 0, eNB_index,
} else { UE_mac_inst[Mod_idP].
scheduling_info.maxHARQ_Tx);
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;
} 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) {
} else { UE_mac_inst[Mod_idP].scheduling_info.sr_ProhibitTimer =
UE_mac_inst[Mod_idP].scheduling_info.sr_ProhibitTimer = 0; (uint16_t) * mac_MainConfig->ext1->sr_ProhibitTimer_r9;
} } else {
UE_mac_inst[Mod_idP].scheduling_info.sr_ProhibitTimer = 0;
if (mac_MainConfig->ext2 && mac_MainConfig->ext2->mac_MainConfig_v1020) { }
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; if (mac_MainConfig->ext2
} else { && mac_MainConfig->ext2->mac_MainConfig_v1020) {
UE_mac_inst[Mod_idP].scheduling_info.extendedBSR_Sizes_r10 = (uint16_t)0; if (mac_MainConfig->ext2->
} mac_MainConfig_v1020->extendedBSR_Sizes_r10) {
if (mac_MainConfig->ext2->mac_MainConfig_v1020->extendedPHR_r10) { UE_mac_inst[Mod_idP].scheduling_info.
UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 = (uint16_t) *mac_MainConfig->ext2->mac_MainConfig_v1020->extendedPHR_r10; extendedBSR_Sizes_r10 =
} else { (uint16_t) *
UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 = (uint16_t)0; 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.
UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 = (uint16_t)0; extendedBSR_Sizes_r10 = (uint16_t) 0;
} }
if (mac_MainConfig->ext2->mac_MainConfig_v1020->
extendedPHR_r10) {
UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 =
(uint16_t) *
mac_MainConfig->ext2->mac_MainConfig_v1020->
extendedPHR_r10;
} else {
UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 =
(uint16_t) 0;
}
} else {
UE_mac_inst[Mod_idP].scheduling_info.extendedBSR_Sizes_r10 =
(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 =
UE_mac_inst[Mod_idP].BSR_reporting_active = BSR_TRIGGER_NONE; MAC_UE_BSR_TIMER_NOT_RUNNING;
LOG_D(MAC,"[UE %d]: periodic BSR %d (SF), retx BSR %d (SF)\n", UE_mac_inst[Mod_idP].BSR_reporting_active = BSR_TRIGGER_NONE;
Mod_idP,
UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_SF, LOG_D(MAC, "[UE %d]: periodic BSR %d (SF), retx BSR %d (SF)\n",
UE_mac_inst[Mod_idP].scheduling_info.retxBSR_SF); Mod_idP,
UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_SF,
UE_mac_inst[Mod_idP].scheduling_info.drx_config = mac_MainConfig->drx_Config; UE_mac_inst[Mod_idP].scheduling_info.retxBSR_SF);
UE_mac_inst[Mod_idP].scheduling_info.phr_config = mac_MainConfig->phr_Config;
UE_mac_inst[Mod_idP].scheduling_info.drx_config =
if (mac_MainConfig->phr_Config) { mac_MainConfig->drx_Config;
UE_mac_inst[Mod_idP].PHR_state = mac_MainConfig->phr_Config->present; UE_mac_inst[Mod_idP].scheduling_info.phr_config =
UE_mac_inst[Mod_idP].PHR_reconfigured = 1; mac_MainConfig->phr_Config;
UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_Timer = mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer;
UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_Timer = mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer; if (mac_MainConfig->phr_Config) {
UE_mac_inst[Mod_idP].scheduling_info.PathlossChange = mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange; UE_mac_inst[Mod_idP].PHR_state =
} else { mac_MainConfig->phr_Config->present;
UE_mac_inst[Mod_idP].PHR_reconfigured = 0; UE_mac_inst[Mod_idP].PHR_reconfigured = 1;
UE_mac_inst[Mod_idP].PHR_state = MAC_MainConfig__phr_Config_PR_setup; UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_Timer =
UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_Timer = MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer;
UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_Timer = MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_Timer =
UE_mac_inst[Mod_idP].scheduling_info.PathlossChange = MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; 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 {
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].scheduling_info.periodicPHR_Timer =
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.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;
LOG_D(MAC,
"[UE %d] config PHR (%d): periodic %d (SF) prohibit %d (SF) pathlosschange %d (db) \n",
Mod_idP,
(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.prohibitPHR_SF,
UE_mac_inst[Mod_idP].scheduling_info.PathlossChange_db);
} }
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.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;
LOG_D(MAC,"[UE %d] config PHR (%d): periodic %d (SF) prohibit %d (SF) pathlosschange %d (db) \n",
Mod_idP,
(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.prohibitPHR_SF,
UE_mac_inst[Mod_idP].scheduling_info.PathlossChange_db);
}
if (physicalConfigDedicated != NULL) {
phy_config_dedicated_ue(Mod_idP,0,eNB_index,physicalConfigDedicated);
UE_mac_inst[Mod_idP].physicalConfigDedicated=physicalConfigDedicated; // for SR proc
}
#if defined(Rel10) || defined(Rel14)
if (sCellToAddMod_r10 != NULL) { if (physicalConfigDedicated != NULL) {
phy_config_dedicated_ue(Mod_idP, 0, eNB_index,
physicalConfigDedicated);
UE_mac_inst[Mod_idP].physicalConfigDedicated = physicalConfigDedicated; // for SR proc
}
#if defined(Rel10) || defined(Rel14)
if (sCellToAddMod_r10 != NULL) {
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
}
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
}
#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] =
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); 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]);
if(mobilityControlInfo != NULL) { }
LOG_D(MAC,"[UE%d] MAC Reset procedure triggered by RRC eNB %d \n",Mod_idP,eNB_index); phy_config_meas_ue(Mod_idP, 0, eNB_index,
ue_mac_reset(Mod_idP,eNB_index); UE_mac_inst[Mod_idP].n_adj_cells,
UE_mac_inst[Mod_idP].adj_cell_id);
if(mobilityControlInfo->radioResourceConfigCommon.rach_ConfigCommon) { }
memcpy((void *)&UE_mac_inst[Mod_idP].radioResourceConfigCommon->rach_ConfigCommon,
(void *)mobilityControlInfo->radioResourceConfigCommon.rach_ConfigCommon,
sizeof(RACH_ConfigCommon_t));
}
memcpy((void *)&UE_mac_inst[Mod_idP].radioResourceConfigCommon->prach_Config.prach_ConfigInfo,
(void *)mobilityControlInfo->radioResourceConfigCommon.prach_Config.prach_ConfigInfo,
sizeof(PRACH_ConfigInfo_t));
UE_mac_inst[Mod_idP].radioResourceConfigCommon->prach_Config.rootSequenceIndex = mobilityControlInfo->radioResourceConfigCommon.prach_Config.rootSequenceIndex;
if(mobilityControlInfo->radioResourceConfigCommon.pdsch_ConfigCommon) {
memcpy((void *)&UE_mac_inst[Mod_idP].radioResourceConfigCommon->pdsch_ConfigCommon,
(void *)mobilityControlInfo->radioResourceConfigCommon.pdsch_ConfigCommon,
sizeof(PDSCH_ConfigCommon_t));
}
// not a pointer: mobilityControlInfo->radioResourceConfigCommon.pusch_ConfigCommon
memcpy((void *)&UE_mac_inst[Mod_idP].radioResourceConfigCommon->pusch_ConfigCommon,
(void *)&mobilityControlInfo->radioResourceConfigCommon.pusch_ConfigCommon,
sizeof(PUSCH_ConfigCommon_t));
if(mobilityControlInfo->radioResourceConfigCommon.phich_Config) {
/* memcpy((void *)&UE_mac_inst[Mod_idP].radioResourceConfigCommon->phich_Config,
(void *)mobilityControlInfo->radioResourceConfigCommon.phich_Config,
sizeof(PHICH_Config_t)); */
}
if(mobilityControlInfo->radioResourceConfigCommon.pucch_ConfigCommon) {
memcpy((void *)&UE_mac_inst[Mod_idP].radioResourceConfigCommon->pucch_ConfigCommon,
(void *)mobilityControlInfo->radioResourceConfigCommon.pucch_ConfigCommon,
sizeof(PUCCH_ConfigCommon_t));
}
if(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));
}
if(mobilityControlInfo->radioResourceConfigCommon.uplinkPowerControlCommon) {
memcpy((void *)&UE_mac_inst[Mod_idP].radioResourceConfigCommon->uplinkPowerControlCommon,
(void *)mobilityControlInfo->radioResourceConfigCommon.uplinkPowerControlCommon,
sizeof(UplinkPowerControlCommon_t));
}
//configure antennaInfoCommon somewhere here..
if(mobilityControlInfo->radioResourceConfigCommon.p_Max) {
//to be configured
}
if(mobilityControlInfo->radioResourceConfigCommon.tdd_Config) {
UE_mac_inst[Mod_idP].tdd_Config = mobilityControlInfo->radioResourceConfigCommon.tdd_Config;
}
if(mobilityControlInfo->radioResourceConfigCommon.ul_CyclicPrefixLength) {
memcpy((void *)&UE_mac_inst[Mod_idP].radioResourceConfigCommon->ul_CyclicPrefixLength,
(void *)mobilityControlInfo->radioResourceConfigCommon.ul_CyclicPrefixLength,
sizeof(UL_CyclicPrefixLength_t));
}
// store the previous rnti in case of failure, and set thenew rnti
UE_mac_inst[Mod_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));
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) {
memcpy((void*)UE_mac_inst[Mod_idP].rach_ConfigDedicated,
(void*)mobilityControlInfo->rach_ConfigDedicated,
sizeof(*mobilityControlInfo->rach_ConfigDedicated));
} }
phy_config_afterHO_ue(Mod_idP,0,eNB_index,mobilityControlInfo,0);
} if (mobilityControlInfo != NULL) {
LOG_D(MAC, "[UE%d] MAC Reset procedure triggered by RRC eNB %d \n",
if (mbsfn_SubframeConfigList != NULL) { Mod_idP, eNB_index);
LOG_I(MAC,"[UE %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n", Mod_idP, mbsfn_SubframeConfigList->list.count); ue_mac_reset(Mod_idP, eNB_index);
UE_mac_inst[Mod_idP].num_sf_allocation_pattern= mbsfn_SubframeConfigList->list.count;
if (mobilityControlInfo->radioResourceConfigCommon.
for (i=0; i<mbsfn_SubframeConfigList->list.count; i++) { rach_ConfigCommon) {
LOG_I(MAC, "[UE %d] Configuring MBSFN_SubframeConfig %d from received SIB2 \n", Mod_idP, i); memcpy((void *)
UE_mac_inst[Mod_idP].mbsfn_SubframeConfig[i] = mbsfn_SubframeConfigList->list.array[i]; &UE_mac_inst[Mod_idP].radioResourceConfigCommon->
// LOG_I("[UE %d] MBSFN_SubframeConfig[%d] pattern is %ld\n", Mod_idP, rach_ConfigCommon,
// UE_mac_inst[Mod_idP].mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]); (void *) mobilityControlInfo->
radioResourceConfigCommon.rach_ConfigCommon,
sizeof(RACH_ConfigCommon_t));
}
memcpy((void *) &UE_mac_inst[Mod_idP].
radioResourceConfigCommon->prach_Config.prach_ConfigInfo,
(void *) mobilityControlInfo->
radioResourceConfigCommon.prach_Config.prach_ConfigInfo,
sizeof(PRACH_ConfigInfo_t));
UE_mac_inst[Mod_idP].radioResourceConfigCommon->
prach_Config.rootSequenceIndex =
mobilityControlInfo->radioResourceConfigCommon.
prach_Config.rootSequenceIndex;
if (mobilityControlInfo->radioResourceConfigCommon.
pdsch_ConfigCommon) {
memcpy((void *)
&UE_mac_inst[Mod_idP].radioResourceConfigCommon->
pdsch_ConfigCommon,
(void *) mobilityControlInfo->
radioResourceConfigCommon.pdsch_ConfigCommon,
sizeof(PDSCH_ConfigCommon_t));
}
// not a pointer: mobilityControlInfo->radioResourceConfigCommon.pusch_ConfigCommon
memcpy((void *) &UE_mac_inst[Mod_idP].
radioResourceConfigCommon->pusch_ConfigCommon,
(void *) &mobilityControlInfo->
radioResourceConfigCommon.pusch_ConfigCommon,
sizeof(PUSCH_ConfigCommon_t));
if (mobilityControlInfo->radioResourceConfigCommon.phich_Config) {
/* memcpy((void *)&UE_mac_inst[Mod_idP].radioResourceConfigCommon->phich_Config,
(void *)mobilityControlInfo->radioResourceConfigCommon.phich_Config,
sizeof(PHICH_Config_t)); */
}
if (mobilityControlInfo->radioResourceConfigCommon.
pucch_ConfigCommon) {
memcpy((void *)
&UE_mac_inst[Mod_idP].radioResourceConfigCommon->
pucch_ConfigCommon,
(void *) mobilityControlInfo->
radioResourceConfigCommon.pucch_ConfigCommon,
sizeof(PUCCH_ConfigCommon_t));
}
if (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));
}
if (mobilityControlInfo->
radioResourceConfigCommon.uplinkPowerControlCommon) {
memcpy((void *)
&UE_mac_inst[Mod_idP].radioResourceConfigCommon->
uplinkPowerControlCommon,
(void *) mobilityControlInfo->
radioResourceConfigCommon.uplinkPowerControlCommon,
sizeof(UplinkPowerControlCommon_t));
}
//configure antennaInfoCommon somewhere here..
if (mobilityControlInfo->radioResourceConfigCommon.p_Max) {
//to be configured
}
if (mobilityControlInfo->radioResourceConfigCommon.tdd_Config) {
UE_mac_inst[Mod_idP].tdd_Config =
mobilityControlInfo->radioResourceConfigCommon.tdd_Config;
}
if (mobilityControlInfo->
radioResourceConfigCommon.ul_CyclicPrefixLength) {
memcpy((void *)
&UE_mac_inst[Mod_idP].radioResourceConfigCommon->
ul_CyclicPrefixLength,
(void *) mobilityControlInfo->
radioResourceConfigCommon.ul_CyclicPrefixLength,
sizeof(UL_CyclicPrefixLength_t));
}
// store the previous rnti in case of failure, and set thenew rnti
UE_mac_inst[Mod_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));
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) {
memcpy((void *) UE_mac_inst[Mod_idP].rach_ConfigDedicated,
(void *) mobilityControlInfo->rach_ConfigDedicated,
sizeof(*mobilityControlInfo->rach_ConfigDedicated));
}
phy_config_afterHO_ue(Mod_idP, 0, eNB_index, mobilityControlInfo,
0);
} }
}
#if defined(Rel10) || defined(Rel14)
if (mbsfn_AreaInfoList != NULL) { if (mbsfn_SubframeConfigList != NULL) {
LOG_I(MAC,"[UE %d][CONFIG] Received %d MBSFN Area Info\n", Mod_idP, mbsfn_AreaInfoList->list.count); LOG_I(MAC,
UE_mac_inst[Mod_idP].num_active_mbsfn_area = mbsfn_AreaInfoList->list.count; "[UE %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n",
Mod_idP, mbsfn_SubframeConfigList->list.count);
for (i =0; i< mbsfn_AreaInfoList->list.count; i++) { UE_mac_inst[Mod_idP].num_sf_allocation_pattern =
UE_mac_inst[Mod_idP].mbsfn_AreaInfo[i] = mbsfn_AreaInfoList->list.array[i]; mbsfn_SubframeConfigList->list.count;
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); for (i = 0; i < mbsfn_SubframeConfigList->list.count; i++) {
phy_config_sib13_ue(Mod_idP,0,eNB_index,i,UE_mac_inst[Mod_idP].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9); LOG_I(MAC,
"[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,
// UE_mac_inst[Mod_idP].mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]);
}
} }
} #if defined(Rel10) || defined(Rel14)
if (pmch_InfoList != NULL) { if (mbsfn_AreaInfoList != NULL) {
LOG_I(MAC, "[UE %d][CONFIG] Received %d MBSFN Area Info\n",
// 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)); Mod_idP, mbsfn_AreaInfoList->list.count);
UE_mac_inst[Mod_idP].num_active_mbsfn_area =
LOG_I(MAC, "[UE %d] Configuring PMCH_config from MCCH MESSAGE \n",Mod_idP); mbsfn_AreaInfoList->list.count;
for (i =0; i< pmch_InfoList->list.count; i++) { for (i = 0; i < mbsfn_AreaInfoList->list.count; i++) {
UE_mac_inst[Mod_idP].pmch_Config[i] = &pmch_InfoList->list.array[i]->pmch_Config_r9; UE_mac_inst[Mod_idP].mbsfn_AreaInfo[i] =
LOG_I(MAC, "[UE %d] PMCH[%d]: MCH_Scheduling_Period = %ld\n", Mod_idP, i, mbsfn_AreaInfoList->list.array[i];
UE_mac_inst[Mod_idP].pmch_Config[i]->mch_SchedulingPeriod_r9); 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);
}
} }
UE_mac_inst[Mod_idP].mcch_status = 1;
}
if (pmch_InfoList != NULL) {
// LOG_I(MAC,"DUY: lcid when entering rrc_mac config_req is %02d\n",(pmch_InfoList->list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9));
LOG_I(MAC, "[UE %d] Configuring PMCH_config from MCCH MESSAGE \n",
Mod_idP);
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;
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;
}
#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
...@@ -111,7 +111,7 @@ ...@@ -111,7 +111,7 @@
#ifdef USER_MODE #ifdef USER_MODE
#define printk printf #define printk printf
#endif //USER_MODE #endif //USER_MODE
/*!\brief Maximum number of logical channl group IDs */ /*!\brief Maximum number of logical channl group IDs */
#define MAX_NUM_LCGID 4 #define MAX_NUM_LCGID 4
...@@ -132,17 +132,17 @@ ...@@ -132,17 +132,17 @@
/*!\brief size of buffer status report table */ /*!\brief size of buffer status report table */
#define BSR_TABLE_SIZE 64 #define BSR_TABLE_SIZE 64
/*!\brief The power headroom reporting range is from -23 ...+40 dB and beyond, with step 1 */ /*!\brief The power headroom reporting range is from -23 ...+40 dB and beyond, with step 1 */
#define PHR_MAPPING_OFFSET 23 // if ( x>= -23 ) val = floor (x + 23) #define PHR_MAPPING_OFFSET 23 // if ( x>= -23 ) val = floor (x + 23)
/*!\brief maximum number of resource block groups */ /*!\brief maximum number of resource block groups */
#define N_RBG_MAX 25 // for 20MHz channel BW #define N_RBG_MAX 25 // for 20MHz channel BW
/*!\brief minimum value for channel quality indicator */ /*!\brief minimum value for channel quality indicator */
#define MIN_CQI_VALUE 0 #define MIN_CQI_VALUE 0
/*!\brief maximum value for channel quality indicator */ /*!\brief maximum value for channel quality indicator */
#define MAX_CQI_VALUE 15 #define MAX_CQI_VALUE 15
/*!\briefmaximum number of supported bandwidth (1.4, 5, 10, 20 MHz) */ /*!\briefmaximum number of supported bandwidth (1.4, 5, 10, 20 MHz) */
#define MAX_SUPPORTED_BW 4 #define MAX_SUPPORTED_BW 4
/*!\brief CQI values range from 1 to 15 (4 bits) */ /*!\brief CQI values range from 1 to 15 (4 bits) */
#define CQI_VALUE_RANGE 16 #define CQI_VALUE_RANGE 16
/*!\brief value for indicating BSR Timer is not running */ /*!\brief value for indicating BSR Timer is not running */
#define MAC_UE_BSR_TIMER_NOT_RUNNING (0xFFFF) #define MAC_UE_BSR_TIMER_NOT_RUNNING (0xFFFF)
...@@ -157,30 +157,30 @@ ...@@ -157,30 +157,30 @@
#define MIN_MAC_HDR_RLC_SIZE (1 + MIN_RLC_PDU_SIZE) #define MIN_MAC_HDR_RLC_SIZE (1 + MIN_RLC_PDU_SIZE)
/*!\brief maximum number of slices / groups */ /*!\brief maximum number of slices / groups */
#define MAX_NUM_SLICES 4 #define MAX_NUM_SLICES 4
/* /*
* eNB part * eNB part
*/ */
/* /*
* UE/ENB common part * UE/ENB common part
*/ */
/*!\brief MAC header of Random Access Response for Random access preamble identifier (RAPID) */ /*!\brief MAC header of Random Access Response for Random access preamble identifier (RAPID) */
typedef struct { 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 {
uint8_t BI:4; uint8_t BI:4;
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;
...@@ -212,124 +212,124 @@ typedef struct { ...@@ -212,124 +212,124 @@ typedef struct {
*/ */
/*!\brief MAC subheader short with 7bit Length field */ /*!\brief MAC subheader short with 7bit Length field */
typedef struct { typedef struct {
uint8_t LCID:5; // octet 1 LSB uint8_t LCID:5; // octet 1 LSB
uint8_t E:1; uint8_t E:1;
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
uint8_t E:1; uint8_t E:1;
uint8_t R:2; // octet 1 MSB uint8_t R:2; // octet 1 MSB
uint8_t L_MSB:7; uint8_t L_MSB:7;
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*/
typedef struct { typedef struct {
uint8_t Buffer_size3:6; uint8_t Buffer_size3:6;
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
/*!\brief Values of BCCH logical channel (fake)*/ /*!\brief Values of BCCH logical channel (fake)*/
#define BCCH 3 // SI #define BCCH 3 // SI
/*!\brief Values of PCCH logical channel (fake)*/ /*!\brief Values of PCCH logical channel (fake)*/
#define PCCH 4 // Paging #define PCCH 4 // Paging
/*!\brief Values of PCCH logical channel (fake) */ /*!\brief Values of PCCH logical channel (fake) */
#define MIBCH 5 // MIB #define MIBCH 5 // MIB
/*!\brief Values of BCCH SIB1_BR logical channel (fake) */ /*!\brief Values of BCCH SIB1_BR logical channel (fake) */
#define BCCH_SIB1_BR 6 // SIB1_BR #define BCCH_SIB1_BR 6 // SIB1_BR
/*!\brief Values of BCCH SIB_BR logical channel (fake) */ /*!\brief Values of BCCH SIB_BR logical channel (fake) */
#define BCCH_SI_BR 7 // SI-BR #define BCCH_SI_BR 7 // SI-BR
/*!\brief Value of CCCH / SRB0 logical channel */ /*!\brief Value of CCCH / SRB0 logical channel */
#define CCCH 0 // srb0 #define CCCH 0 // srb0
/*!\brief DCCH / SRB1 logical channel */ /*!\brief DCCH / SRB1 logical channel */
#define DCCH 1 // srb1 #define DCCH 1 // srb1
/*!\brief DCCH1 / SRB2 logical channel */ /*!\brief DCCH1 / SRB2 logical channel */
#define DCCH1 2 // srb2 #define DCCH1 2 // srb2
/*!\brief DTCH DRB1 logical channel */ /*!\brief DTCH DRB1 logical channel */
#define DTCH 3 // LCID #define DTCH 3 // LCID
/*!\brief MCCH logical channel */ /*!\brief MCCH logical channel */
#define MCCH 4 #define MCCH 4
/*!\brief MTCH logical channel */ /*!\brief MTCH logical channel */
#define MTCH 1 #define MTCH 1
// DLSCH LCHAN ID // DLSCH LCHAN ID
/*!\brief LCID of UE contention resolution identity for DLSCH*/ /*!\brief LCID of UE contention resolution identity for DLSCH*/
#define UE_CONT_RES 28 #define UE_CONT_RES 28
...@@ -364,972 +364,963 @@ typedef struct { ...@@ -364,972 +364,963 @@ typedef struct {
/*!\brief LCID of long BSR for ULSCH */ /*!\brief LCID of long BSR for ULSCH */
#define LONG_BSR 30 #define LONG_BSR 30
/*!\bitmaps for BSR Triggers */ /*!\bitmaps for BSR Triggers */
#define BSR_TRIGGER_NONE (0) /* No BSR Trigger */ #define BSR_TRIGGER_NONE (0) /* No BSR Trigger */
#define BSR_TRIGGER_REGULAR (1) /* For Regular and ReTxBSR Expiry Triggers */ #define BSR_TRIGGER_REGULAR (1) /* For Regular and ReTxBSR Expiry Triggers */
#define BSR_TRIGGER_PERIODIC (2) /* For BSR Periodic Timer Expiry Trigger */ #define BSR_TRIGGER_PERIODIC (2) /* For BSR Periodic Timer Expiry Trigger */
#define BSR_TRIGGER_PADDING (4) /* For Padding BSR Trigger */ #define BSR_TRIGGER_PADDING (4) /* For Padding BSR Trigger */
/*! \brief Downlink SCH PDU Structure */ /*! \brief Downlink SCH PDU Structure */
typedef struct { typedef struct {
uint8_t payload[8][SCH_PAYLOAD_SIZE_MAX]; uint8_t payload[8][SCH_PAYLOAD_SIZE_MAX];
uint16_t Pdu_size[8]; uint16_t Pdu_size[8];
} __attribute__ ((__packed__)) DLSCH_PDU; } __attribute__ ((__packed__)) DLSCH_PDU;
/*! \brief MCH PDU Structure */ /*! \brief MCH PDU Structure */
typedef struct { typedef struct {
int8_t payload[SCH_PAYLOAD_SIZE_MAX]; int8_t payload[SCH_PAYLOAD_SIZE_MAX];
uint16_t Pdu_size; uint16_t Pdu_size;
uint8_t mcs; uint8_t mcs;
uint8_t sync_area; uint8_t sync_area;
uint8_t msi_active; uint8_t msi_active;
uint8_t mcch_active; uint8_t mcch_active;
uint8_t mtch_active; uint8_t mtch_active;
} __attribute__ ((__packed__)) MCH_PDU; } __attribute__ ((__packed__)) MCH_PDU;
/*! \brief Uplink SCH PDU Structure */ /*! \brief Uplink SCH PDU Structure */
typedef struct { typedef struct {
int8_t payload[SCH_PAYLOAD_SIZE_MAX]; /*!< \brief SACH payload */ int8_t payload[SCH_PAYLOAD_SIZE_MAX]; /*!< \brief SACH payload */
uint16_t Pdu_size; uint16_t Pdu_size;
} __attribute__ ((__packed__)) ULSCH_PDU; } __attribute__ ((__packed__)) ULSCH_PDU;
#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,
S_UL_NUM_STATUS S_UL_NUM_STATUS
} UE_ULSCH_STATUS; } UE_ULSCH_STATUS;
/*!\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,
S_DL_NUM_STATUS S_DL_NUM_STATUS
} UE_DLSCH_STATUS; } UE_DLSCH_STATUS;
/*!\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
CBA_RS /// random allocation CBA_RS /// random allocation
} CBA_POLICY; } CBA_POLICY;
/*! \brief temporary struct for ULSCH sched */ /*! \brief temporary struct for ULSCH sched */
typedef struct { typedef struct {
rnti_t rnti; rnti_t rnti;
uint16_t subframe; uint16_t subframe;
uint16_t serving_num; uint16_t serving_num;
UE_ULSCH_STATUS status; UE_ULSCH_STATUS status;
} eNB_ULSCH_INFO; } eNB_ULSCH_INFO;
/*! \brief temp struct for DLSCH sched */ /*! \brief temp struct for DLSCH sched */
typedef struct { typedef struct {
rnti_t rnti; rnti_t rnti;
uint16_t weight; uint16_t weight;
uint16_t subframe; uint16_t subframe;
uint16_t serving_num; uint16_t serving_num;
UE_DLSCH_STATUS status; UE_DLSCH_STATUS status;
} eNB_DLSCH_INFO; } eNB_DLSCH_INFO;
/*! \brief eNB overall statistics */ /*! \brief eNB overall statistics */
typedef struct { typedef struct {
/// num BCCH PDU per CC /// num BCCH PDU per CC
uint32_t total_num_bcch_pdu; uint32_t total_num_bcch_pdu;
/// BCCH buffer size /// BCCH buffer size
uint32_t bcch_buffer; uint32_t bcch_buffer;
/// total BCCH buffer size /// total BCCH buffer size
uint32_t total_bcch_buffer; uint32_t total_bcch_buffer;
/// BCCH MCS /// BCCH MCS
uint32_t bcch_mcs; uint32_t bcch_mcs;
/// num CCCH PDU per CC /// num CCCH PDU per CC
uint32_t total_num_ccch_pdu; uint32_t total_num_ccch_pdu;
/// BCCH buffer size /// BCCH buffer size
uint32_t ccch_buffer; uint32_t ccch_buffer;
/// total BCCH buffer size /// total BCCH buffer size
uint32_t total_ccch_buffer; uint32_t total_ccch_buffer;
/// BCCH MCS /// BCCH MCS
uint32_t ccch_mcs; uint32_t ccch_mcs;
/// num active users /// num active users
uint16_t num_dlactive_UEs; uint16_t num_dlactive_UEs;
/// available number of PRBs for a give SF /// available number of PRBs for a give SF
uint16_t available_prbs; uint16_t available_prbs;
/// total number of PRB available for the user plane /// total number of PRB available for the user plane
uint32_t total_available_prbs; uint32_t total_available_prbs;
/// aggregation /// aggregation
/// total avilable nccc : num control channel element /// total avilable nccc : num control channel element
uint16_t available_ncces; uint16_t available_ncces;
// only for a new transmission, should be extended for retransmission // only for a new transmission, should be extended for retransmission
// current dlsch bit rate for all transport channels // current dlsch bit rate for all transport channels
uint32_t dlsch_bitrate; uint32_t dlsch_bitrate;
// //
uint32_t dlsch_bytes_tx; uint32_t dlsch_bytes_tx;
// //
uint32_t dlsch_pdus_tx; uint32_t dlsch_pdus_tx;
// //
uint32_t total_dlsch_bitrate; uint32_t total_dlsch_bitrate;
// //
uint32_t total_dlsch_bytes_tx; uint32_t total_dlsch_bytes_tx;
// //
uint32_t total_dlsch_pdus_tx; uint32_t total_dlsch_pdus_tx;
// here for RX // here for RX
// //
uint32_t ulsch_bitrate; uint32_t ulsch_bitrate;
// //
uint32_t ulsch_bytes_rx; uint32_t ulsch_bytes_rx;
// //
uint64_t ulsch_pdus_rx; uint64_t ulsch_pdus_rx;
uint32_t total_ulsch_bitrate; uint32_t total_ulsch_bitrate;
// //
uint32_t total_ulsch_bytes_rx; uint32_t total_ulsch_bytes_rx;
// //
uint32_t total_ulsch_pdus_rx; uint32_t total_ulsch_pdus_rx;
/// MAC agent-related stats /// MAC agent-related stats
/// total number of scheduling decisions /// total number of scheduling decisions
int sched_decisions; int sched_decisions;
/// missed deadlines /// missed deadlines
int missed_deadlines; int missed_deadlines;
} eNB_STATS; } eNB_STATS;
/*! \brief eNB statistics for the connected UEs*/ /*! \brief eNB statistics for the connected UEs*/
typedef struct { typedef struct {
/// CRNTI of UE /// CRNTI of UE
rnti_t crnti; ///user id (rnti) of connected UEs rnti_t crnti; ///user id (rnti) of connected UEs
// rrc status // rrc status
uint8_t rrc_status; uint8_t rrc_status;
/// harq pid /// harq pid
uint8_t harq_pid; uint8_t harq_pid;
/// harq rounf /// harq rounf
uint8_t harq_round; uint8_t harq_round;
/// total available number of PRBs for a new transmission /// total available number of PRBs for a new transmission
uint16_t rbs_used; uint16_t rbs_used;
/// total available number of PRBs for a retransmission /// total available number of PRBs for a retransmission
uint16_t rbs_used_retx; uint16_t rbs_used_retx;
/// total nccc used for a new transmission: num control channel element /// total nccc used for a new transmission: num control channel element
uint16_t ncce_used; uint16_t ncce_used;
/// total avilable nccc for a retransmission: num control channel element /// total avilable nccc for a retransmission: num control channel element
uint16_t ncce_used_retx; uint16_t ncce_used_retx;
// mcs1 before the rate adaptaion // mcs1 before the rate adaptaion
uint8_t dlsch_mcs1; uint8_t dlsch_mcs1;
/// Target mcs2 after rate-adaptation /// Target mcs2 after rate-adaptation
uint8_t dlsch_mcs2; uint8_t dlsch_mcs2;
// current TBS with mcs2 // current TBS with mcs2
uint32_t TBS; uint32_t TBS;
// total TBS with mcs2 // total TBS with mcs2
// uint32_t total_TBS; // uint32_t total_TBS;
// total rb used for a new transmission // total rb used for a new transmission
uint32_t total_rbs_used; uint32_t total_rbs_used;
// total rb used for retransmission // total rb used for retransmission
uint32_t total_rbs_used_retx; uint32_t total_rbs_used_retx;
/// TX /// TX
/// Num pkt /// Num pkt
uint32_t num_pdu_tx[NB_RB_MAX]; uint32_t num_pdu_tx[NB_RB_MAX];
/// num bytes /// num bytes
uint32_t num_bytes_tx[NB_RB_MAX]; uint32_t num_bytes_tx[NB_RB_MAX];
/// num retransmission / harq /// num retransmission / harq
uint32_t num_retransmission; uint32_t num_retransmission;
/// instantaneous tx throughput for each TTI /// instantaneous tx throughput for each TTI
// uint32_t tti_throughput[NB_RB_MAX]; // uint32_t tti_throughput[NB_RB_MAX];
/// overall /// overall
// //
uint32_t dlsch_bitrate; uint32_t dlsch_bitrate;
//total //total
uint32_t total_dlsch_bitrate; uint32_t total_dlsch_bitrate;
/// headers+ CE + padding bytes for a MAC PDU /// headers+ CE + padding bytes for a MAC PDU
uint64_t overhead_bytes; uint64_t overhead_bytes;
/// headers+ CE + padding bytes for a MAC PDU /// headers+ CE + padding bytes for a MAC PDU
uint64_t total_overhead_bytes; uint64_t total_overhead_bytes;
/// headers+ CE + padding bytes for a MAC PDU /// headers+ CE + padding bytes for a MAC PDU
uint64_t avg_overhead_bytes; uint64_t avg_overhead_bytes;
// MAC multiplexed payload // MAC multiplexed payload
uint64_t total_sdu_bytes; uint64_t total_sdu_bytes;
// total MAC pdu bytes // total MAC pdu bytes
uint64_t total_pdu_bytes; uint64_t total_pdu_bytes;
// total num pdu // total num pdu
uint32_t total_num_pdus; uint32_t total_num_pdus;
// //
// uint32_t avg_pdu_size; // uint32_t avg_pdu_size;
/// RX /// RX
/// PUCCH1a/b power (dBm) /// PUCCH1a/b power (dBm)
int32_t Po_PUCCH_dBm; int32_t Po_PUCCH_dBm;
/// Indicator that Po_PUCCH has been updated by PHY /// Indicator that Po_PUCCH has been updated by PHY
int32_t Po_PUCCH_update; int32_t Po_PUCCH_update;
/// Uplink measured RSSI /// Uplink measured RSSI
int32_t UL_rssi; int32_t UL_rssi;
/// preassigned mcs after rate adaptation /// preassigned mcs after rate adaptation
uint8_t ulsch_mcs1; uint8_t ulsch_mcs1;
/// adjusted mcs /// adjusted mcs
uint8_t ulsch_mcs2; uint8_t ulsch_mcs2;
/// estimated average pdu inter-departure time /// estimated average pdu inter-departure time
uint32_t avg_pdu_idt; uint32_t avg_pdu_idt;
/// estimated average pdu size /// estimated average pdu size
uint32_t avg_pdu_ps; uint32_t avg_pdu_ps;
/// ///
uint32_t aggregated_pdu_size; uint32_t aggregated_pdu_size;
uint32_t aggregated_pdu_arrival; uint32_t aggregated_pdu_arrival;
/// uplink transport block size /// uplink transport block size
uint32_t ulsch_TBS; uint32_t ulsch_TBS;
/// total rb used for a new uplink transmission /// total rb used for a new uplink transmission
uint32_t num_retransmission_rx; uint32_t num_retransmission_rx;
/// total rb used for a new uplink transmission /// total rb used for a new uplink transmission
uint32_t rbs_used_rx; uint32_t rbs_used_rx;
/// total rb used for a new uplink retransmission /// total rb used for a new uplink retransmission
uint32_t rbs_used_retx_rx; uint32_t rbs_used_retx_rx;
/// total rb used for a new uplink transmission /// total rb used for a new uplink transmission
uint32_t total_rbs_used_rx; uint32_t total_rbs_used_rx;
/// normalized rx power /// normalized rx power
int32_t normalized_rx_power; int32_t normalized_rx_power;
/// target rx power /// target rx power
int32_t target_rx_power; int32_t target_rx_power;
/// num rx pdu /// num rx pdu
uint32_t num_pdu_rx[NB_RB_MAX]; uint32_t num_pdu_rx[NB_RB_MAX];
/// num bytes rx /// num bytes rx
uint32_t num_bytes_rx[NB_RB_MAX]; uint32_t num_bytes_rx[NB_RB_MAX];
/// instantaneous rx throughput for each TTI /// instantaneous rx throughput for each TTI
// uint32_t tti_goodput[NB_RB_MAX]; // uint32_t tti_goodput[NB_RB_MAX];
/// errors /// errors
uint32_t num_errors_rx; uint32_t num_errors_rx;
uint64_t overhead_bytes_rx; uint64_t overhead_bytes_rx;
/// headers+ CE + padding bytes for a MAC PDU /// headers+ CE + padding bytes for a MAC PDU
uint64_t total_overhead_bytes_rx; uint64_t total_overhead_bytes_rx;
/// headers+ CE + padding bytes for a MAC PDU /// headers+ CE + padding bytes for a MAC PDU
uint64_t avg_overhead_bytes_rx; uint64_t avg_overhead_bytes_rx;
// //
uint32_t ulsch_bitrate; uint32_t ulsch_bitrate;
//total //total
uint32_t total_ulsch_bitrate; uint32_t total_ulsch_bitrate;
/// overall /// overall
/// MAC pdu bytes /// MAC pdu bytes
uint64_t pdu_bytes_rx; uint64_t pdu_bytes_rx;
/// total MAC pdu bytes /// total MAC pdu bytes
uint64_t total_pdu_bytes_rx; uint64_t total_pdu_bytes_rx;
/// total num pdu /// total num pdu
uint32_t total_num_pdus_rx; uint32_t total_num_pdus_rx;
/// num of error pdus /// num of error pdus
uint32_t total_num_errors_rx; uint32_t total_num_errors_rx;
} eNB_UE_STATS; } eNB_UE_STATS;
/*! \brief eNB template for UE context information */ /*! \brief eNB template for UE context information */
typedef struct { typedef struct {
/// C-RNTI of UE /// C-RNTI of UE
rnti_t rnti; rnti_t rnti;
/// NDI from last scheduling /// NDI from last scheduling
uint8_t oldNDI[8]; uint8_t oldNDI[8];
/// mcs1 from last scheduling /// mcs1 from last scheduling
uint8_t oldmcs1[8]; uint8_t oldmcs1[8];
/// mcs2 from last scheduling /// mcs2 from last scheduling
uint8_t oldmcs2[8]; uint8_t oldmcs2[8];
/// NDI from last UL scheduling /// NDI from last UL scheduling
uint8_t oldNDI_UL[8]; uint8_t oldNDI_UL[8];
/// mcs from last UL scheduling /// mcs from last UL scheduling
uint8_t mcs_UL[8]; uint8_t mcs_UL[8];
/// TBS from last UL scheduling /// TBS from last UL scheduling
uint8_t TBS_UL[8]; uint8_t TBS_UL[8];
/// Flag to indicate UL has been scheduled at least once /// Flag to indicate UL has been scheduled at least once
boolean_t ul_active; boolean_t ul_active;
/// Flag to indicate UE has been configured (ACK from RRCConnectionSetup received) /// Flag to indicate UE has been configured (ACK from RRCConnectionSetup received)
boolean_t configured; boolean_t configured;
/// MCS from last scheduling /// MCS from last scheduling
uint8_t mcs[8]; uint8_t mcs[8];
/// TPC from last scheduling /// TPC from last scheduling
uint8_t oldTPC[8]; uint8_t oldTPC[8];
// PHY interface info // PHY interface info
/// Number of Allocated RBs for DL after scheduling (prior to frequency allocation) /// Number of Allocated RBs for DL after scheduling (prior to frequency allocation)
uint16_t nb_rb[8]; // num_max_harq uint16_t nb_rb[8]; // num_max_harq
/// Number of Allocated RBs for UL after scheduling /// Number of Allocated RBs for UL after scheduling
uint16_t nb_rb_ul[8]; // num_max_harq uint16_t nb_rb_ul[8]; // num_max_harq
/// Number of Allocated RBs for UL after scheduling /// Number of Allocated RBs for UL after scheduling
uint16_t first_rb_ul[8]; // num_max_harq uint16_t first_rb_ul[8]; // num_max_harq
/// Cyclic shift for DMRS after scheduling /// Cyclic shift for DMRS after scheduling
uint16_t cshift[8]; // num_max_harq uint16_t cshift[8]; // num_max_harq
/// Number of Allocated RBs by the ulsch preprocessor /// Number of Allocated RBs by the ulsch preprocessor
uint8_t pre_allocated_nb_rb_ul; uint8_t pre_allocated_nb_rb_ul;
/// index of Allocated RBs by the ulsch preprocessor /// index of Allocated RBs by the ulsch preprocessor
int8_t pre_allocated_rb_table_index_ul; int8_t pre_allocated_rb_table_index_ul;
/// total allocated RBs /// total allocated RBs
int8_t total_allocated_rbs; int8_t total_allocated_rbs;
/// pre-assigned MCS by the ulsch preprocessor /// pre-assigned MCS by the ulsch preprocessor
uint8_t pre_assigned_mcs_ul; uint8_t pre_assigned_mcs_ul;
/// assigned MCS by the ulsch scheduler /// assigned MCS by the ulsch scheduler
uint8_t assigned_mcs_ul; uint8_t assigned_mcs_ul;
/// DL DAI /// DL DAI
uint8_t DAI; uint8_t DAI;
/// UL DAI /// UL DAI
uint8_t DAI_ul[10]; uint8_t DAI_ul[10];
/// UL Scheduling Request Received /// UL Scheduling Request Received
uint8_t ul_SR; uint8_t ul_SR;
///Resource Block indication for each sub-band in MU-MIMO ///Resource Block indication for each sub-band in MU-MIMO
uint8_t rballoc_subband[8][50]; uint8_t rballoc_subband[8][50];
// Logical channel info for link with RLC // Logical channel info for link with RLC
/// Last received UE BSR info for each logical channel group id /// Last received UE BSR info for each logical channel group id
uint8_t bsr_info[MAX_NUM_LCGID]; uint8_t bsr_info[MAX_NUM_LCGID];
/// LCGID mapping /// LCGID mapping
long lcgidmap[11]; long lcgidmap[11];
/// phr information /// phr information
int8_t phr_info; int8_t phr_info;
/// phr information /// phr information
int8_t phr_info_configured; int8_t phr_info_configured;
///dl buffer info ///dl buffer info
uint32_t dl_buffer_info[MAX_NUM_LCID]; uint32_t dl_buffer_info[MAX_NUM_LCID];
/// total downlink buffer info /// total downlink buffer info
uint32_t dl_buffer_total; uint32_t dl_buffer_total;
/// total downlink pdus /// total downlink pdus
uint32_t dl_pdus_total; uint32_t dl_pdus_total;
/// downlink pdus for each LCID /// downlink pdus for each LCID
uint32_t dl_pdus_in_buffer[MAX_NUM_LCID]; uint32_t dl_pdus_in_buffer[MAX_NUM_LCID];
/// creation time of the downlink buffer head for each LCID /// creation time of the downlink buffer head for each LCID
uint32_t dl_buffer_head_sdu_creation_time[MAX_NUM_LCID]; uint32_t dl_buffer_head_sdu_creation_time[MAX_NUM_LCID];
/// maximum creation time of the downlink buffer head across all LCID /// maximum creation time of the downlink buffer head across all LCID
uint32_t dl_buffer_head_sdu_creation_time_max; uint32_t dl_buffer_head_sdu_creation_time_max;
/// a flag indicating that the downlink head SDU is segmented /// a flag indicating that the downlink head SDU is segmented
uint8_t dl_buffer_head_sdu_is_segmented[MAX_NUM_LCID]; uint8_t dl_buffer_head_sdu_is_segmented[MAX_NUM_LCID];
/// size of remaining size to send for the downlink head SDU /// size of remaining size to send for the downlink head SDU
uint32_t dl_buffer_head_sdu_remaining_size_to_send[MAX_NUM_LCID]; uint32_t dl_buffer_head_sdu_remaining_size_to_send[MAX_NUM_LCID];
/// total uplink buffer size /// total uplink buffer size
uint32_t ul_total_buffer; uint32_t ul_total_buffer;
/// uplink buffer creation time for each LCID /// uplink buffer creation time for each LCID
uint32_t ul_buffer_creation_time[MAX_NUM_LCGID]; uint32_t ul_buffer_creation_time[MAX_NUM_LCGID];
/// maximum uplink buffer creation time across all the LCIDs /// maximum uplink buffer creation time across all the LCIDs
uint32_t ul_buffer_creation_time_max; uint32_t ul_buffer_creation_time_max;
/// uplink buffer size per LCID /// uplink buffer size per LCID
uint32_t ul_buffer_info[MAX_NUM_LCGID]; uint32_t ul_buffer_info[MAX_NUM_LCGID];
/// UE tx power /// UE tx power
int32_t ue_tx_power; int32_t ue_tx_power;
/// stores the frame where the last TPC was transmitted /// stores the frame where the last TPC was transmitted
uint32_t pusch_tpc_tx_frame; uint32_t pusch_tpc_tx_frame;
uint32_t pusch_tpc_tx_subframe; uint32_t pusch_tpc_tx_subframe;
uint32_t pucch_tpc_tx_frame; uint32_t pucch_tpc_tx_frame;
uint32_t pucch_tpc_tx_subframe; uint32_t pucch_tpc_tx_subframe;
#ifdef LOCALIZATION #ifdef LOCALIZATION
eNB_UE_estimated_distances distance; eNB_UE_estimated_distances distance;
#endif #endif
#ifdef Rel14 #ifdef Rel14
uint8_t rach_resource_type; uint8_t rach_resource_type;
uint16_t mpdcch_repetition_cnt; uint16_t mpdcch_repetition_cnt;
frame_t Msg2_frame; frame_t Msg2_frame;
#endif #endif
sub_frame_t Msg2_subframe; sub_frame_t Msg2_subframe;
PhysicalConfigDedicated_t *physicalConfigDedicated; PhysicalConfigDedicated_t *physicalConfigDedicated;
} UE_TEMPLATE; } UE_TEMPLATE;
/*! \brief scheduling control information set through an API (not used)*/ /*! \brief scheduling control information set through an API (not used)*/
typedef struct { typedef struct {
///UL transmission bandwidth in RBs ///UL transmission bandwidth in RBs
uint8_t ul_bandwidth[MAX_NUM_LCID]; uint8_t ul_bandwidth[MAX_NUM_LCID];
///DL transmission bandwidth in RBs ///DL transmission bandwidth in RBs
uint8_t dl_bandwidth[MAX_NUM_LCID]; uint8_t dl_bandwidth[MAX_NUM_LCID];
//To do GBR bearer //To do GBR bearer
uint8_t min_ul_bandwidth[MAX_NUM_LCID]; uint8_t min_ul_bandwidth[MAX_NUM_LCID];
uint8_t min_dl_bandwidth[MAX_NUM_LCID]; uint8_t min_dl_bandwidth[MAX_NUM_LCID];
///aggregated bit rate of non-gbr bearer per UE ///aggregated bit rate of non-gbr bearer per UE
uint64_t ue_AggregatedMaximumBitrateDL; uint64_t ue_AggregatedMaximumBitrateDL;
///aggregated bit rate of non-gbr bearer per UE ///aggregated bit rate of non-gbr bearer per UE
uint64_t ue_AggregatedMaximumBitrateUL; uint64_t ue_AggregatedMaximumBitrateUL;
///CQI scheduling interval in subframes. ///CQI scheduling interval in subframes.
uint16_t cqiSchedInterval; uint16_t cqiSchedInterval;
///Contention resolution timer used during random access ///Contention resolution timer used during random access
uint8_t mac_ContentionResolutionTimer; uint8_t mac_ContentionResolutionTimer;
uint16_t max_allowed_rbs[MAX_NUM_LCID]; uint16_t max_allowed_rbs[MAX_NUM_LCID];
uint8_t max_mcs[MAX_NUM_LCID]; uint8_t max_mcs[MAX_NUM_LCID];
uint16_t priority[MAX_NUM_LCID]; uint16_t priority[MAX_NUM_LCID];
// resource scheduling information // resource scheduling information
/// Current DL harq round per harq_pid on each CC /// Current DL harq round per harq_pid on each CC
uint8_t round[MAX_NUM_CCs][10]; uint8_t round[MAX_NUM_CCs][10];
/// Current Active TBs per harq_pid on each CC /// Current Active TBs per harq_pid on each CC
uint8_t tbcnt[MAX_NUM_CCs][10]; uint8_t tbcnt[MAX_NUM_CCs][10];
/// Current UL harq round per harq_pid on each CC /// Current UL harq round per harq_pid on each CC
uint8_t round_UL[MAX_NUM_CCs][8]; uint8_t round_UL[MAX_NUM_CCs][8];
uint8_t dl_pow_off[MAX_NUM_CCs]; uint8_t dl_pow_off[MAX_NUM_CCs];
uint16_t pre_nb_available_rbs[MAX_NUM_CCs]; uint16_t pre_nb_available_rbs[MAX_NUM_CCs];
unsigned char rballoc_sub_UE[MAX_NUM_CCs][N_RBG_MAX]; unsigned char rballoc_sub_UE[MAX_NUM_CCs][N_RBG_MAX];
uint16_t ta_timer; uint16_t ta_timer;
int16_t ta_update; int16_t ta_update;
uint16_t ul_consecutive_errors; uint16_t ul_consecutive_errors;
int32_t context_active_timer; int32_t context_active_timer;
int32_t cqi_req_timer; int32_t cqi_req_timer;
int32_t ul_inactivity_timer; int32_t ul_inactivity_timer;
int32_t ul_failure_timer; int32_t ul_failure_timer;
int32_t ul_scheduled; int32_t ul_scheduled;
int32_t ra_pdcch_order_sent; int32_t ra_pdcch_order_sent;
int32_t ul_out_of_sync; int32_t ul_out_of_sync;
int32_t phr_received; int32_t phr_received;
uint8_t periodic_ri_received[NFAPI_CC_MAX]; uint8_t periodic_ri_received[NFAPI_CC_MAX];
uint8_t aperiodic_ri_received[NFAPI_CC_MAX]; uint8_t aperiodic_ri_received[NFAPI_CC_MAX];
uint8_t pucch1_cqi_update[NFAPI_CC_MAX]; uint8_t pucch1_cqi_update[NFAPI_CC_MAX];
uint8_t pucch1_snr[NFAPI_CC_MAX]; uint8_t pucch1_snr[NFAPI_CC_MAX];
uint8_t pucch2_cqi_update[NFAPI_CC_MAX]; uint8_t pucch2_cqi_update[NFAPI_CC_MAX];
uint8_t pucch2_snr[NFAPI_CC_MAX]; uint8_t pucch2_snr[NFAPI_CC_MAX];
uint8_t pucch3_cqi_update[NFAPI_CC_MAX]; uint8_t pucch3_cqi_update[NFAPI_CC_MAX];
uint8_t pucch3_snr[NFAPI_CC_MAX]; uint8_t pucch3_snr[NFAPI_CC_MAX];
uint8_t pusch_snr[NFAPI_CC_MAX]; uint8_t pusch_snr[NFAPI_CC_MAX];
uint16_t feedback_cnt[NFAPI_CC_MAX]; uint16_t feedback_cnt[NFAPI_CC_MAX];
uint16_t timing_advance; uint16_t timing_advance;
uint16_t timing_advance_r9; uint16_t timing_advance_r9;
uint8_t periodic_wideband_cqi[NFAPI_CC_MAX]; uint8_t periodic_wideband_cqi[NFAPI_CC_MAX];
uint8_t periodic_wideband_spatial_diffcqi[NFAPI_CC_MAX]; uint8_t periodic_wideband_spatial_diffcqi[NFAPI_CC_MAX];
uint8_t periodic_wideband_pmi[NFAPI_CC_MAX]; uint8_t periodic_wideband_pmi[NFAPI_CC_MAX];
uint8_t periodic_subband_cqi[NFAPI_CC_MAX][16]; uint8_t periodic_subband_cqi[NFAPI_CC_MAX][16];
uint8_t periodic_subband_spatial_diffcqi[NFAPI_CC_MAX][16]; uint8_t periodic_subband_spatial_diffcqi[NFAPI_CC_MAX][16];
uint8_t aperiodic_subband_cqi0[NFAPI_CC_MAX][25]; uint8_t aperiodic_subband_cqi0[NFAPI_CC_MAX][25];
uint8_t aperiodic_subband_pmi[NFAPI_CC_MAX][25]; uint8_t aperiodic_subband_pmi[NFAPI_CC_MAX][25];
uint8_t aperiodic_subband_diffcqi0[NFAPI_CC_MAX][25]; uint8_t aperiodic_subband_diffcqi0[NFAPI_CC_MAX][25];
uint8_t aperiodic_subband_cqi1[NFAPI_CC_MAX][25]; uint8_t aperiodic_subband_cqi1[NFAPI_CC_MAX][25];
uint8_t aperiodic_subband_diffcqi1[NFAPI_CC_MAX][25]; uint8_t aperiodic_subband_diffcqi1[NFAPI_CC_MAX][25];
uint8_t aperiodic_wideband_cqi0[NFAPI_CC_MAX]; uint8_t aperiodic_wideband_cqi0[NFAPI_CC_MAX];
uint8_t aperiodic_wideband_pmi[NFAPI_CC_MAX]; uint8_t aperiodic_wideband_pmi[NFAPI_CC_MAX];
uint8_t aperiodic_wideband_cqi1[NFAPI_CC_MAX]; uint8_t aperiodic_wideband_cqi1[NFAPI_CC_MAX];
uint8_t aperiodic_wideband_pmi1[NFAPI_CC_MAX]; uint8_t aperiodic_wideband_pmi1[NFAPI_CC_MAX];
uint8_t dl_cqi[NFAPI_CC_MAX]; uint8_t dl_cqi[NFAPI_CC_MAX];
} UE_sched_ctrl; } UE_sched_ctrl;
/*! \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) /// Subframe where preamble was received
uint8_t RA_dci_size_bytes1; uint8_t preamble_subframe;
/// Size of DCI for RA-Response (bits) /// Subframe where Msg2 is to be sent
uint8_t RA_dci_size_bits1; uint8_t Msg2_subframe;
/// Actual DCI to transmit for RA-Response /// Frame where Msg2 is to be sent
uint8_t RA_alloc_pdu1[(MAX_DCI_SIZE_BITS>>3)+1]; frame_t Msg2_frame;
/// DCI format for RA-Response (should be 1A) /// Subframe where Msg3 is to be sent
uint8_t RA_dci_fmt1; sub_frame_t Msg3_subframe;
/// Size of DCI for Msg4/ContRes (bytes) /// Frame where Msg3 is to be sent
uint8_t RA_dci_size_bytes2; frame_t Msg3_frame;
/// Size of DCI for Msg4/ContRes (bits) /// Subframe where Msg4 is to be sent
uint8_t RA_dci_size_bits2; sub_frame_t Msg4_subframe;
/// Actual DCI to transmit for Msg4/ContRes /// Frame where Msg4 is to be sent
uint8_t RA_alloc_pdu2[(MAX_DCI_SIZE_BITS>>3)+1]; frame_t Msg4_frame;
/// DCI format for Msg4/ContRes (should be 1A) /// harq_pid used for Msg4 transmission
uint8_t RA_dci_fmt2; uint8_t harq_pid;
/// Flag to indicate the eNB should generate RAR. This is triggered by detection of PRACH /// UE RNTI allocated during RAR
uint8_t generate_rar; rnti_t rnti;
/// Subframe where preamble was received /// RA RNTI allocated from received PRACH
uint8_t preamble_subframe; uint16_t RA_rnti;
/// Subframe where Msg2 is to be sent /// Received preamble_index
uint8_t Msg2_subframe; uint8_t preamble_index;
/// Frame where Msg2 is to be sent /// Received UE Contention Resolution Identifier
frame_t Msg2_frame; uint8_t cont_res_id[6];
/// Subframe where Msg3 is to be sent /// Timing offset indicated by PHY
sub_frame_t Msg3_subframe; int16_t timing_offset;
/// Frame where Msg3 is to be sent /// Timeout for RRC connection
frame_t Msg3_frame; int16_t RRC_timer;
/// Subframe where Msg4 is to be sent /// Msg3 first RB
sub_frame_t Msg4_subframe; uint8_t msg3_first_rb;
/// Frame where Msg4 is to be sent /// Msg3 number of RB
frame_t Msg4_frame; uint8_t msg3_nb_rb;
/// 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. /// Msg3 MCS
uint8_t generate_Msg4; uint8_t msg3_mcs;
/// Flag to indicate that eNB is waiting for ACK that UE has received Msg3. /// Msg3 TPC command
uint8_t wait_ack_Msg4; uint8_t msg3_TPC;
/// harq_pid used for Msg4 transmission /// Msg3 ULdelay command
uint8_t harq_pid; uint8_t msg3_ULdelay;
/// UE RNTI allocated during RAR /// Msg3 cqireq command
rnti_t rnti; uint8_t msg3_cqireq;
/// RA RNTI allocated from received PRACH /// Round of Msg3 HARQ
uint16_t RA_rnti; uint8_t msg3_round;
/// Received preamble_index /// TBS used for Msg4
uint8_t preamble_index; int msg4_TBsize;
/// Received UE Contention Resolution Identifier /// MCS used for Msg4
uint8_t cont_res_id[6]; int msg4_mcs;
/// Timing offset indicated by PHY
int16_t timing_offset;
/// Timeout for RRC connection
int16_t RRC_timer;
/// Msg3 first RB
uint8_t msg3_first_rb;
/// Msg3 number of RB
uint8_t msg3_nb_rb;
/// Msg3 MCS
uint8_t msg3_mcs;
/// Msg3 TPC command
uint8_t msg3_TPC;
/// Msg3 ULdelay command
uint8_t msg3_ULdelay;
/// Msg3 cqireq command
uint8_t msg3_cqireq;
/// Round of Msg3 HARQ
uint8_t msg3_round;
/// TBS used for Msg4
int msg4_TBsize;
/// MCS used for Msg4
int msg4_mcs;
#ifdef Rel14 #ifdef Rel14
uint8_t rach_resource_type; uint8_t rach_resource_type;
uint8_t msg2_mpdcch_repetition_cnt; uint8_t msg2_mpdcch_repetition_cnt;
uint8_t msg4_mpdcch_repetition_cnt; uint8_t msg4_mpdcch_repetition_cnt;
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 */
typedef struct { typedef struct {
uint8_t sbmap[NUMBER_OF_SUBBANDS_MAX]; //13 = number of SB MAX for 100 PRB uint8_t sbmap[NUMBER_OF_SUBBANDS_MAX]; //13 = number of SB MAX for 100 PRB
uint8_t periodicity; uint8_t periodicity;
uint8_t first_subframe; uint8_t first_subframe;
uint8_t sb_size; uint8_t sb_size;
uint8_t nb_active_sb; uint8_t nb_active_sb;
} SBMAP_CONF; } SBMAP_CONF;
/*! \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
/// DLSCH pdu *physicalConfigDedicated[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
DLSCH_PDU DLSCH_pdu[MAX_NUM_CCs][2][NUMBER_OF_UE_MAX]; /// DLSCH pdu
/// DCI template and MAC connection parameters for UEs DLSCH_PDU DLSCH_pdu[MAX_NUM_CCs][2][NUMBER_OF_UE_MAX];
UE_TEMPLATE UE_template[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; /// DCI template and MAC connection parameters for UEs
/// DCI template and MAC connection for RA processes UE_TEMPLATE UE_template[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
int pCC_id[NUMBER_OF_UE_MAX]; /// DCI template and MAC connection for RA processes
/// sorted downlink component carrier for the scheduler int pCC_id[NUMBER_OF_UE_MAX];
int ordered_CCids[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; /// sorted downlink component carrier for the scheduler
/// number of downlink active component carrier int ordered_CCids[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
int numactiveCCs[NUMBER_OF_UE_MAX]; /// number of downlink active component carrier
/// sorted uplink component carrier for the scheduler int numactiveCCs[NUMBER_OF_UE_MAX];
int ordered_ULCCids[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; /// sorted uplink component carrier for the scheduler
/// number of uplink active component carrier int ordered_ULCCids[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
int numactiveULCCs[NUMBER_OF_UE_MAX]; /// number of uplink active component carrier
/// number of downlink active component carrier int numactiveULCCs[NUMBER_OF_UE_MAX];
uint8_t dl_CC_bitmap[NUMBER_OF_UE_MAX]; /// number of downlink active component carrier
/// eNB to UE statistics uint8_t dl_CC_bitmap[NUMBER_OF_UE_MAX];
eNB_UE_STATS eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; /// eNB to UE statistics
/// scheduling control info eNB_UE_STATS eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
UE_sched_ctrl UE_sched_ctrl[NUMBER_OF_UE_MAX]; /// scheduling control info
int next[NUMBER_OF_UE_MAX]; UE_sched_ctrl UE_sched_ctrl[NUMBER_OF_UE_MAX];
int head; int next[NUMBER_OF_UE_MAX];
int next_ul[NUMBER_OF_UE_MAX]; int head;
int head_ul; int next_ul[NUMBER_OF_UE_MAX];
int avail; int head_ul;
int num_UEs; int avail;
boolean_t active[NUMBER_OF_UE_MAX]; int num_UEs;
boolean_t active[NUMBER_OF_UE_MAX];
} UE_list_t; } UE_list_t;
/*! \brief eNB common channels */ /*! \brief eNB common channels */
typedef struct { typedef struct {
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;
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
TDD_Config_t *tdd_Config; TDD_Config_t *tdd_Config;
SchedulingInfoList_t *schedulingInfoList; SchedulingInfoList_t *schedulingInfoList;
ARFCN_ValueEUTRA_t ul_CarrierFreq; ARFCN_ValueEUTRA_t ul_CarrierFreq;
long ul_Bandwidth; long ul_Bandwidth;
/// Outgoing MIB PDU for PHY /// Outgoing MIB PDU for PHY
MIB_PDU MIB_pdu; MIB_PDU MIB_pdu;
/// Outgoing BCCH pdu for PHY /// Outgoing BCCH pdu for PHY
BCCH_PDU BCCH_pdu; BCCH_PDU BCCH_pdu;
/// Outgoing BCCH DCI allocation /// Outgoing BCCH DCI allocation
uint32_t BCCH_alloc_pdu; uint32_t BCCH_alloc_pdu;
/// Outgoing CCCH pdu for PHY /// Outgoing CCCH pdu for PHY
CCCH_PDU CCCH_pdu; CCCH_PDU CCCH_pdu;
/// Outgoing 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
uint8_t vrb_map_UL[100]; uint8_t vrb_map_UL[100];
/// MBSFN SubframeConfig /// MBSFN SubframeConfig
struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[8]; struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[8];
/// number of subframe allocation pattern available for MBSFN sync area /// number of subframe allocation pattern available for MBSFN sync area
uint8_t num_sf_allocation_pattern; uint8_t num_sf_allocation_pattern;
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
/// MBMS Flag /// MBMS Flag
uint8_t MBMS_flag; uint8_t MBMS_flag;
/// Outgoing MCCH pdu for PHY /// Outgoing MCCH pdu for PHY
MCCH_PDU MCCH_pdu; MCCH_PDU MCCH_pdu;
/// MCCH active flag /// MCCH active flag
uint8_t msi_active; uint8_t msi_active;
/// MCCH active flag /// MCCH active flag
uint8_t mcch_active; uint8_t mcch_active;
/// MTCH active flag /// MTCH active flag
uint8_t mtch_active; uint8_t mtch_active;
/// number of active MBSFN area /// number of active MBSFN area
uint8_t num_active_mbsfn_area; uint8_t num_active_mbsfn_area;
/// MBSFN Area Info /// MBSFN Area Info
struct MBSFN_AreaInfo_r9 *mbsfn_AreaInfo[MAX_MBSFN_AREA]; struct MBSFN_AreaInfo_r9 *mbsfn_AreaInfo[MAX_MBSFN_AREA];
/// PMCH Config /// PMCH Config
struct PMCH_Config_r9 *pmch_Config[MAX_PMCH_perMBSFN]; struct PMCH_Config_r9 *pmch_Config[MAX_PMCH_perMBSFN];
/// MBMS session info list /// MBMS session info list
struct MBMS_SessionInfoList_r9 *mbms_SessionList[MAX_PMCH_perMBSFN]; struct MBMS_SessionInfoList_r9 *mbms_SessionList[MAX_PMCH_perMBSFN];
/// Outgoing MCH pdu for PHY /// Outgoing MCH pdu for PHY
MCH_PDU MCH_pdu; MCH_PDU MCH_pdu;
#endif #endif
#ifdef Rel14 #ifdef Rel14
/// Rel13 parameters from SIB1 /// Rel13 parameters from SIB1
SystemInformationBlockType1_v1310_IEs_t *sib1_v13ext; SystemInformationBlockType1_v1310_IEs_t *sib1_v13ext;
/// Counter for SIB1-BR scheduling /// Counter for SIB1-BR scheduling
int SIB1_BR_cnt; int SIB1_BR_cnt;
/// Outgoing BCCH-BR pdu for PHY /// Outgoing BCCH-BR pdu for PHY
BCCH_PDU BCCH_BR_pdu[20]; BCCH_PDU BCCH_BR_pdu[20];
#endif #endif
} COMMON_channels_t; } COMMON_channels_t;
/*! \brief top level eNB MAC structure */ /*! \brief top level eNB MAC structure */
typedef struct eNB_MAC_INST_s { typedef struct eNB_MAC_INST_s {
/// Ethernet parameters for northbound midhaul interface /// Ethernet parameters for northbound midhaul interface
eth_params_t eth_params_n; eth_params_t eth_params_n;
/// Ethernet parameters for fronthaul interface /// Ethernet parameters for fronthaul interface
eth_params_t eth_params_s; eth_params_t eth_params_s;
/// ///
module_id_t Mod_id; module_id_t Mod_id;
/// frame counter /// frame counter
frame_t frame; frame_t frame;
/// subframe counter /// subframe counter
sub_frame_t subframe; sub_frame_t subframe;
/// Pointer to IF module instance for PHY /// Pointer to IF module instance for PHY
IF_Module_t *if_inst; IF_Module_t *if_inst;
/// Common cell resources /// Common cell resources
COMMON_channels_t common_channels[MAX_NUM_CCs]; COMMON_channels_t common_channels[MAX_NUM_CCs];
/// current PDU index (BCH,MCH,DLSCH) /// current PDU index (BCH,MCH,DLSCH)
uint16_t pdu_index[MAX_NUM_CCs]; uint16_t pdu_index[MAX_NUM_CCs];
/// 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
/// NFAPI DL Config Request Structure dl_config_pdu_list[MAX_NUM_CCs][MAX_NUM_DL_PDU];
nfapi_dl_config_request_t DL_req[MAX_NUM_CCs]; /// NFAPI DL Config Request Structure
/// Preallocated UL pdu list nfapi_dl_config_request_t DL_req[MAX_NUM_CCs];
nfapi_ul_config_request_pdu_t ul_config_pdu_list[MAX_NUM_CCs][MAX_NUM_UL_PDU]; /// Preallocated UL pdu list
/// Preallocated UL pdu list for ULSCH (n+k delay) nfapi_ul_config_request_pdu_t
nfapi_ul_config_request_pdu_t ul_config_pdu_list_tmp[MAX_NUM_CCs][10][MAX_NUM_UL_PDU]; ul_config_pdu_list[MAX_NUM_CCs][MAX_NUM_UL_PDU];
/// NFAPI UL Config Request Structure, send to L1 4 subframes before processing takes place /// Preallocated UL pdu list for ULSCH (n+k delay)
nfapi_ul_config_request_t UL_req[MAX_NUM_CCs]; nfapi_ul_config_request_pdu_t
/// NFAPI "Temporary" UL Config Request Structure, holds future UL_config requests ul_config_pdu_list_tmp[MAX_NUM_CCs][10][MAX_NUM_UL_PDU];
nfapi_ul_config_request_t UL_req_tmp[MAX_NUM_CCs][10]; /// NFAPI UL Config Request Structure, send to L1 4 subframes before processing takes place
/// Preallocated HI_DCI0 pdu list nfapi_ul_config_request_t UL_req[MAX_NUM_CCs];
nfapi_hi_dci0_request_pdu_t hi_dci0_pdu_list[MAX_NUM_CCs][MAX_NUM_HI_DCI0_PDU]; /// NFAPI "Temporary" UL Config Request Structure, holds future UL_config requests
/// NFAPI HI/DCI0 Config Request Structure nfapi_ul_config_request_t UL_req_tmp[MAX_NUM_CCs][10];
nfapi_hi_dci0_request_t HI_DCI0_req[MAX_NUM_CCs]; /// Preallocated HI_DCI0 pdu list
/// Prealocated TX pdu list nfapi_hi_dci0_request_pdu_t
nfapi_tx_request_pdu_t tx_request_pdu[MAX_NUM_CCs][MAX_NUM_TX_REQUEST_PDU]; hi_dci0_pdu_list[MAX_NUM_CCs][MAX_NUM_HI_DCI0_PDU];
/// NFAPI DL PDU structure /// NFAPI HI/DCI0 Config Request Structure
nfapi_tx_request_t TX_req[MAX_NUM_CCs]; nfapi_hi_dci0_request_t HI_DCI0_req[MAX_NUM_CCs];
/// UL handle /// Prealocated TX pdu list
uint32_t ul_handle; nfapi_tx_request_pdu_t
UE_list_t UE_list; tx_request_pdu[MAX_NUM_CCs][MAX_NUM_TX_REQUEST_PDU];
/// NFAPI DL PDU structure
///subband bitmap configuration nfapi_tx_request_t TX_req[MAX_NUM_CCs];
SBMAP_CONF sbmap_conf; /// UL handle
/// CCE table used to build DCI scheduling information uint32_t ul_handle;
int CCE_table[MAX_NUM_CCs][800]; UE_list_t UE_list;
/// active flag for Other lcid
uint8_t lcid_active[NB_RB_MAX]; ///subband bitmap configuration
/// eNB stats SBMAP_CONF sbmap_conf;
eNB_STATS eNB_stats[MAX_NUM_CCs]; /// CCE table used to build DCI scheduling information
// MAC function execution peformance profiler int CCE_table[MAX_NUM_CCs][800];
/// processing time of eNB scheduler /// active flag for Other lcid
time_stats_t eNB_scheduler; uint8_t lcid_active[NB_RB_MAX];
/// processing time of eNB scheduler for SI /// eNB stats
time_stats_t schedule_si; eNB_STATS eNB_stats[MAX_NUM_CCs];
/// processing time of eNB scheduler for Random access // MAC function execution peformance profiler
time_stats_t schedule_ra; /// processing time of eNB scheduler
/// processing time of eNB ULSCH scheduler time_stats_t eNB_scheduler;
time_stats_t schedule_ulsch; /// processing time of eNB scheduler for SI
/// processing time of eNB DCI generation time_stats_t schedule_si;
time_stats_t fill_DLSCH_dci; /// processing time of eNB scheduler for Random access
/// processing time of eNB MAC preprocessor time_stats_t schedule_ra;
time_stats_t schedule_dlsch_preprocessor; /// processing time of eNB ULSCH scheduler
/// processing time of eNB DLSCH scheduler time_stats_t schedule_ulsch;
time_stats_t schedule_dlsch; // include rlc_data_req + MAC header + preprocessor /// processing time of eNB DCI generation
/// processing time of eNB MCH scheduler time_stats_t fill_DLSCH_dci;
time_stats_t schedule_mch; /// processing time of eNB MAC preprocessor
/// processing time of eNB ULSCH reception time_stats_t schedule_dlsch_preprocessor;
time_stats_t rx_ulsch_sdu; // include rlc_data_ind /// processing time of eNB DLSCH scheduler
time_stats_t schedule_dlsch; // include rlc_data_req + MAC header + preprocessor
/// processing time of eNB MCH scheduler
time_stats_t schedule_mch;
/// processing time of eNB ULSCH reception
time_stats_t rx_ulsch_sdu; // include rlc_data_ind
} eNB_MAC_INST; } eNB_MAC_INST;
/* /*
* UE part * UE part
*/ */
typedef enum { typedef enum {
TYPE0, TYPE0,
TYPE1, TYPE1,
TYPE1A, TYPE1A,
TYPE2, TYPE2,
TYPE2A, TYPE2A,
TYPEUESPEC TYPEUESPEC
} MPDCCH_TYPES_t; } MPDCCH_TYPES_t;
/*!\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
} UE_L2_STATE_t; } UE_L2_STATE_t;
/*!\brief UE scheduling info */ /*!\brief UE scheduling info */
typedef struct { typedef struct {
/// buffer status for each lcgid /// buffer status for each lcgid
uint8_t BSR[MAX_NUM_LCGID]; // should be more for mesh topology uint8_t BSR[MAX_NUM_LCGID]; // should be more for mesh topology
/// keep the number of bytes in rlc buffer for each lcgid /// keep the number of bytes in rlc buffer for each lcgid
int32_t BSR_bytes[MAX_NUM_LCGID]; int32_t BSR_bytes[MAX_NUM_LCGID];
/// after multiplexing buffer remain for each lcid /// after multiplexing buffer remain for each lcid
int32_t LCID_buffer_remain[MAX_NUM_LCID]; int32_t LCID_buffer_remain[MAX_NUM_LCID];
/// sum of all lcid buffer size /// sum of all lcid buffer size
uint16_t All_lcid_buffer_size_lastTTI; uint16_t All_lcid_buffer_size_lastTTI;
/// buffer status for each lcid /// buffer status for each lcid
uint8_t LCID_status[MAX_NUM_LCID]; uint8_t LCID_status[MAX_NUM_LCID];
/// SR pending as defined in 36.321 /// SR pending as defined in 36.321
uint8_t SR_pending; uint8_t SR_pending;
/// SR_COUNTER as defined in 36.321 /// SR_COUNTER as defined in 36.321
uint16_t SR_COUNTER; uint16_t SR_COUNTER;
/// logical channel group ide for each LCID /// logical channel group ide for each LCID
uint8_t LCGID[MAX_NUM_LCID]; uint8_t LCGID[MAX_NUM_LCID];
/// retxBSR-Timer, default value is sf2560 /// retxBSR-Timer, default value is sf2560
uint16_t retxBSR_Timer; uint16_t retxBSR_Timer;
/// retxBSR_SF, number of subframe before triggering a regular BSR /// retxBSR_SF, number of subframe before triggering a regular BSR
uint16_t retxBSR_SF; uint16_t retxBSR_SF;
/// periodicBSR-Timer, default to infinity /// periodicBSR-Timer, default to infinity
uint16_t periodicBSR_Timer; uint16_t periodicBSR_Timer;
/// periodicBSR_SF, number of subframe before triggering a periodic BSR /// periodicBSR_SF, number of subframe before triggering a periodic BSR
uint16_t periodicBSR_SF; uint16_t periodicBSR_SF;
/// default value is 0: not configured /// default value is 0: not configured
uint16_t sr_ProhibitTimer; uint16_t sr_ProhibitTimer;
/// sr ProhibitTime running /// sr ProhibitTime running
uint8_t sr_ProhibitTimer_Running; uint8_t sr_ProhibitTimer_Running;
/// default value to n5 /// default value to n5
uint16_t maxHARQ_Tx; uint16_t maxHARQ_Tx;
/// default value is false /// default value is false
uint16_t ttiBundling; uint16_t ttiBundling;
/// default value is release /// default value is release
struct DRX_Config *drx_config; struct DRX_Config *drx_config;
/// default value is release /// default value is release
struct MAC_MainConfig__phr_Config *phr_config; struct MAC_MainConfig__phr_Config *phr_config;
///timer before triggering a periodic PHR ///timer before triggering a periodic PHR
uint16_t periodicPHR_Timer; uint16_t periodicPHR_Timer;
///timer before triggering a prohibit PHR ///timer before triggering a prohibit PHR
uint16_t prohibitPHR_Timer; uint16_t prohibitPHR_Timer;
///DL Pathloss change value ///DL Pathloss change value
uint16_t PathlossChange; uint16_t PathlossChange;
///number of subframe before triggering a periodic PHR ///number of subframe before triggering a periodic PHR
int16_t periodicPHR_SF; int16_t periodicPHR_SF;
///number of subframe before triggering a prohibit PHR ///number of subframe before triggering a prohibit PHR
int16_t prohibitPHR_SF; int16_t prohibitPHR_SF;
///DL Pathloss Change in db ///DL Pathloss Change in db
uint16_t PathlossChange_db; uint16_t PathlossChange_db;
/// default value is false /// default value is false
uint16_t extendedBSR_Sizes_r10; uint16_t extendedBSR_Sizes_r10;
/// default value is false /// default value is false
uint16_t extendedPHR_r10; uint16_t extendedPHR_r10;
//Bj bucket usage per lcid //Bj bucket usage per lcid
int16_t Bj[MAX_NUM_LCID]; int16_t Bj[MAX_NUM_LCID];
// Bucket size per lcid // Bucket size per lcid
int16_t bucket_size[MAX_NUM_LCID]; int16_t bucket_size[MAX_NUM_LCID];
} UE_SCHEDULING_INFO; } UE_SCHEDULING_INFO;
/*!\brief Top level UE MAC structure */ /*!\brief Top level UE MAC structure */
typedef struct { typedef struct {
uint16_t Node_id; uint16_t Node_id;
/// RX frame counter /// RX frame counter
frame_t rxFrame; frame_t rxFrame;
/// RX subframe counter /// RX subframe counter
sub_frame_t rxSubframe; sub_frame_t rxSubframe;
/// TX frame counter /// TX frame counter
frame_t txFrame; frame_t txFrame;
/// TX subframe counter /// TX subframe counter
sub_frame_t txSubframe; sub_frame_t txSubframe;
/// C-RNTI of UE /// C-RNTI of UE
uint16_t crnti; uint16_t crnti;
/// C-RNTI of UE before HO /// C-RNTI of UE before HO
rnti_t crnti_before_ho; ///user id (rnti) of connected UEs rnti_t crnti_before_ho; ///user id (rnti) of connected UEs
/// uplink active flag /// uplink active flag
uint8_t ul_active; uint8_t ul_active;
/// pointer to RRC PHY configuration /// pointer to RRC PHY configuration
RadioResourceConfigCommonSIB_t *radioResourceConfigCommon; RadioResourceConfigCommonSIB_t *radioResourceConfigCommon;
/// pointer to RACH_ConfigDedicated (NULL when not active, i.e. upon HO completion or T304 expiry) /// pointer to RACH_ConfigDedicated (NULL when not active, i.e. upon HO completion or T304 expiry)
struct RACH_ConfigDedicated *rach_ConfigDedicated; struct RACH_ConfigDedicated *rach_ConfigDedicated;
/// pointer to RRC PHY configuration /// pointer to RRC PHY configuration
struct PhysicalConfigDedicated *physicalConfigDedicated; struct PhysicalConfigDedicated *physicalConfigDedicated;
#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;
/// Number of adjacent cells to measure /// Number of adjacent cells to measure
uint8_t n_adj_cells; uint8_t n_adj_cells;
/// Array of adjacent physical cell ids /// Array of adjacent physical cell ids
uint32_t adj_cell_id[6]; uint32_t adj_cell_id[6];
/// Pointer to RRC MAC configuration /// Pointer to RRC MAC configuration
MAC_MainConfig_t *macConfig; MAC_MainConfig_t *macConfig;
/// Pointer to RRC Measurement gap configuration /// Pointer to RRC Measurement gap configuration
MeasGapConfig_t *measGapConfig; MeasGapConfig_t *measGapConfig;
/// Pointers to LogicalChannelConfig indexed by LogicalChannelIdentity. Note NULL means LCHAN is inactive. /// Pointers to LogicalChannelConfig indexed by LogicalChannelIdentity. Note NULL means LCHAN is inactive.
LogicalChannelConfig_t *logicalChannelConfig[MAX_NUM_LCID]; LogicalChannelConfig_t *logicalChannelConfig[MAX_NUM_LCID];
/// Scheduling Information /// Scheduling Information
UE_SCHEDULING_INFO scheduling_info; UE_SCHEDULING_INFO scheduling_info;
/// Outgoing CCCH pdu for PHY /// Outgoing CCCH pdu for PHY
CCCH_PDU CCCH_pdu; CCCH_PDU CCCH_pdu;
/// Outgoing RAR pdu for PHY /// Outgoing RAR pdu for PHY
RAR_PDU RAR_pdu; RAR_PDU RAR_pdu;
/// Incoming DLSCH pdu for PHY /// Incoming DLSCH pdu for PHY
DLSCH_PDU DLSCH_pdu[NUMBER_OF_UE_MAX][2]; DLSCH_PDU DLSCH_pdu[NUMBER_OF_UE_MAX][2];
/// number of attempt for rach /// number of attempt for rach
uint8_t RA_attempt_number; uint8_t RA_attempt_number;
/// Random-access procedure flag /// Random-access procedure flag
uint8_t RA_active; uint8_t RA_active;
/// Random-access window counter /// Random-access window counter
int8_t RA_window_cnt; int8_t RA_window_cnt;
/// Random-access Msg3 size in bytes /// Random-access Msg3 size in bytes
uint8_t RA_Msg3_size; uint8_t RA_Msg3_size;
/// Random-access prachMaskIndex /// Random-access prachMaskIndex
uint8_t RA_prachMaskIndex; uint8_t RA_prachMaskIndex;
/// Flag indicating Preamble set (A,B) used for first Msg3 transmission /// Flag indicating Preamble set (A,B) used for first Msg3 transmission
uint8_t RA_usedGroupA; uint8_t RA_usedGroupA;
/// Random-access Resources /// Random-access Resources
PRACH_RESOURCES_t RA_prach_resources; PRACH_RESOURCES_t RA_prach_resources;
/// Random-access PREAMBLE_TRANSMISSION_COUNTER /// Random-access PREAMBLE_TRANSMISSION_COUNTER
uint8_t RA_PREAMBLE_TRANSMISSION_COUNTER; uint8_t RA_PREAMBLE_TRANSMISSION_COUNTER;
/// Random-access backoff counter /// Random-access backoff counter
int16_t RA_backoff_cnt; int16_t RA_backoff_cnt;
/// Random-access variable for window calculation (frame of last change in window counter) /// Random-access variable for window calculation (frame of last change in window counter)
uint32_t RA_tx_frame; uint32_t RA_tx_frame;
/// Random-access variable for window calculation (subframe of last change in window counter) /// Random-access variable for window calculation (subframe of last change in window counter)
uint8_t RA_tx_subframe; uint8_t RA_tx_subframe;
/// Random-access Group B maximum path-loss /// Random-access Group B maximum path-loss
/// Random-access variable for backoff (frame of last change in backoff counter) /// Random-access variable for backoff (frame of last change in backoff counter)
uint32_t RA_backoff_frame; uint32_t RA_backoff_frame;
/// Random-access variable for backoff (subframe of last change in backoff counter) /// Random-access variable for backoff (subframe of last change in backoff counter)
uint8_t RA_backoff_subframe; uint8_t RA_backoff_subframe;
/// Random-access Group B maximum path-loss /// Random-access Group B maximum path-loss
uint16_t RA_maxPL; uint16_t RA_maxPL;
/// Random-access Contention Resolution Timer active flag /// Random-access Contention Resolution Timer active flag
uint8_t RA_contention_resolution_timer_active; uint8_t RA_contention_resolution_timer_active;
/// Random-access Contention Resolution Timer count value /// Random-access Contention Resolution Timer count value
uint8_t RA_contention_resolution_cnt; uint8_t RA_contention_resolution_cnt;
/// power headroom reporitng reconfigured /// power headroom reporitng reconfigured
uint8_t PHR_reconfigured; uint8_t PHR_reconfigured;
/// power headroom state as configured by the higher layers /// power headroom state as configured by the higher layers
uint8_t PHR_state; uint8_t PHR_state;
/// power backoff due to power management (as allowed by P-MPRc) for this cell /// power backoff due to power management (as allowed by P-MPRc) for this cell
uint8_t PHR_reporting_active; uint8_t PHR_reporting_active;
/// power backoff due to power management (as allowed by P-MPRc) for this cell /// power backoff due to power management (as allowed by P-MPRc) for this cell
uint8_t power_backoff_db[NUMBER_OF_eNB_MAX]; uint8_t power_backoff_db[NUMBER_OF_eNB_MAX];
/// BSR report falg management /// BSR report falg management
uint8_t BSR_reporting_active; uint8_t BSR_reporting_active;
/// retxBSR-Timer expires flag /// retxBSR-Timer expires flag
uint8_t retxBSRTimer_expires_flag; uint8_t retxBSRTimer_expires_flag;
/// periodBSR-Timer expires flag /// periodBSR-Timer expires flag
uint8_t periodBSRTimer_expires_flag; uint8_t periodBSRTimer_expires_flag;
/// MBSFN_Subframe Configuration /// MBSFN_Subframe Configuration
struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[8]; // FIXME replace 8 by MAX_MBSFN_AREA? struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[8]; // FIXME replace 8 by MAX_MBSFN_AREA?
/// number of subframe allocation pattern available for MBSFN sync area /// number of subframe allocation pattern available for MBSFN sync area
uint8_t num_sf_allocation_pattern; uint8_t num_sf_allocation_pattern;
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
/// number of active MBSFN area /// number of active MBSFN area
uint8_t num_active_mbsfn_area; uint8_t num_active_mbsfn_area;
/// MBSFN Area Info /// MBSFN Area Info
struct MBSFN_AreaInfo_r9 *mbsfn_AreaInfo[MAX_MBSFN_AREA]; struct MBSFN_AreaInfo_r9 *mbsfn_AreaInfo[MAX_MBSFN_AREA];
/// PMCH Config /// PMCH Config
struct PMCH_Config_r9 *pmch_Config[MAX_PMCH_perMBSFN]; struct PMCH_Config_r9 *pmch_Config[MAX_PMCH_perMBSFN];
/// 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
uint16_t cba_rnti[NUM_MAX_CBA_GROUP]; uint16_t cba_rnti[NUM_MAX_CBA_GROUP];
/// last SFN for CBA channel access /// last SFN for CBA channel access
uint8_t cba_last_access[NUM_MAX_CBA_GROUP]; uint8_t cba_last_access[NUM_MAX_CBA_GROUP];
//#endif //#endif
/// total UE scheduler processing time /// total UE scheduler processing time
time_stats_t ue_scheduler; // total time_stats_t ue_scheduler; // total
/// 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
time_stats_t rx_mch_sdu; time_stats_t rx_mch_sdu;
/// UE BCCH rx processing time including RLC interface (mac_rrc_data_ind) /// UE BCCH rx processing time including RLC interface (mac_rrc_data_ind)
time_stats_t rx_si; time_stats_t rx_si;
/// UE PCCH rx processing time including RLC interface (mac_rrc_data_ind) /// UE PCCH rx processing time including RLC interface (mac_rrc_data_ind)
time_stats_t rx_p; time_stats_t rx_p;
} UE_MAC_INST; } UE_MAC_INST;
/*! \brief ID of the neighboring cells used for HO*/ /*! \brief ID of the neighboring cells used for HO*/
typedef struct { typedef struct {
uint16_t cell_ids[6]; uint16_t cell_ids[6];
uint8_t n_adj_cells; uint8_t n_adj_cells;
} neigh_cell_id_t; } neigh_cell_id_t;
#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,481 +68,693 @@ ...@@ -68,481 +68,693 @@
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;
uint8_t TSFC; uint8_t TSFC;
uint16_t deltaTSFC; // bitmap uint16_t deltaTSFC; // bitmap
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 =
// check if SRS is enabled in this frame/subframe &cc[CC_id].radioResourceConfigCommon->
if (soundingRS_UL_ConfigCommon) { soundingRS_UL_ConfigCommon;
srs_SubframeConfig = soundingRS_UL_ConfigCommon->choice.setup.srs_SubframeConfig; // check if SRS is enabled in this frame/subframe
if (cc[CC_id].tdd_Config == NULL) { // FDD if (soundingRS_UL_ConfigCommon) {
deltaTSFC = deltaTSFCTabType1[srs_SubframeConfig][0]; srs_SubframeConfig =
TSFC = deltaTSFCTabType1[srs_SubframeConfig][1]; soundingRS_UL_ConfigCommon->choice.setup.
} srs_SubframeConfig;
else { // TDD if (cc[CC_id].tdd_Config == NULL) { // FDD
deltaTSFC = deltaTSFCTabType2[srs_SubframeConfig][0]; deltaTSFC = deltaTSFCTabType1[srs_SubframeConfig][0];
TSFC = deltaTSFCTabType2[srs_SubframeConfig][1]; TSFC = deltaTSFCTabType1[srs_SubframeConfig][1];
} } else { // TDD
// Sounding reference signal subframes are the subframes satisfying ns/2 mod TSFC (- deltaTSFC deltaTSFC = deltaTSFCTabType2[srs_SubframeConfig][0];
uint16_t tmp = (subframeP % TSFC); TSFC = deltaTSFCTabType2[srs_SubframeConfig][1];
}
if((1<<tmp) & deltaTSFC) { // Sounding reference signal subframes are the subframes satisfying ns/2 mod TSFC (- deltaTSFC
// This is an SRS subframe, loop over UEs uint16_t tmp = (subframeP % TSFC);
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 ((1 << tmp) & deltaTSFC) {
ul_req = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body; // This is an SRS subframe, loop over UEs
for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
if (RC.mac[module_idP]->UE_list.active[UE_id] != TRUE)
// drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet continue;
if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED) continue; ul_req =
&RC.mac[module_idP]->UL_req[CC_id].
AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",UE_id); ul_config_request_body;
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) { // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet
get_srs_pos(&cc[CC_id], soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex, &srsPeriodicity, &srsOffset); if (mac_eNB_get_rrc_status
if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset) { (module_idP,
// Prorgram SRS UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED)
ul_req->srs_present = 1; continue;
nfapi_ul_config_request_pdu_t* ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus];
memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t)); AssertFatal(UE_list->UE_template[CC_id]
ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_SRS_PDU_TYPE; [UE_id].physicalConfigDedicated != NULL,
ul_config_pdu->pdu_size = 2+(uint8_t)(2+sizeof(nfapi_ul_config_srs_pdu)); "physicalConfigDedicated is null for UE %d\n",
ul_config_pdu->srs_pdu.srs_pdu_rel8.size = (uint8_t)sizeof(nfapi_ul_config_srs_pdu);; UE_id);
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; if ((soundingRS_UL_ConfigDedicated =
ul_config_pdu->srs_pdu.srs_pdu_rel8.frequency_domain_position = soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition; UE_list->UE_template[CC_id]
ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_hopping_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth;; [UE_id].
ul_config_pdu->srs_pdu.srs_pdu_rel8.transmission_comb = soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb; physicalConfigDedicated->soundingRS_UL_ConfigDedicated)
ul_config_pdu->srs_pdu.srs_pdu_rel8.i_srs = soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex; != NULL) {
ul_config_pdu->srs_pdu.srs_pdu_rel8.sounding_reference_cyclic_shift = soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift; if (soundingRS_UL_ConfigDedicated->present ==
// ul_config_pdu->srs_pdu.srs_pdu_rel10.antenna_port = ;// SoundingRS_UL_ConfigDedicated_PR_setup) {
// ul_config_pdu->srs_pdu.srs_pdu_rel13.number_of_combs = ;// get_srs_pos(&cc[CC_id],
RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP<<4)+subframeP; soundingRS_UL_ConfigDedicated->choice.
ul_req->number_of_pdus++; setup.srs_ConfigIndex,
} // if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset) &srsPeriodicity, &srsOffset);
} // if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) if (((10 * frameP +
} // if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL) subframeP) % srsPeriodicity) ==
} // for (UE_id ... srsOffset) {
} // if((1<<tmp) & deltaTSFC) // Prorgram SRS
ul_req->srs_present = 1;
}// SRS config nfapi_ul_config_request_pdu_t
} * ul_config_pdu =
&ul_req->
ul_config_pdu_list
[ul_req->number_of_pdus];
memset((void *) ul_config_pdu, 0,
sizeof
(nfapi_ul_config_request_pdu_t));
ul_config_pdu->pdu_type =
NFAPI_UL_CONFIG_SRS_PDU_TYPE;
ul_config_pdu->pdu_size =
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_rel13.number_of_combs = ;//
RC.mac[module_idP]->UL_req[CC_id].sfn_sf =
(frameP << 4) + subframeP;
ul_req->number_of_pdus++;
} // if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset)
} // if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup)
} // if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL)
} // for (UE_id ...
} // if((1<<tmp) & deltaTSFC)
} // 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 =
// drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body;
if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED) continue;
// drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet
AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",UE_id); if (mac_eNB_get_rrc_status
(module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED)
if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig) { continue;
if ((cqi_ReportPeriodic = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic)!=NULL &&
(cqi_ReportPeriodic->present!=CQI_ReportPeriodic_PR_release)) { AssertFatal(UE_list->
//Rel8 Periodic CQI/PMI/RI reporting UE_template[CC_id][UE_id].physicalConfigDedicated
!= NULL,
get_csi_params(cc,cqi_ReportPeriodic,&Npd,&N_OFFSET_CQI,&H); "physicalConfigDedicated is null for UE %d\n",
UE_id);
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; if (UE_list->
// Program CQI UE_template[CC_id][UE_id].physicalConfigDedicated->
nfapi_ul_config_request_pdu_t* ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; cqi_ReportConfig) {
memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t)); if ((cqi_ReportPeriodic =
ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE; UE_list->
ul_config_pdu->pdu_size = 2+(uint8_t)(2+sizeof(nfapi_ul_config_uci_cqi_pdu)); UE_template[CC_id][UE_id].physicalConfigDedicated->
ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; cqi_ReportConfig->cqi_ReportPeriodic) != NULL
ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.pucch_index = cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; && (cqi_ReportPeriodic->present !=
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], CQI_ReportPeriodic_PR_release)) {
CC_id, //Rel8 Periodic CQI/PMI/RI reporting
cc,
get_tmode(module_idP,CC_id,UE_id), get_csi_params(cc, cqi_ReportPeriodic, &Npd,
cqi_ReportPeriodic); &N_OFFSET_CQI, &H);
ul_req->number_of_pdus++;
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;
// Program CQI
nfapi_ul_config_request_pdu_t *ul_config_pdu =
&ul_req->ul_config_pdu_list[ul_req->
number_of_pdus];
memset((void *) ul_config_pdu, 0,
sizeof(nfapi_ul_config_request_pdu_t));
ul_config_pdu->pdu_type =
NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE;
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 =
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);
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 =
ul_req->number_of_pdus++; 2 + (uint8_t) (2 +
} sizeof
(nfapi_ul_config_uci_cqi_pdu));
} // if ((cqi_ReportPeriodic = cqi_ReportConfig->cqi_ReportPeriodic)!=NULL) { ul_config_pdu->uci_cqi_pdu.
} // if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig) ue_information.ue_information_rel8.rnti =
} // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { UE_list->UE_template[CC_id][UE_id].rnti;
} // for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { 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++;
}
} // if ((cqi_ReportPeriodic = cqi_ReportConfig->cqi_ReportPeriodic)!=NULL) {
} // if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig)
} // 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++) {
} }
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;
nfapi_ul_config_request_body_t *ul_req; nfapi_ul_config_request_body_t *ul_req;
int CC_id; int CC_id;
int UE_id; int UE_id;
SchedulingRequestConfig_t *SRconfig; SchedulingRequestConfig_t *SRconfig;
int skip_ue; int skip_ue;
int is_harq; int is_harq;
nfapi_ul_config_sr_information sr; nfapi_ul_config_sr_information sr;
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++) {
if (RC.mac[module_idP]->UE_list.active[UE_id]!=TRUE) continue; for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
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;
AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",UE_id); 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
if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED) continue; AssertFatal(UE_list->
UE_template[CC_id][UE_id].physicalConfigDedicated
if ((SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig)!=NULL) { != NULL,
if (SRconfig->present == SchedulingRequestConfig_PR_setup) { "physicalConfigDedicated is null for UE %d\n",
if (SRconfig->choice.setup.sr_ConfigIndex <= 4) { // 5 ms SR period UE_id);
if ((subframeP%5) != SRconfig->choice.setup.sr_ConfigIndex)
continue; // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet
} else if (SRconfig->choice.setup.sr_ConfigIndex <= 14) { // 10 ms SR period if (mac_eNB_get_rrc_status
if (subframeP!=(SRconfig->choice.setup.sr_ConfigIndex-5)) (module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED)
continue; continue;
} else if (SRconfig->choice.setup.sr_ConfigIndex <= 34) { // 20 ms SR period
if ((10*(frameP&1)+subframeP) != (SRconfig->choice.setup.sr_ConfigIndex-15)) if ((SRconfig =
continue; UE_list->
} else if (SRconfig->choice.setup.sr_ConfigIndex <= 74) { // 40 ms SR period UE_template[CC_id][UE_id].physicalConfigDedicated->
if ((10*(frameP&3)+subframeP) != (SRconfig->choice.setup.sr_ConfigIndex-35)) schedulingRequestConfig) != NULL) {
continue; if (SRconfig->present == SchedulingRequestConfig_PR_setup) {
} else if (SRconfig->choice.setup.sr_ConfigIndex <= 154) { // 80 ms SR period if (SRconfig->choice.setup.sr_ConfigIndex <= 4) { // 5 ms SR period
if ((10*(frameP&7)+subframeP) != (SRconfig->choice.setup.sr_ConfigIndex-75)) if ((subframeP % 5) !=
continue; SRconfig->choice.setup.sr_ConfigIndex)
} continue;
} // SRconfig->present == SchedulingRequestConfig_PR_setup) } else if (SRconfig->choice.setup.sr_ConfigIndex <= 14) { // 10 ms SR period
} // SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig)!=NULL) if (subframeP !=
(SRconfig->choice.setup.sr_ConfigIndex - 5))
// if we get here there is some PUCCH1 reception to schedule for SR continue;
} else if (SRconfig->choice.setup.sr_ConfigIndex <= 34) { // 20 ms SR period
skip_ue=0; if ((10 * (frameP & 1) + subframeP) !=
is_harq = 0; (SRconfig->choice.setup.sr_ConfigIndex - 15))
// check that there is no existing UL grant for ULSCH which overrides the SR continue;
for (i = 0; i < ul_req->number_of_pdus; i++) { } else if (SRconfig->choice.setup.sr_ConfigIndex <= 74) { // 40 ms SR period
if (((ul_req->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE)|| if ((10 * (frameP & 3) + subframeP) !=
(ul_req->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE)|| (SRconfig->choice.setup.sr_ConfigIndex - 35))
(ul_req->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE)|| continue;
(ul_req->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE))&& } else if (SRconfig->choice.setup.sr_ConfigIndex <= 154) { // 80 ms SR period
(ul_req->ul_config_pdu_list[i].ulsch_pdu.ulsch_pdu_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) { if ((10 * (frameP & 7) + subframeP) !=
skip_ue=1; (SRconfig->choice.setup.sr_ConfigIndex - 75))
break; continue;
} }
/* if there is already an HARQ pdu, convert to SR_HARQ */ } // SRconfig->present == SchedulingRequestConfig_PR_setup)
else if ((ul_req->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE)&& } // SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig)!=NULL)
(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; // if we get here there is some PUCCH1 reception to schedule for SR
break;
} skip_ue = 0;
} is_harq = 0;
// check that there is no existing UL grant for ULSCH which overrides the SR
// drop the allocation because ULSCH with handle it with BSR for (i = 0; i < ul_req->number_of_pdus; i++) {
if (skip_ue==1) continue; if (((ul_req->ul_config_pdu_list[i].pdu_type ==
NFAPI_UL_CONFIG_ULSCH_PDU_TYPE)
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); || (ul_req->ul_config_pdu_list[i].pdu_type ==
NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE)
// check Rel10 or Rel8 SR || (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 ==
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;
}
/* 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)
&& (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;
break;
}
}
// drop the allocation because ULSCH with handle it with BSR
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);
// 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->
sr.sr_information_rel10.number_of_pucch_resources = 1; UE_template[CC_id][UE_id].physicalConfigDedicated->
sr.sr_information_rel10.pucch_index_p1 = *UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020->sr_PUCCH_ResourceIndexP1_r10; ext2->schedulingRequestConfig_v1020)
} else && (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.pucch_index_p1 =
*UE_list->
UE_template[CC_id][UE_id].physicalConfigDedicated->
ext2->
schedulingRequestConfig_v1020->sr_PUCCH_ResourceIndexP1_r10;
} 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->
/* if there is already an HARQ pdu, convert to SR_HARQ */ schedulingRequestConfig->choice.setup.
if (is_harq) { sr_PUCCH_ResourceIndex;
nfapi_ul_config_harq_information h = ul_req->ul_config_pdu_list[i].uci_harq_pdu.harq_information; }
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; /* if there is already an HARQ pdu, convert to SR_HARQ */
ul_req->ul_config_pdu_list[i].uci_sr_harq_pdu.harq_information = h; if (is_harq) {
} else { nfapi_ul_config_harq_information h =
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[i].uci_harq_pdu.
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; harq_information;
ul_req->ul_config_pdu_list[ul_req->number_of_pdus].uci_sr_pdu.sr_information = sr; ul_req->ul_config_pdu_list[i].pdu_type =
ul_req->number_of_pdus++; NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE;
} /* if (is_harq) */ ul_req->ul_config_pdu_list[i].uci_sr_harq_pdu.
} // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) sr_information = sr;
} // for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) ul_req->ul_config_pdu_list[i].uci_sr_harq_pdu.
harq_information = h;
} 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].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++;
} /* if (is_harq) */
} // 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++)
} }
void check_ul_failure(module_id_t module_idP,int CC_id,int UE_id, void
frame_t frameP, sub_frame_t subframeP) check_ul_failure(module_id_t module_idP, int CC_id, int UE_id,
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)
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]; // add a format 1A dci for this UE to request an RA procedure (only one UE per subframe)
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); nfapi_dl_config_request_pdu_t *dl_config_pdu =
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; &DL_req[CC_id].
dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu)); dl_config_request_body.dl_config_pdu_list[DL_req[CC_id].
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; dl_config_request_body.number_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); memset((void *) dl_config_pdu, 0,
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; sizeof(nfapi_dl_config_request_pdu_t));
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->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power dl_config_pdu->pdu_size =
(uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu));
AssertFatal((cc[CC_id].mib->message.dl_Bandwidth >=0) && (cc[CC_id].mib->message.dl_Bandwidth<6), dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format =
"illegal dl_Bandwidth %d\n",(int)cc[CC_id].mib->message.dl_Bandwidth); NFAPI_DL_DCI_FORMAT_1A;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = pdcch_order_table[cc[CC_id].mib->message.dl_Bandwidth]; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level =
DL_req[CC_id].dl_config_request_body.number_dci++; get_aggregation(get_bw_index(module_idP, CC_id),
DL_req[CC_id].dl_config_request_body.number_pdu++; UE_list->UE_sched_ctrl[UE_id].
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); dl_cqi[CC_id], format1A);
} dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti;
else { // ra_pdcch_sent==1 dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications
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); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power
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 AssertFatal((cc[CC_id].mib->message.dl_Bandwidth >= 0)
} && (cc[CC_id].mib->message.dl_Bandwidth < 6),
"illegal dl_Bandwidth %d\n",
UE_list->UE_sched_ctrl[UE_id].ul_failure_timer++; (int) cc[CC_id].mib->message.dl_Bandwidth);
// check threshold dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.
if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 200) { resource_block_coding =
// inform RRC of failure and clear timer pdcch_order_table[cc[CC_id].mib->message.dl_Bandwidth];
LOG_I(MAC,"UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n",UE_id,rnti); DL_req[CC_id].dl_config_request_body.number_dci++;
mac_eNB_rrc_ul_failure(module_idP,CC_id,frameP,subframeP,rnti); DL_req[CC_id].dl_config_request_body.number_pdu++;
UE_list->UE_sched_ctrl[UE_id].ul_failure_timer=0; LOG_I(MAC,
UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync=1; "UE %d rnti %x: sending PDCCH order for RAPROC (failure timer %d), resource_block_coding %d \n",
} UE_id, rnti,
} // ul_failure_timer>0 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)
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++;
// check threshold
if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 200) {
// 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);
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
} }
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];
nfapi_hi_dci0_request_t *HI_DCI0_req = &eNB->HI_DCI0_req[0]; nfapi_hi_dci0_request_t *HI_DCI0_req = &eNB->HI_DCI0_req[0];
nfapi_tx_request_t *TX_req = &eNB->TX_req[0]; nfapi_tx_request_t *TX_req = &eNB->TX_req[0];
eNB->pdu_index[CC_idP] = 0; eNB->pdu_index[CC_idP] = 0;
DL_req[CC_idP].dl_config_request_body.number_pdcch_ofdm_symbols = 1; DL_req[CC_idP].dl_config_request_body.number_pdcch_ofdm_symbols = 1;
DL_req[CC_idP].dl_config_request_body.number_dci = 0; DL_req[CC_idP].dl_config_request_body.number_dci = 0;
DL_req[CC_idP].dl_config_request_body.number_pdu = 0; DL_req[CC_idP].dl_config_request_body.number_pdu = 0;
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 =
HI_DCI0_req[CC_idP].hi_dci0_request_body.number_of_dci = 0; subframeP + (frameP << 4);
HI_DCI0_req[CC_idP].hi_dci0_request_body.number_of_dci = 0;
UL_req[CC_idP].ul_config_request_body.number_of_pdus = 0; UL_req[CC_idP].ul_config_request_body.number_of_pdus = 0;
UL_req[CC_idP].ul_config_request_body.rach_prach_frequency_resources = 0; // ignored, handled by PHY for now UL_req[CC_idP].ul_config_request_body.rach_prach_frequency_resources = 0; // ignored, handled by PHY for now
UL_req[CC_idP].ul_config_request_body.srs_present = 0; // ignored, handled by PHY for now UL_req[CC_idP].ul_config_request_body.srs_present = 0; // ignored, handled by PHY for now
TX_req[CC_idP].tx_request_body.number_of_pdus = 0; TX_req[CC_idP].tx_request_body.number_of_pdus = 0;
} }
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;
nfapi_ul_config_request_body_t *ul_req_tmp; nfapi_ul_config_request_body_t *ul_req_tmp;
nfapi_ul_config_request_body_t *ul_req; nfapi_ul_config_request_body_t *ul_req;
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 =
ul_req = &eNB->UL_req[CC_id].ul_config_request_body; &eNB->UL_req_tmp[CC_id][subframeP].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;
#if defined(FLEXRAN_AGENT_SB_IF) #if defined(FLEXRAN_AGENT_SB_IF)
Protocol__FlexranMessage *msg; Protocol__FlexranMessage *msg;
#endif #endif
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);
}
// refresh UE list based on UEs dropped by PHY in previous subframe
for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
if (UE_list->active[i] != TRUE) continue;
rnti = UE_RNTI(module_idP, i);
CC_id = UE_PCCID(module_idP, i);
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,
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_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].pucch1_snr[CC_id]-128)/2);
}
RC.eNB[module_idP][CC_id]->pusch_stats_bsr[i][(frameP*10)+subframeP]=-63; clear_nfapi_information(RC.mac[module_idP], CC_id, frameP,
if (i==UE_list->head) subframeP);
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
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++; // refresh UE list based on UEs dropped by PHY in previous subframe
LOG_D(MAC,"UE %d/%x : ul_inactivity %d, cqi_req %d\n",i,rnti, for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ul_inactivity_timer, if (UE_list->active[i] != TRUE)
RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer); continue;
check_ul_failure(module_idP,CC_id,i,frameP,subframeP);
rnti = UE_RNTI(module_idP, i);
CC_id = UE_PCCID(module_idP, i);
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,
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_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].pucch1_snr[CC_id] - 128) / 2);
}
RC.eNB[module_idP][CC_id]->pusch_stats_bsr[i][(frameP * 10) +
subframeP] = -63;
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
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++;
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].cqi_req_timer);
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,
pdcp_run(&ctxt); NOT_A_RNTI, frameP, subframeP,
module_idP);
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] =
stop_meas(&RC.mac[module_idP]->schedule_mch); schedule_MBMS(module_idP, CC_id, frameP, subframeP);
stop_meas(&RC.mac[module_idP]->schedule_mch);
}
} }
}
#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)
// This schedules SI for legacy LTE and eMTC starting in subframeP schedule_mib(module_idP, frameP, subframeP);
schedule_SI(module_idP,frameP,subframeP); // This schedules SI for legacy LTE and eMTC starting in subframeP
// This schedules Random-Access for legacy LTE and eMTC starting in subframeP schedule_SI(module_idP, frameP, subframeP);
schedule_RA(module_idP,frameP,subframeP); // This schedules Random-Access for legacy LTE and eMTC starting in subframeP
// copy previously scheduled UL resources (ULSCH + HARQ) schedule_RA(module_idP, frameP, subframeP);
copy_ulreq(module_idP,frameP,subframeP); // copy previously scheduled UL resources (ULSCH + HARQ)
// This schedules SRS in subframeP copy_ulreq(module_idP, frameP, subframeP);
schedule_SRS(module_idP,frameP,subframeP); // This schedules SRS in subframeP
// This schedules ULSCH in subframeP (dci0) schedule_SRS(module_idP, frameP, subframeP);
schedule_ulsch(module_idP,frameP,subframeP); // This schedules ULSCH in subframeP (dci0)
// This schedules UCI_SR in subframeP schedule_ulsch(module_idP, frameP, subframeP);
schedule_SR(module_idP,frameP,subframeP); // This schedules UCI_SR in subframeP
// This schedules UCI_CSI in subframeP schedule_SR(module_idP, frameP, subframeP);
schedule_CSI(module_idP, frameP, subframeP); // This schedules UCI_CSI in subframeP
schedule_CSI(module_idP, frameP, subframeP);
// This schedules DLSCH in subframeP
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); // This schedules DLSCH in subframeP
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);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT); 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);
} }
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,714 +65,822 @@ ...@@ -65,714 +65,822 @@
#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)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
int8_t bcch_sdu_length; int8_t bcch_sdu_length;
int CC_id; int CC_id;
eNB_MAC_INST *eNB = RC.mac[module_idP]; eNB_MAC_INST *eNB = RC.mac[module_idP];
COMMON_channels_t *cc; COMMON_channels_t *cc;
uint8_t *vrb_map; uint8_t *vrb_map;
int first_rb = -1; int first_rb = -1;
int N_RB_DL; int N_RB_DL;
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)
else continue;
switch ((cc->mib->message.schedulingInfoSIB1_BR_r13-1)%3) { else
case 0: // repetition 4 switch ((cc->mib->message.schedulingInfoSIB1_BR_r13 - 1) % 3) {
k = (frameP>>1)&3; case 0: // repetition 4
if ((subframeP!=(4+sfoffset)) || ((frameP&1)!=foffset)) continue; k = (frameP >> 1) & 3;
break; if ((subframeP != (4 + sfoffset))
case 1: // repetition 8 || ((frameP & 1) != foffset))
k = frameP&3; continue;
AssertFatal(N_RB_DL>15,"SIB1-BR repetition 8 not allowed for N_RB_DL= %d\n",N_RB_DL); break;
if ((foffset==0) && (subframeP!=(4+sfoffset))) continue; case 1: // repetition 8
else if ((foffset==1) && (subframeP!=((9+sfoffset)%10))) continue; k = frameP & 3;
break; AssertFatal(N_RB_DL > 15,
case 2: // repetition 16 "SIB1-BR repetition 8 not allowed for N_RB_DL= %d\n",
k = ((10*frameP) + subframeP)&3; N_RB_DL);
AssertFatal(N_RB_DL>15,"SIB1-BR repetition 16 not allowed for N_RB_DL= %d\n",N_RB_DL); if ((foffset == 0) && (subframeP != (4 + sfoffset)))
if ((sfoffset == 1) && ((subframeP!=0)||(subframeP!=5))) continue; continue;
else if ((sfoffset == 0) && (foffset==0) && (subframeP!=4) && (subframeP!=9)) continue; else if ((foffset == 1)
else if ((sfoffset == 0) && (foffset==1) && (subframeP!=0) && (subframeP!=9)) continue; && (subframeP != ((9 + sfoffset) % 10)))
break; continue;
} break;
// if we get here we have to schedule SIB1_BR in this frame/subframe case 2: // repetition 16
k = ((10 * frameP) + subframeP) & 3;
// keep counter of SIB1_BR repetitions in 8 frame period to choose narrowband on which to transmit AssertFatal(N_RB_DL > 15,
if ((frameP&7) == 0) cc->SIB1_BR_cnt=0; "SIB1-BR repetition 16 not allowed for N_RB_DL= %d\n",
else cc->SIB1_BR_cnt++; N_RB_DL);
if ((sfoffset == 1)
// Frequency-domain scheduling && ((subframeP != 0) || (subframeP != 5)))
switch (N_RB_DL) { continue;
case 6: else if ((sfoffset == 0) && (foffset == 0)
case 15: && (subframeP != 4) && (subframeP != 9))
default: continue;
m=1; else if ((sfoffset == 0) && (foffset == 1)
n_NB=0; && (subframeP != 0) && (subframeP != 9))
N_S_NB=0; continue;
Sj=NULL; break;
break; }
case 25: // if we get here we have to schedule SIB1_BR in this frame/subframe
m=2;
N_S_NB = 2; // keep counter of SIB1_BR repetitions in 8 frame period to choose narrowband on which to transmit
Sj = Sj25; if ((frameP & 7) == 0)
break; cc->SIB1_BR_cnt = 0;
case 50: else
m=2; cc->SIB1_BR_cnt++;
N_S_NB = 6;
Sj = Sj50; // Frequency-domain scheduling
break; switch (N_RB_DL) {
case 75: case 6:
m=4; case 15:
N_S_NB = 10; default:
Sj = Sj75; m = 1;
break; n_NB = 0;
case 100: N_S_NB = 0;
m=4; Sj = NULL;
N_S_NB = 14; break;
Sj = Sj100; case 25:
break; m = 2;
} N_S_NB = 2;
// Note: definition of k above and rvidx from 36.321 section 5.3.1 Sj = Sj25;
rvidx = (((3*k)>>1) + (k&1))&3; break;
case 50:
i = cc->SIB1_BR_cnt & (m-1); m = 2;
N_S_NB = 6;
n_NB = Sj[((cc->physCellId % N_S_NB) + (i*N_S_NB/m))%N_S_NB]; Sj = Sj50;
break;
case 75:
bcch_sdu_length = mac_rrc_data_req(module_idP, m = 4;
CC_id, N_S_NB = 10;
frameP, Sj = Sj75;
BCCH_SIB1_BR,1, break;
&cc->BCCH_BR_pdu[0].payload[0], case 100:
1, m = 4;
module_idP, N_S_NB = 14;
0); // not used in this case Sj = Sj100;
break;
AssertFatal(cc->mib->message.schedulingInfoSIB1_BR_r13<19,"schedulingInfoSIB1_BR_r13 %d > 18\n", }
(int)cc->mib->message.schedulingInfoSIB1_BR_r13); // Note: definition of k above and rvidx from 36.321 section 5.3.1
rvidx = (((3 * k) >> 1) + (k & 1)) & 3;
AssertFatal(bcch_sdu_length>0,"RRC returned 0 bytes for SIB1-BR\n");
i = cc->SIB1_BR_cnt & (m - 1);
TBS = SIB1_BR_TBS_table[(cc->mib->message.schedulingInfoSIB1_BR_r13-1)/3]>>3;
n_NB = Sj[((cc->physCellId % N_S_NB) + (i * N_S_NB / m)) % N_S_NB];
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); 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
// allocate all 6 PRBs in narrowband for SIB1_BR AssertFatal(cc->mib->message.schedulingInfoSIB1_BR_r13 < 19,
"schedulingInfoSIB1_BR_r13 %d > 18\n",
first_rb = narrowband_to_first_rb(cc,n_NB); (int) cc->mib->message.schedulingInfoSIB1_BR_r13);
vrb_map[first_rb] = 1; AssertFatal(bcch_sdu_length > 0,
vrb_map[first_rb+1] = 1; "RRC returned 0 bytes for SIB1-BR\n");
vrb_map[first_rb+2] = 1;
vrb_map[first_rb+3] = 1; TBS =
vrb_map[first_rb+4] = 1; SIB1_BR_TBS_table[(cc->mib->message.schedulingInfoSIB1_BR_r13 -
vrb_map[first_rb+5] = 1; 1) / 3] >> 3;
dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; AssertFatal(bcch_sdu_length <= TBS,
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); "length returned by RRC %d is not compatible with the TBS %d from MIB\n",
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; bcch_sdu_length, TBS);
dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu));
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = TBS; if ((frameP & 1023) < 200)
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; LOG_D(MAC,
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; "[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",
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D module_idP, frameP, subframeP, CC_id, bcch_sdu_length,
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized n_NB, i, m, N_S_NB, rvidx);
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 // allocate all 6 PRBs in narrowband for SIB1_BR
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = rvidx;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block first_rb = narrowband_to_first_rb(cc, n_NB);
dl_config_pdu->dlsch_pdu.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; vrb_map[first_rb] = 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; vrb_map[first_rb + 1] = 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; vrb_map[first_rb + 2] = 1;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; vrb_map[first_rb + 3] = 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; vrb_map[first_rb + 4] = 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB vrb_map[first_rb + 5] = 1;
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 = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored memset((void *) dl_config_pdu, 0,
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB==1 ) ? 1 : 2; sizeof(nfapi_dl_config_request_pdu_t));
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; dl_config_pdu->pdu_size =
// Rel10 fields (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu));
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = TBS;
// Rel13 fields dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index =
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 1; // CEModeA UE eNB->pdu_index[CC_id];
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 0; // SIB1-BR dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SFx 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.bf_vector = ; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding =
dl_req->number_pdu++; getRIV(N_RB_DL, first_rb, 6);
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK
// Program TX Request dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = rvidx;
TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block
TX_req->pdu_length = bcch_sdu_length; dl_config_pdu->dlsch_pdu.
TX_req->pdu_index = eNB->pdu_index[CC_id]++; dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0;
TX_req->num_segments = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme =
TX_req->segments[0].segment_length = bcch_sdu_length; (cc->p_eNB == 1) ? 0 : 1;
TX_req->segments[0].segment_data = cc->BCCH_BR_pdu[0].payload; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1;
eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; 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.ue_category_capacity = 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB
if (opt_enabled == 1) { dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index =
trace_pdu(1, 0;
&cc->BCCH_BR_pdu[0].payload[0], dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0;
bcch_sdu_length, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored
0xffff, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode =
4, (cc->p_eNB == 1) ? 1 : 2;
0xffff, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1;
eNB->frame, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1;
eNB->subframe, // Rel10 fields
0, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3;
0); // Rel13 fields
LOG_D(OPT,"[eNB %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 1; // CEModeA UE
module_idP, frameP, CC_id, 0xffff, bcch_sdu_length); dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 0; // SIB1-BR
} dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SFx
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", // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ;
frameP, dl_req->number_pdu++;
CC_id,
bcch_sdu_length); // Program TX Request
} else { TX_req =
LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH-BR 0->DLSCH (FDD) for CC_id %d SIB1-BR %d bytes\n", &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->
frameP, TX_req
CC_id, [CC_id].tx_request_body.number_of_pdus];
bcch_sdu_length); TX_req->pdu_length = bcch_sdu_length;
} TX_req->pdu_index = eNB->pdu_index[CC_id]++;
TX_req->num_segments = 1;
TX_req->segments[0].segment_length = bcch_sdu_length;
TX_req->segments[0].segment_data = cc->BCCH_BR_pdu[0].payload;
eNB->TX_req[CC_id].tx_request_body.number_of_pdus++;
if (opt_enabled == 1) {
trace_pdu(1,
&cc->BCCH_BR_pdu[0].payload[0],
bcch_sdu_length,
0xffff, 4, 0xffff, 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);
}
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",
frameP, CC_id, bcch_sdu_length);
} else {
LOG_D(MAC,
"[eNB] Frame %d : Scheduling BCCH-BR 0->DLSCH (FDD) for CC_id %d SIB1-BR %d bytes\n",
frameP, CC_id, bcch_sdu_length);
}
} }
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, sub_frame_t subframeP)
frame_t frameP,
sub_frame_t subframeP)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
int8_t bcch_sdu_length; int8_t bcch_sdu_length;
int CC_id; int CC_id;
eNB_MAC_INST *eNB = RC.mac[module_idP]; eNB_MAC_INST *eNB = RC.mac[module_idP];
COMMON_channels_t *cc; COMMON_channels_t *cc;
uint8_t *vrb_map; uint8_t *vrb_map;
int first_rb = -1; int first_rb = -1;
int N_RB_DL; int N_RB_DL;
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 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)
else { continue;
else {
AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13!=NULL,
"sib_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); AssertFatal(cc->
sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13
SchedulingInfoList_BR_r13_t *schedulingInfoList_BR_r13 = cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->schedulingInfoList_BR_r13; != NULL,
AssertFatal(schedulingInfoList_BR_r13!=NULL, "sib_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n");
"sib_v13ext->schedulingInfoList_BR_r13 is null\n");
SchedulingInfoList_BR_r13_t *schedulingInfoList_BR_r13 =
SchedulingInfoList_t *schedulingInfoList = cc->schedulingInfoList; cc->sib1_v13ext->
AssertFatal(schedulingInfoList_BR_r13->list.count==schedulingInfoList->list.count, bandwidthReducedAccessRelatedInfo_r13->schedulingInfoList_BR_r13;
"schedulingInfolist_BR.r13->list.count %d != schedulingInfoList.list.count %d\n", AssertFatal(schedulingInfoList_BR_r13 != NULL,
schedulingInfoList_BR_r13->list.count,schedulingInfoList->list.count); "sib_v13ext->schedulingInfoList_BR_r13 is null\n");
AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13<=SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200, SchedulingInfoList_t *schedulingInfoList =
"si_WindowLength_BR_r13 %d > %d\n", cc->schedulingInfoList;
(int)cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13, AssertFatal(schedulingInfoList_BR_r13->list.count ==
SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200); schedulingInfoList->list.count,
"schedulingInfolist_BR.r13->list.count %d != schedulingInfoList.list.count %d\n",
// check that SI frequency-hopping is disabled schedulingInfoList_BR_r13->list.count,
AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_HoppingConfigCommon_r13==SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_HoppingConfigCommon_r13_off, schedulingInfoList->list.count);
"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]; AssertFatal(cc->
sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13
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, SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200,
"si_RepetitionPattern_r13 %d > %d\n", "si_WindowLength_BR_r13 %d > %d\n",
(int)si_RepetitionPattern_r13, (int) cc->
SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_RepetitionPattern_r13_every8thRF); sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13,
// cycle through SIB list SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200);
for (i=0;i<schedulingInfoList_BR_r13->list.count;i++) { // check that SI frequency-hopping is disabled
long si_Periodicity = schedulingInfoList->list.array[i]->si_Periodicity; AssertFatal(cc->
long si_Narrowband_r13 = schedulingInfoList_BR_r13->list.array[i]->si_Narrowband_r13; sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_HoppingConfigCommon_r13
long si_TBS_r13 = si_TBS_r13tab[schedulingInfoList_BR_r13->list.array[i]->si_TBS_r13]; ==
SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_HoppingConfigCommon_r13_off,
// check if the SI is to be scheduled now "Deactivate SI_HoppingConfigCommon_r13 in configuration file, not supported for now\n");
int period_in_sf = 80<<si_Periodicity; // 2^i * 80 subframes, note: si_Periodicity is 2^i * 80ms long si_WindowLength_BR_r13 =
int sf_mod_period = absSF%period_in_sf; si_WindowLength_BR_r13tab[cc->
int k = sf_mod_period&3; sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13];
// Note: definition of k and rvidx from 36.321 section 5.3.1
rvidx = (((3*k)>>1) + (k&1))&3; long si_RepetitionPattern_r13 =
cc->sib1_v13ext->
if ((sf_mod_period < si_WindowLength_BR_r13) && bandwidthReducedAccessRelatedInfo_r13->si_RepetitionPattern_r13;
((frameP&(((1<<si_RepetitionPattern_r13)-1)))==0)) { // this SIB is to be scheduled AssertFatal(si_RepetitionPattern_r13 <=
SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_RepetitionPattern_r13_every8thRF,
bcch_sdu_length = mac_rrc_data_req(module_idP, "si_RepetitionPattern_r13 %d > %d\n",
CC_id, (int) si_RepetitionPattern_r13,
frameP, SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_RepetitionPattern_r13_every8thRF);
BCCH_SI_BR+i,1, // cycle through SIB list
&cc->BCCH_BR_pdu[i+1].payload[0],
1, for (i = 0; i < schedulingInfoList_BR_r13->list.count; i++) {
module_idP, long si_Periodicity =
0); // not used in this case schedulingInfoList->list.array[i]->si_Periodicity;
long si_Narrowband_r13 =
AssertFatal(bcch_sdu_length>0,"RRC returned 0 bytes for SI-BR %d\n",i); schedulingInfoList_BR_r13->list.array[i]->
si_Narrowband_r13;
if (bcch_sdu_length > 0) { long si_TBS_r13 =
AssertFatal(bcch_sdu_length <= (si_TBS_r13>>3), si_TBS_r13tab[schedulingInfoList_BR_r13->
"RRC provided bcch with length %d > %d (si_TBS_r13 %d)\n", list.array[i]->si_TBS_r13];
bcch_sdu_length,(int)(si_TBS_r13>>3),(int)schedulingInfoList_BR_r13->list.array[i]->si_TBS_r13);
// check if the SI is to be scheduled now
// allocate all 6 PRBs in narrowband for SIB1_BR 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;
// check that SIB1 didn't take this narrowband int k = sf_mod_period & 3;
if (vrb_map[first_rb] > 0) continue; // Note: definition of k and rvidx from 36.321 section 5.3.1
rvidx = (((3 * k) >> 1) + (k & 1)) & 3;
first_rb = narrowband_to_first_rb(cc,si_Narrowband_r13-1);
vrb_map[first_rb] = 1; if ((sf_mod_period < si_WindowLength_BR_r13)
vrb_map[first_rb+1] = 1; && ((frameP & (((1 << si_RepetitionPattern_r13) - 1))) == 0)) { // this SIB is to be scheduled
vrb_map[first_rb+2] = 1;
vrb_map[first_rb+4] = 1; 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
vrb_map[first_rb+5] = 1;
AssertFatal(bcch_sdu_length > 0,
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", "RRC returned 0 bytes for SI-BR %d\n", i);
module_idP,frameP,subframeP,CC_id,(int)si_Narrowband_r13-1,rvidx,
sf_mod_period,(int)si_WindowLength_BR_r13,(int)si_RepetitionPattern_r13, if (bcch_sdu_length > 0) {
bcch_sdu_length); AssertFatal(bcch_sdu_length <= (si_TBS_r13 >> 3),
"RRC provided bcch with length %d > %d (si_TBS_r13 %d)\n",
bcch_sdu_length,
(int) (si_TBS_r13 >> 3),
(int) schedulingInfoList_BR_r13->
dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; list.array[i]->si_TBS_r13);
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; // allocate all 6 PRBs in narrowband for SIB1_BR
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; // check that SIB1 didn't take this narrowband
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; if (vrb_map[first_rb] > 0)
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; continue;
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 first_rb =
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL,first_rb,6); narrowband_to_first_rb(cc,
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK si_Narrowband_r13 - 1);
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = rvidx; vrb_map[first_rb] = 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block vrb_map[first_rb + 1] = 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; vrb_map[first_rb + 2] = 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB==1 ) ? 0 : 1; vrb_map[first_rb + 4] = 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; vrb_map[first_rb + 5] = 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; if ((frameP & 1023) < 200)
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; LOG_D(MAC,
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB "[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",
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; module_idP, frameP, subframeP, CC_id,
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; (int) si_Narrowband_r13 - 1, rvidx,
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored sf_mod_period,
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB==1 ) ? 1 : 2; (int) si_WindowLength_BR_r13,
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; (int) si_RepetitionPattern_r13,
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; bcch_sdu_length);
// 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;
// Rel13 fields
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 =
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = absSF - sf_mod_period; &dl_req->dl_config_pdu_list[dl_req->
number_pdu];
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; memset((void *) dl_config_pdu, 0,
dl_req->number_pdu++; sizeof(nfapi_dl_config_request_pdu_t));
dl_config_pdu->pdu_type =
// Program TX Request NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; dl_config_pdu->pdu_size =
TX_req->pdu_length = bcch_sdu_length; (uint8_t) (2 +
TX_req->pdu_index = eNB->pdu_index[CC_id]++; sizeof(nfapi_dl_config_dlsch_pdu));
TX_req->num_segments = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length =
TX_req->segments[0].segment_length = bcch_sdu_length; si_TBS_r13 >> 3;
TX_req->segments[0].segment_data = cc->BCCH_BR_pdu[i+1].payload; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index =
eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; eNB->pdu_index[CC_id];
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti =
if (opt_enabled == 1) { 0xFFFF;
trace_pdu(1, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D
&cc->BCCH_BR_pdu[i+1].payload[0], dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized
bcch_sdu_length, dl_config_pdu->dlsch_pdu.
0xffff, dlsch_pdu_rel8.resource_block_coding =
4, getRIV(N_RB_DL, first_rb, 6);
0xffff, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK
eNB->frame, dl_config_pdu->dlsch_pdu.
eNB->subframe, dlsch_pdu_rel8.redundancy_version = rvidx;
0, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block
0); dl_config_pdu->dlsch_pdu.
LOG_D(OPT,"[eNB %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", dlsch_pdu_rel8.transport_block_to_codeword_swap_flag
module_idP, frameP, CC_id, 0xffff, bcch_sdu_length); = 0;
} dl_config_pdu->dlsch_pdu.
if (cc->tdd_Config!=NULL) { //TDD dlsch_pdu_rel8.transmission_scheme =
LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH-BR %d->DLSCH (TDD) for CC_id %d SI-BR %d bytes\n", (cc->p_eNB == 1) ? 0 : 1;
frameP,i, dl_config_pdu->dlsch_pdu.
CC_id, dlsch_pdu_rel8.number_of_layers = 1;
bcch_sdu_length); dl_config_pdu->dlsch_pdu.
} else { dlsch_pdu_rel8.number_of_subbands = 1;
LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH-BR %d->DLSCH (FDD) for CC_id %d SI-BR %d bytes\n", // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ;
frameP,i, dl_config_pdu->dlsch_pdu.
CC_id, dlsch_pdu_rel8.ue_category_capacity = 1;
bcch_sdu_length); 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;
} // scheduling in current frame/subframe dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0;
} //for SI List dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored
} // eMTC is activated dl_config_pdu->dlsch_pdu.
} // CC_id dlsch_pdu_rel8.transmission_mode =
return; (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)
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.
pdsch_start =
cc[CC_id].
sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
// Rel13 fields
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.initial_transmission_sf_io =
absSF - sf_mod_period;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ;
dl_req->number_pdu++;
// 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->pdu_length = bcch_sdu_length;
TX_req->pdu_index = eNB->pdu_index[CC_id]++;
TX_req->num_segments = 1;
TX_req->segments[0].segment_length =
bcch_sdu_length;
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) {
trace_pdu(1,
&cc->BCCH_BR_pdu[i + 1].payload[0],
bcch_sdu_length,
0xffff,
4,
0xffff, 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);
}
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 {
LOG_D(MAC,
"[eNB] Frame %d : Scheduling BCCH-BR %d->DLSCH (FDD) for CC_id %d SI-BR %d bytes\n",
frameP, i, CC_id, bcch_sdu_length);
}
}
} // scheduling in current frame/subframe
} //for SI List
} // eMTC is activated
} // CC_id
return;
} }
#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;
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;
int mib_sdu_length; int mib_sdu_length;
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, LOG_D(MAC, "Frame %d, subframe %d: BCH PDU length %d\n",
MIBCH,1, frameP, subframeP, mib_sdu_length);
&cc->MIB_pdu.payload[0],
1, if (mib_sdu_length > 0) {
module_idP,
0); // not used in this case LOG_D(MAC,
"Frame %d, subframe %d: Adding BCH PDU in position %d (length %d)\n",
LOG_D(MAC,"Frame %d, subframe %d: BCH PDU length %d\n", frameP, subframeP, dl_req->number_pdu, mib_sdu_length);
frameP,subframeP,mib_sdu_length);
if ((frameP & 1023) < 40)
if (mib_sdu_length > 0) { LOG_D(MAC,
"[eNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes (cc->mib->message.schedulingInfoSIB1_BR_r13 %d)\n",
LOG_D(MAC,"Frame %d, subframe %d: Adding BCH PDU in position %d (length %d)\n", module_idP, frameP, CC_id, mib_sdu_length,
frameP,subframeP,dl_req->number_pdu,mib_sdu_length); (int) cc->mib->message.schedulingInfoSIB1_BR_r13);
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); 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,
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); sizeof(nfapi_dl_config_request_pdu_t));
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_BCH_PDU_TYPE, dl_config_pdu->pdu_type =
dl_config_pdu->pdu_size = 2+sizeof(nfapi_dl_config_bch_pdu); NFAPI_DL_CONFIG_BCH_PDU_TYPE, dl_config_pdu->pdu_size =
dl_config_pdu->bch_pdu.bch_pdu_rel8.length = mib_sdu_length; 2 + sizeof(nfapi_dl_config_bch_pdu);
dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; dl_config_pdu->bch_pdu.bch_pdu_rel8.length = mib_sdu_length;
dl_config_pdu->bch_pdu.bch_pdu_rel8.transmission_power = 6000; dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index =
dl_req->number_pdu++; eNB->pdu_index[CC_id];
dl_config_pdu->bch_pdu.bch_pdu_rel8.transmission_power = 6000;
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 request LOG_D(MAC, "eNB->DL_req[0].number_pdu %d (%p)\n",
dl_req->number_pdu, &dl_req->number_pdu);
TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; // DL request
TX_req->pdu_length = 3;
TX_req->pdu_index = eNB->pdu_index[CC_id]++; TX_req =
TX_req->num_segments = 1; &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req
TX_req->segments[0].segment_length = 0; [CC_id].tx_request_body.number_of_pdus];
TX_req->segments[0].segment_data = cc[CC_id].MIB_pdu.payload; TX_req->pdu_length = 3;
eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; TX_req->pdu_index = eNB->pdu_index[CC_id]++;
TX_req->num_segments = 1;
TX_req->segments[0].segment_length = 0;
TX_req->segments[0].segment_data = cc[CC_id].MIB_pdu.payload;
eNB->TX_req[CC_id].tx_request_body.number_of_pdus++;
}
} }
}
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
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)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
int8_t bcch_sdu_length; int8_t bcch_sdu_length;
int mcs = -1; int mcs = -1;
int CC_id; int CC_id;
eNB_MAC_INST *eNB = RC.mac[module_idP]; eNB_MAC_INST *eNB = RC.mac[module_idP];
COMMON_channels_t *cc; COMMON_channels_t *cc;
uint8_t *vrb_map; uint8_t *vrb_map;
int first_rb = -1; int first_rb = -1;
int N_RB_DL; int N_RB_DL;
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;
start_meas(&eNB->schedule_si); start_meas(&eNB->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, if (bcch_sdu_length > 0) {
BCCH,1, LOG_D(MAC,
&cc->BCCH_pdu.payload[0], "[eNB %d] Frame %d : BCCH->DLSCH CC_id %d, Received %d bytes \n",
1, module_idP, frameP, CC_id, bcch_sdu_length);
module_idP,
0); // not used in this case // Allocate 4 PRBs in a random location
/*
if (bcch_sdu_length > 0) { while (1) {
LOG_D(MAC,"[eNB %d] Frame %d : BCCH->DLSCH CC_id %d, Received %d bytes \n",module_idP,frameP,CC_id,bcch_sdu_length); first_rb = (unsigned char)(taus()%(PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.N_RB_DL-4));
if ((vrb_map[first_rb] != 1) &&
// Allocate 4 PRBs in a random location (vrb_map[first_rb+1] != 1) &&
/* (vrb_map[first_rb+2] != 1) &&
while (1) { (vrb_map[first_rb+3] != 1))
first_rb = (unsigned char)(taus()%(PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.N_RB_DL-4)); break;
if ((vrb_map[first_rb] != 1) && }
(vrb_map[first_rb+1] != 1) && */
(vrb_map[first_rb+2] != 1) && switch (N_RB_DL) {
(vrb_map[first_rb+3] != 1)) case 6:
break; first_rb = 0;
} break;
*/ case 15:
switch (N_RB_DL) { first_rb = 6;
case 6: break;
first_rb = 0; case 25:
break; first_rb = 11;
case 15: break;
first_rb = 6; case 50:
break; first_rb = 23;
case 25: break;
first_rb = 11; case 100:
break; first_rb = 48;
case 50: break;
first_rb = 23; }
break;
case 100: vrb_map[first_rb] = 1;
first_rb = 48; vrb_map[first_rb + 1] = 1;
break; vrb_map[first_rb + 2] = 1;
} vrb_map[first_rb + 3] = 1;
vrb_map[first_rb] = 1; // Get MCS for length of SI, 3 PRBs
vrb_map[first_rb+1] = 1; if (bcch_sdu_length <= 7) {
vrb_map[first_rb+2] = 1; mcs = 0;
vrb_map[first_rb+3] = 1; } else if (bcch_sdu_length <= 11) {
mcs = 1;
// Get MCS for length of SI, 3 PRBs } else if (bcch_sdu_length <= 18) {
if (bcch_sdu_length <= 7) { mcs = 2;
mcs=0; } else if (bcch_sdu_length <= 22) {
} else if (bcch_sdu_length <= 11) { mcs = 3;
mcs=1; } else if (bcch_sdu_length <= 26) {
} else if (bcch_sdu_length <= 18) { mcs = 4;
mcs=2; } else if (bcch_sdu_length <= 28) {
} else if (bcch_sdu_length <= 22) { mcs = 5;
mcs=3; } else if (bcch_sdu_length <= 32) {
} else if (bcch_sdu_length <= 26) { mcs = 6;
mcs=4; } else if (bcch_sdu_length <= 41) {
} else if (bcch_sdu_length <= 28) { mcs = 7;
mcs=5; } else if (bcch_sdu_length <= 49) {
} else if (bcch_sdu_length <= 32) { mcs = 8;
mcs=6; }
} else if (bcch_sdu_length <= 41) {
mcs=7;
} else if (bcch_sdu_length <= 49) { dl_config_pdu =
mcs=8; &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 = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; dl_config_pdu->pdu_size =
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu));
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format =
dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu)); NFAPI_DL_DCI_FORMAT_1A;
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.
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; 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.
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; new_data_indicator_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.mcs_1 = mcs;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL,first_rb,4); redundancy_version_1 = 0;
dl_config_pdu->dci_dl_pdu.
dci_dl_pdu_rel8.resource_block_coding =
getRIV(N_RB_DL, first_rb, 4);
// Rel10 fields
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3;
// Rel13 fields
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE
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
if (!CCE_allocation_infeasible
(module_idP, CC_id, 0, subframeP,
dl_config_pdu->dci_dl_pdu.
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_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));
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.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.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.
redundancy_version = 0;
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.
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.ue_category_capacity = 1;
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.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.
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_vector =
1;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ;
dl_req->number_pdu++;
// 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->pdu_length = bcch_sdu_length;
TX_req->pdu_index = eNB->pdu_index[CC_id]++;
TX_req->num_segments = 1;
TX_req->segments[0].segment_length = bcch_sdu_length;
TX_req->segments[0].segment_data =
cc->BCCH_pdu.payload;
eNB->TX_req[CC_id].tx_request_body.number_of_pdus++;
} else {
LOG_E(MAC,
"[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) {
trace_pdu(1,
&cc->BCCH_pdu.payload[0],
bcch_sdu_length,
0xffff,
4, 0xffff, 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);
}
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",
frameP, CC_id, bcch_sdu_length, mcs);
} else {
LOG_D(MAC,
"[eNB] Frame %d : Scheduling BCCH->DLSCH (FDD) for CC_id %d SI %d bytes (mcs %d, rb 3)\n",
frameP, CC_id, bcch_sdu_length, mcs);
}
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].total_bcch_buffer += bcch_sdu_length;
eNB->eNB_stats[CC_id].bcch_mcs = mcs;
} else {
// Rel10 fields //LOG_D(MAC,"[eNB %d] Frame %d : BCCH not active \n",Mod_id,frame);
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; }
// Rel13 fields
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE
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
if (!CCE_allocation_infeasible(module_idP,CC_id,0,subframeP,
dl_config_pdu->dci_dl_pdu.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_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));
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.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.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.redundancy_version = 0;
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.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.ue_category_capacity = 1;
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.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.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_vector = 1;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ;
dl_req->number_pdu++;
// 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->pdu_length = bcch_sdu_length;
TX_req->pdu_index = eNB->pdu_index[CC_id]++;
TX_req->num_segments = 1;
TX_req->segments[0].segment_length = bcch_sdu_length;
TX_req->segments[0].segment_data = cc->BCCH_pdu.payload;
eNB->TX_req[CC_id].tx_request_body.number_of_pdus++;
}
else {
LOG_E(MAC,"[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) {
trace_pdu(1,
&cc->BCCH_pdu.payload[0],
bcch_sdu_length,
0xffff,
4,
0xffff,
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);
}
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",
frameP,
CC_id,
bcch_sdu_length,
mcs);
} else {
LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH->DLSCH (FDD) for CC_id %d SI %d bytes (mcs %d, rb 3)\n",
frameP,
CC_id,
bcch_sdu_length,
mcs);
} }
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].total_bcch_buffer+=bcch_sdu_length;
eNB->eNB_stats[CC_id].bcch_mcs=mcs;
} else {
//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;
} }
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -52,10 +52,10 @@ ...@@ -52,10 +52,10 @@
#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
#define ENABLE_MAC_PAYLOAD_DEBUG #define ENABLE_MAC_PAYLOAD_DEBUG
#define DEBUG_eNB_SCHEDULER 1 #define DEBUG_eNB_SCHEDULER 1
...@@ -63,607 +63,746 @@ ...@@ -63,607 +63,746 @@
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,
return -1; "[eNB %d] CC_id %d MBSFN synchronization area %d out of range\n ",
} else if (RC.mac[module_idP]->common_channels[CC_id].mbsfn_SubframeConfig[mbsfn_sync_area] != NULL) { module_idP, CC_id, mbsfn_sync_area);
return mbsfn_sync_area; return -1;
} else { } else if (RC.mac[module_idP]->
LOG_W(MAC,"[eNB %d] CC_id %d MBSFN Subframe Config pattern %d not found \n ", module_idP, CC_id, mbsfn_sync_area); common_channels[CC_id].mbsfn_SubframeConfig[mbsfn_sync_area]
return -1; != NULL) {
} return mbsfn_sync_area;
} else {
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;
}
} }
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 =
unsigned char mcch_sdu_length; 8 << (RC.mac[module_idP]->common_channels[CC_id].
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; pmch_Config[0]->mch_SchedulingPeriod_r9);
int ii=0, msi_pos=0; unsigned char mcch_sdu_length;
int mcch_mcs = -1; unsigned char header_len_mcch = 0, header_len_msi =
uint16_t TBS,j=-1,padding=0,post_padding=0; 0, header_len_mtch = 0, header_len_mtch_temp =
mac_rlc_status_resp_t rlc_status; 0, header_len_mcch_temp = 0, header_len_msi_temp = 0;
int num_mtch; int ii = 0, msi_pos = 0;
int msi_length,i,k; int mcch_mcs = -1;
unsigned char sdu_lcids[11], num_sdus=0, offset=0; uint16_t TBS, j = -1, padding = 0, post_padding = 0;
uint16_t sdu_lengths[11], sdu_length_total=0; mac_rlc_status_resp_t rlc_status;
unsigned char mch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; // check the max value, this is for dlsch only int num_mtch;
int msi_length, i, k;
COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id]; unsigned char sdu_lcids[11], num_sdus = 0, offset = 0;
uint16_t sdu_lengths[11], sdu_length_total = 0;
cc->MCH_pdu.Pdu_size=0; unsigned char mch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; // check the max value, this is for dlsch only
for (i=0; COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id];
i< cc->num_active_mbsfn_area;
i++ ) { cc->MCH_pdu.Pdu_size = 0;
// assume, that there is always a mapping
if ((j=get_mbsfn_sf_alloction(module_idP,CC_id,i)) == -1) { for (i = 0; i < cc->num_active_mbsfn_area; i++) {
return 0; // assume, that there is always a mapping
} if ((j = get_mbsfn_sf_alloction(module_idP, CC_id, i)) == -1) {
return 0;
mbsfn_period = 1<<(cc->mbsfn_SubframeConfig[j]->radioframeAllocationPeriod); }
mcch_period = 32<<(cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9);
msi_pos=0; mbsfn_period =
ii=0; 1 << (cc->mbsfn_SubframeConfig[j]->radioframeAllocationPeriod);
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_period =
module_idP, CC_id, frameP, subframeP,i,cc->num_active_mbsfn_area, 32 << (cc->mbsfn_AreaInfo[i]->
j,cc->num_sf_allocation_pattern,mbsfn_period,mcch_period); mcch_Config_r9.mcch_RepetitionPeriod_r9);
msi_pos = 0;
ii = 0;
switch (cc->mbsfn_AreaInfo[i]->mcch_Config_r9.signallingMCS_r9) { LOG_D(MAC,
case 0: "[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_mcs = 2; module_idP, CC_id, frameP, subframeP, i,
break; cc->num_active_mbsfn_area, j, cc->num_sf_allocation_pattern,
mbsfn_period, mcch_period);
case 1:
mcch_mcs = 7;
break; switch (cc->mbsfn_AreaInfo[i]->mcch_Config_r9.signallingMCS_r9) {
case 0:
case 2: mcch_mcs = 2;
mcch_mcs = 13; break;
break;
case 1:
case 3: mcch_mcs = 7;
mcch_mcs = 19; break;
break;
} case 2:
mcch_mcs = 13;
// 1st: Check the MBSFN subframes from SIB2 info (SF allocation pattern i, max 8 non-overlapping patterns exist) break;
if (frameP % mbsfn_period == cc->mbsfn_SubframeConfig[j]->radioframeAllocationOffset) { // MBSFN frameP
if (cc->mbsfn_SubframeConfig[j]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { // one-frameP format case 3:
mcch_mcs = 19;
// Find the first subframeP in this MCH to transmit MSI break;
if (frameP % mch_scheduling_period == cc->mbsfn_SubframeConfig[j]->radioframeAllocationOffset ) { }
while (ii == 0) {
ii = cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & (0x80>>msi_pos); // 1st: Check the MBSFN subframes from SIB2 info (SF allocation pattern i, max 8 non-overlapping patterns exist)
msi_pos++; if (frameP % mbsfn_period == cc->mbsfn_SubframeConfig[j]->radioframeAllocationOffset) { // MBSFN frameP
} if (cc->mbsfn_SubframeConfig[j]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { // one-frameP format
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", // Find the first subframeP in this MCH to transmit MSI
module_idP, CC_id, frameP, subframeP,i,j, if (frameP % mch_scheduling_period ==
cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0], msi_pos); cc->mbsfn_SubframeConfig[j]->
} radioframeAllocationOffset) {
while (ii == 0) {
// Check if the subframeP is for MSI, MCCH or MTCHs and Set the correspoding flag to 1 ii = cc->
switch (subframeP) { mbsfn_SubframeConfig[j]->subframeAllocation.
case 1: choice.oneFrame.buf[0] & (0x80 >> msi_pos);
if (cc->tdd_Config == NULL) { msi_pos++;
if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) { }
if (msi_pos == 1) {
msi_flag = 1; 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",
module_idP, CC_id, frameP, subframeP, i, j,
if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && cc->mbsfn_SubframeConfig[j]->
((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) ) { subframeAllocation.choice.oneFrame.buf[0],
mcch_flag = 1; msi_pos);
} }
// Check if the subframeP is for MSI, MCCH or MTCHs and Set the correspoding flag to 1
mtch_flag = 1; switch (subframeP) {
} case 1:
} if (cc->tdd_Config == NULL) {
if ((cc->
break; mbsfn_SubframeConfig[j]->subframeAllocation.
choice.oneFrame.buf[0] & MBSFN_FDD_SF1) ==
case 2: MBSFN_FDD_SF1) {
if (cc->tdd_Config == NULL) { if (msi_pos == 1) {
if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) { msi_flag = 1;
if (msi_pos == 2) { }
msi_flag = 1;
} if ((frameP % mcch_period ==
cc->mbsfn_AreaInfo[i]->
if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && 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; ((cc->mbsfn_AreaInfo[i]->
} mcch_Config_r9.sf_AllocInfo_r9.
buf[0] & MBSFN_FDD_SF1) ==
mtch_flag = 1; MBSFN_FDD_SF1)) {
} mcch_flag = 1;
} }
break; mtch_flag = 1;
}
case 3: }
if (cc->tdd_Config != NULL) { // TDD
if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) { break;
if (msi_pos == 1) {
msi_flag = 1; case 2:
} if (cc->tdd_Config == NULL) {
if ((cc->
if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && mbsfn_SubframeConfig[j]->subframeAllocation.
((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) ) { choice.oneFrame.buf[0] & MBSFN_FDD_SF2) ==
mcch_flag = 1; MBSFN_FDD_SF2) {
} if (msi_pos == 2) {
msi_flag = 1;
mtch_flag = 1; }
}
} else { // FDD if ((frameP % mcch_period ==
if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) { cc->mbsfn_AreaInfo[i]->
if (msi_pos == 3) { mcch_Config_r9.mcch_Offset_r9)
msi_flag = 1; &&
} ((cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.sf_AllocInfo_r9.
if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && buf[0] & MBSFN_FDD_SF2) ==
((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) ) { MBSFN_FDD_SF2)) {
mcch_flag = 1; mcch_flag = 1;
} }
mtch_flag = 1; mtch_flag = 1;
} }
} }
break; break;
case 4: case 3:
if (cc->tdd_Config != NULL) { if (cc->tdd_Config != NULL) { // TDD
if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) { if ((cc->
if (msi_pos == 2) { mbsfn_SubframeConfig[j]->subframeAllocation.
msi_flag = 1; choice.oneFrame.buf[0] & MBSFN_TDD_SF3) ==
} MBSFN_TDD_SF3) {
if (msi_pos == 1) {
if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && msi_flag = 1;
((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) ) { }
mcch_flag = 1;
} if ((frameP % mcch_period ==
cc->mbsfn_AreaInfo[i]->
mtch_flag = 1; mcch_Config_r9.mcch_Offset_r9)
} &&
} ((cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.sf_AllocInfo_r9.
break; buf[0] & MBSFN_TDD_SF3) ==
MBSFN_TDD_SF3)) {
case 6: mcch_flag = 1;
if (cc->tdd_Config == NULL) { }
if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) {
if (msi_pos == 4) { mtch_flag = 1;
msi_flag = 1; }
} } else { // FDD
if ((cc->
if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && mbsfn_SubframeConfig[j]->subframeAllocation.
((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) ) { choice.oneFrame.buf[0] & MBSFN_FDD_SF3) ==
mcch_flag = 1; MBSFN_FDD_SF3) {
} if (msi_pos == 3) {
msi_flag = 1;
mtch_flag = 1; }
}
} if ((frameP % mcch_period ==
cc->mbsfn_AreaInfo[i]->
break; mcch_Config_r9.mcch_Offset_r9)
&&
case 7: ((cc->mbsfn_AreaInfo[i]->
if (cc->tdd_Config != NULL) { // TDD mcch_Config_r9.sf_AllocInfo_r9.
if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) { buf[0] & MBSFN_FDD_SF3) ==
if (msi_pos == 3) { MBSFN_FDD_SF3)) {
msi_flag = 1; mcch_flag = 1;
} }
if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && mtch_flag = 1;
((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) ) { }
mcch_flag = 1; }
}
break;
mtch_flag = 1;
} case 4:
} else { // FDD if (cc->tdd_Config != NULL) {
if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) { if ((cc->
if (msi_pos == 5) { mbsfn_SubframeConfig[j]->subframeAllocation.
msi_flag = 1; choice.oneFrame.buf[0] & MBSFN_TDD_SF4) ==
} MBSFN_TDD_SF4) {
if (msi_pos == 2) {
if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && msi_flag = 1;
((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) ) { }
mcch_flag = 1;
} if ((frameP % mcch_period ==
cc->mbsfn_AreaInfo[i]->
mtch_flag = 1; mcch_Config_r9.mcch_Offset_r9)
} &&
} ((cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.sf_AllocInfo_r9.
break; buf[0] & MBSFN_TDD_SF4) ==
MBSFN_TDD_SF4)) {
case 8: mcch_flag = 1;
if (cc->tdd_Config != NULL) { //TDD }
if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) {
if (msi_pos == 4) { mtch_flag = 1;
msi_flag = 1; }
} }
if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && break;
((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) ) {
mcch_flag = 1; case 6:
} if (cc->tdd_Config == NULL) {
if ((cc->
mtch_flag = 1; mbsfn_SubframeConfig[j]->subframeAllocation.
} choice.oneFrame.buf[0] & MBSFN_FDD_SF6) ==
} else { // FDD MBSFN_FDD_SF6) {
if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) { if (msi_pos == 4) {
if (msi_pos == 6) { msi_flag = 1;
msi_flag = 1; }
}
if ((frameP % mcch_period ==
if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && cc->mbsfn_AreaInfo[i]->
((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) ) { mcch_Config_r9.mcch_Offset_r9)
mcch_flag = 1; &&
} ((cc->mbsfn_AreaInfo[i]->
mcch_Config_r9.sf_AllocInfo_r9.
mtch_flag = 1; buf[0] & MBSFN_FDD_SF6) ==
} MBSFN_FDD_SF6)) {
} mcch_flag = 1;
}
break;
mtch_flag = 1;
case 9: }
if (cc->tdd_Config != NULL) { }
if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) {
if (msi_pos == 5) { break;
msi_flag = 1;
} case 7:
if (cc->tdd_Config != NULL) { // TDD
if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) && if ((cc->
((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) ) { mbsfn_SubframeConfig[j]->subframeAllocation.
mcch_flag = 1; choice.oneFrame.buf[0] & MBSFN_TDD_SF7) ==
} MBSFN_TDD_SF7) {
if (msi_pos == 3) {
mtch_flag = 1; msi_flag = 1;
} }
}
if ((frameP % mcch_period ==
break; cc->mbsfn_AreaInfo[i]->
}// end switch mcch_Config_r9.mcch_Offset_r9)
&&
// sf allocation is non-overlapping ((cc->mbsfn_AreaInfo[i]->
if ((msi_flag==1) || (mcch_flag==1) || (mtch_flag==1)) { mcch_Config_r9.sf_AllocInfo_r9.
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", buf[0] & MBSFN_TDD_SF7) ==
module_idP, CC_id, frameP, subframeP,i,j,msi_flag,mcch_flag,mtch_flag); MBSFN_TDD_SF7)) {
break; mcch_flag = 1;
} }
} else { // four-frameP format
} mtch_flag = 1;
}
} else { // FDD
if ((cc->
mbsfn_SubframeConfig[j]->subframeAllocation.
choice.oneFrame.buf[0] & MBSFN_FDD_SF7) ==
MBSFN_FDD_SF7) {
if (msi_pos == 5) {
msi_flag = 1;
}
if ((frameP % mcch_period ==
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;
}
mtch_flag = 1;
}
}
break;
case 8:
if (cc->tdd_Config != NULL) { //TDD
if ((cc->
mbsfn_SubframeConfig[j]->subframeAllocation.
choice.oneFrame.buf[0] & MBSFN_TDD_SF8) ==
MBSFN_TDD_SF8) {
if (msi_pos == 4) {
msi_flag = 1;
}
if ((frameP % mcch_period ==
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;
}
mtch_flag = 1;
}
} else { // FDD
if ((cc->
mbsfn_SubframeConfig[j]->subframeAllocation.
choice.oneFrame.buf[0] & MBSFN_FDD_SF8) ==
MBSFN_FDD_SF8) {
if (msi_pos == 6) {
msi_flag = 1;
}
if ((frameP % mcch_period ==
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;
}
mtch_flag = 1;
}
}
break;
case 9:
if (cc->tdd_Config != NULL) {
if ((cc->
mbsfn_SubframeConfig[j]->subframeAllocation.
choice.oneFrame.buf[0] & MBSFN_TDD_SF9) ==
MBSFN_TDD_SF9) {
if (msi_pos == 5) {
msi_flag = 1;
}
if ((frameP % mcch_period ==
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;
}
mtch_flag = 1;
}
}
break;
} // end switch
// sf allocation is non-overlapping
if ((msi_flag == 1) || (mcch_flag == 1)
|| (mtch_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",
module_idP, CC_id, frameP, subframeP, i, j,
msi_flag, mcch_flag, mtch_flag);
break;
}
} else { // four-frameP format
}
}
} // end of for loop
cc->msi_active = 0;
cc->mcch_active = 0;
cc->mtch_active = 0;
// Calculate the mcs
if ((msi_flag == 1) || (mcch_flag == 1)) {
cc->MCH_pdu.mcs = mcch_mcs;
} else if (mtch_flag == 1) { // only MTCH in this subframeP
cc->MCH_pdu.mcs = cc->pmch_Config[0]->dataMCS_r9;
} }
} // end of for loop // 2nd: Create MSI, get MCCH from RRC and MTCHs from RLC
cc->msi_active=0; // there is MSI (MCH Scheduling Info)
cc->mcch_active=0; if (msi_flag == 1) {
cc->mtch_active=0; // Create MSI here
uint16_t msi_control_element[29], *msi_ptr;
// Calculate the mcs
if ((msi_flag==1) || (mcch_flag==1)) { msi_ptr = &msi_control_element[0];
cc->MCH_pdu.mcs = mcch_mcs; ((MSI_ELEMENT *) msi_ptr)->lcid = MCCH_LCHANID; //MCCH
} else if (mtch_flag == 1) { // only MTCH in this subframeP
cc->MCH_pdu.mcs = cc->pmch_Config[0]->dataMCS_r9; if (mcch_flag == 1) {
} ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0;
((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0;
} else { // no mcch for this MSP
// 2nd: Create MSI, get MCCH from RRC and MTCHs from RLC ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x7; // stop value is 2047
((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xff;
// there is MSI (MCH Scheduling Info) }
if (msi_flag == 1) {
// Create MSI here msi_ptr += sizeof(MSI_ELEMENT);
uint16_t msi_control_element[29], *msi_ptr;
//Header for MTCHs
msi_ptr = &msi_control_element[0]; num_mtch = cc->mbms_SessionList[0]->list.count;
((MSI_ELEMENT *) msi_ptr)->lcid = MCCH_LCHANID; //MCCH
for (k = 0; k < num_mtch; k++) { // loop for all session in this MCH (MCH[0]) at this moment
if (mcch_flag==1) { ((MSI_ELEMENT *) msi_ptr)->lcid = cc->mbms_SessionList[0]->list.array[k]->logicalChannelIdentity_r9; //mtch_lcid;
((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; // last subframeP of this mtch (only one mtch now)
((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0; ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xB;
} else { // no mcch for this MSP msi_ptr += sizeof(MSI_ELEMENT);
((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x7;// stop value is 2047 }
((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xff;
msi_length = msi_ptr - msi_control_element;
if (msi_length < 128) {
header_len_msi = 2;
} else {
header_len_msi = 3;
}
LOG_D(MAC,
"[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 length is %d bytes\n",msi_length);
// Store MSI data to mch_buffer[0]
memcpy((char *) &mch_buffer[sdu_length_total],
msi_control_element, msi_length);
sdu_lcids[num_sdus] = MCH_SCHDL_INFO;
sdu_lengths[num_sdus] = msi_length;
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]);
num_sdus++;
cc->msi_active = 1;
} }
// there is MCCH
msi_ptr+= sizeof(MSI_ELEMENT); if (mcch_flag == 1) {
LOG_D(MAC,
//Header for MTCHs "[eNB %d] CC_id %d Frame %d Subframe %d: Schedule MCCH MESSAGE (area %d, sfAlloc %d)\n",
num_mtch = cc->mbms_SessionList[0]->list.count; module_idP, CC_id, frameP, subframeP, i, j);
for (k=0; k<num_mtch; k++) { // loop for all session in this MCH (MCH[0]) at this moment mcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MCCH, 1, &cc->MCCH_pdu.payload[0], 1, // this is eNB
((MSI_ELEMENT *) msi_ptr)->lcid = cc->mbms_SessionList[0]->list.array[k]->logicalChannelIdentity_r9;//mtch_lcid; module_idP, // index
((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; // last subframeP of this mtch (only one mtch now) i); // this is the mbsfn sync area index
((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xB;
msi_ptr+=sizeof(MSI_ELEMENT); 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",
module_idP, CC_id, frameP, subframeP, mcch_sdu_length);
header_len_mcch = 2;
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",
module_idP, CC_id, frameP, subframeP,
mcch_sdu_length, mcch_mcs);
} 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",
module_idP, CC_id, frameP, subframeP,
mcch_sdu_length, mcch_mcs);
}
cc->mcch_active = 1;
memcpy((char *) &mch_buffer[sdu_length_total],
&cc->MCCH_pdu.payload[0], mcch_sdu_length);
sdu_lcids[num_sdus] = MCCH_LCHANID;
sdu_lengths[num_sdus] = mcch_sdu_length;
if (sdu_lengths[num_sdus] > 128) {
header_len_mcch = 3;
}
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]);
num_sdus++;
}
} }
msi_length = msi_ptr-msi_control_element; TBS =
get_TBS_DL(cc->MCH_pdu.mcs, to_prb(cc->mib->message.dl_Bandwidth));
if (msi_length<128) {
header_len_msi = 2;
} else {
header_len_msi = 3;
}
LOG_D(MAC,"[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 length is %d bytes\n",msi_length);
// Store MSI data to mch_buffer[0]
memcpy((char *)&mch_buffer[sdu_length_total],
msi_control_element,
msi_length);
sdu_lcids[num_sdus] = MCH_SCHDL_INFO;
sdu_lengths[num_sdus] = msi_length;
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]);
num_sdus++;
cc->msi_active=1;
}
// there is MCCH
if (mcch_flag == 1) {
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);
mcch_sdu_length = mac_rrc_data_req(module_idP,
CC_id,
frameP,
MCCH,1,
&cc->MCCH_pdu.payload[0],
1,// this is eNB
module_idP, // index
i); // this is the mbsfn sync area index
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",
module_idP,CC_id,frameP,subframeP,mcch_sdu_length);
header_len_mcch = 2;
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",
module_idP, CC_id,
frameP,subframeP,
mcch_sdu_length,
mcch_mcs);
} 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",
module_idP, CC_id,
frameP, subframeP,
mcch_sdu_length,
mcch_mcs);
}
cc->mcch_active=1;
memcpy((char *)&mch_buffer[sdu_length_total],
&cc->MCCH_pdu.payload[0],
mcch_sdu_length);
sdu_lcids[num_sdus] = MCCH_LCHANID;
sdu_lengths[num_sdus] = mcch_sdu_length;
if (sdu_lengths[num_sdus]>128) {
header_len_mcch = 3;
}
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]);
num_sdus++;
}
}
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
//if ((i == 0) && ((RC.mac[module_idP]->MBMS_flag != multicast_relay) || (RC.mac[module_idP]->mcch_active==0))) { //if ((i == 0) && ((RC.mac[module_idP]->MBMS_flag != multicast_relay) || (RC.mac[module_idP]->mcch_active==0))) {
#endif #endif
// there is MTCHs, loop if there are more than 1 // there is MTCHs, loop if there are more than 1
if (mtch_flag == 1) { if (mtch_flag == 1) {
// Calculate TBS // Calculate TBS
/* if ((msi_flag==1) || (mcch_flag==1)) { /* if ((msi_flag==1) || (mcch_flag==1)) {
TBS = mac_xface->get_TBS(mcch_mcs, mac_xface->frame_parms->N_RB_DL); TBS = mac_xface->get_TBS(mcch_mcs, mac_xface->frame_parms->N_RB_DL);
} }
else { // only MTCH in this subframeP else { // only MTCH in this subframeP
TBS = mac_xface->get_TBS(RC.mac[module_idP]->pmch_Config[0]->dataMCS_r9, mac_xface->frame_parms->N_RB_DL); TBS = mac_xface->get_TBS(RC.mac[module_idP]->pmch_Config[0]->dataMCS_r9, mac_xface->frame_parms->N_RB_DL);
} }
// 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 subframe %d: Schedule MTCH (area %d, sfAlloc %d)\n",Mod_id,CC_id,frame,subframe,i,j); LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframe %d: Schedule MTCH (area %d, sfAlloc %d)\n",Mod_id,CC_id,frame,subframe,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,"[eNB %d], CC_id %d, Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n",
Mod_id,CC_id,frame,MTCH,TBS, Mod_id,CC_id,frame,MTCH,TBS,
TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch); TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch);
rlc_status = mac_rlc_status_ind(Mod_id,frame,1,RLC_MBMS_YES,MTCH+ (maxDRB + 3) * MAX_MOBILES_PER_RG, rlc_status = mac_rlc_status_ind(Mod_id,frame,1,RLC_MBMS_YES,MTCH+ (maxDRB + 3) * MAX_MOBILES_PER_RG,
TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch); TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch);
printf("frame %d, subframe %d, rlc_status.bytes_in_buffer is %d\n",frame,subframe, rlc_status.bytes_in_buffer); printf("frame %d, subframe %d, rlc_status.bytes_in_buffer is %d\n",frame,subframe, rlc_status.bytes_in_buffer);
*/ */
// 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",
header_len_mtch = 3; module_idP, CC_id, frameP, subframeP, i, j);
LOG_D(MAC,"[eNB %d], CC_id %d, Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n",
module_idP,CC_id,frameP,MTCH,TBS, header_len_mtch = 3;
TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch); LOG_D(MAC,
"[eNB %d], CC_id %d, Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n",
rlc_status = mac_rlc_status_ind(module_idP,0,frameP,subframeP,module_idP,ENB_FLAG_YES,MBMS_FLAG_YES,MTCH, module_idP, CC_id, frameP, MTCH, TBS,
TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch); TBS - header_len_mcch - header_len_msi - sdu_length_total -
LOG_D(MAC,"e-MBMS log channel %u frameP %d, subframeP %d, rlc_status.bytes_in_buffer is %d\n", header_len_mtch);
MTCH,frameP,subframeP, rlc_status.bytes_in_buffer);
rlc_status =
if (rlc_status.bytes_in_buffer >0) { mac_rlc_status_ind(module_idP, 0, frameP, subframeP,
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, ENB_FLAG_YES, MBMS_FLAG_YES,
module_idP,CC_id,frameP,TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch,header_len_mtch); MTCH,
TBS - header_len_mcch - header_len_msi -
sdu_lengths[num_sdus] = mac_rlc_data_req( sdu_length_total - header_len_mtch);
module_idP, LOG_D(MAC,
0, "e-MBMS log channel %u frameP %d, subframeP %d, rlc_status.bytes_in_buffer is %d\n",
module_idP, MTCH, frameP, subframeP, rlc_status.bytes_in_buffer);
frameP,
ENB_FLAG_YES, if (rlc_status.bytes_in_buffer > 0) {
MBMS_FLAG_YES, LOG_I(MAC,
MTCH, "[eNB %d][MBMS USER-PLANE], CC_id %d, Frame %d, MTCH->MCH, Requesting %d bytes from RLC (header len mtch %d)\n",
0, //not used module_idP, CC_id, frameP,
(char*)&mch_buffer[sdu_length_total]); TBS - header_len_mcch - header_len_msi -
//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_length_total - header_len_mtch, header_len_mtch);
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);
cc->mtch_active=1; sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 0, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_YES, MTCH, 0, //not used
sdu_lcids[num_sdus] = MTCH; (char *)
sdu_length_total += sdu_lengths[num_sdus]; &mch_buffer
[sdu_length_total]);
if (sdu_lengths[num_sdus] < 128) { //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]);
header_len_mtch = 2; 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);
num_sdus++; cc->mtch_active = 1;
} else { sdu_lcids[num_sdus] = MTCH;
header_len_mtch = 0; sdu_length_total += sdu_lengths[num_sdus];
if (sdu_lengths[num_sdus] < 128) {
header_len_mtch = 2;
}
num_sdus++;
} else {
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 +
// Adjust the last subheader header_len_mtch) > 0) {
/* if ((msi_flag==1) || (mcch_flag==1)) { // Adjust the last subheader
RC.mac[module_idP]->MCH_pdu.mcs = mcch_mcs; /* if ((msi_flag==1) || (mcch_flag==1)) {
} RC.mac[module_idP]->MCH_pdu.mcs = mcch_mcs;
else if (mtch_flag == 1) { // only MTCH in this subframeP }
RC.mac[module_idP]->MCH_pdu.mcs = RC.mac[module_idP]->pmch_Config[0]->dataMCS_r9; else if (mtch_flag == 1) { // only MTCH in this subframeP
} RC.mac[module_idP]->MCH_pdu.mcs = RC.mac[module_idP]->pmch_Config[0]->dataMCS_r9;
*/ }
header_len_mtch_temp = header_len_mtch; */
header_len_mcch_temp = header_len_mcch; header_len_mtch_temp = header_len_mtch;
header_len_msi_temp = header_len_msi; header_len_mcch_temp = header_len_mcch;
header_len_msi_temp = header_len_msi;
if (header_len_mtch>0) {
header_len_mtch=1; // remove Length field in the subheader for the last PDU if (header_len_mtch > 0) {
} else if (header_len_mcch>0) { header_len_mtch = 1; // remove Length field in the subheader for the last PDU
header_len_mcch=1; } else if (header_len_mcch > 0) {
header_len_mcch = 1;
} else {
header_len_msi = 1;
}
// Calculate the padding
if ((TBS - header_len_mtch - header_len_mcch - header_len_msi -
sdu_length_total) < 0) {
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;
} else
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;
} else { // using post_padding, give back the Length field of subheader for the last PDU
padding = 0;
if (header_len_mtch > 0) {
header_len_mtch = header_len_mtch_temp;
} else if (header_len_mcch > 0) {
header_len_mcch = header_len_mcch_temp;
} else {
header_len_msi = header_len_msi_temp;
}
post_padding =
TBS - sdu_length_total - header_len_msi - header_len_mcch -
header_len_mtch;
}
// Generate the MAC Header for MCH
// 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, num_sdus, sdu_lengths, sdu_lcids, 255, // no drx
31, // no timing advance
NULL, // no contention res id
padding, post_padding);
cc->MCH_pdu.Pdu_size = TBS;
cc->MCH_pdu.sync_area = i;
cc->MCH_pdu.msi_active = cc->msi_active;
cc->MCH_pdu.mcch_active = cc->mcch_active;
cc->MCH_pdu.mtch_active = cc->mtch_active;
LOG_D(MAC,
" MCS for this sf is %d (mcch active %d, mtch active %d)\n",
cc->MCH_pdu.mcs, cc->MCH_pdu.mcch_active,
cc->MCH_pdu.mtch_active);
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",
module_idP, CC_id, sdu_length_total, num_sdus,
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
memcpy(&cc->MCH_pdu.payload[offset], mch_buffer, sdu_length_total);
// filling remainder of MCH with random data if necessery
for (j = 0; j < (TBS - sdu_length_total - offset); j++) {
cc->MCH_pdu.payload[offset + sdu_length_total + j] =
(char) (taus() & 0xff);
}
/* Tracing of PDU is done on UE side */
if (opt_enabled == 1) {
trace_pdu(1, (uint8_t *) cc->MCH_pdu.payload, TBS, module_idP, 6, 0xffff, // M_RNTI = 6 in wirehsark
RC.mac[module_idP]->frame,
RC.mac[module_idP]->subframe, 0, 0);
LOG_D(OPT,
"[eNB %d][MCH] CC_id %d Frame %d : MAC PDU with size %d\n",
module_idP, CC_id, frameP, TBS);
}
/*
for (j=0;j<sdu_length_total;j++)
printf("%2x.",RC.mac[module_idP]->MCH_pdu.payload[j+offset]);
printf(" \n"); */
return 1;
} else { } else {
header_len_msi=1; cc->MCH_pdu.Pdu_size = 0;
} cc->MCH_pdu.sync_area = 0;
cc->MCH_pdu.msi_active = 0;
// Calculate the padding cc->MCH_pdu.mcch_active = 0;
if ((TBS - header_len_mtch - header_len_mcch - header_len_msi - sdu_length_total) < 0) { cc->MCH_pdu.mtch_active = 0;
LOG_E(MAC,"Error in building MAC PDU, TBS %d < PDU %d \n", // for testing purpose, fill with random data
TBS, header_len_mtch + header_len_mcch + header_len_msi + sdu_length_total); //for (j=0;j<(TBS-sdu_length_total-offset);j++)
return 0; // RC.mac[module_idP]->MCH_pdu.payload[offset+sdu_length_total+j] = (char)(taus()&0xff);
} else if ((TBS - header_len_mtch - header_len_mcch - header_len_msi - sdu_length_total) <= 2) { return 0;
padding = (TBS - header_len_mtch - header_len_mcch - header_len_msi - sdu_length_total);
post_padding = 0;
} else { // using post_padding, give back the Length field of subheader for the last PDU
padding = 0;
if (header_len_mtch>0) {
header_len_mtch = header_len_mtch_temp;
} else if (header_len_mcch>0) {
header_len_mcch = header_len_mcch_temp;
} else {
header_len_msi = header_len_msi_temp;
}
post_padding = TBS - sdu_length_total - header_len_msi - header_len_mcch - header_len_mtch;
}
// Generate the MAC Header for MCH
// 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,
num_sdus,
sdu_lengths,
sdu_lcids,
255, // no drx
31, // no timing advance
NULL, // no contention res id
padding,
post_padding);
cc->MCH_pdu.Pdu_size=TBS;
cc->MCH_pdu.sync_area=i;
cc->MCH_pdu.msi_active= cc->msi_active;
cc->MCH_pdu.mcch_active= cc->mcch_active;
cc->MCH_pdu.mtch_active= cc->mtch_active;
LOG_D(MAC," MCS for this sf is %d (mcch active %d, mtch active %d)\n", cc->MCH_pdu.mcs,
cc->MCH_pdu.mcch_active,cc->MCH_pdu.mtch_active );
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",
module_idP,CC_id,sdu_length_total,num_sdus,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
memcpy(&cc->MCH_pdu.payload[offset],mch_buffer,sdu_length_total);
// filling remainder of MCH with random data if necessery
for (j=0; j<(TBS-sdu_length_total-offset); j++) {
cc->MCH_pdu.payload[offset+sdu_length_total+j] = (char)(taus()&0xff);
}
/* Tracing of PDU is done on UE side */
if (opt_enabled ==1 ) {
trace_pdu(1, (uint8_t *)cc->MCH_pdu.payload,
TBS, module_idP, 6, 0xffff, // M_RNTI = 6 in wirehsark
RC.mac[module_idP]->frame, RC.mac[module_idP]->subframe,0,0);
LOG_D(OPT,"[eNB %d][MCH] CC_id %d Frame %d : MAC PDU with size %d\n",
module_idP, CC_id, frameP, TBS);
} }
//this is for testing
/* /*
for (j=0;j<sdu_length_total;j++) if (mtch_flag == 1) {
printf("%2x.",RC.mac[module_idP]->MCH_pdu.payload[j+offset]); // LOG_D(MAC,"DUY: mch_buffer length so far is : %ld\n", &mch_buffer[sdu_length_total]-&mch_buffer[0]);
printf(" \n");*/ return 1;
return 1; }
} else { else
cc->MCH_pdu.Pdu_size=0; return 0;
cc->MCH_pdu.sync_area=0; */
cc->MCH_pdu.msi_active=0;
cc->MCH_pdu.mcch_active=0;
cc->MCH_pdu.mtch_active=0;
// for testing purpose, fill with random data
//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);
return 0;
}
//this is for testing
/*
if (mtch_flag == 1) {
// LOG_D(MAC,"DUY: mch_buffer length so far is : %ld\n", &mch_buffer[sdu_length_total]-&mch_buffer[0]);
return 1;
}
else
return 0;
*/
} }
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.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
#ifdef USER_MODE #ifdef USER_MODE
//#include "stdio.h" //#include "stdio.h"
#endif //USER_MODE #endif //USER_MODE
#include "PHY/defs.h" #include "PHY/defs.h"
#include "defs.h" #include "defs.h"
...@@ -56,8 +56,8 @@ extern UE_RRC_INST *UE_rrc_inst; ...@@ -56,8 +56,8 @@ extern UE_RRC_INST *UE_rrc_inst;
extern UE_MAC_INST *UE_mac_inst; extern UE_MAC_INST *UE_mac_inst;
extern eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8 extern eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8
extern eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8 extern eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8
...@@ -79,28 +79,26 @@ extern uint32_t RRC_CONNECTION_FLAG; ...@@ -79,28 +79,26 @@ extern uint32_t RRC_CONNECTION_FLAG;
extern uint8_t rb_table[34]; extern uint8_t rb_table[34];
extern DCI0_5MHz_TDD_1_6_t UL_alloc_pdu; extern DCI0_5MHz_TDD_1_6_t UL_alloc_pdu;
extern DCI1A_5MHz_TDD_1_6_t RA_alloc_pdu; extern DCI1A_5MHz_TDD_1_6_t RA_alloc_pdu;
extern DCI1A_5MHz_TDD_1_6_t DLSCH_alloc_pdu1A; extern DCI1A_5MHz_TDD_1_6_t DLSCH_alloc_pdu1A;
extern DCI1A_5MHz_TDD_1_6_t BCCH_alloc_pdu; extern DCI1A_5MHz_TDD_1_6_t BCCH_alloc_pdu;
extern DCI1A_5MHz_TDD_1_6_t CCCH_alloc_pdu; extern DCI1A_5MHz_TDD_1_6_t CCCH_alloc_pdu;
extern DCI1_5MHz_TDD_t DLSCH_alloc_pdu; extern DCI1_5MHz_TDD_t DLSCH_alloc_pdu;
extern DCI0_5MHz_FDD_t UL_alloc_pdu_fdd; extern DCI0_5MHz_FDD_t UL_alloc_pdu_fdd;
extern DCI1A_5MHz_FDD_t DLSCH_alloc_pdu1A_fdd; extern DCI1A_5MHz_FDD_t DLSCH_alloc_pdu1A_fdd;
extern DCI1A_5MHz_FDD_t RA_alloc_pdu_fdd; extern DCI1A_5MHz_FDD_t RA_alloc_pdu_fdd;
extern DCI1A_5MHz_FDD_t BCCH_alloc_pdu_fdd; extern DCI1A_5MHz_FDD_t BCCH_alloc_pdu_fdd;
extern DCI1A_5MHz_FDD_t CCCH_alloc_pdu_fdd; extern DCI1A_5MHz_FDD_t CCCH_alloc_pdu_fdd;
extern DCI1_5MHz_FDD_t DLSCH_alloc_pdu_fdd; extern DCI1_5MHz_FDD_t DLSCH_alloc_pdu_fdd;
extern DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu1; extern DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu1;
extern DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu2; 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
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
*------------------------------------------------------------------------------- *-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance: * For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org * contact@openairinterface.org
*/ */
/*! \file flexran_agent_mac_proto.h /*! \file flexran_agent_mac_proto.h
* \brief MAC functions for FlexRAN agent * \brief MAC functions for FlexRAN agent
...@@ -39,150 +39,178 @@ ...@@ -39,150 +39,178 @@
/* /*
* 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);
/* /*
* top level flexran scheduler used by the eNB scheduler * top level flexran scheduler used by the eNB scheduler
*/ */
void flexran_schedule_ue_spec_default(mid_t mod_id, 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
*/ */
void void
flexran_schedule_ue_spec_embb(mid_t mod_id, flexran_schedule_ue_spec_embb(mid_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);
/* /*
* slice specific scheduler for urllc * slice specific scheduler for urllc
*/ */
void void
flexran_schedule_ue_spec_urllc(mid_t mod_id, flexran_schedule_ue_spec_urllc(mid_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);
/* /*
* slice specific scheduler for mmtc * slice specific scheduler for mmtc
*/ */
void void
flexran_schedule_ue_spec_mmtc(mid_t mod_id, flexran_schedule_ue_spec_mmtc(mid_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);
/* /*
* slice specific scheduler for best effort traffic * slice specific scheduler for best effort traffic
*/ */
void void
flexran_schedule_ue_spec_be(mid_t mod_id, flexran_schedule_ue_spec_be(mid_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);
/* /*
* common flexran scheduler function * common flexran scheduler function
*/ */
void void
flexran_schedule_ue_spec_common(mid_t mod_id, flexran_schedule_ue_spec_common(mid_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);
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 slice_id);
int flexran_slice_member(int UE_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,
int slice_id,
void _store_dlsch_buffer (module_id_t Mod_id, frame_t frameP, sub_frame_t subframeP);
int slice_id,
frame_t frameP,
sub_frame_t subframeP); void _assign_rbs_required(module_id_t Mod_id,
int slice_id,
frame_t frameP,
void _assign_rbs_required (module_id_t Mod_id, sub_frame_t subframe,
int slice_id, uint16_t
frame_t frameP, nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
sub_frame_t subframe, uint16_t
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], nb_rbs_allowed_slice[MAX_NUM_CCs]
uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES], [MAX_NUM_SLICES], int min_rb_unit[MAX_NUM_CCs]);
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
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], 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],
uint16_t
void _dlsch_scheduler_pre_processor_allocate (module_id_t Mod_id, nb_rbs_allowed_slice[MAX_NUM_CCs]
int UE_id, [MAX_NUM_SLICES],
uint8_t CC_id, unsigned char
int N_RBG, rballoc_sub[MAX_NUM_CCs]
int transmission_mode, [N_RBG_MAX],
int min_rb_unit, unsigned char
uint8_t N_RB_DL, MIMO_mode_indicator[MAX_NUM_CCs]
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], [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], void _dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id,
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]); int UE_id,
uint8_t CC_id,
int N_RBG,
int transmission_mode,
int min_rb_unit,
uint8_t N_RB_DL,
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],
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
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
*------------------------------------------------------------------------------- *-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance: * For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org * contact@openairinterface.org
*/ */
/*! \file flexran_agent_scheduler_dataplane.c /*! \file flexran_agent_scheduler_dataplane.c
* \brief data plane procedures related to eNB scheduling * \brief data plane procedures related to eNB scheduling
...@@ -57,495 +57,532 @@ ...@@ -57,495 +57,532 @@
#include "flexran_agent_common.h" #include "flexran_agent_common.h"
#include "SIMULATION/TOOLS/defs.h" // for taus #include "SIMULATION/TOOLS/defs.h" // for taus
void
flexran_apply_dl_scheduling_decisions(mid_t mod_id,
uint32_t frame,
uint32_t subframe,
int *mbsfn_flag,
Protocol__FlexranMessage *
dl_scheduling_info)
{
Protocol__FlexDlMacConfig *mac_config =
dl_scheduling_info->dl_mac_config_msg;
// Check if there is anything to schedule for random access
if (mac_config->n_dl_rar > 0) {
/*TODO: call the random access data plane function */
}
// Check if there is anything to schedule for paging/broadcast
if (mac_config->n_dl_broadcast > 0) {
/*TODO: call the broadcast/paging data plane function */
}
// Check if there is anything to schedule for the UEs
if (mac_config->n_dl_ue_data > 0) {
flexran_apply_ue_spec_scheduling_decisions(mod_id, frame, subframe,
mbsfn_flag,
mac_config->
n_dl_ue_data,
mac_config->dl_ue_data);
}
}
void flexran_apply_dl_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,
Protocol__FlexranMessage *dl_scheduling_info) { uint32_t n_dl_ue_data,
Protocol__FlexDlData **
Protocol__FlexDlMacConfig *mac_config = dl_scheduling_info->dl_mac_config_msg; dl_ue_data)
{
// Check if there is anything to schedule for random access
if (mac_config->n_dl_rar > 0) { uint8_t CC_id;
/*TODO: call the random access data plane function*/ int UE_id;
} mac_rlc_status_resp_t rlc_status;
unsigned char ta_len = 0;
// Check if there is anything to schedule for paging/broadcast unsigned char header_len = 0, header_len_tmp = 0;
if (mac_config->n_dl_broadcast > 0) { unsigned char sdu_lcids[11], offset, num_sdus = 0;
/*TODO: call the broadcast/paging data plane function*/ uint16_t nb_rb;
} uint16_t TBS, sdu_lengths[11], rnti, padding = 0, post_padding = 0;
unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES];
// Check if there is anything to schedule for the UEs uint8_t round = 0;
if (mac_config->n_dl_ue_data > 0) { uint8_t harq_pid = 0;
flexran_apply_ue_spec_scheduling_decisions(mod_id, frame, subframe, mbsfn_flag, // LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs];
mac_config->n_dl_ue_data, mac_config->dl_ue_data); LTE_eNB_UE_stats *eNB_UE_stats = NULL;
} uint16_t sdu_length_total = 0;
short ta_update = 0;
} eNB_MAC_INST *eNB = &eNB_mac_inst[mod_id];
UE_list_t *UE_list = &eNB->UE_list;
// static int32_t tpc_accumulated=0;
UE_sched_ctrl *ue_sched_ctl;
int last_sdu_header_len = 0;
int i, j;
Protocol__FlexDlData *dl_data;
Protocol__FlexDlDci *dl_dci;
uint32_t rlc_size, n_lc, lcid;
// For each UE-related command
for (i = 0; i < n_dl_ue_data; i++) {
dl_data = dl_ue_data[i];
dl_dci = dl_data->dl_dci;
CC_id = dl_data->serv_cell_index;
// frame_parms[CC_id] = mac_xface->get_lte_frame_parms(mod_id, CC_id);
rnti = dl_data->rnti;
UE_id = find_ue(rnti, PHY_vars_eNB_g[mod_id][CC_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);
round = dl_dci->rv[0];
harq_pid = dl_dci->harq_process;
//LOG_I(FLEXRAN_AGENT, "[Frame %d][Subframe %d] Scheduling harq %d\n", frame, subframe, harq_pid);
// LOG_I(FLEXRAN_AGENT, "[Frame %d][Subframe %d]Now scheduling harq_pid %d (round %d)\n", frame, subframe, harq_pid, round);
// If this is a new transmission
if (round == 0) {
// First we have to deal with the creation of the PDU based on the message instructions
rlc_status.bytes_in_buffer = 0;
TBS = dl_dci->tbs_size[0];
if (dl_data->n_ce_bitmap > 0) {
//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;
}
num_sdus = 0;
sdu_length_total = 0;
n_lc = dl_data->n_rlc_pdu;
// Go through each one of the channel commands and create SDUs
header_len = 0;
last_sdu_header_len = 0;
for (j = 0; j < n_lc; j++) {
sdu_lengths[j] = 0;
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;
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);
if (rlc_size > 0) {
rlc_status = mac_rlc_status_ind(mod_id,
rnti,
mod_id,
frame,
subframe,
ENB_FLAG_YES,
MBMS_FLAG_NO, lcid, 0);
if (rlc_status.bytes_in_buffer > 0) {
if (rlc_status.bytes_in_buffer < rlc_size) {
rlc_size = rlc_status.bytes_in_buffer;
}
if (rlc_size <= 2) {
rlc_size = 3;
}
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
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) {
sdu_lengths[j] = mac_rlc_data_req(mod_id, rnti, mod_id, frame, 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]);
sdu_length_total += sdu_lengths[j];
sdu_lcids[j] = lcid;
UE_list->
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) {
header_len += 2;
last_sdu_header_len = 2;
} else {
header_len += 3;
last_sdu_header_len = 3;
}
num_sdus++;
}
}
}
} // SDU creation end
if (((sdu_length_total + header_len + ta_len) > 0)) {
header_len_tmp = header_len;
// If we have only a single SDU, header length becomes 1
if ((num_sdus) == 1) {
//if (header_len == 2 || header_len == 3) {
header_len = 1;
} else {
header_len = (header_len - last_sdu_header_len) + 1;
}
// If we need a 1 or 2 bit padding or no padding at all
if ((TBS - header_len - sdu_length_total - ta_len) <= 2 || (TBS - header_len - sdu_length_total - ta_len) > TBS) { //protect from overflow
padding =
(TBS - header_len - sdu_length_total - ta_len);
post_padding = 0;
} else { // The last sdu needs to have a length field, since we add padding
padding = 0;
header_len = header_len_tmp;
post_padding = TBS - sdu_length_total - header_len - ta_len; // 1 is for the postpadding header
}
if (ta_len > 0) {
// Reset the measurement
ta_update = flexran_get_TA(mod_id, UE_id, CC_id);
ue_sched_ctl->ta_timer = 20;
eNB_UE_stats->timing_advance_update = 0;
} else {
ta_update = 0;
}
// If there is nothing to schedule, just leave
if ((sdu_length_total) <= 0) {
harq_pid_updated[UE_id][harq_pid] = 1;
harq_pid_round[UE_id][harq_pid] = 0;
continue;
}
// 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], num_sdus, //num_sdus
sdu_lengths, //
sdu_lcids, 255, // no drx
ta_update, // timing advance
NULL, // contention res id
padding, post_padding);
void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
uint32_t frame,
uint32_t subframe,
int *mbsfn_flag,
uint32_t n_dl_ue_data,
Protocol__FlexDlData **dl_ue_data) {
uint8_t CC_id;
int UE_id;
mac_rlc_status_resp_t rlc_status;
unsigned char ta_len=0;
unsigned char header_len = 0, header_len_tmp = 0;
unsigned char sdu_lcids[11],offset,num_sdus=0;
uint16_t nb_rb;
uint16_t TBS, sdu_lengths[11],rnti,padding=0,post_padding=0;
unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES];
uint8_t round = 0;
uint8_t harq_pid = 0;
// LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs];
LTE_eNB_UE_stats *eNB_UE_stats = NULL;
uint16_t sdu_length_total = 0;
short ta_update = 0;
eNB_MAC_INST *eNB = &eNB_mac_inst[mod_id];
UE_list_t *UE_list = &eNB->UE_list;
// static int32_t tpc_accumulated=0;
UE_sched_ctrl *ue_sched_ctl;
int last_sdu_header_len = 0;
int i, j;
Protocol__FlexDlData *dl_data;
Protocol__FlexDlDci *dl_dci;
uint32_t rlc_size, n_lc, lcid;
// For each UE-related command
for (i = 0; i < n_dl_ue_data; i++) {
dl_data = dl_ue_data[i];
dl_dci = dl_data->dl_dci;
CC_id = dl_data->serv_cell_index;
// frame_parms[CC_id] = mac_xface->get_lte_frame_parms(mod_id, CC_id);
rnti = dl_data->rnti;
UE_id = find_ue(rnti, PHY_vars_eNB_g[mod_id][CC_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);
round = dl_dci->rv[0];
harq_pid = dl_dci->harq_process;
//LOG_I(FLEXRAN_AGENT, "[Frame %d][Subframe %d] Scheduling harq %d\n", frame, subframe, harq_pid);
// LOG_I(FLEXRAN_AGENT, "[Frame %d][Subframe %d]Now scheduling harq_pid %d (round %d)\n", frame, subframe, harq_pid, round);
// If this is a new transmission
if (round == 0) {
// First we have to deal with the creation of the PDU based on the message instructions
rlc_status.bytes_in_buffer = 0;
TBS = dl_dci->tbs_size[0];
if (dl_data->n_ce_bitmap > 0) {
//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;
}
num_sdus = 0;
sdu_length_total = 0;
n_lc = dl_data->n_rlc_pdu;
// Go through each one of the channel commands and create SDUs
header_len = 0;
last_sdu_header_len = 0;
for (j = 0; j < n_lc; j++) {
sdu_lengths[j] = 0;
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;
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);
if (rlc_size > 0) {
rlc_status = mac_rlc_status_ind(mod_id,
rnti,
mod_id,
frame,
subframe,
ENB_FLAG_YES,
MBMS_FLAG_NO,
lcid,
0);
if (rlc_status.bytes_in_buffer > 0) {
if (rlc_status.bytes_in_buffer < rlc_size) {
rlc_size = rlc_status.bytes_in_buffer;
}
if (rlc_size <= 2) {
rlc_size = 3; #ifdef DEBUG_eNB_SCHEDULER
} LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n");
rlc_status = mac_rlc_status_ind(mod_id, for (i = 0; i < 16; i++) {
rnti, LOG_T(MAC, "%x.", dlsch_buffer[i]);
mod_id, }
frame,
subframe, LOG_T(MAC, "\n");
ENB_FLAG_YES, #endif
MBMS_FLAG_NO, // cycle through SDUs and place in dlsch_buffer
lcid, memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].
rlc_size); // transport block set size 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]);
LOG_D(MAC, "[TEST] RLC can give %d bytes for LCID %d during second call\n", rlc_status.bytes_in_buffer, lcid);
// fill remainder of DLSCH with random data
if (rlc_status.bytes_in_buffer > 0) { for (j = 0; j < (TBS - sdu_length_total - offset); j++) {
UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset +
sdu_lengths[j] = mac_rlc_data_req(mod_id, sdu_length_total
rnti, + j] =
mod_id, (char) (taus() & 0xff);
frame, }
ENB_FLAG_YES,
MBMS_FLAG_NO, //eNB_mac_inst[0].DLSCH_pdu[0][0].payload[0][offset+sdu_lengths[0]+j] = (char)(taus()&0xff);
lcid, if (opt_enabled == 1) {
rlc_size, //not used trace_pdu(1,
(char *)&dlsch_buffer[sdu_length_total]); (uint8_t *)
UE_list->DLSCH_pdu[CC_id][0][UE_id].
LOG_D(MAC,"[eNB %d][LCID %d] CC_id %d Got %d bytes from RLC\n",mod_id, lcid, CC_id, sdu_lengths[j]); payload[0], TBS, mod_id, 3, UE_RNTI(mod_id,
sdu_length_total += sdu_lengths[j]; UE_id),
sdu_lcids[j] = lcid; eNB->frame, eNB->subframe, 0, 0);
LOG_D(OPT,
UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid] += 1; "[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n",
UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[j]; mod_id, CC_id, frame, UE_RNTI(mod_id, UE_id),
TBS);
if (sdu_lengths[j] < 128) { }
header_len += 2; // store stats
last_sdu_header_len = 2; eNB->eNB_stats[CC_id].dlsch_bytes_tx += sdu_length_total;
} else { eNB->eNB_stats[CC_id].dlsch_pdus_tx += 1;
header_len += 3; UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi =
last_sdu_header_len = 3; eNB_UE_stats->DL_cqi[0];
}
num_sdus++; 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_round = round;
//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
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);
while (stats_tbs < TBS) {
nb_rb += get_min_rb_unit(mod_id, CC_id);
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]);
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].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].overhead_bytes =
TBS - sdu_length_total;
UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes +=
sdu_length_total;
UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes += TBS;
UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus += 1;
//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);
} else {
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_round[UE_id][harq_pid] = 0;
continue;
} }
}
}
} // SDU creation end
if (((sdu_length_total + header_len + ta_len) > 0)) {
header_len_tmp = header_len;
// If we have only a single SDU, header length becomes 1
if ((num_sdus) == 1) {
//if (header_len == 2 || header_len == 3) {
header_len = 1;
} else { } else {
header_len = (header_len - last_sdu_header_len) + 1; // No need to create anything apart of DCI in case of retransmission
} /*TODO: Must add these */
// eNB_UE_stats->dlsch_trials[round]++;
// If we need a 1 or 2 bit padding or no padding at all //UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission+=1;
if ((TBS - header_len - sdu_length_total - ta_len) <= 2 //UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx=nb_rb;
|| (TBS - header_len - sdu_length_total - ta_len) > TBS) { //protect from overflow //UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_retx+=nb_rb;
padding = (TBS - header_len - sdu_length_total - ta_len); //UE_list->eNB_UE_stats[CC_id][UE_id].ncce_used_retx=nCCECC_id];
post_padding = 0;
} else { // The last sdu needs to have a length field, since we add padding
padding = 0;
header_len = header_len_tmp;
post_padding = TBS - sdu_length_total - header_len - ta_len; // 1 is for the postpadding header
}
if (ta_len > 0) {
// Reset the measurement
ta_update = flexran_get_TA(mod_id, UE_id, CC_id);
ue_sched_ctl->ta_timer = 20;
eNB_UE_stats->timing_advance_update = 0;
} else {
ta_update = 0;
} }
// If there is nothing to schedule, just leave // UE_list->UE_template[CC_id][UE_id].oldNDI[dl_dci->harq_process] = dl_dci->ndi[0];
if ((sdu_length_total) <= 0) { // eNB_UE_stats->dlsch_mcs1 = dl_dci->mcs[0];
harq_pid_updated[UE_id][harq_pid] = 1;
harq_pid_round[UE_id][harq_pid] = 0;
continue;
}
// LOG_I(FLEXRAN_AGENT, "[Frame %d][Subframe %d] TBS is %d and bytes are %d\n", frame, subframe, TBS, sdu_length_total); //Fill the proper DCI of OAI
flexran_fill_oai_dci(mod_id, CC_id, rnti, dl_dci);
offset = generate_dlsch_header((unsigned char*)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], }
num_sdus, //num_sdus }
sdu_lengths, //
sdu_lcids,
255, // no drx
ta_update, // timing advance
NULL, // contention res id
padding,
post_padding);
void
flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti,
Protocol__FlexDlDci * dl_dci)
{
void *DLSCH_dci = NULL;
DCI_PDU *DCI_pdu;
unsigned char harq_pid = 0;
#ifdef DEBUG_eNB_SCHEDULER // unsigned char round = 0;
LOG_T(MAC,"[eNB %d] First 16 bytes of DLSCH : \n"); LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs];
int size_bits = 0, size_bytes = 0;
for (i=0; i<16; i++) { eNB_MAC_INST *eNB = &eNB_mac_inst[mod_id];
LOG_T(MAC,"%x.",dlsch_buffer[i]); UE_list_t *UE_list = &eNB->UE_list;
LTE_eNB_UE_stats *eNB_UE_stats = NULL;
int UE_id = find_ue(rnti, PHY_vars_eNB_g[mod_id][CC_id]);
uint32_t format;
harq_pid = dl_dci->harq_process;
// round = dl_dci->rv[0];
// Note this code is for a specific DCI format
DLSCH_dci =
(void *) UE_list->UE_template[CC_id][UE_id].DLSCH_DCI[harq_pid];
DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu;
frame_parms[CC_id] = mac_xface->get_lte_frame_parms(mod_id, CC_id);
if (dl_dci->has_tpc == 1) {
// Check if tpc has been set and reset measurement */
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->Po_PUCCH_update = 0;
} }
}
LOG_T(MAC,"\n");
#endif
// cycle through SDUs and place in dlsch_buffer switch (frame_parms[CC_id]->N_RB_DL) {
memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset],dlsch_buffer,sdu_length_total); case 6:
// memcpy(&eNB_mac_inst[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); if (frame_parms[CC_id]->frame_type == TDD) {
if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
// fill remainder of DLSCH with random data FILL_DCI_TDD_1(DCI1_1_5MHz_TDD_t, DLSCH_dci, dl_dci);
for (j=0; j<(TBS-sdu_length_total-offset); j++) { size_bytes = sizeof(DCI1_1_5MHz_TDD_t);
UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset+sdu_length_total+j] = (char)(taus()&0xff); size_bits = sizeof_DCI1_1_5MHz_TDD_t;
} else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
//TODO
} else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
//TODO
}
} else {
if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
FILL_DCI_FDD_1(DCI1_1_5MHz_FDD_t, DLSCH_dci, dl_dci);
size_bytes = 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) {
//TODO
} else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
//TODO
}
}
break;
case 25:
if (frame_parms[CC_id]->frame_type == TDD) {
if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
FILL_DCI_TDD_1(DCI1_5MHz_TDD_t, DLSCH_dci, dl_dci);
size_bytes = sizeof(DCI1_5MHz_TDD_t);
size_bits = sizeof_DCI1_5MHz_TDD_t;
} else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
//TODO
} else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
//TODO
}
} else {
if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
FILL_DCI_FDD_1(DCI1_5MHz_FDD_t, DLSCH_dci, dl_dci);
size_bytes = sizeof(DCI1_5MHz_FDD_t);
size_bits = sizeof_DCI1_5MHz_FDD_t;
} else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
//TODO
} else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
//TODO
}
} }
break;
//eNB_mac_inst[0].DLSCH_pdu[0][0].payload[0][offset+sdu_lengths[0]+j] = (char)(taus()&0xff); case 50:
if (opt_enabled == 1) { if (frame_parms[CC_id]->frame_type == TDD) {
trace_pdu(1, (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
TBS, mod_id, 3, UE_RNTI(mod_id, UE_id), FILL_DCI_TDD_1(DCI1_10MHz_TDD_t, DLSCH_dci, dl_dci);
eNB->frame, eNB->subframe,0,0); size_bytes = sizeof(DCI1_10MHz_TDD_t);
LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", size_bits = sizeof_DCI1_10MHz_TDD_t;
mod_id, CC_id, frame, UE_RNTI(mod_id,UE_id), TBS); } else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
//TODO
} else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
//TODO
}
} else {
if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
FILL_DCI_FDD_1(DCI1_10MHz_FDD_t, DLSCH_dci, dl_dci);
size_bytes = sizeof(DCI1_10MHz_FDD_t);
size_bits = sizeof_DCI1_10MHz_FDD_t;
} else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
//TODO
} else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
//TODO
}
} }
break;
// store stats case 100:
eNB->eNB_stats[CC_id].dlsch_bytes_tx+=sdu_length_total; if (frame_parms[CC_id]->frame_type == TDD) {
eNB->eNB_stats[CC_id].dlsch_pdus_tx+=1; if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->DL_cqi[0]; FILL_DCI_TDD_1(DCI1_20MHz_TDD_t, DLSCH_dci, dl_dci);
size_bytes = sizeof(DCI1_20MHz_TDD_t);
UE_list->eNB_UE_stats[CC_id][UE_id].crnti= rnti; size_bits = sizeof_DCI1_20MHz_TDD_t;
UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status=mac_eNB_get_rrc_status(mod_id, rnti); } else if (dl_dci->format ==
UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round; //TODO
} else if (dl_dci->format ==
//nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
//Find the number of resource blocks and set them to the template for retransmissions //TODO
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); } else {
if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
while (stats_tbs < TBS) { FILL_DCI_FDD_1(DCI1_20MHz_FDD_t, DLSCH_dci, dl_dci);
nb_rb += get_min_rb_unit(mod_id, CC_id); size_bytes = sizeof(DCI1_20MHz_FDD_t);
stats_tbs = mac_xface->get_TBS_DL(dl_dci->mcs[0], nb_rb); size_bits = sizeof_DCI1_20MHz_FDD_t;
} else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
//TODO
} else if (dl_dci->format ==
PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
//TODO
}
} }
break;
// 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].total_rbs_used += nb_rb;
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].overhead_bytes= TBS - sdu_length_total;
UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes+= sdu_length_total;
UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes+= TBS;
UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus+=1;
//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);
} else {
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_round[UE_id][harq_pid] = 0;
continue;
}
} else {
// No need to create anything apart of DCI in case of retransmission
/*TODO: Must add these */
// eNB_UE_stats->dlsch_trials[round]++;
//UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission+=1;
//UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx=nb_rb;
//UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_retx+=nb_rb;
//UE_list->eNB_UE_stats[CC_id][UE_id].ncce_used_retx=nCCECC_id];
} }
// UE_list->UE_template[CC_id][UE_id].oldNDI[dl_dci->harq_process] = dl_dci->ndi[0]; //Set format to the proper type
// eNB_UE_stats->dlsch_mcs1 = dl_dci->mcs[0]; switch (dl_dci->format) {
case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1:
//Fill the proper DCI of OAI format = format1;
flexran_fill_oai_dci(mod_id, CC_id, rnti, dl_dci); break;
} case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1A:
} format = format1A;
void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti, break;
Protocol__FlexDlDci *dl_dci) { case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1B:
format = format1B;
void *DLSCH_dci = NULL; break;
DCI_PDU *DCI_pdu; case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1C:
format = format1C;
unsigned char harq_pid = 0; break;
// unsigned char round = 0; case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D:
LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; format = format1E_2A_M10PRB;
int size_bits = 0, size_bytes = 0; break;
eNB_MAC_INST *eNB = &eNB_mac_inst[mod_id]; case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2:
UE_list_t *UE_list = &eNB->UE_list; format = format2;
LTE_eNB_UE_stats *eNB_UE_stats = NULL; break;
case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A:
int UE_id = find_ue(rnti, PHY_vars_eNB_g[mod_id][CC_id]); format = format2A;
break;
uint32_t format; case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2B:
format = format2B;
harq_pid = dl_dci->harq_process; break;
// round = dl_dci->rv[0]; case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_3:
format = 3;
// Note this code is for a specific DCI format break;
DLSCH_dci = (void *)UE_list->UE_template[CC_id][UE_id].DLSCH_DCI[harq_pid]; default:
DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu; /*TODO: Need to deal with unsupported DCI type */
return;
frame_parms[CC_id] = mac_xface->get_lte_frame_parms(mod_id, CC_id);
if (dl_dci->has_tpc == 1) {
// Check if tpc has been set and reset measurement */
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->Po_PUCCH_update = 0;
}
}
switch (frame_parms[CC_id]->N_RB_DL) {
case 6:
if (frame_parms[CC_id]->frame_type == TDD) {
if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
FILL_DCI_TDD_1(DCI1_1_5MHz_TDD_t, DLSCH_dci, dl_dci);
size_bytes = 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) {
//TODO
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
//TODO
}
} else {
if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
FILL_DCI_FDD_1(DCI1_1_5MHz_FDD_t, DLSCH_dci, dl_dci);
size_bytes = 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) {
//TODO
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
//TODO
}
}
break;
case 25:
if (frame_parms[CC_id]->frame_type == TDD) {
if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
FILL_DCI_TDD_1(DCI1_5MHz_TDD_t, DLSCH_dci, dl_dci);
size_bytes = sizeof(DCI1_5MHz_TDD_t);
size_bits = sizeof_DCI1_5MHz_TDD_t;
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
//TODO
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
//TODO
}
} else {
if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
FILL_DCI_FDD_1(DCI1_5MHz_FDD_t, DLSCH_dci, dl_dci);
size_bytes = sizeof(DCI1_5MHz_FDD_t);
size_bits = sizeof_DCI1_5MHz_FDD_t;
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
//TODO
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
//TODO
}
} }
break;
case 50: add_ue_spec_dci(DCI_pdu,
if (frame_parms[CC_id]->frame_type == TDD) { DLSCH_dci,
if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) { rnti,
FILL_DCI_TDD_1(DCI1_10MHz_TDD_t, DLSCH_dci, dl_dci); size_bytes, dl_dci->aggr_level, size_bits, format, 0);
size_bytes = sizeof(DCI1_10MHz_TDD_t);
size_bits = sizeof_DCI1_10MHz_TDD_t;
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
//TODO
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
//TODO
}
} else {
if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
FILL_DCI_FDD_1(DCI1_10MHz_FDD_t, DLSCH_dci, dl_dci);
size_bytes = sizeof(DCI1_10MHz_FDD_t);
size_bits = sizeof_DCI1_10MHz_FDD_t;
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
//TODO
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
//TODO
}
}
break;
case 100:
if (frame_parms[CC_id]->frame_type == TDD) {
if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
FILL_DCI_TDD_1(DCI1_20MHz_TDD_t, DLSCH_dci, dl_dci);
size_bytes = sizeof(DCI1_20MHz_TDD_t);
size_bits = sizeof_DCI1_20MHz_TDD_t;
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
//TODO
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
//TODO
}
} else {
if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
FILL_DCI_FDD_1(DCI1_20MHz_FDD_t, DLSCH_dci, dl_dci);
size_bytes = sizeof(DCI1_20MHz_FDD_t);
size_bits = sizeof_DCI1_20MHz_FDD_t;
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
//TODO
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
//TODO
}
}
break;
}
//Set format to the proper type
switch(dl_dci->format) {
case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1:
format = format1;
break;
case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1A:
format = format1A;
break;
case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1B:
format = format1B;
break;
case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1C:
format = format1C;
break;
case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D:
format = format1E_2A_M10PRB;
break;
case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2:
format = format2;
break;
case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A:
format = format2A;
break;
case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2B:
format = format2B;
break;
case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_3:
format = 3;
break;
default:
/*TODO: Need to deal with unsupported DCI type*/
return;
}
add_ue_spec_dci(DCI_pdu,
DLSCH_dci,
rnti,
size_bytes,
dl_dci->aggr_level,
size_bits,
format,
0);
} }
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
*------------------------------------------------------------------------------- *-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance: * For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org * contact@openairinterface.org
*/ */
/*! \file flexran_agent_scheduler_dlsch_ue_remote.c /*! \file flexran_agent_scheduler_dlsch_ue_remote.c
* \brief procedures related to remote scheduling in the DLSCH transport channel * \brief procedures related to remote scheduling in the DLSCH transport channel
...@@ -44,137 +44,159 @@ int queue_initialized = 0; ...@@ -44,137 +44,159 @@ 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)) { {
// LOG_I(MAC, "Will skip subframe %d %d\n", subframe, frame);
// for (int i = 0; i < 3; i++) {
// LOG_I(MAC, "%d\n", sched[i]); //if ((subframe == skip_subframe) && (frame % period == 0)) {
// } // LOG_I(MAC, "Will skip subframe %d %d\n", subframe, frame);
//} // for (int i = 0; i < 3; i++) {
// LOG_I(MAC, "%d\n", sched[i]);
/* if (frame == 500 && subframe == 1) { */ // }
/* char policy[] = "rrc: \n - ul_scheduler: \n behavior : tester_function\n parameters:\n period: !!int 3\nmac: \n - dl_scheduler: \n parameters: \n period : !!int 40\n skip_subframe : !!int 3\n sched : [!!int 4, !!int 5, !!int 6]"; */ //}
/* apply_reconfiguration_policy(mod_id, policy, strlen(policy)); */
/* } */ /* if (frame == 500 && subframe == 1) { */
/* char policy[] = "rrc: \n - ul_scheduler: \n behavior : tester_function\n parameters:\n period: !!int 3\nmac: \n - dl_scheduler: \n parameters: \n period : !!int 40\n skip_subframe : !!int 3\n sched : [!!int 4, !!int 5, !!int 6]"; */
eNB_MAC_INST *eNB; /* apply_reconfiguration_policy(mod_id, policy, strlen(policy)); */
/* } */
if (!queue_initialized) {
TAILQ_INIT(&queue_head); eNB_MAC_INST *eNB;
queue_initialized = 1;
} if (!queue_initialized) {
TAILQ_INIT(&queue_head);
eNB = &eNB_mac_inst[mod_id]; queue_initialized = 1;
dl_mac_config_element_t *dl_config_elem;
int diff;
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
while(queue_head.tqh_first != NULL) {
dl_config_elem = queue_head.tqh_first;
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
if ( diff == 0) { // Now
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);
*dl_info = dl_config_elem->dl_info;
free(dl_config_elem);
eNB->eNB_stats[mod_id].sched_decisions++;
return;
} 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");
TAILQ_REMOVE(&queue_head, queue_head.tqh_first, configs);
flexran_agent_mac_destroy_dl_config(dl_config_elem->dl_info);
free(dl_config_elem);
eNB->eNB_stats[mod_id].sched_decisions++;
eNB->eNB_stats[mod_id].missed_deadlines++;
} 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");
flexran_agent_mac_create_empty_dl_config(mod_id, dl_info);
return;
} }
}
eNB = &eNB_mac_inst[mod_id];
//Done with the local cache. Now we need to check if something new arrived
flexran_agent_get_pending_dl_mac_config(mod_id, dl_info); dl_mac_config_element_t *dl_config_elem;
while (*dl_info != NULL) {
int diff;
diff = get_sf_difference(mod_id, (*dl_info)->dl_mac_config_msg->sfn_sf); LOG_D(MAC, "[TEST] Current frame and subframe %d, %d\n", frame,
if (diff == 0) { // Got a command for this sfn_sf subframe);
LOG_D(MAC, "Found a decision for this subframe pending. Let's use it\n"); // First we check to see if we have a scheduling decision for this sfn_sf already in our queue
eNB->eNB_stats[mod_id].sched_decisions++; while (queue_head.tqh_first != NULL) {
return; dl_config_elem = queue_head.tqh_first;
} else if (diff < 0) {
LOG_D(MAC, "Found a decision for a previous subframe. Let's get rid of it\n"); diff =
flexran_agent_mac_destroy_dl_config(*dl_info); get_sf_difference(mod_id,
*dl_info = NULL; dl_config_elem->dl_info->
flexran_agent_get_pending_dl_mac_config(mod_id, dl_info); dl_mac_config_msg->sfn_sf);
eNB->eNB_stats[mod_id].sched_decisions++; // Check if this decision is for now, for a later or a previous subframe
eNB->eNB_stats[mod_id].missed_deadlines++; if (diff == 0) { // Now
} else { // Intended for future subframe. Store it in local cache LOG_D(MAC,
LOG_D(MAC, "Found a decision for a future subframe in the queue. Let's store it in the cache\n"); "Found a decision for this subframe in the queue. Let's use it!\n");
dl_mac_config_element_t *e = malloc(sizeof(dl_mac_config_element_t)); TAILQ_REMOVE(&queue_head, queue_head.tqh_first, configs);
e->dl_info = *dl_info; *dl_info = dl_config_elem->dl_info;
TAILQ_INSERT_TAIL(&queue_head, e, configs); free(dl_config_elem);
flexran_agent_mac_create_empty_dl_config(mod_id, dl_info); eNB->eNB_stats[mod_id].sched_decisions++;
// No need to look for another. Messages arrive ordered return;
return; } 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");
TAILQ_REMOVE(&queue_head, queue_head.tqh_first, configs);
flexran_agent_mac_destroy_dl_config(dl_config_elem->dl_info);
free(dl_config_elem);
eNB->eNB_stats[mod_id].sched_decisions++;
eNB->eNB_stats[mod_id].missed_deadlines++;
} 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");
flexran_agent_mac_create_empty_dl_config(mod_id, dl_info);
return;
}
} }
}
//Done with the local cache. Now we need to check if something new arrived
// We found no pending command, so we will simply pass an empty one flexran_agent_get_pending_dl_mac_config(mod_id, dl_info);
flexran_agent_mac_create_empty_dl_config(mod_id, dl_info); while (*dl_info != NULL) {
diff =
get_sf_difference(mod_id,
(*dl_info)->dl_mac_config_msg->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");
eNB->eNB_stats[mod_id].sched_decisions++;
return;
} else if (diff < 0) {
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);
*dl_info = NULL;
flexran_agent_get_pending_dl_mac_config(mod_id, dl_info);
eNB->eNB_stats[mod_id].sched_decisions++;
eNB->eNB_stats[mod_id].missed_deadlines++;
} 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");
dl_mac_config_element_t *e =
malloc(sizeof(dl_mac_config_element_t));
e->dl_info = *dl_info;
TAILQ_INSERT_TAIL(&queue_head, e, configs);
flexran_agent_mac_create_empty_dl_config(mod_id, dl_info);
// No need to look for another. Messages arrive ordered
return;
}
}
// We found no pending command, so we will simply pass an empty one
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_subframe = flexran_get_current_subframe(mod_id); uint16_t current_frame = flexran_get_current_system_frame_num(mod_id);
uint32_t current_sfn_sf = flexran_get_sfn_sf(mod_id); uint16_t current_subframe = flexran_get_current_subframe(mod_id);
uint32_t current_sfn_sf = flexran_get_sfn_sf(mod_id);
if (sfn_sf == current_sfn_sf) {
return 0; if (sfn_sf == current_sfn_sf) {
} return 0;
uint16_t frame_mask = ((1<<12) - 1);
uint16_t frame = (sfn_sf & (frame_mask << 4)) >> 4;
uint16_t sf_mask = ((1<<4) - 1);
uint16_t subframe = (sfn_sf & sf_mask);
LOG_D(MAC, "[TEST] Target frame and subframe %d, %d\n", frame, subframe);
if (frame == current_frame) {
return subframe - current_subframe;
} else if (frame > current_frame) {
diff_in_subframes = ((frame*10)+subframe) - ((current_frame*10)+current_subframe);
// diff_in_subframes = 9 - current_subframe;
//diff_in_subframes += (subframe + 1);
//diff_in_subframes += (frame-2) * 10;
if (diff_in_subframes > SCHED_AHEAD_SUBFRAMES) {
return -1;
} else {
return 1;
} }
} else { //frame < current_frame
//diff_in_subframes = 9 - current_subframe; uint16_t frame_mask = ((1 << 12) - 1);
//diff_in_subframes += (subframe + 1); uint16_t frame = (sfn_sf & (frame_mask << 4)) >> 4;
//if (frame > 0) {
// diff_in_subframes += (frame - 1) * 10; uint16_t sf_mask = ((1 << 4) - 1);
//} uint16_t subframe = (sfn_sf & sf_mask);
//diff_in_subframes += (1023 - current_frame) * 10;
diff_in_subframes = 10240 - ((current_frame*10)+current_subframe) + ((frame*10)+subframe); LOG_D(MAC, "[TEST] Target frame and subframe %d, %d\n", frame,
if (diff_in_subframes > SCHED_AHEAD_SUBFRAMES) { subframe);
return -1;
} else { if (frame == current_frame) {
return 1; return subframe - current_subframe;
} else if (frame > current_frame) {
diff_in_subframes =
((frame * 10) + subframe) - ((current_frame * 10) +
current_subframe);
// diff_in_subframes = 9 - current_subframe;
//diff_in_subframes += (subframe + 1);
//diff_in_subframes += (frame-2) * 10;
if (diff_in_subframes > SCHED_AHEAD_SUBFRAMES) {
return -1;
} else {
return 1;
}
} else { //frame < current_frame
//diff_in_subframes = 9 - current_subframe;
//diff_in_subframes += (subframe + 1);
//if (frame > 0) {
// diff_in_subframes += (frame - 1) * 10;
//}
//diff_in_subframes += (1023 - current_frame) * 10;
diff_in_subframes =
10240 - ((current_frame * 10) + current_subframe) +
((frame * 10) + subframe);
if (diff_in_subframes > SCHED_AHEAD_SUBFRAMES) {
return -1;
} else {
return 1;
}
} }
}
} }
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
*------------------------------------------------------------------------------- *-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance: * For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org * contact@openairinterface.org
*/ */
/*! \file flexran_agent_scheduler_dlsch_ue_remote.h /*! \file flexran_agent_scheduler_dlsch_ue_remote.h
* \brief Local stub for remote scheduler used by the controller * \brief Local stub for remote scheduler used by the controller
...@@ -46,8 +46,8 @@ ...@@ -46,8 +46,8 @@
#define SCHED_AHEAD_SUBFRAMES 20 #define SCHED_AHEAD_SUBFRAMES 20
typedef struct dl_mac_config_element_s { typedef struct dl_mac_config_element_s {
Protocol__FlexranMessage *dl_info; Protocol__FlexranMessage *dl_info;
TAILQ_ENTRY(dl_mac_config_element_s) configs; TAILQ_ENTRY(dl_mac_config_element_s) configs;
} dl_mac_config_element_t; } dl_mac_config_element_t;
TAILQ_HEAD(DlMacConfigHead, dl_mac_config_element_s); TAILQ_HEAD(DlMacConfigHead, dl_mac_config_element_s);
...@@ -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
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
*------------------------------------------------------------------------------- *-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance: * For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org * contact@openairinterface.org
*/ */
/*! \file flexran_dci_conversions.h /*! \file flexran_dci_conversions.h
* \brief Conversion helpers from flexran messages to OAI formats DCI * \brief Conversion helpers from flexran messages to OAI formats DCI
...@@ -47,5 +47,5 @@ ...@@ -47,5 +47,5 @@
((TYPE*)DCI)->mcs = FLEXRAN_DCI->mcs[0]; \ ((TYPE*)DCI)->mcs = FLEXRAN_DCI->mcs[0]; \
((TYPE*)DCI)->TPC = FLEXRAN_DCI->tpc; \ ((TYPE*)DCI)->TPC = FLEXRAN_DCI->tpc; \
((TYPE*)DCI)->ndi = FLEXRAN_DCI->ndi[0]; ((TYPE*)DCI)->ndi = FLEXRAN_DCI->ndi[0];
#endif #endif
...@@ -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));
} }
...@@ -29,104 +29,104 @@ ...@@ -29,104 +29,104 @@
void init_transport_channels(unsigned char transmission_mode) void init_transport_channels(unsigned char transmission_mode)
{ {
// init DCI structures for testing // init DCI structures for testing
UL_alloc_pdu.type = 0; UL_alloc_pdu.type = 0;
UL_alloc_pdu.hopping = 0; UL_alloc_pdu.hopping = 0;
UL_alloc_pdu.rballoc = UL_RB_ALLOC; UL_alloc_pdu.rballoc = UL_RB_ALLOC;
UL_alloc_pdu.mcs = 2; UL_alloc_pdu.mcs = 2;
UL_alloc_pdu.ndi = 1; UL_alloc_pdu.ndi = 1;
UL_alloc_pdu.TPC = 0; UL_alloc_pdu.TPC = 0;
UL_alloc_pdu.cqi_req = 1; UL_alloc_pdu.cqi_req = 1;
/* /*
BCCH_alloc_pdu.type = 1; BCCH_alloc_pdu.type = 1;
BCCH_alloc_pdu.vrb_type = 0; BCCH_alloc_pdu.vrb_type = 0;
BCCH_alloc_pdu.rballoc = BCCH_RB_ALLOC; BCCH_alloc_pdu.rballoc = BCCH_RB_ALLOC;
BCCH_alloc_pdu.ndi = 1; BCCH_alloc_pdu.ndi = 1;
BCCH_alloc_pdu.rv = 1; BCCH_alloc_pdu.rv = 1;
BCCH_alloc_pdu.mcs = 1; BCCH_alloc_pdu.mcs = 1;
BCCH_alloc_pdu.harq_pid = 0; BCCH_alloc_pdu.harq_pid = 0;
BCCH_alloc_pdu.TPC = 1; // set to 3 PRB BCCH_alloc_pdu.TPC = 1; // set to 3 PRB
// for FDD mode // for FDD mode
BCCH_alloc_pdu_fdd.type = 1; BCCH_alloc_pdu_fdd.type = 1;
BCCH_alloc_pdu_fdd.vrb_type = 0; BCCH_alloc_pdu_fdd.vrb_type = 0;
BCCH_alloc_pdu_fdd.rballoc = BCCH_RB_ALLOC; BCCH_alloc_pdu_fdd.rballoc = BCCH_RB_ALLOC;
BCCH_alloc_pdu_fdd.ndi = 1; BCCH_alloc_pdu_fdd.ndi = 1;
BCCH_alloc_pdu_fdd.rv = 1; BCCH_alloc_pdu_fdd.rv = 1;
BCCH_alloc_pdu_fdd.mcs = 1; BCCH_alloc_pdu_fdd.mcs = 1;
BCCH_alloc_pdu_fdd.harq_pid = 0; BCCH_alloc_pdu_fdd.harq_pid = 0;
BCCH_alloc_pdu_fdd.TPC = 1; // set to 3 PRB BCCH_alloc_pdu_fdd.TPC = 1; // set to 3 PRB
*/ */
DLSCH_alloc_pdu1A.type = 1; DLSCH_alloc_pdu1A.type = 1;
DLSCH_alloc_pdu1A.vrb_type = 0; DLSCH_alloc_pdu1A.vrb_type = 0;
DLSCH_alloc_pdu1A.rballoc = BCCH_RB_ALLOC; DLSCH_alloc_pdu1A.rballoc = BCCH_RB_ALLOC;
DLSCH_alloc_pdu1A.ndi = 1; DLSCH_alloc_pdu1A.ndi = 1;
DLSCH_alloc_pdu1A.rv = 1; DLSCH_alloc_pdu1A.rv = 1;
DLSCH_alloc_pdu1A.mcs = 2; DLSCH_alloc_pdu1A.mcs = 2;
DLSCH_alloc_pdu1A.harq_pid = 0; DLSCH_alloc_pdu1A.harq_pid = 0;
DLSCH_alloc_pdu1A.TPC = 1; // set to 3 PRB DLSCH_alloc_pdu1A.TPC = 1; // set to 3 PRB
DLSCH_alloc_pdu1A_fdd.type = 1; DLSCH_alloc_pdu1A_fdd.type = 1;
DLSCH_alloc_pdu1A_fdd.vrb_type = 0; DLSCH_alloc_pdu1A_fdd.vrb_type = 0;
DLSCH_alloc_pdu1A_fdd.rballoc = BCCH_RB_ALLOC; DLSCH_alloc_pdu1A_fdd.rballoc = BCCH_RB_ALLOC;
DLSCH_alloc_pdu1A_fdd.ndi = 1; DLSCH_alloc_pdu1A_fdd.ndi = 1;
DLSCH_alloc_pdu1A_fdd.rv = 1; DLSCH_alloc_pdu1A_fdd.rv = 1;
DLSCH_alloc_pdu1A_fdd.mcs = 2; DLSCH_alloc_pdu1A_fdd.mcs = 2;
DLSCH_alloc_pdu1A_fdd.harq_pid = 0; DLSCH_alloc_pdu1A_fdd.harq_pid = 0;
DLSCH_alloc_pdu1A_fdd.TPC = 1; // set to 3 PRB DLSCH_alloc_pdu1A_fdd.TPC = 1; // set to 3 PRB
RA_alloc_pdu.type = 1; RA_alloc_pdu.type = 1;
RA_alloc_pdu.vrb_type = 0; RA_alloc_pdu.vrb_type = 0;
RA_alloc_pdu.rballoc = RA_RB_ALLOC; RA_alloc_pdu.rballoc = RA_RB_ALLOC;
RA_alloc_pdu.ndi = 1; RA_alloc_pdu.ndi = 1;
RA_alloc_pdu.rv = 0; RA_alloc_pdu.rv = 0;
RA_alloc_pdu.mcs = 0; RA_alloc_pdu.mcs = 0;
RA_alloc_pdu.harq_pid = 0; RA_alloc_pdu.harq_pid = 0;
RA_alloc_pdu.TPC = 1; RA_alloc_pdu.TPC = 1;
RA_alloc_pdu_fdd.type = 1; RA_alloc_pdu_fdd.type = 1;
RA_alloc_pdu_fdd.vrb_type = 0; RA_alloc_pdu_fdd.vrb_type = 0;
RA_alloc_pdu_fdd.rballoc = RA_RB_ALLOC; RA_alloc_pdu_fdd.rballoc = RA_RB_ALLOC;
RA_alloc_pdu_fdd.ndi = 1; RA_alloc_pdu_fdd.ndi = 1;
RA_alloc_pdu_fdd.rv = 1; RA_alloc_pdu_fdd.rv = 1;
RA_alloc_pdu_fdd.mcs = 1; RA_alloc_pdu_fdd.mcs = 1;
RA_alloc_pdu_fdd.harq_pid = 0; RA_alloc_pdu_fdd.harq_pid = 0;
RA_alloc_pdu_fdd.TPC = 1; RA_alloc_pdu_fdd.TPC = 1;
DLSCH_alloc_pdu1.rballoc = 0xf; DLSCH_alloc_pdu1.rballoc = 0xf;
DLSCH_alloc_pdu1.TPC = 0; DLSCH_alloc_pdu1.TPC = 0;
DLSCH_alloc_pdu1.dai = 0; DLSCH_alloc_pdu1.dai = 0;
DLSCH_alloc_pdu1.harq_pid = 0; DLSCH_alloc_pdu1.harq_pid = 0;
DLSCH_alloc_pdu1.tb_swap = 0; DLSCH_alloc_pdu1.tb_swap = 0;
DLSCH_alloc_pdu1.mcs1 = 4; DLSCH_alloc_pdu1.mcs1 = 4;
DLSCH_alloc_pdu1.ndi1 = 1; DLSCH_alloc_pdu1.ndi1 = 1;
DLSCH_alloc_pdu1.rv1 = 0; DLSCH_alloc_pdu1.rv1 = 0;
// Forget second codeword // Forget second codeword
if (transmission_mode == 6) { if (transmission_mode == 6) {
DLSCH_alloc_pdu1.tpmi = 5; // PUSCH_PRECODING0 DLSCH_alloc_pdu1.tpmi = 5; // PUSCH_PRECODING0
} else { } else {
DLSCH_alloc_pdu1.tpmi = 0; DLSCH_alloc_pdu1.tpmi = 0;
} }
DLSCH_alloc_pdu2.rah = 0; DLSCH_alloc_pdu2.rah = 0;
DLSCH_alloc_pdu2.rballoc = DLSCH_RB_ALLOC; DLSCH_alloc_pdu2.rballoc = DLSCH_RB_ALLOC;
DLSCH_alloc_pdu2.TPC = 0; DLSCH_alloc_pdu2.TPC = 0;
DLSCH_alloc_pdu2.dai = 0; DLSCH_alloc_pdu2.dai = 0;
DLSCH_alloc_pdu2.harq_pid = 0; DLSCH_alloc_pdu2.harq_pid = 0;
DLSCH_alloc_pdu2.tb_swap = 0; DLSCH_alloc_pdu2.tb_swap = 0;
DLSCH_alloc_pdu2.mcs1 = 4; DLSCH_alloc_pdu2.mcs1 = 4;
DLSCH_alloc_pdu2.ndi1 = 1; DLSCH_alloc_pdu2.ndi1 = 1;
DLSCH_alloc_pdu2.rv1 = 0; DLSCH_alloc_pdu2.rv1 = 0;
// Forget second codeword // Forget second codeword
if (transmission_mode == 6) { if (transmission_mode == 6) {
DLSCH_alloc_pdu2.tpmi = 5; // PUSCH_PRECODING0 DLSCH_alloc_pdu2.tpmi = 5; // PUSCH_PRECODING0
} else { } else {
DLSCH_alloc_pdu2.tpmi = 0; DLSCH_alloc_pdu2.tpmi = 0;
} }
} }
...@@ -48,66 +48,72 @@ ...@@ -48,66 +48,72 @@
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 {
UE_mac_inst = NULL;
} }
} else {
UE_mac_inst = NULL;
}
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");
return(0); LOG_I(MAC, "[MAIN][INIT] Init function finished\n");
return (0);
} }
...@@ -115,183 +121,107 @@ int mac_top_init_ue(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, ...@@ -115,183 +121,107 @@ 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) {
RC.mac = (eNB_MAC_INST**)malloc16(RC.nb_macrlc_inst*sizeof(eNB_MAC_INST*)); if (RC.nb_macrlc_inst > 0) {
AssertFatal(RC.mac != NULL,"can't ALLOCATE %zu Bytes for %d eNB_MAC_INST with size %zu \n", RC.mac =
RC.nb_macrlc_inst*sizeof(eNB_MAC_INST*), (eNB_MAC_INST **) malloc16(RC.nb_macrlc_inst *
RC.nb_macrlc_inst, sizeof(eNB_MAC_INST *));
sizeof(eNB_MAC_INST)); AssertFatal(RC.mac != NULL,
for (i=0;i<RC.nb_macrlc_inst;i++) { "can't ALLOCATE %zu Bytes for %d eNB_MAC_INST with size %zu \n",
RC.mac[i] = (eNB_MAC_INST*)malloc16(sizeof(eNB_MAC_INST)); RC.nb_macrlc_inst * sizeof(eNB_MAC_INST *),
AssertFatal(RC.mac != NULL, RC.nb_macrlc_inst, 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.nb_macrlc_inst,sizeof(eNB_MAC_INST)); RC.mac[i] = (eNB_MAC_INST *) malloc16(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); AssertFatal(RC.mac != NULL,
bzero(RC.mac[i],sizeof(eNB_MAC_INST)); "can't ALLOCATE %zu Bytes for %d eNB_MAC_INST with size %zu \n",
RC.mac[i]->Mod_id = i; RC.nb_macrlc_inst * sizeof(eNB_MAC_INST *),
for (j=0;j<MAX_NUM_CCs;j++) { RC.nb_macrlc_inst, sizeof(eNB_MAC_INST));
RC.mac[i]->DL_req[j].dl_config_request_body.dl_config_pdu_list = RC.mac[i]->dl_config_pdu_list[j]; LOG_D(MAC,
RC.mac[i]->UL_req[j].ul_config_request_body.ul_config_pdu_list = RC.mac[i]->ul_config_pdu_list[j]; "[MAIN] ALLOCATE %zu Bytes for %d eNB_MAC_INST @ %p\n",
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]; sizeof(eNB_MAC_INST), RC.nb_macrlc_inst, RC.mac);
RC.mac[i]->HI_DCI0_req[j].hi_dci0_request_body.hi_dci0_pdu_list = RC.mac[i]->hi_dci0_pdu_list[j]; bzero(RC.mac[i], sizeof(eNB_MAC_INST));
RC.mac[i]->TX_req[j].tx_request_body.tx_pdu_list = RC.mac[i]->tx_request_pdu[j]; RC.mac[i]->Mod_id = i;
RC.mac[i]->ul_handle = 0; 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]->UL_req[j].ul_config_request_body.
ul_config_pdu_list = RC.mac[i]->ul_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]->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;
}
}
AssertFatal(rlc_module_init() == 0,
"Could not initialize RLC layer\n");
// These should be out of here later
pdcp_layer_init();
rrc_init_global_param();
} else {
RC.mac = NULL;
} }
AssertFatal(rlc_module_init()==0,"Could not initialize RLC layer\n"); // Initialize Linked-List for Active UEs
for (i = 0; i < RC.nb_macrlc_inst; i++) {
mac = RC.mac[i];
// These should be out of here later
pdcp_layer_init ();
rrc_init_global_param(); mac->if_inst = IF_Module_init(i);
} else { UE_list = &mac->UE_list;
RC.mac = NULL;
}
// Initialize Linked-List for Active UEs
for(i=0; i<RC.nb_macrlc_inst; i++) {
mac = RC.mac[i];
UE_list->num_UEs = 0;
UE_list->head = -1;
UE_list->head_ul = -1;
UE_list->avail = 0;
mac->if_inst = IF_Module_init(i); for (list_el = 0; list_el < NUMBER_OF_UE_MAX - 1; list_el++) {
UE_list->next[list_el] = list_el + 1;
UE_list->next_ul[list_el] = list_el + 1;
}
UE_list = &mac->UE_list; UE_list->next[list_el] = -1;
UE_list->next_ul[list_el] = -1;
}
UE_list->num_UEs=0; }
UE_list->head=-1;
UE_list->head_ul=-1;
UE_list->avail=0;
for (list_el=0; list_el<NUMBER_OF_UE_MAX-1; list_el++) { void mac_init_cell_params(int Mod_idP, int CC_idP)
UE_list->next[list_el]=list_el+1; {
UE_list->next_ul[list_el]=list_el+1;
}
UE_list->next[list_el]=-1; int j;
UE_list->next_ul[list_el]=-1; UE_TEMPLATE *UE_template;
}
} 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];
void mac_init_cell_params(int Mod_idP,int CC_idP) { memset(&RC.mac[Mod_idP]->eNB_stats, 0, sizeof(eNB_STATS));
UE_template =
int j; (UE_TEMPLATE *) & RC.mac[Mod_idP]->UE_list.UE_template[CC_idP][0];
RA_TEMPLATE *RA_template;
UE_TEMPLATE *UE_template; for (j = 0; j < NUMBER_OF_UE_MAX; j++) {
int size_bytes1,size_bytes2,size_bits1,size_bits2; UE_template[j].rnti = 0;
// initiallize the eNB to UE statistics
LOG_D(MAC,"[MAIN][eNB %d] CC_id %d initializing RA_template\n",Mod_idP, CC_idP); memset(&RC.mac[Mod_idP]->UE_list.eNB_UE_stats[CC_idP][j], 0,
LOG_D(MAC, "[MSC_NEW][FRAME 00000][MAC_eNB][MOD %02d][]\n", Mod_idP); sizeof(eNB_UE_STATS));
COMMON_channels_t *cc = &RC.mac[Mod_idP]->common_channels[CC_idP];
RA_template = (RA_TEMPLATE *)&cc->RA_template[0];
for (j=0; j<NB_RA_PROC_MAX; j++) {
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;
RA_template[j].RA_dci_fmt2 = format1A;
}
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
memset (&RC.mac[Mod_idP]->UE_list.eNB_UE_stats[CC_idP][j],0,sizeof(eNB_UE_STATS));
}
} }
...@@ -300,17 +230,17 @@ int rlcmac_init_global_param(void) ...@@ -300,17 +230,17 @@ 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
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -43,12 +43,11 @@ ...@@ -43,12 +43,11 @@
*/ */
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,
void dlsch_scheduler_pre_processor_reset (int module_idP,int UE_id, frame_t frameP, sub_frame_t subframeP);
uint8_t CC_id,
int frameP, void dlsch_scheduler_pre_processor_reset(int module_idP, int UE_id,
int subframeP, uint8_t CC_id,
int N_RBG, int frameP,
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], int subframeP,
uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX], int N_RBG,
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[MAX_NUM_CCs]
[NUMBER_OF_UE_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,12 +251,13 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame ...@@ -218,12 +251,13 @@ 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
); );
/* \brief Function in eNB to fill RAR pdu when requested by PHY. This provides a single RAR SDU for the moment and returns the t-CRNTI. /* \brief Function in eNB to fill RAR pdu when requested by PHY. This provides a single RAR SDU for the moment and returns the t-CRNTI.
@param Mod_id Instance ID of eNB @param Mod_id Instance ID of eNB
...@@ -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
...@@ -269,12 +302,10 @@ void cancel_ra_proc(module_id_t module_idP,int CC_id,frame_t frameP, uint16_t pr ...@@ -269,12 +302,10 @@ void cancel_ra_proc(module_id_t module_idP,int CC_id,frame_t frameP, uint16_t pr
@param Msg3_subframe subframe where scheduling takes place @param Msg3_subframe subframe where scheduling takes place
*/ */
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 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
...@@ -286,14 +317,13 @@ void set_msg3_subframe(module_id_t Mod_id, ...@@ -286,14 +317,13 @@ void set_msg3_subframe(module_id_t Mod_id,
@param ul_cqi Uplink CQI estimate after this pdu (SNR quantized to 8 bits, -64 ... 63.5 dB in .5dB steps) @param ul_cqi Uplink CQI estimate after this pdu (SNR quantized to 8 bits, -64 ... 63.5 dB in .5dB steps)
*/ */
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);
/* \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,69 +381,70 @@ uint8_t *get_dlsch_sdu(module_id_t module_idP,int CC_id,frame_t frameP,rnti_t rn ...@@ -345,69 +381,70 @@ 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,
const int nCCE, const int nCCE,
const int common_dci, const int common_dci,
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 tdd_config, UE_list_t * UE_list);
uint8_t CC_id,
uint8_t tdd_config, uint8_t find_num_active_UEs_in_cbagroup(module_id_t module_idP,
UE_list_t *UE_list); unsigned char group_id);
uint8_t UE_is_to_be_scheduled(module_id_t module_idP, int CC_id,
uint8_t find_num_active_UEs_in_cbagroup(module_id_t module_idP, unsigned char group_id); uint8_t UE_id);
uint8_t UE_is_to_be_scheduled(module_id_t module_idP,int CC_id,uint8_t UE_id);
/** \brief Round-robin scheduler for ULSCH traffic. /** \brief Round-robin scheduler for ULSCH traffic.
@param Mod_id Instance ID for eNB @param Mod_id Instance ID for eNB
@param subframe Subframe number on which to act @param subframe Subframe number on which to act
@returns UE index that is to be scheduled if needed/room @returns UE index that is to be scheduled if needed/room
*/ */
module_id_t schedule_next_ulue(module_id_t module_idP, 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,17 +580,17 @@ in the ULSCH buffer. ...@@ -529,17 +580,17 @@ 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
in 36-321 MAC layer specifications. It returns the number of bytes used for the header to be used as an offset for the payload in 36-321 MAC layer specifications. It returns the number of bytes used for the header to be used as an offset for the payload
...@@ -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 int CC_id);
const uint8_t eNB_index,
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);
...@@ -767,14 +829,14 @@ in the DLSCH buffer. ...@@ -767,14 +829,14 @@ in the DLSCH buffer.
@returns Number of bytes used for header @returns Number of bytes used for header
*/ */
unsigned char generate_dlsch_header(unsigned char *mac_header, unsigned char generate_dlsch_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,
unsigned char drx_cmd, unsigned char drx_cmd,
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);
/** \brief RRC eNB Configuration primitive for PHY/MAC. Allows configuration of PHY/MAC resources based on System Information (SI), RRCConnectionSetup and RRCConnectionReconfiguration messages. /** \brief RRC eNB Configuration primitive for PHY/MAC. Allows configuration of PHY/MAC resources based on System Information (SI), RRCConnectionSetup and RRCConnectionReconfiguration messages.
@param Mod_id Instance ID of eNB @param Mod_id Instance ID of eNB
...@@ -798,51 +860,55 @@ unsigned char generate_dlsch_header(unsigned char *mac_header, ...@@ -798,51 +860,55 @@ unsigned char generate_dlsch_header(unsigned char *mac_header,
@param sib1_ext_r13 SI Scheduling information for SI-BR UEs @param sib1_ext_r13 SI Scheduling information for SI-BR UEs
*/ */
int rrc_mac_config_req_eNB(module_id_t module_idP, int rrc_mac_config_req_eNB(module_id_t module_idP,
int CC_id, int CC_id,
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
); );
/** \brief RRC eNB Configuration primitive for PHY/MAC. Allows configuration of PHY/MAC resources based on System Information (SI), RRCConnectionSetup and RRCConnectionReconfiguration messages. /** \brief RRC eNB Configuration primitive for PHY/MAC. Allows configuration of PHY/MAC resources based on System Information (SI), RRCConnectionSetup and RRCConnectionReconfiguration messages.
@param Mod_id Instance ID of ue @param Mod_id Instance ID of ue
...@@ -864,132 +930,154 @@ int rrc_mac_config_req_eNB(module_id_t module_idP, ...@@ -864,132 +930,154 @@ int rrc_mac_config_req_eNB(module_id_t module_idP,
@param mbsfn_AreaInfoList pointer to MBSFN Area Info list from SIB13 @param mbsfn_AreaInfoList pointer to MBSFN Area Info list from SIB13
@param pmch_InfoList pointer to PMCH_InfoList from MBSFNAreaConfiguration Message (MCCH Message) @param pmch_InfoList pointer to PMCH_InfoList from MBSFNAreaConfiguration Message (MCCH Message)
*/ */
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,
uint16_t rnti, uint8_t * pdu, uint8_t length);
uint8_t resource_block_start,
uint8_t number_of_resource_blocks, void extract_pusch_csi(module_id_t mod_idP, int CC_idP, int UE_id,
uint8_t mcs, frame_t frameP, sub_frame_t subframeP,
uint8_t cyclic_shift_2_for_drms, uint8_t * pdu, uint8_t length);
uint8_t frequency_hopping_enabled_flag,
uint8_t frequency_hopping_bits, uint16_t fill_nfapi_tx_req(nfapi_tx_request_body_t * tx_req_body,
uint8_t new_data_indication, uint16_t absSF, uint16_t pdu_length,
uint8_t redundancy_version, uint16_t pdu_index, uint8_t * pdu);
uint8_t harq_process_number,
uint8_t ul_tx_mode, void fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t *
uint8_t current_tx_nb, ul_config_pdu, uint8_t cqi_req,
uint8_t n_srs, COMMON_channels_t * cc,
uint16_t size struct PhysicalConfigDedicated
); *physicalConfigDedicated,
uint8_t tmode, uint32_t handle,
uint16_t rnti,
uint8_t resource_block_start,
uint8_t
number_of_resource_blocks,
uint8_t mcs,
uint8_t cyclic_shift_2_for_drms,
uint8_t
frequency_hopping_enabled_flag,
uint8_t frequency_hopping_bits,
uint8_t new_data_indication,
uint8_t redundancy_version,
uint8_t harq_process_number,
uint8_t ul_tx_mode,
uint8_t current_tx_nb,
uint8_t n_srs, 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,
...@@ -998,7 +1086,7 @@ void fill_nfapi_dlsch_config(eNB_MAC_INST *eNB, nfapi_dl_config_request_body_t * ...@@ -998,7 +1086,7 @@ void fill_nfapi_dlsch_config(eNB_MAC_INST *eNB, nfapi_dl_config_request_body_t *
uint8_t transmission_scheme, uint8_t transmission_scheme,
uint8_t number_of_layers, uint8_t number_of_layers,
uint8_t number_of_subbands, uint8_t number_of_subbands,
// uint8_t codebook_index, // uint8_t codebook_index,
uint8_t ue_category_capacity, uint8_t ue_category_capacity,
uint8_t pa, uint8_t pa,
uint8_t delta_power_offset_index, uint8_t delta_power_offset_index,
...@@ -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
/** @}*/ /** @}*/
...@@ -47,482 +47,604 @@ ...@@ -47,482 +47,604 @@
#include "SIMULATION/simulation_defs.h" #include "SIMULATION/simulation_defs.h"
#endif #endif
#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 =
uint8_t preambleformat; UE_mac_inst[module_idP].radioResourceConfigCommon->
prach_Config.prach_ConfigInfo.prach_ConfigIndex;
if (UE_mac_inst[module_idP].tdd_Config) { // TDD uint8_t preambleformat;
if (prachConfigIndex < 20) {
preambleformat = 0; if (UE_mac_inst[module_idP].tdd_Config) { // TDD
} else if (prachConfigIndex < 30) { if (prachConfigIndex < 20) {
preambleformat = 1; preambleformat = 0;
} else if (prachConfigIndex < 40) { } else if (prachConfigIndex < 30) {
preambleformat = 2; preambleformat = 1;
} else if (prachConfigIndex < 48) { } else if (prachConfigIndex < 40) {
preambleformat = 3; preambleformat = 2;
} else { } else if (prachConfigIndex < 48) {
preambleformat = 4; preambleformat = 3;
} else {
preambleformat = 4;
}
} else { // FDD
preambleformat = prachConfigIndex >> 2;
} }
} else { // FDD
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
int CC_id, get_prach_resources(module_id_t module_idP,
uint8_t eNB_index, int CC_id,
uint8_t t_id, uint8_t eNB_index,
uint8_t first_Msg3, uint8_t t_id,
RACH_ConfigDedicated_t *rach_ConfigDedicated) uint8_t first_Msg3,
RACH_ConfigDedicated_t * rach_ConfigDedicated)
{ {
uint8_t Msg3_size = UE_mac_inst[module_idP].RA_Msg3_size; uint8_t Msg3_size = UE_mac_inst[module_idP].RA_Msg3_size;
PRACH_RESOURCES_t *prach_resources = &UE_mac_inst[module_idP].RA_prach_resources; PRACH_RESOURCES_t *prach_resources =
RACH_ConfigCommon_t *rach_ConfigCommon = NULL; &UE_mac_inst[module_idP].RA_prach_resources;
uint8_t noGroupB = 0; RACH_ConfigCommon_t *rach_ConfigCommon = NULL;
uint8_t f_id = 0,num_prach=0; uint8_t noGroupB = 0;
int numberOfRA_Preambles; uint8_t f_id = 0, num_prach = 0;
int messageSizeGroupA; int numberOfRA_Preambles;
int sizeOfRA_PreamblesGroupA; int messageSizeGroupA;
int messagePowerOffsetGroupB; int sizeOfRA_PreamblesGroupA;
int PLThreshold; int messagePowerOffsetGroupB;
int PLThreshold;
AssertFatal(CC_id==0,
"Transmission on secondary CCs is not supported yet\n"); AssertFatal(CC_id == 0,
AssertFatal(UE_mac_inst[module_idP].radioResourceConfigCommon!=NULL, "Transmission on secondary CCs is not supported yet\n");
"[UE %d] FATAL radioResourceConfigCommon is NULL !!!\n",module_idP); AssertFatal(UE_mac_inst[module_idP].radioResourceConfigCommon != NULL,
"[UE %d] FATAL radioResourceConfigCommon is NULL !!!\n",
rach_ConfigCommon = &UE_mac_inst[module_idP].radioResourceConfigCommon->rach_ConfigCommon; module_idP);
numberOfRA_Preambles = (1+rach_ConfigCommon->preambleInfo.numberOfRA_Preambles)<<2;
rach_ConfigCommon =
if (rach_ConfigDedicated) { // This is for network controlled Mobility, later &UE_mac_inst[module_idP].radioResourceConfigCommon->
if (rach_ConfigDedicated->ra_PRACH_MaskIndex != 0) { rach_ConfigCommon;
prach_resources->ra_PreambleIndex = rach_ConfigDedicated->ra_PreambleIndex; numberOfRA_Preambles =
prach_resources->ra_RACH_MaskIndex = rach_ConfigDedicated->ra_PRACH_MaskIndex; (1 + rach_ConfigCommon->preambleInfo.numberOfRA_Preambles) << 2;
return;
if (rach_ConfigDedicated) { // This is for network controlled Mobility, later
if (rach_ConfigDedicated->ra_PRACH_MaskIndex != 0) {
prach_resources->ra_PreambleIndex =
rach_ConfigDedicated->ra_PreambleIndex;
prach_resources->ra_RACH_MaskIndex =
rach_ConfigDedicated->ra_PRACH_MaskIndex;
return;
}
} }
}
/* TODO: gcc warns if this variable is not always set, let's put -1 for no more warning */ /* TODO: gcc warns if this variable is not always set, let's put -1 for no more warning */
messageSizeGroupA = -1; messageSizeGroupA = -1;
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.
case 0: preamblesGroupAConfig->sizeOfRA_PreamblesGroupA + 1) << 2;
messageSizeGroupA = 56; switch (rach_ConfigCommon->preambleInfo.
break; preamblesGroupAConfig->messageSizeGroupA) {
case 1: case 0:
messageSizeGroupA = 144; messageSizeGroupA = 56;
break; break;
case 2: case 1:
messageSizeGroupA = 208; messageSizeGroupA = 144;
break; break;
case 3: case 2:
messageSizeGroupA = 256; messageSizeGroupA = 208;
break; break;
} case 3:
messageSizeGroupA = 256;
break;
}
/* 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.
case 0: preamblesGroupAConfig->messagePowerOffsetGroupB) {
messagePowerOffsetGroupB = -9999; case 0:
break; messagePowerOffsetGroupB = -9999;
case 1: break;
messagePowerOffsetGroupB = 0; case 1:
break; messagePowerOffsetGroupB = 0;
case 2: break;
messagePowerOffsetGroupB = 5; case 2:
break; messagePowerOffsetGroupB = 5;
case 3: break;
messagePowerOffsetGroupB = 8; case 3:
break; messagePowerOffsetGroupB = 8;
case 4: break;
messagePowerOffsetGroupB = 10; case 4:
break; messagePowerOffsetGroupB = 10;
case 5: break;
messagePowerOffsetGroupB = 12; case 5:
break; messagePowerOffsetGroupB = 12;
case 6: break;
messagePowerOffsetGroupB = 15; case 6:
break; messagePowerOffsetGroupB = 15;
case 7: break;
messagePowerOffsetGroupB = 18; case 7:
break; messagePowerOffsetGroupB = 18;
} break;
}
PLThreshold = 0 - get_DELTA_PREAMBLE(module_idP,CC_id) - get_Po_NOMINAL_PUSCH(module_idP,CC_id) - messagePowerOffsetGroupB; PLThreshold =
// Note Pcmax is set to 0 here, we have to fix this 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
if (sizeOfRA_PreamblesGroupA == numberOfRA_Preambles) { if (sizeOfRA_PreamblesGroupA == numberOfRA_Preambles) {
noGroupB = 1; noGroupB = 1;
} }
}
if (first_Msg3 == 1) {
if (noGroupB == 1) {
// 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_RACH_MaskIndex = 0;
UE_mac_inst[module_idP].RA_usedGroupA = 1;
} else if ((Msg3_size <messageSizeGroupA) ||
(get_PL(module_idP,0,eNB_index) > PLThreshold)) {
// 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_RACH_MaskIndex = 0;
UE_mac_inst[module_idP].RA_usedGroupA = 1;
} else { // use Group B
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = sizeOfRA_PreamblesGroupA +
(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_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER = get_Po_NOMINAL_PUSCH(module_idP,CC_id); if (first_Msg3 == 1) {
} else { // Msg3 is being retransmitted if (noGroupB == 1) {
if (UE_mac_inst[module_idP].RA_usedGroupA == 1) { // use Group A procedure
if (rach_ConfigCommon->preambleInfo.preamblesGroupAConfig) { UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex =
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = (taus())%rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA; (taus()) % numberOfRA_Preambles;
} else { UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex =
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = (taus())&0x3f; 0;
} UE_mac_inst[module_idP].RA_usedGroupA = 1;
} else if ((Msg3_size < messageSizeGroupA) ||
(get_PL(module_idP, 0, eNB_index) > PLThreshold)) {
// 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_RACH_MaskIndex =
0;
UE_mac_inst[module_idP].RA_usedGroupA = 1;
} else { // use Group B
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex =
sizeOfRA_PreamblesGroupA +
(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_prach_resources.ra_RACH_MaskIndex = 0; UE_mac_inst[module_idP].
} else { RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER =
// FIXME rach_ConfigCommon->preambleInfo.preamblesGroupAConfig may be zero get_Po_NOMINAL_PUSCH(module_idP, CC_id);
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = } else { // Msg3 is being retransmitted
rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA + if (UE_mac_inst[module_idP].RA_usedGroupA == 1) {
(taus())%(rach_ConfigCommon->preambleInfo.numberOfRA_Preambles - if (rach_ConfigCommon->preambleInfo.preamblesGroupAConfig) {
rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA); UE_mac_inst[module_idP].RA_prach_resources.
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0; ra_PreambleIndex =
(taus()) %
rach_ConfigCommon->preambleInfo.
preamblesGroupAConfig->sizeOfRA_PreamblesGroupA;
} else {
UE_mac_inst[module_idP].RA_prach_resources.
ra_PreambleIndex = (taus()) & 0x3f;
}
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex =
0;
} else {
// FIXME rach_ConfigCommon->preambleInfo.preamblesGroupAConfig may be zero
UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex =
rach_ConfigCommon->preambleInfo.
preamblesGroupAConfig->sizeOfRA_PreamblesGroupA +
(taus()) %
(rach_ConfigCommon->preambleInfo.numberOfRA_Preambles -
rach_ConfigCommon->preambleInfo.
preamblesGroupAConfig->sizeOfRA_PreamblesGroupA);
UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex =
0;
}
} }
}
// choose random PRACH resource in TDD
if (UE_mac_inst[module_idP].tdd_Config) {
num_prach = get_num_prach_tdd(module_idP);
if ((num_prach>0) && (num_prach<6)) { // choose random PRACH resource in TDD
UE_mac_inst[module_idP].RA_prach_resources.ra_TDD_map_index = (taus()%num_prach); if (UE_mac_inst[module_idP].tdd_Config) {
} num_prach = get_num_prach_tdd(module_idP);
f_id = get_fid_prach_tdd(module_idP, if ((num_prach > 0) && (num_prach < 6)) {
UE_mac_inst[module_idP].RA_prach_resources.ra_TDD_map_index); UE_mac_inst[module_idP].RA_prach_resources.ra_TDD_map_index =
} (taus() % num_prach);
}
// choose RA-RNTI f_id = get_fid_prach_tdd(module_idP,
UE_mac_inst[module_idP].RA_prach_resources.ra_RNTI = 1 + t_id + 10*f_id; UE_mac_inst
[module_idP].RA_prach_resources.
ra_TDD_map_index);
}
// choose RA-RNTI
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,
module_idP, frameP, 1, UE_mac_inst[module_idP].RA_Msg3_size); 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);
}
} }
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_mac_inst[module_idP].RA_contention_resolution_cnt = 0; "[UE %d][RAPROC] Frame %d : Msg3_tx: Setting contention resolution timer\n",
UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 1; module_idP, frameP);
UE_mac_inst[module_idP].RA_contention_resolution_cnt = 0;
if (opt_enabled) { // msg3 UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 1;
trace_pdu(0, &UE_mac_inst[module_idP].CCCH_pdu.payload[0], UE_mac_inst[module_idP].RA_Msg3_size,
module_idP, 3, UE_mac_inst[module_idP].crnti, UE_mac_inst[module_idP].txFrame, UE_mac_inst[module_idP].txSubframe, 0, 0); if (opt_enabled) { // msg3
LOG_D(OPT,"[UE %d][RAPROC] MSG3 Frame %d trace pdu Preamble %d with size %d\n", trace_pdu(0, &UE_mac_inst[module_idP].CCCH_pdu.payload[0],
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].RA_Msg3_size, module_idP, 3,
} UE_mac_inst[module_idP].crnti,
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 =
int32_t frame_diff = 0; (struct RACH_ConfigCommon *) NULL;
mac_rlc_status_resp_t rlc_status; int32_t frame_diff = 0;
uint8_t dcch_header_len = 0; mac_rlc_status_resp_t rlc_status;
uint16_t sdu_lengths[8]; uint8_t dcch_header_len = 0;
uint8_t ulsch_buff[MAX_ULSCH_PAYLOAD_BYTES]; uint16_t sdu_lengths[8];
uint8_t ulsch_buff[MAX_ULSCH_PAYLOAD_BYTES];
AssertFatal(CC_id==0,
"Transmission on secondary CCs is not supported yet\n"); AssertFatal(CC_id == 0,
"Transmission on secondary CCs is not supported yet\n");
if (UE_mode == PRACH) {
if (UE_mac_inst[module_idP].radioResourceConfigCommon) { if (UE_mode == PRACH) {
rach_ConfigCommon = &UE_mac_inst[module_idP].radioResourceConfigCommon->rach_ConfigCommon; if (UE_mac_inst[module_idP].radioResourceConfigCommon) {
} else { rach_ConfigCommon =
return(NULL); &UE_mac_inst[module_idP].
} radioResourceConfigCommon->rach_ConfigCommon;
} else {
if (UE_mac_inst[module_idP].RA_active == 0) { return (NULL);
LOG_I(MAC,"RA not active\n");
// check if RRC is ready to initiate the RA procedure
Size = mac_rrc_data_req(module_idP,
CC_id,
frameP,
CCCH,1,
&UE_mac_inst[module_idP].CCCH_pdu.payload[sizeof(SCH_SUBHEADER_SHORT)+1],0,
eNB_indexP,
0);
Size16 = (uint16_t)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",
frameP, module_idP, eNB_indexP, module_idP);
LOG_I(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n",module_idP,frameP,Size);
if (Size>0) {
UE_mac_inst[module_idP].RA_active = 1;
UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER = 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_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)
AssertFatal(rach_ConfigCommon!=NULL,
"[UE %d] FATAL Frame %d: rach_ConfigCommon is NULL !!!\n",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) {
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_tx_frame = frameP; if (UE_mac_inst[module_idP].RA_active == 0) {
UE_mac_inst[module_idP].RA_tx_subframe = subframeP; LOG_I(MAC, "RA not active\n");
UE_mac_inst[module_idP].RA_backoff_frame = frameP; // check if RRC is ready to initiate the RA procedure
UE_mac_inst[module_idP].RA_backoff_subframe = subframeP; Size = mac_rrc_data_req(module_idP,
// Fill in preamble and PRACH resource CC_id,
get_prach_resources(module_idP,CC_id,eNB_indexP,subframeP,1,NULL); frameP,
CCCH, 1,
generate_ulsch_header((uint8_t*)&UE_mac_inst[module_idP].CCCH_pdu.payload[0], // mac header &UE_mac_inst[module_idP].
1, // num sdus CCCH_pdu.payload[sizeof
0, // short pading (SCH_SUBHEADER_SHORT)
&Size16, // sdu length + 1], 0, eNB_indexP,
&lcid, // sdu lcid 0);
NULL, // power headroom Size16 = (uint16_t) Size;
NULL, // crnti
NULL, // truncated bsr // LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n",module_idP,frameP,Size);
NULL, // short bsr LOG_I(RRC,
NULL, // long_bsr "[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- MAC_DATA_REQ (RRCConnectionRequest eNB %d) --->][MAC_UE][MOD %02d][]\n",
1); //post_padding frameP, module_idP, eNB_indexP, module_idP);
return(&UE_mac_inst[module_idP].RA_prach_resources); LOG_I(MAC,
"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n",
} else if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[DCCH]] > 0) { module_idP, frameP, Size);
// 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 if (Size > 0) {
rlc_status = mac_rlc_status_ind(module_idP,UE_mac_inst[module_idP].crnti, eNB_indexP,frameP,subframeP,ENB_FLAG_NO,MBMS_FLAG_NO,
DCCH, UE_mac_inst[module_idP].RA_active = 1;
6); UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER =
1;
if (UE_mac_inst[module_idP].crnti_before_ho) UE_mac_inst[module_idP].RA_Msg3_size =
LOG_D(MAC, Size + sizeof(SCH_SUBHEADER_SHORT) +
"[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", sizeof(SCH_SUBHEADER_SHORT);
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); UE_mac_inst[module_idP].RA_prachMaskIndex = 0;
else UE_mac_inst[module_idP].RA_prach_resources.Msg3 =
LOG_D(MAC,"[UE %d] Frame %d : UL-DCCH -> ULSCH, RRC message has %d bytes to send through PRACH(mac header len %d)\n", UE_mac_inst[module_idP].CCCH_pdu.payload;
module_idP,frameP, rlc_status.bytes_in_buffer,dcch_header_len); 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)
sdu_lengths[0] = mac_rlc_data_req(module_idP, UE_mac_inst[module_idP].crnti, AssertFatal(rach_ConfigCommon != NULL,
eNB_indexP, frameP,ENB_FLAG_NO, MBMS_FLAG_NO, "[UE %d] FATAL Frame %d: rach_ConfigCommon is NULL !!!\n",
DCCH, module_idP, frameP);
6, //not used UE_mac_inst[module_idP].RA_window_cnt =
(char *)&ulsch_buff[0]); 2 +
rach_ConfigCommon->ra_SupervisionInfo.
LOG_D(MAC,"[UE %d] TX Got %d bytes for DCCH\n",module_idP,sdu_lengths[0]); ra_ResponseWindowSize;
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]] = if (UE_mac_inst[module_idP].RA_window_cnt == 9) {
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]]); UE_mac_inst[module_idP].RA_window_cnt = 10; // Note: 9 subframe window doesn't exist, after 8 is 10!
}
//TO DO: fill BSR infos in UL TBS
UE_mac_inst[module_idP].RA_tx_frame = frameP;
//header_len +=2; UE_mac_inst[module_idP].RA_tx_subframe = subframeP;
UE_mac_inst[module_idP].RA_active = 1; UE_mac_inst[module_idP].RA_backoff_frame = frameP;
UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER = 1; UE_mac_inst[module_idP].RA_backoff_subframe = subframeP;
UE_mac_inst[module_idP].RA_Msg3_size = Size+dcch_header_len; // Fill in preamble and PRACH resource
UE_mac_inst[module_idP].RA_prachMaskIndex = 0; get_prach_resources(module_idP, CC_id, eNB_indexP,
UE_mac_inst[module_idP].RA_prach_resources.Msg3 = ulsch_buff; subframeP, 1, NULL);
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)
generate_ulsch_header((uint8_t *) & UE_mac_inst[module_idP].CCCH_pdu.payload[0], // mac header
AssertFatal(rach_ConfigCommon!=NULL, 1, // num sdus
"[UE %d] FATAL Frame %d: rach_ConfigCommon is NULL !!!\n",module_idP,frameP); 0, // short pading
UE_mac_inst[module_idP].RA_window_cnt = 2+ rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize; &Size16, // sdu length
&lcid, // sdu lcid
if (UE_mac_inst[module_idP].RA_window_cnt == 9) { NULL, // power headroom
UE_mac_inst[module_idP].RA_window_cnt = 10; // Note: 9 subframe window doesn't exist, after 8 is 10! NULL, // crnti
} NULL, // truncated bsr
NULL, // short bsr
NULL, // long_bsr
UE_mac_inst[module_idP].RA_tx_frame = frameP; 1); //post_padding
UE_mac_inst[module_idP].RA_tx_subframe = subframeP; return (&UE_mac_inst[module_idP].RA_prach_resources);
UE_mac_inst[module_idP].RA_backoff_frame = frameP;
UE_mac_inst[module_idP].RA_backoff_subframe = subframeP; } else if (UE_mac_inst[module_idP].
// Fill in preamble and PRACH resource scheduling_info.BSR_bytes[UE_mac_inst[module_idP].
get_prach_resources(module_idP,CC_id,eNB_indexP,subframeP,1,NULL); scheduling_info.LCGID
generate_ulsch_header((uint8_t*)ulsch_buff, // mac header [DCCH]] > 0) {
1, // num sdus // This is for triggering a transmission on DCCH using PRACH (during handover, or sending SR for example)
0, // short pading dcch_header_len = 2 + 2; /// SHORT Subheader + C-RNTI control element
&Size16, // sdu length rlc_status =
&lcid, // sdu lcid mac_rlc_status_ind(module_idP,
NULL, // power headroom UE_mac_inst[module_idP].crnti,
&UE_mac_inst[module_idP].crnti, // crnti eNB_indexP, frameP, subframeP,
NULL, // truncated bsr ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 6);
NULL, // short bsr
NULL, // long_bsr if (UE_mac_inst[module_idP].crnti_before_ho)
0); //post_padding 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",
return(&UE_mac_inst[module_idP].RA_prach_resources); module_idP, frameP,
} UE_mac_inst[module_idP].crnti,
} else { // RACH is active UE_mac_inst[module_idP].crnti_before_ho,
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, rlc_status.bytes_in_buffer, dcch_header_len);
frameP,subframeP,UE_mac_inst[module_idP].RA_window_cnt, else
UE_mac_inst[module_idP].RA_tx_frame,UE_mac_inst[module_idP].RA_tx_subframe); LOG_D(MAC,
"[UE %d] Frame %d : UL-DCCH -> ULSCH, RRC message has %d bytes to send through PRACH(mac header len %d)\n",
// compute backoff parameters module_idP, frameP, rlc_status.bytes_in_buffer,
if (UE_mac_inst[module_idP].RA_backoff_cnt>0) { dcch_header_len);
frame_diff = (sframe_t)frameP - UE_mac_inst[module_idP].RA_backoff_frame;
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
if (frame_diff < 0) { (char *) &ulsch_buff[0]);
frame_diff = -frame_diff;
} LOG_D(MAC, "[UE %d] TX Got %d bytes for DCCH\n",
module_idP, sdu_lengths[0]);
UE_mac_inst[module_idP].RA_backoff_cnt -= ((10*frame_diff) + (subframeP-UE_mac_inst[module_idP].RA_backoff_subframe)); update_bsr(module_idP, frameP, subframeP, eNB_indexP);
UE_mac_inst[module_idP].
UE_mac_inst[module_idP].RA_backoff_frame = frameP; scheduling_info.BSR[UE_mac_inst[module_idP].
UE_mac_inst[module_idP].RA_backoff_subframe = subframeP; scheduling_info.LCGID[DCCH]] =
} locate_BsrIndexByBufferSize(BSR_TABLE, BSR_TABLE_SIZE,
UE_mac_inst
// compute RA window parameters [module_idP].scheduling_info.BSR_bytes
if (UE_mac_inst[module_idP].RA_window_cnt>0) { [UE_mac_inst
frame_diff = (frame_t)frameP - UE_mac_inst[module_idP].RA_tx_frame; [module_idP].scheduling_info.LCGID
[DCCH]]);
if (frame_diff < 0) {
frame_diff = -frame_diff; //TO DO: fill BSR infos in UL TBS
}
//header_len +=2;
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_active = 1;
LOG_D(MAC,"[MAC][UE %d][RAPROC] frameP %d, subframe %d: RA Active, adjusted window cnt %d\n",module_idP, UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER =
frameP,subframeP,UE_mac_inst[module_idP].RA_window_cnt); 1;
} UE_mac_inst[module_idP].RA_Msg3_size =
Size + dcch_header_len;
if ((UE_mac_inst[module_idP].RA_window_cnt<=0) && UE_mac_inst[module_idP].RA_prachMaskIndex = 0;
(UE_mac_inst[module_idP].RA_backoff_cnt<=0)) { UE_mac_inst[module_idP].RA_prach_resources.Msg3 =
ulsch_buff;
UE_mac_inst[module_idP].RA_tx_frame = frameP; 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_tx_subframe = subframeP;
UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER++; AssertFatal(rach_ConfigCommon != NULL,
UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER += "[UE %d] FATAL Frame %d: rach_ConfigCommon is NULL !!!\n",
(rach_ConfigCommon->powerRampingParameters.powerRampingStep<<1); // 2dB increments in ASN.1 definition module_idP, frameP);
int preambleTransMax = -1; UE_mac_inst[module_idP].RA_window_cnt =
switch (rach_ConfigCommon->ra_SupervisionInfo.preambleTransMax) { 2 +
case PreambleTransMax_n3: rach_ConfigCommon->ra_SupervisionInfo.
preambleTransMax = 3; ra_ResponseWindowSize;
break;
case PreambleTransMax_n4: if (UE_mac_inst[module_idP].RA_window_cnt == 9) {
preambleTransMax = 4; UE_mac_inst[module_idP].RA_window_cnt = 10; // Note: 9 subframe window doesn't exist, after 8 is 10!
break; }
case PreambleTransMax_n5:
preambleTransMax = 5;
break; UE_mac_inst[module_idP].RA_tx_frame = frameP;
case PreambleTransMax_n6: UE_mac_inst[module_idP].RA_tx_subframe = subframeP;
preambleTransMax = 6; UE_mac_inst[module_idP].RA_backoff_frame = frameP;
break; UE_mac_inst[module_idP].RA_backoff_subframe = subframeP;
case PreambleTransMax_n7: // Fill in preamble and PRACH resource
preambleTransMax = 7; get_prach_resources(module_idP, CC_id, eNB_indexP,
break; subframeP, 1, NULL);
case PreambleTransMax_n8: generate_ulsch_header((uint8_t *) ulsch_buff, // mac header
preambleTransMax = 8; 1, // num sdus
break; 0, // short pading
case PreambleTransMax_n10: &Size16, // sdu length
preambleTransMax = 10; &lcid, // sdu lcid
break; NULL, // power headroom
case PreambleTransMax_n20: &UE_mac_inst[module_idP].crnti, // crnti
preambleTransMax = 20; NULL, // truncated bsr
break; NULL, // short bsr
case PreambleTransMax_n50: NULL, // long_bsr
preambleTransMax = 50; 0); //post_padding
break;
case PreambleTransMax_n100: return (&UE_mac_inst[module_idP].RA_prach_resources);
preambleTransMax = 100; }
break; } else { // RACH is active
case PreambleTransMax_n200: LOG_D(MAC,
preambleTransMax = 200; "[MAC][UE %d][RAPROC] frameP %d, subframe %d: RA Active, window cnt %d (RA_tx_frame %d, RA_tx_subframe %d)\n",
break; module_idP, frameP, subframeP,
} UE_mac_inst[module_idP].RA_window_cnt,
UE_mac_inst[module_idP].RA_tx_frame,
if (UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER == preambleTransMax) { UE_mac_inst[module_idP].RA_tx_subframe);
LOG_D(MAC,"[UE %d] Frame %d: Maximum number of RACH attempts (%d)\n",module_idP,frameP,preambleTransMax);
// send message to RRC // compute backoff parameters
UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER=1; if (UE_mac_inst[module_idP].RA_backoff_cnt > 0) {
UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER = get_Po_NOMINAL_PUSCH(module_idP,CC_id); frame_diff =
(sframe_t) frameP -
UE_mac_inst[module_idP].RA_backoff_frame;
if (frame_diff < 0) {
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_frame = frameP;
UE_mac_inst[module_idP].RA_backoff_subframe = subframeP;
}
// compute RA window parameters
if (UE_mac_inst[module_idP].RA_window_cnt > 0) {
frame_diff =
(frame_t) frameP - UE_mac_inst[module_idP].RA_tx_frame;
if (frame_diff < 0) {
frame_diff = -frame_diff;
}
UE_mac_inst[module_idP].RA_window_cnt -=
((10 * frame_diff) +
(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) &&
(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_subframe = subframeP;
UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER++;
UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER += (rach_ConfigCommon->powerRampingParameters.powerRampingStep << 1); // 2dB increments in ASN.1 definition
int preambleTransMax = -1;
switch (rach_ConfigCommon->ra_SupervisionInfo.
preambleTransMax) {
case PreambleTransMax_n3:
preambleTransMax = 3;
break;
case PreambleTransMax_n4:
preambleTransMax = 4;
break;
case PreambleTransMax_n5:
preambleTransMax = 5;
break;
case PreambleTransMax_n6:
preambleTransMax = 6;
break;
case PreambleTransMax_n7:
preambleTransMax = 7;
break;
case PreambleTransMax_n8:
preambleTransMax = 8;
break;
case PreambleTransMax_n10:
preambleTransMax = 10;
break;
case PreambleTransMax_n20:
preambleTransMax = 20;
break;
case PreambleTransMax_n50:
preambleTransMax = 50;
break;
case PreambleTransMax_n100:
preambleTransMax = 100;
break;
case PreambleTransMax_n200:
preambleTransMax = 200;
break;
}
if (UE_mac_inst[module_idP].
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
UE_mac_inst[module_idP].
RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
UE_mac_inst[module_idP].
RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER
= get_Po_NOMINAL_PUSCH(module_idP, CC_id);
}
UE_mac_inst[module_idP].RA_window_cnt =
2 +
rach_ConfigCommon->ra_SupervisionInfo.
ra_ResponseWindowSize;
UE_mac_inst[module_idP].RA_backoff_cnt = 0;
// Fill in preamble and PRACH resource
get_prach_resources(module_idP, CC_id, eNB_indexP,
subframeP, 0, NULL);
return (&UE_mac_inst[module_idP].RA_prach_resources);
}
} }
} else if (UE_mode == PUSCH) {
UE_mac_inst[module_idP].RA_window_cnt = 2+ rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize; LOG_D(MAC,
UE_mac_inst[module_idP].RA_backoff_cnt = 0; "[UE %d] FATAL: Should not have checked for RACH in PUSCH yet ...",
module_idP);
// Fill in preamble and PRACH resource AssertFatal(1 == 0, "");
get_prach_resources(module_idP,CC_id,eNB_indexP,subframeP,0,NULL);
return(&UE_mac_inst[module_idP].RA_prach_resources);
}
} }
} else if (UE_mode == PUSCH) {
LOG_D(MAC,"[UE %d] FATAL: Should not have checked for RACH in PUSCH yet ...",module_idP); return (NULL);
AssertFatal(1==0,"");
}
return(NULL);
} }
...@@ -40,269 +40,246 @@ ...@@ -40,269 +40,246 @@
#define DEBUG_RAR #define DEBUG_RAR
extern unsigned int localRIV2alloc_LUT25[512]; extern unsigned int localRIV2alloc_LUT25[512];
extern unsigned int distRIV2alloc_LUT25[512]; extern unsigned int distRIV2alloc_LUT25[512];
extern unsigned short RIV2nb_rb_LUT25[512]; extern unsigned short RIV2nb_rb_LUT25[512];
extern unsigned short RIV2first_rb_LUT25[512]; 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,
const frame_t frameP, RA_t * ra,
uint8_t* const dlsch_buffer, const frame_t frameP,
const uint16_t N_RB_UL, uint8_t * const dlsch_buffer,
const uint8_t input_buffer_length const uint16_t N_RB_UL, 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; // subheader fixed
rarh->E = 0; // First and last RAR
AssertFatal(CC_id < MAX_NUM_CCs, "CC_id %u < MAX_NUM_CCs %u", CC_id, MAX_NUM_CCs); rarh->T = 1; // 0 for E/T/R/R/BI subheader, 1 for E/T/RAPID subheader
rarh->RAPID = ra->preamble_index; // Respond to Preamble 0 only for the moment
for (i=0; i<NB_RA_PROC_MAX; i++) { rar[4] = (uint8_t) (ra->rnti >> 8);
if (RC.mac[module_idP]->common_channels[CC_id].RA_template[i].generate_rar == 1) { rar[5] = (uint8_t) (ra->rnti & 0xff);
ra_idx=i; //ra->timing_offset = 0;
RC.mac[module_idP]->common_channels[CC_id].RA_template[i].generate_rar = 0; ra->timing_offset /= 16; //T_A = N_TA/16, where N_TA should be on a 30.72Msps
break; rar[0] = (uint8_t) (ra->timing_offset >> (2 + 4)); // 7 MSBs 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->msg3_first_rb = 6;
ra->msg3_nb_rb = 1;
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[2] = ((uint8_t) (rballoc & 0xff)) << 1; // 7 LSBs of rballoc
ra->msg3_mcs = 10;
ra->msg3_TPC = 3;
ra->msg3_ULdelay = 0;
ra->msg3_cqireq = 0;
rar[2] |= ((ra->msg3_mcs & 0x8) >> 3); // mcs 10
rar[3] =
(((ra->msg3_mcs & 0x7) << 5)) | ((ra->msg3_TPC & 7) << 2) |
((ra->msg3_ULdelay & 1) << 1) | (ra->msg3_cqireq & 1);
if (opt_enabled) {
trace_pdu(1, dlsch_buffer, input_buffer_length, module_idP, 2, 1,
RC.mac[module_idP]->frame, RC.mac[module_idP]->subframe,
0, 0);
LOG_D(OPT,
"[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);
} }
}
RA_template = &RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx]; return (ra->rnti);
//DevAssert( ra_idx != -1 );
if (ra_idx==-1)
return(0);
// subheader fixed
rarh->E = 0; // First and last RAR
rarh->T = 1; // 0 for E/T/R/R/BI subheader, 1 for E/T/RAPID subheader
rarh->RAPID = RA_template->preamble_index; // Respond to Preamble 0 only for the moment
rar[4] = (uint8_t)(RA_template->rnti>>8);
rar[5] = (uint8_t)(RA_template->rnti&0xff);
//RA_template->timing_offset = 0;
RA_template->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[1] = (uint8_t)(RA_template->timing_offset<<(4-2))&0xf0; // 4 LSBs of timing advance + divide by 4
RA_template->msg3_first_rb=6;
RA_template->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
rar[1] |= (rballoc>>7)&7; // Hopping = 0 (bit 3), 3 MSBs of rballoc
rar[2] = ((uint8_t)(rballoc&0xff))<<1; // 7 LSBs of rballoc
RA_template->msg3_mcs = 10;
RA_template->msg3_TPC = 3;
RA_template->msg3_ULdelay = 0;
RA_template->msg3_cqireq = 0;
rar[2] |= ((RA_template->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);
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",
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) {
trace_pdu(1, dlsch_buffer, input_buffer_length, module_idP, 2, 1,
RC.mac[module_idP]->frame, RC.mac[module_idP]->subframe, 0, 0);
LOG_D(OPT,"[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_template->rnti,
rarh->RAPID, input_buffer_length);
}
return(RA_template->rnti);
} }
#ifdef Rel14 #ifdef Rel14
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
unsigned short fill_rar_br(eNB_MAC_INST *eNB, unsigned short
int CC_id, fill_rar_br(eNB_MAC_INST * eNB,
RA_TEMPLATE *RA_template, int CC_id,
const frame_t frameP, RA_t * ra,
const sub_frame_t subframeP, const frame_t frameP,
uint8_t* const dlsch_buffer, const sub_frame_t subframeP,
const uint8_t ce_level uint8_t * const dlsch_buffer, 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[4] = (uint8_t)(RA_template->rnti&0xff); rar[3] = (uint8_t) (ra->rnti >> 8);
} 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", }
frameP, LOG_D(MAC,
*(uint8_t*)rarh,rar[0],rar[1],rar[2],rar[3],rar[4],rar[5], "[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",
ce_level, frameP, *(uint8_t *) rarh, rar[0], rar[1], rar[2], rar[3],
RA_template->rnti, rar[4], rar[5], ce_level, ra->rnti, rarh->RAPID,
rarh->RAPID,RA_template->preamble_index, ra->preamble_index, ra->timing_offset);
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,
LOG_D(OPT,"[RAPROC] RAR Frame %d trace pdu for rnti %x and rapid %d size %d\n", "[RAPROC] RAR Frame %d trace pdu for rnti %x and rapid %d size %d\n",
frameP, RA_template->rnti, frameP, ra->rnti, rarh->RAPID, input_buffer_length);
rarh->RAPID, input_buffer_length); }
}
return (ra->rnti);
return(RA_template->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
uint8_t n_rarh = 0; // number of MAC RAR subheaders uint8_t n_rarh = 0; // number of MAC RAR subheaders
uint8_t best_rx_rapid = -1; // the closest RAPID receive from all RARs uint8_t best_rx_rapid = -1; // the closest RAPID receive from all RARs
while (1) { while (1) {
n_rarh++; n_rarh++;
if (rarh->T == 1) { if (rarh->T == 1) {
n_rarpy++; n_rarpy++;
LOG_D(MAC, "RAPID %d\n", rarh->RAPID); LOG_D(MAC, "RAPID %d\n", rarh->RAPID);
} }
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);
break; rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6);
} break;
}
if (abs((int)rarh->RAPID - (int)preamble_index) < abs((int)best_rx_rapid - (int)preamble_index)) {
best_rx_rapid = rarh->RAPID; if (abs((int) rarh->RAPID - (int) preamble_index) <
rar = (uint8_t *)(dlsch_buffer+n_rarh + (n_rarpy-1)*6); abs((int) best_rx_rapid - (int) preamble_index)) {
} best_rx_rapid = rarh->RAPID;
rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6);
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);
break; if (rarh->E == 0) {
} else { LOG_I(PHY,
rarh++; "No RAR found with the intended RAPID. The closest RAPID in all RARs is %d\n",
} best_rx_rapid);
}; break;
LOG_D(MAC, "number of RAR subheader %d; number of RAR pyloads %d\n", n_rarh, n_rarpy); } else {
rarh++;
if (CC_id>0) { }
LOG_W(MAC,"Should not have received RAR on secondary CCs! \n"); };
return(0xffff); LOG_D(MAC, "number of RAR subheader %d; number of RAR pyloads %d\n",
} n_rarh, n_rarpy);
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, if (CC_id > 0) {
*(uint8_t*)rarh,rar[0],rar[1],rar[2],rar[3],rar[4],rar[5], LOG_W(MAC, "Should not have received RAR on secondary CCs! \n");
rarh->RAPID,preamble_index); return (0xffff);
}
LOG_I(MAC,
"[eNB %d][RAPROC] Frame %d Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n",
module_idP, frameP, *(uint8_t *) rarh, rar[0], rar[1], rar[2],
rar[3], rar[4], rar[5], rarh->RAPID, preamble_index);
#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_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->R %d\n",module_idP,rar->R);
// LOG_I(MAC,"[UE %d][RAPROC] rar->hopping_flag %d\n",module_idP,rar->hopping_flag); LOG_D(MAC, "[UE %d][RAPROC] rar->Timing_Advance_Command %d\n",
// LOG_I(MAC,"[UE %d][RAPROC] rar->rb_alloc %d\n",module_idP,rar->rb_alloc); module_idP, (((uint16_t) (rar[0] & 0x7f)) << 4) + (rar[1] >> 4));
// LOG_I(MAC,"[UE %d][RAPROC] rar->mcs %d\n",module_idP,rar->mcs); // LOG_I(MAC,"[UE %d][RAPROC] rar->hopping_flag %d\n",module_idP,rar->hopping_flag);
// LOG_I(MAC,"[UE %d][RAPROC] rar->TPC %d\n",module_idP,rar->TPC); // LOG_I(MAC,"[UE %d][RAPROC] rar->rb_alloc %d\n",module_idP,rar->rb_alloc);
// LOG_I(MAC,"[UE %d][RAPROC] rar->UL_delay %d\n",module_idP,rar->UL_delay); // LOG_I(MAC,"[UE %d][RAPROC] rar->mcs %d\n",module_idP,rar->mcs);
// LOG_I(MAC,"[UE %d][RAPROC] rar->cqi_req %d\n",module_idP,rar->cqi_req); // LOG_I(MAC,"[UE %d][RAPROC] rar->TPC %d\n",module_idP,rar->TPC);
LOG_D(MAC,"[UE %d][RAPROC] rar->t_crnti %x\n",module_idP,(uint16_t)rar[5]+(rar[4]<<8)); // 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_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,
module_idP, CC_id, frameP, ra_rnti); "[UE %d][RAPROC] CC_id %d RAR Frame %d trace pdu for ra-RNTI %x\n",
trace_pdu(1, (uint8_t*)dlsch_buffer, n_rarh + n_rarpy*6, module_idP, 2, ra_rnti, module_idP, CC_id, frameP, ra_rnti);
UE_mac_inst[module_idP].rxFrame, UE_mac_inst[module_idP].rxSubframe, 0, 0); trace_pdu(1, (uint8_t *) dlsch_buffer, n_rarh + n_rarpy * 6,
} module_idP, 2, ra_rnti, UE_mac_inst[module_idP].rxFrame,
UE_mac_inst[module_idP].rxSubframe, 0, 0);
if (preamble_index == rarh->RAPID) { }
*t_crnti = (uint16_t)rar[5]+(rar[4]<<8);//rar->t_crnti;
UE_mac_inst[module_idP].crnti = *t_crnti;//rar->t_crnti; if (preamble_index == rarh->RAPID) {
//return(rar->Timing_Advance_Command); *t_crnti = (uint16_t) rar[5] + (rar[4] << 8); //rar->t_crnti;
ret = ((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4)); UE_mac_inst[module_idP].crnti = *t_crnti; //rar->t_crnti;
} else { //return(rar->Timing_Advance_Command);
UE_mac_inst[module_idP].crnti=0; ret = ((((uint16_t) (rar[0] & 0x7f)) << 4) + (rar[1] >> 4));
ret = (0xffff); } else {
} UE_mac_inst[module_idP].crnti = 0;
ret = (0xffff);
// 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+1, (uint8_t*)rar , 6); // move the selected RAR to the front of the RA_PDSCH buffer
memcpy(selected_rar_buffer + 0, (uint8_t *) rarh, 1);
return ret; memcpy(selected_rar_buffer + 1, (uint8_t *) rar, 6);
return ret;
} }
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -34,25 +34,32 @@ ...@@ -34,25 +34,32 @@
#define __MAC_VARS_H__ #define __MAC_VARS_H__
#ifdef USER_MODE #ifdef USER_MODE
//#include "stdio.h" //#include "stdio.h"
#endif //USER_MODE #endif //USER_MODE
#include "PHY/defs.h" #include "PHY/defs.h"
#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,
// extended bsr table--currently not used 8787, 10287, 12043, 14099,
const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE] = {0,10,13,16,19,23,29,35,43,53,65,80,98,120,147, 16507, 19325, 22624, 26487, 31009, 36304, 42502, 49759, 58255, 68201,
181,223,274,337,414,509,625,769,945,1162,1429, 79846, 93479, 109439, 128125, 150000, 300000
1757,2161,2657,3267,4017,4940,6074,7469,9185, };
11294,13888,17077,20999,25822,31752,39045,48012,
59039,72598,89272,109774,134986,165989,204111, // extended bsr table--currently not used
250990,308634,379519,466683,573866,705666,867737, const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE] =
1067031,1312097,1613447,1984009,2439678,3000000, { 0, 10, 13, 16, 19, 23, 29, 35, 43, 53, 65, 80, 98, 120, 147,
6000000}; 181, 223, 274, 337, 414, 509, 625, 769, 945, 1162, 1429,
1757, 2161, 2657, 3267, 4017, 4940, 6074, 7469, 9185,
11294, 13888, 17077, 20999, 25822, 31752, 39045, 48012,
59039, 72598, 89272, 109774, 134986, 165989, 204111,
250990, 308634, 379519, 466683, 573866, 705666, 867737,
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,24 +71,26 @@ const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE] = {0,10,13,16,19,23,29,35,43,5 ...@@ -64,24 +71,26 @@ 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]= {
{3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}, // 1.4_DCI0_CRC_Size < 38 bits const uint8_t cqi2fmt1x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE] = {
{3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, // 5_DCI0_CRC_SIZE < 43 {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, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0}, // 10_DCI0_CRC_SIZE < 47 {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, 2, 1, 1, 1, 1, 0, 0, 0, 0} // 20_DCI0_CRC_SIZE < 55 {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
}; };
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 const uint8_t cqi2fmt2x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE] = {
{3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, // 5_DCI0_CRC_SIZE = 55 {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, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0}, // 10_DCI0_CRC_SIZE = 59 {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, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0} // 20_DCI0_CRC_SIZE = 64 {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, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0} // 20_DCI0_CRC_SIZE = 64
}; };
//uint32_t EBSR_Level[63]={0,10,13,16,19,23,29,35,43,53,65,80,98,120,147,181}; //uint32_t EBSR_Level[63]={0,10,13,16,19,23,29,35,43,53,65,80,98,120,147,181};
...@@ -89,7 +98,7 @@ const uint8_t cqi2fmt2x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE]= { ...@@ -89,7 +98,7 @@ const uint8_t cqi2fmt2x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE]= {
uint32_t RRC_CONNECTION_FLAG; uint32_t RRC_CONNECTION_FLAG;
UE_MAC_INST *UE_mac_inst; //[NB_MODULE_MAX]; UE_MAC_INST *UE_mac_inst; //[NB_MODULE_MAX];
MAC_RLC_XFACE *Mac_rlc_xface; MAC_RLC_XFACE *Mac_rlc_xface;
/// Primary component carrier index of eNB /// Primary component carrier index of eNB
...@@ -97,39 +106,39 @@ int pCC_id[NUMBER_OF_eNB_MAX]; ...@@ -97,39 +106,39 @@ int pCC_id[NUMBER_OF_eNB_MAX];
eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8 eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8
eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8 eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8
#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
DCI0_5MHz_TDD_1_6_t UL_alloc_pdu; DCI0_5MHz_TDD_1_6_t UL_alloc_pdu;
DCI1A_5MHz_TDD_1_6_t DLSCH_alloc_pdu1A; DCI1A_5MHz_TDD_1_6_t DLSCH_alloc_pdu1A;
DCI1A_5MHz_TDD_1_6_t RA_alloc_pdu; DCI1A_5MHz_TDD_1_6_t RA_alloc_pdu;
DCI1A_5MHz_TDD_1_6_t BCCH_alloc_pdu; DCI1A_5MHz_TDD_1_6_t BCCH_alloc_pdu;
DCI1A_5MHz_TDD_1_6_t CCCH_alloc_pdu; DCI1A_5MHz_TDD_1_6_t CCCH_alloc_pdu;
DCI1_5MHz_TDD_t DLSCH_alloc_pdu; DCI1_5MHz_TDD_t DLSCH_alloc_pdu;
#if defined(Rel10) || defined(Rel14) #if defined(Rel10) || defined(Rel14)
DCI1C_5MHz_t MCCH_alloc_pdu; DCI1C_5MHz_t MCCH_alloc_pdu;
#endif #endif
DCI0_5MHz_FDD_t UL_alloc_pdu_fdd; DCI0_5MHz_FDD_t UL_alloc_pdu_fdd;
DCI1A_5MHz_FDD_t DLSCH_alloc_pdu1A_fdd; DCI1A_5MHz_FDD_t DLSCH_alloc_pdu1A_fdd;
DCI1A_5MHz_FDD_t RA_alloc_pdu_fdd; DCI1A_5MHz_FDD_t RA_alloc_pdu_fdd;
DCI1A_5MHz_FDD_t BCCH_alloc_pdu_fdd; DCI1A_5MHz_FDD_t BCCH_alloc_pdu_fdd;
DCI1A_5MHz_FDD_t CCCH_alloc_pdu_fdd; DCI1A_5MHz_FDD_t CCCH_alloc_pdu_fdd;
DCI1_5MHz_FDD_t DLSCH_alloc_pdu_fdd; DCI1_5MHz_FDD_t DLSCH_alloc_pdu_fdd;
DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu1; DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu1;
DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu2; DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu2;
...@@ -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