From 4af41d2a265f2fdfbe0ba26bdb37bc4ba7706471 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Sat, 3 Feb 2018 07:53:33 -0800 Subject: [PATCH] more correction of indentation --- openair2/LAYER2/MAC/eNB_scheduler_bch.c | 329 +- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 3376 ++++++++++----------- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 2506 +++++++-------- 3 files changed, 2887 insertions(+), 3324 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c index 9a1046ff26..258ca36c02 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c @@ -235,35 +235,28 @@ schedule_SIB1_BR(module_id_t module_idP, 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->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = TBS; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = - eNB->pdu_index[CC_id]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.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, 6); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 6); dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = rvidx; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.transport_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.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.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.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; // Rel10 fields @@ -280,10 +273,7 @@ schedule_SIB1_BR(module_id_t module_idP, dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; // Program TX Request - TX_req = - &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB-> - TX_req - [CC_id].tx_request_body.number_of_pdus]; + TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; TX_req->pdu_length = bcch_sdu_length; TX_req->pdu_index = eNB->pdu_index[CC_id]++; TX_req->num_segments = 1; @@ -315,11 +305,8 @@ schedule_SIB1_BR(module_id_t module_idP, } } -int si_WindowLength_BR_r13tab - [SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_spare] -= { 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 }; +int si_WindowLength_BR_r13tab[SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_spare] = { 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 @@ -354,65 +341,40 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, if (cc->mib->message.schedulingInfoSIB1_BR_r13 == 0) continue; else { - - - AssertFatal(cc-> - sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 - != NULL, + AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 != NULL, "sib_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); - SchedulingInfoList_BR_r13_t *schedulingInfoList_BR_r13 = - cc->sib1_v13ext-> - bandwidthReducedAccessRelatedInfo_r13->schedulingInfoList_BR_r13; + SchedulingInfoList_BR_r13_t *schedulingInfoList_BR_r13 = cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->schedulingInfoList_BR_r13; AssertFatal(schedulingInfoList_BR_r13 != NULL, "sib_v13ext->schedulingInfoList_BR_r13 is null\n"); - SchedulingInfoList_t *schedulingInfoList = - cc->schedulingInfoList; - AssertFatal(schedulingInfoList_BR_r13->list.count == - schedulingInfoList->list.count, + SchedulingInfoList_t *schedulingInfoList = cc->schedulingInfoList; + AssertFatal(schedulingInfoList_BR_r13->list.count == schedulingInfoList->list.count, "schedulingInfolist_BR.r13->list.count %d != schedulingInfoList.list.count %d\n", schedulingInfoList_BR_r13->list.count, schedulingInfoList->list.count); - AssertFatal(cc-> - sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13 - <= - SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200, + AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13<=SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200, "si_WindowLength_BR_r13 %d > %d\n", - (int) cc-> - sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13, + (int) cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13, SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200); // check that SI frequency-hopping is disabled - AssertFatal(cc-> - sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_HoppingConfigCommon_r13 - == - SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_HoppingConfigCommon_r13_off, + AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_HoppingConfigCommon_r13 == SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_HoppingConfigCommon_r13_off, "Deactivate SI_HoppingConfigCommon_r13 in configuration file, not supported for now\n"); - long si_WindowLength_BR_r13 = - si_WindowLength_BR_r13tab[cc-> - sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13]; + long si_WindowLength_BR_r13 = si_WindowLength_BR_r13tab[cc->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, + long si_RepetitionPattern_r13 = cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_RepetitionPattern_r13; + AssertFatal(si_RepetitionPattern_r13<=SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_RepetitionPattern_r13_every8thRF, "si_RepetitionPattern_r13 %d > %d\n", (int) si_RepetitionPattern_r13, SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_RepetitionPattern_r13_every8thRF); // cycle through SIB list for (i = 0; i < schedulingInfoList_BR_r13->list.count; i++) { - long si_Periodicity = - schedulingInfoList->list.array[i]->si_Periodicity; - long si_Narrowband_r13 = - schedulingInfoList_BR_r13->list.array[i]-> - si_Narrowband_r13; - long si_TBS_r13 = - si_TBS_r13tab[schedulingInfoList_BR_r13-> - list.array[i]->si_TBS_r13]; + long si_Periodicity = schedulingInfoList->list.array[i]->si_Periodicity; + long si_Narrowband_r13 = schedulingInfoList_BR_r13->list.array[i]->si_Narrowband_r13; + long si_TBS_r13 = si_TBS_r13tab[schedulingInfoList_BR_r13->list.array[i]->si_TBS_r13]; // check if the SI is to be scheduled now int period_in_sf = 80 << si_Periodicity; // 2^i * 80 subframes, note: si_Periodicity is 2^i * 80ms @@ -434,18 +396,14 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, "RRC provided bcch with length %d > %d (si_TBS_r13 %d)\n", bcch_sdu_length, (int) (si_TBS_r13 >> 3), - (int) schedulingInfoList_BR_r13-> - list.array[i]->si_TBS_r13); + (int) schedulingInfoList_BR_r13->list.array[i]->si_TBS_r13); // allocate all 6 PRBs in narrowband for SIB1_BR // check that SIB1 didn't take this narrowband - if (vrb_map[first_rb] > 0) - continue; + if (vrb_map[first_rb] > 0) continue; - first_rb = - narrowband_to_first_rb(cc, - si_Narrowband_r13 - 1); + first_rb = narrowband_to_first_rb(cc,si_Narrowband_r13 - 1); vrb_map[first_rb] = 1; vrb_map[first_rb + 1] = 1; vrb_map[first_rb + 2] = 1; @@ -465,89 +423,54 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, - 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 = &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.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = - si_TBS_r13 >> 3; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = - eNB->pdu_index[CC_id]; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = - 0xFFFF; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = si_TBS_r13 >> 3; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.resource_block_coding = - getRIV(N_RB_DL, first_rb, 6); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 6); dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.redundancy_version = rvidx; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = rvidx; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.transport_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.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.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.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.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; // Rel10 fields (for PDSCH starting symbol) dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10. - pdsch_start = - cc[CC_id]. - sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; // Rel13 fields dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; 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_rel13.initial_transmission_sf_io = absSF - sf_mod_period; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; dl_req->number_pdu++; dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; // Program TX Request - TX_req = - &eNB->TX_req[CC_id]. - tx_request_body.tx_pdu_list[eNB->TX_req[CC_id]. - tx_request_body.number_of_pdus]; + TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; TX_req->pdu_length = bcch_sdu_length; TX_req->pdu_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++; + 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++; eNB->TX_req[CC_id].sfn_sf = sfn_sf; eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; @@ -620,19 +543,16 @@ schedule_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) 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, sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = - NFAPI_DL_CONFIG_BCH_PDU_TYPE, dl_config_pdu->pdu_size = + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_BCH_PDU_TYPE, dl_config_pdu->pdu_size = 2 + sizeof(nfapi_dl_config_bch_pdu); - dl_config_pdu->bch_pdu.bch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG; - dl_config_pdu->bch_pdu.bch_pdu_rel8.length = mib_sdu_length; - dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index = - eNB->pdu_index[CC_id]; + dl_config_pdu->bch_pdu.bch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG; + dl_config_pdu->bch_pdu.bch_pdu_rel8.length = mib_sdu_length; + dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; dl_config_pdu->bch_pdu.bch_pdu_rel8.transmission_power = 6000; - dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; dl_req->number_pdu++; dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST; @@ -641,9 +561,7 @@ schedule_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) LOG_D(MAC, "eNB->DL_req[0].number_pdu %d (%p)\n", dl_req->number_pdu, &dl_req->number_pdu); // DL request - TX_req = - &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req - [CC_id].tx_request_body.number_of_pdus]; + TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; TX_req->pdu_length = 3; TX_req->pdu_index = eNB->pdu_index[CC_id]++; TX_req->num_segments = 1; @@ -753,114 +671,81 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) } - dl_config_pdu = - &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = - NFAPI_DL_DCI_FORMAT_1A; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level = 4; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFF; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_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->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFF; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_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.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. - new_data_indicator_1 = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - redundancy_version_1 = 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.new_data_indicator_1 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.resource_block_coding = - getRIV(N_RB_DL, first_rb, 4); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); dl_config_request->sfn_sf = sfn_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)) { + 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]; + 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.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = bcch_sdu_length; - 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 + sizeof(nfapi_dl_config_request_p du_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.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = bcch_sdu_length; + 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.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.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++; // Rel10 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; // Rel13 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; - 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 + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; + 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 - dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST; - dl_config_request->sfn_sf = sfn_sf; + dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST; + dl_config_request->sfn_sf = sfn_sf; // Program TX Request - TX_req = - &eNB->TX_req[CC_id]. - tx_request_body.tx_pdu_list[eNB->TX_req[CC_id]. - tx_request_body.number_of_pdus]; + TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; TX_req->pdu_length = bcch_sdu_length; TX_req->pdu_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; + TX_req->segments[0].segment_data = cc->BCCH_pdu.payload; eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; eNB->TX_req[CC_id].sfn_sf = sfn_sf; eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 9f2ab1cba8..4d298f69f5 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -74,13 +74,13 @@ add_ue_dlsch_info(module_id_t module_idP, { //LOG_D(MAC, "%s(module_idP:%d, CC_id:%d, UE_id:%d, subframeP:%d, status:%d) serving_num:%d rnti:%x\n", __FUNCTION__, module_idP, CC_id, UE_id, subframeP, status, eNB_dlsch_info[module_idP][CC_id][UE_id].serving_num, UE_RNTI(module_idP,UE_id)); - eNB_dlsch_info[module_idP][CC_id][UE_id].rnti = - UE_RNTI(module_idP, UE_id); - // eNB_dlsch_info[module_idP][CC_id][ue_mod_idP].weight = weight; - eNB_dlsch_info[module_idP][CC_id][UE_id].subframe = subframeP; - eNB_dlsch_info[module_idP][CC_id][UE_id].status = status; + eNB_dlsch_info[module_idP][CC_id][UE_id].rnti = + UE_RNTI(module_idP, UE_id); + // eNB_dlsch_info[module_idP][CC_id][ue_mod_idP].weight = weight; + eNB_dlsch_info[module_idP][CC_id][UE_id].subframe = subframeP; + eNB_dlsch_info[module_idP][CC_id][UE_id].status = status; - eNB_dlsch_info[module_idP][CC_id][UE_id].serving_num++; + eNB_dlsch_info[module_idP][CC_id][UE_id].serving_num++; } @@ -91,27 +91,25 @@ schedule_next_dlue(module_id_t module_idP, int CC_id, //------------------------------------------------------------------------------ { - int next_ue; - UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; + int next_ue; + UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; - for (next_ue = UE_list->head; next_ue >= 0; - next_ue = UE_list->next[next_ue]) { - if (eNB_dlsch_info[module_idP][CC_id][next_ue].status == - S_DL_WAITING) { - return next_ue; - } + for (next_ue = UE_list->head; next_ue >= 0; + next_ue = UE_list->next[next_ue]) { + if (eNB_dlsch_info[module_idP][CC_id][next_ue].status == + S_DL_WAITING) { + return next_ue; } + } - for (next_ue = UE_list->head; next_ue >= 0; - next_ue = UE_list->next[next_ue]) { - if (eNB_dlsch_info[module_idP][CC_id][next_ue].status == - S_DL_BUFFERED) { - eNB_dlsch_info[module_idP][CC_id][next_ue].status = - S_DL_WAITING; - } + for (next_ue = UE_list->head; next_ue >= 0; + next_ue = UE_list->next[next_ue]) { + if (eNB_dlsch_info[module_idP][CC_id][next_ue].status == S_DL_BUFFERED) { + eNB_dlsch_info[module_idP][CC_id][next_ue].status = S_DL_WAITING; } + } - return (-1); //next_ue; + return (-1); //next_ue; } @@ -129,187 +127,183 @@ generate_dlsch_header(unsigned char *mac_header, //------------------------------------------------------------------------------ { - SCH_SUBHEADER_FIXED *mac_header_ptr = - (SCH_SUBHEADER_FIXED *) mac_header; - uint8_t first_element = 0, last_size = 0, i; - uint8_t mac_header_control_elements[16], *ce_ptr; + SCH_SUBHEADER_FIXED *mac_header_ptr = (SCH_SUBHEADER_FIXED *) mac_header; + uint8_t first_element = 0, last_size = 0, i; + uint8_t mac_header_control_elements[16], *ce_ptr; - ce_ptr = &mac_header_control_elements[0]; + ce_ptr = &mac_header_control_elements[0]; - // compute header components + // compute header components - if ((short_padding == 1) || (short_padding == 2)) { - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_PADDING; - first_element = 1; - last_size = 1; + if ((short_padding == 1) || (short_padding == 2)) { + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = SHORT_PADDING; + first_element = 1; + last_size = 1; + } + + if (short_padding == 2) { + mac_header_ptr->E = 1; + mac_header_ptr++; + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = SHORT_PADDING; + last_size = 1; + } + + if (drx_cmd != 255) { + if (first_element > 0) { + mac_header_ptr->E = 1; + mac_header_ptr++; + } else { + first_element = 1; } - if (short_padding == 2) { - mac_header_ptr->E = 1; - mac_header_ptr++; - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_PADDING; - last_size = 1; + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = DRX_CMD; + last_size = 1; + } + + if (timing_advance_cmd != 31) { + if (first_element > 0) { + mac_header_ptr->E = 1; + mac_header_ptr++; + } else { + first_element = 1; } - if (drx_cmd != 255) { - if (first_element > 0) { - mac_header_ptr->E = 1; - mac_header_ptr++; - } else { - first_element = 1; - } + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = TIMING_ADV_CMD; + last_size = 1; + // msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); + ((TIMING_ADVANCE_CMD *) ce_ptr)->R = 0; + AssertFatal(timing_advance_cmd < 64, + "timing_advance_cmd %d > 63\n", timing_advance_cmd); + ((TIMING_ADVANCE_CMD *) ce_ptr)->TA = timing_advance_cmd; //(timing_advance_cmd+31)&0x3f; + LOG_D(MAC, "timing advance =%d (%d)\n", timing_advance_cmd, + ((TIMING_ADVANCE_CMD *) ce_ptr)->TA); + ce_ptr += sizeof(TIMING_ADVANCE_CMD); + //msg("offset %d\n",ce_ptr-mac_header_control_elements); + } - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = DRX_CMD; - last_size = 1; + if (ue_cont_res_id) { + if (first_element > 0) { + mac_header_ptr->E = 1; + /* + printf("[eNB][MAC] last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); + */ + mac_header_ptr++; + } else { + first_element = 1; } - if (timing_advance_cmd != 31) { - if (first_element > 0) { - mac_header_ptr->E = 1; - mac_header_ptr++; - } else { - first_element = 1; - } + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = UE_CONT_RES; + last_size = 1; - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = TIMING_ADV_CMD; - last_size = 1; - // msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); - ((TIMING_ADVANCE_CMD *) ce_ptr)->R = 0; - AssertFatal(timing_advance_cmd < 64, - "timing_advance_cmd %d > 63\n", timing_advance_cmd); - ((TIMING_ADVANCE_CMD *) ce_ptr)->TA = timing_advance_cmd; //(timing_advance_cmd+31)&0x3f; - LOG_D(MAC, "timing advance =%d (%d)\n", timing_advance_cmd, - ((TIMING_ADVANCE_CMD *) ce_ptr)->TA); - ce_ptr += sizeof(TIMING_ADVANCE_CMD); - //msg("offset %d\n",ce_ptr-mac_header_control_elements); + LOG_T(MAC, + "[eNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n", + ue_cont_res_id[0], ue_cont_res_id[1], ue_cont_res_id[2], + ue_cont_res_id[3], ue_cont_res_id[4], ue_cont_res_id[5]); + + memcpy(ce_ptr, ue_cont_res_id, 6); + ce_ptr += 6; + // msg("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements); + } + //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); + + for (i = 0; i < num_sdus; i++) { + LOG_T(MAC, "[eNB] Generate DLSCH header num sdu %d len sdu %d\n", + num_sdus, sdu_lengths[i]); + + if (first_element > 0) { + mac_header_ptr->E = 1; + /*msg("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); + */ + mac_header_ptr += last_size; + //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); + } else { + first_element = 1; } - if (ue_cont_res_id) { - if (first_element > 0) { - mac_header_ptr->E = 1; - /* - printf("[eNB][MAC] last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); - */ - mac_header_ptr++; - } else { - first_element = 1; - } - - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = UE_CONT_RES; - last_size = 1; - - LOG_T(MAC, - "[eNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n", - ue_cont_res_id[0], ue_cont_res_id[1], ue_cont_res_id[2], - ue_cont_res_id[3], ue_cont_res_id[4], ue_cont_res_id[5]); - - memcpy(ce_ptr, ue_cont_res_id, 6); - ce_ptr += 6; - // msg("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements); - } - //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); - - for (i = 0; i < num_sdus; i++) { - LOG_T(MAC, "[eNB] Generate DLSCH header num sdu %d len sdu %d\n", - num_sdus, sdu_lengths[i]); - - if (first_element > 0) { - mac_header_ptr->E = 1; - /*msg("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); - */ - mac_header_ptr += last_size; - //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); - } else { - first_element = 1; - } - - if (sdu_lengths[i] < 128) { - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->R = 0; - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->E = 0; - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F = 0; - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->LCID = sdu_lcids[i]; - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L = - (unsigned char) sdu_lengths[i]; - last_size = 2; - } else { - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->R = 0; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->E = 0; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->F = 1; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->LCID = sdu_lcids[i]; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB = - ((unsigned short) sdu_lengths[i] >> 8) & 0x7f; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB = - (unsigned short) sdu_lengths[i] & 0xff; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->padding = 0x00; - last_size = 3; + if (sdu_lengths[i] < 128) { + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->R = 0; + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->E = 0; + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F = 0; + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->LCID = sdu_lcids[i]; + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L = (unsigned char) sdu_lengths[i]; + last_size = 2; + } else { + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->R = 0; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->E = 0; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->F = 1; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->LCID = sdu_lcids[i]; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB = ((unsigned short) sdu_lengths[i] >> 8) & 0x7f; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB = (unsigned short) sdu_lengths[i] & 0xff; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->padding = 0x00; + last_size = 3; #ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, - "[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n", - sdu_lengths[i], - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB, - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB); + LOG_D(MAC, + "[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n", + sdu_lengths[i], + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB, + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB); #endif - } } + } - /* + /* - printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); + printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); - printf("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); + printf("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); - if (((SCH_SUBHEADER_FIXED*)mac_header_ptr)->LCID < UE_CONT_RES) { - if (((SCH_SUBHEADER_SHORT*)mac_header_ptr)->F == 0) - printf("F = 0, sdu len (L field) %d\n",(((SCH_SUBHEADER_SHORT*)mac_header_ptr)->L)); - else - printf("F = 1, sdu len (L field) %d\n",(((SCH_SUBHEADER_LONG*)mac_header_ptr)->L)); - } - */ - if (post_padding > 0) { // we have lots of padding at the end of the packet - mac_header_ptr->E = 1; - mac_header_ptr += last_size; - // add a padding element - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_PADDING; - mac_header_ptr++; - } else { // no end of packet padding - // last SDU subhead is of fixed type (sdu length implicitly to be computed at UE) - mac_header_ptr++; + if (((SCH_SUBHEADER_FIXED*)mac_header_ptr)->LCID < UE_CONT_RES) { + if (((SCH_SUBHEADER_SHORT*)mac_header_ptr)->F == 0) + printf("F = 0, sdu len (L field) %d\n",(((SCH_SUBHEADER_SHORT*)mac_header_ptr)->L)); + else + printf("F = 1, sdu len (L field) %d\n",(((SCH_SUBHEADER_LONG*)mac_header_ptr)->L)); } + */ + if (post_padding > 0) { // we have lots of padding at the end of the packet + mac_header_ptr->E = 1; + mac_header_ptr += last_size; + // add a padding element + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = SHORT_PADDING; + mac_header_ptr++; + } else { // no end of packet padding + // last SDU subhead is of fixed type (sdu length implicitly to be computed at UE) + mac_header_ptr++; + } - //msg("After subheaders %d\n",(uint8_t*)mac_header_ptr - mac_header); + //msg("After subheaders %d\n",(uint8_t*)mac_header_ptr - mac_header); - if ((ce_ptr - mac_header_control_elements) > 0) { - // printf("Copying %d bytes for control elements\n",ce_ptr-mac_header_control_elements); - memcpy((void *) mac_header_ptr, mac_header_control_elements, - ce_ptr - mac_header_control_elements); - mac_header_ptr += - (unsigned char) (ce_ptr - mac_header_control_elements); - } - //msg("After CEs %d\n",(uint8_t*)mac_header_ptr - mac_header); + if ((ce_ptr - mac_header_control_elements) > 0) { + // printf("Copying %d bytes for control elements\n",ce_ptr-mac_header_control_elements); + memcpy((void *) mac_header_ptr, mac_header_control_elements, + ce_ptr - mac_header_control_elements); + mac_header_ptr += + (unsigned char) (ce_ptr - mac_header_control_elements); + } + //msg("After CEs %d\n",(uint8_t*)mac_header_ptr - mac_header); - return ((unsigned char *) mac_header_ptr - mac_header); + return ((unsigned char *) mac_header_ptr - mac_header); } @@ -320,94 +314,94 @@ set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP, //------------------------------------------------------------------------------ { - eNB_MAC_INST *eNB = RC.mac[module_idP]; - UE_list_t *UE_list = &eNB->UE_list; - unsigned char DAI; - COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; - if (cc->tdd_Config != NULL) { //TDD - DAI = (UE_list->UE_template[CC_idP][UE_idP].DAI - 1) & 3; - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d, subframe %d: DAI %d for UE %d\n", - module_idP, CC_idP, frameP, subframeP, DAI, UE_idP); - // Save DAI for Format 0 DCI + eNB_MAC_INST *eNB = RC.mac[module_idP]; + UE_list_t *UE_list = &eNB->UE_list; + unsigned char DAI; + COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; + if (cc->tdd_Config != NULL) { //TDD + DAI = (UE_list->UE_template[CC_idP][UE_idP].DAI - 1) & 3; + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d, subframe %d: DAI %d for UE %d\n", + module_idP, CC_idP, frameP, subframeP, DAI, UE_idP); + // Save DAI for Format 0 DCI - switch (cc->tdd_Config->subframeAssignment) { - case 0: - // if ((subframeP==0)||(subframeP==1)||(subframeP==5)||(subframeP==6)) - break; + switch (cc->tdd_Config->subframeAssignment) { + case 0: + // if ((subframeP==0)||(subframeP==1)||(subframeP==5)||(subframeP==6)) + break; - case 1: - switch (subframeP) { - case 1: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[7] = DAI; - break; + case 1: + switch (subframeP) { + case 1: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[7] = DAI; + break; - case 4: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[8] = DAI; - break; + case 4: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[8] = DAI; + break; - case 6: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; - break; + case 6: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; + break; - case 9: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; - break; - } + case 9: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; + break; + } - case 2: - // if ((subframeP==3)||(subframeP==8)) - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; - break; + case 2: + // if ((subframeP==3)||(subframeP==8)) + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; + break; - case 3: + case 3: - //if ((subframeP==6)||(subframeP==8)||(subframeP==0)) { - // LOG_D(MAC,"schedule_ue_spec: setting UL DAI to %d for subframeP %d => %d\n",DAI,subframeP, ((subframeP+8)%10)>>1); - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul[((subframeP+8)%10)>>1] = DAI; - //} - switch (subframeP) { - case 5: - case 6: - case 1: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; - break; + //if ((subframeP==6)||(subframeP==8)||(subframeP==0)) { + // LOG_D(MAC,"schedule_ue_spec: setting UL DAI to %d for subframeP %d => %d\n",DAI,subframeP, ((subframeP+8)%10)>>1); + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul[((subframeP+8)%10)>>1] = DAI; + //} + switch (subframeP) { + case 5: + case 6: + case 1: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; + break; - case 7: - case 8: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; - break; + case 7: + case 8: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; + break; - case 9: - case 0: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[4] = DAI; - break; + case 9: + case 0: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[4] = DAI; + break; - default: - break; - } + default: + break; + } - break; + break; - case 4: - // if ((subframeP==8)||(subframeP==9)) - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; - break; + case 4: + // if ((subframeP==8)||(subframeP==9)) + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; + break; - case 5: - // if (subframeP==8) - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; - break; + case 5: + // if (subframeP==8) + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; + break; - case 6: - // if ((subframeP==1)||(subframeP==4)||(subframeP==6)||(subframeP==9)) - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; - break; + case 6: + // if ((subframeP==1)||(subframeP==4)||(subframeP==6)||(subframeP==9)) + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; + break; - default: - break; - } + default: + break; } + } } @@ -421,1106 +415,977 @@ schedule_ue_spec(module_id_t module_idP, { - uint8_t CC_id; - int UE_id; - unsigned char aggregation; - mac_rlc_status_resp_t rlc_status; - unsigned char header_len_dcch = 0, header_len_dcch_tmp = 0; - unsigned char header_len_dtch = 0, header_len_dtch_tmp = - 0, header_len_dtch_last = 0; - unsigned char ta_len = 0; - unsigned char sdu_lcids[NB_RB_MAX], lcid, offset, num_sdus = 0; - uint16_t nb_rb, nb_rb_temp, nb_available_rb; - uint16_t TBS, j, sdu_lengths[NB_RB_MAX], rnti, padding = - 0, post_padding = 0; - unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; - unsigned char round = 0; - unsigned char harq_pid = 0; - eNB_UE_STATS *eNB_UE_stats = NULL; - uint16_t sdu_length_total = 0; + uint8_t CC_id; + int UE_id; + unsigned char aggregation; + mac_rlc_status_resp_t rlc_status; + unsigned char header_len_dcch = 0, header_len_dcch_tmp = 0; + unsigned char header_len_dtch = 0, header_len_dtch_tmp = + 0, header_len_dtch_last = 0; + unsigned char ta_len = 0; + unsigned char sdu_lcids[NB_RB_MAX], lcid, offset, num_sdus = 0; + uint16_t nb_rb, nb_rb_temp, nb_available_rb; + uint16_t TBS, j, sdu_lengths[NB_RB_MAX], rnti, padding = + 0, post_padding = 0; + unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; + unsigned char round = 0; + unsigned char harq_pid = 0; + eNB_UE_STATS *eNB_UE_stats = NULL; + uint16_t sdu_length_total = 0; - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc = eNB->common_channels; - UE_list_t *UE_list = &eNB->UE_list; - int continue_flag = 0; - int32_t normalized_rx_power, target_rx_power; - int32_t tpc = 1; - static int32_t tpc_accumulated = 0; - UE_sched_ctrl *ue_sched_ctl; - int mcs; - int i; - int min_rb_unit[MAX_NUM_CCs]; - int N_RB_DL[MAX_NUM_CCs]; - int total_nb_available_rb[MAX_NUM_CCs]; - int N_RBG[MAX_NUM_CCs]; - nfapi_dl_config_request_body_t *dl_req; - nfapi_dl_config_request_pdu_t *dl_config_pdu; - int tdd_sfa; - int ta_update; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = eNB->common_channels; + UE_list_t *UE_list = &eNB->UE_list; + int continue_flag = 0; + int32_t normalized_rx_power, target_rx_power; + int32_t tpc = 1; + static int32_t tpc_accumulated = 0; + UE_sched_ctrl *ue_sched_ctl; + int mcs; + int i; + int min_rb_unit[MAX_NUM_CCs]; + int N_RB_DL[MAX_NUM_CCs]; + int total_nb_available_rb[MAX_NUM_CCs]; + int N_RBG[MAX_NUM_CCs]; + nfapi_dl_config_request_body_t *dl_req; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + int tdd_sfa; + int ta_update; #if 0 - if (UE_list->head == -1) { - return; - } + if (UE_list->head == -1) { + return; + } #endif - start_meas(&eNB->schedule_dlsch); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN); + start_meas(&eNB->schedule_dlsch); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN); - // for TDD: check that we have to act here, otherwise return - if (cc[0].tdd_Config) { - tdd_sfa = cc[0].tdd_Config->subframeAssignment; - switch (subframeP) { - case 0: - // always continue - break; + // for TDD: check that we have to act here, otherwise return + if (cc[0].tdd_Config) { + tdd_sfa = cc[0].tdd_Config->subframeAssignment; + switch (subframeP) { + case 0: + // always continue + break; + case 1: + return; + break; + case 2: + return; + break; + case 3: + if ((tdd_sfa != 2) && (tdd_sfa != 5)) + return; + break; + case 4: + if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4) + && (tdd_sfa != 5)) + return; + break; + case 5: + break; + case 6: + case 7: + if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4) + && (tdd_sfa != 5)) + return; + break; + case 8: + if ((tdd_sfa != 2) && (tdd_sfa != 3) && (tdd_sfa != 4) + && (tdd_sfa != 5)) + return; + break; + case 9: + if ((tdd_sfa != 1) && (tdd_sfa != 3) && (tdd_sfa != 4) + && (tdd_sfa != 6)) + return; + break; + + } + } + //weight = get_ue_weight(module_idP,UE_id); + aggregation = 2; + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + N_RB_DL[CC_id] = to_prb(cc[CC_id].mib->message.dl_Bandwidth); + min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id); + // get number of PRBs less those used by common channels + total_nb_available_rb[CC_id] = N_RB_DL[CC_id]; + for (i = 0; i < N_RB_DL[CC_id]; i++) + if (cc[CC_id].vrb_map[i] != 0) + total_nb_available_rb[CC_id]--; + + N_RBG[CC_id] = to_rbg(cc[CC_id].mib->message.dl_Bandwidth); + + // store the global enb stats: + eNB->eNB_stats[CC_id].num_dlactive_UEs = UE_list->num_UEs; + eNB->eNB_stats[CC_id].available_prbs = total_nb_available_rb[CC_id]; + eNB->eNB_stats[CC_id].total_available_prbs += total_nb_available_rb[CC_id]; + eNB->eNB_stats[CC_id].dlsch_bytes_tx = 0; + eNB->eNB_stats[CC_id].dlsch_pdus_tx = 0; + } + + /// CALLING Pre_Processor for downlink scheduling (Returns estimation of RBs required by each UE and the allocation on sub-band) + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_IN); + start_meas(&eNB->schedule_dlsch_preprocessor); + dlsch_scheduler_pre_processor(module_idP, + frameP, subframeP, N_RBG, mbsfn_flag); + stop_meas(&eNB->schedule_dlsch_preprocessor); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT); + + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n", CC_id); + + dl_req = &eNB->DL_req[CC_id].dl_config_request_body; + + if (mbsfn_flag[CC_id] > 0) + continue; + + for (UE_id = UE_list->head; UE_id >= 0; + UE_id = UE_list->next[UE_id]) { + continue_flag = 0; // reset the flag to allow allocation for the remaining UEs + rnti = UE_RNTI(module_idP, UE_id); + eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + + + if (rnti == NOT_A_RNTI) { + LOG_D(MAC, "Cannot find rnti for UE_id %d (num_UEs %d)\n", + UE_id, UE_list->num_UEs); + continue_flag = 1; + } + + if (eNB_UE_stats == NULL) { + LOG_D(MAC, "[eNB] Cannot find eNB_UE_stats\n"); + continue_flag = 1; + } + + if (continue_flag != 1) { + switch (get_tmode(module_idP, CC_id, UE_id)) { case 1: - return; - break; case 2: - return; - break; - case 3: - if ((tdd_sfa != 2) && (tdd_sfa != 5)) - return; - break; - case 4: - if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4) - && (tdd_sfa != 5)) - return; - break; - case 5: - break; - case 6: case 7: - if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4) - && (tdd_sfa != 5)) - return; - break; - case 8: - if ((tdd_sfa != 2) && (tdd_sfa != 3) && (tdd_sfa != 4) - && (tdd_sfa != 5)) - return; - break; - case 9: - if ((tdd_sfa != 1) && (tdd_sfa != 3) && (tdd_sfa != 4) - && (tdd_sfa != 6)) - return; - break; - + aggregation = + get_aggregation(get_bw_index(module_idP, CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format1); + break; + case 3: + aggregation = + get_aggregation(get_bw_index(module_idP, CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format2A); + break; + default: + LOG_W(MAC, "Unsupported transmission mode %d\n", + get_tmode(module_idP, CC_id, UE_id)); + aggregation = 2; } - } - //weight = get_ue_weight(module_idP,UE_id); - aggregation = 2; - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - N_RB_DL[CC_id] = to_prb(cc[CC_id].mib->message.dl_Bandwidth); - min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id); - // get number of PRBs less those used by common channels - total_nb_available_rb[CC_id] = N_RB_DL[CC_id]; - for (i = 0; i < N_RB_DL[CC_id]; i++) - if (cc[CC_id].vrb_map[i] != 0) - total_nb_available_rb[CC_id]--; + } + /* if (continue_flag != 1 */ + if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated + CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, + aggregation, rnti)) { + LOG_D(MAC, + "[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n", + module_idP, frameP, UE_id, CC_id); + continue_flag = 1; //to next user (there might be rbs availiable for other UEs in TM5 + } - N_RBG[CC_id] = to_rbg(cc[CC_id].mib->message.dl_Bandwidth); + if (cc[CC_id].tdd_Config != NULL) { //TDD + set_ue_dai(subframeP, + UE_id, + CC_id, + cc[CC_id].tdd_Config->subframeAssignment, + UE_list); + // update UL DAI after DLSCH scheduling + set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP); + } - // store the global enb stats: - eNB->eNB_stats[CC_id].num_dlactive_UEs = UE_list->num_UEs; - eNB->eNB_stats[CC_id].available_prbs = - total_nb_available_rb[CC_id]; - eNB->eNB_stats[CC_id].total_available_prbs += - total_nb_available_rb[CC_id]; - eNB->eNB_stats[CC_id].dlsch_bytes_tx = 0; - eNB->eNB_stats[CC_id].dlsch_pdus_tx = 0; - } - - /// CALLING Pre_Processor for downlink scheduling (Returns estimation of RBs required by each UE and the allocation on sub-band) - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_IN); - start_meas(&eNB->schedule_dlsch_preprocessor); - dlsch_scheduler_pre_processor(module_idP, - frameP, subframeP, N_RBG, mbsfn_flag); - stop_meas(&eNB->schedule_dlsch_preprocessor); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT); - - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n", CC_id); - - dl_req = &eNB->DL_req[CC_id].dl_config_request_body; - - if (mbsfn_flag[CC_id] > 0) - continue; - - for (UE_id = UE_list->head; UE_id >= 0; - UE_id = UE_list->next[UE_id]) { - continue_flag = 0; // reset the flag to allow allocation for the remaining UEs - rnti = UE_RNTI(module_idP, UE_id); - eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - - - if (rnti == NOT_A_RNTI) { - LOG_D(MAC, "Cannot find rnti for UE_id %d (num_UEs %d)\n", - UE_id, UE_list->num_UEs); - continue_flag = 1; - } - - if (eNB_UE_stats == NULL) { - LOG_D(MAC, "[eNB] Cannot find eNB_UE_stats\n"); - continue_flag = 1; - } - - if (continue_flag != 1) { - switch (get_tmode(module_idP, CC_id, UE_id)) { - case 1: - case 2: - case 7: - aggregation = - get_aggregation(get_bw_index(module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format1); - break; - case 3: - aggregation = - get_aggregation(get_bw_index(module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format2A); - break; - default: - LOG_W(MAC, "Unsupported transmission mode %d\n", - get_tmode(module_idP, CC_id, UE_id)); - aggregation = 2; - } - } - /* if (continue_flag != 1 */ - if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated - CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, - aggregation, rnti)) { - LOG_D(MAC, - "[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n", - module_idP, frameP, UE_id, CC_id); - continue_flag = 1; //to next user (there might be rbs availiable for other UEs in TM5 - } - - if (cc[CC_id].tdd_Config != NULL) { //TDD - set_ue_dai(subframeP, - UE_id, - CC_id, - cc[CC_id].tdd_Config->subframeAssignment, - UE_list); - // update UL DAI after DLSCH scheduling - set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP); - } - - if (continue_flag == 1) { - add_ue_dlsch_info(module_idP, - CC_id, UE_id, subframeP, S_DL_NONE); - continue; - } + if (continue_flag == 1) { + add_ue_dlsch_info(module_idP, + CC_id, UE_id, subframeP, S_DL_NONE); + continue; + } #warning RK->CR This old API call has to be revisited for FAPI, or logic must be changed #if 0 - /* add "fake" DCI to have CCE_allocation_infeasible work properly for next allocations */ - /* if we don't add it, next allocations may succeed but overall allocations may fail */ - /* will be removed at the end of this function */ - add_ue_spec_dci(&eNB->common_channels[CC_id].DCI_pdu, &(char[]) { - 0}, rnti, 1, aggregation, 1, format1, 0); + /* add "fake" DCI to have CCE_allocation_infeasible work properly for next allocations */ + /* if we don't add it, next allocations may succeed but overall allocations may fail */ + /* will be removed at the end of this function */ + add_ue_spec_dci(&eNB->common_channels[CC_id].DCI_pdu, &(char[]) { + 0}, rnti, 1, aggregation, 1, format1, 0); #endif - nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id]; + nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id]; - if (cc->tdd_Config) - harq_pid = ((frameP * 10) + subframeP) % 10; - else - harq_pid = ((frameP * 10) + subframeP) & 7; + if (cc->tdd_Config) harq_pid = ((frameP * 10) + subframeP) % 10; + else harq_pid = ((frameP * 10) + subframeP) & 7; - round = ue_sched_ctl->round[CC_id][harq_pid]; + round = ue_sched_ctl->round[CC_id][harq_pid]; - UE_list->eNB_UE_stats[CC_id][UE_id].crnti = rnti; - UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status = - mac_eNB_get_rrc_status(module_idP, rnti); - UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; - UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round; + UE_list->eNB_UE_stats[CC_id][UE_id].crnti = rnti; + UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status = mac_eNB_get_rrc_status(module_idP, rnti); + UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; + UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round; - if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status < - RRC_CONNECTED) - continue; + if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status < RRC_CONNECTED) continue; - sdu_length_total = 0; - num_sdus = 0; + sdu_length_total = 0; + num_sdus = 0; - /* - DevCheck(((eNB_UE_stats->dl_cqi < MIN_CQI_VALUE) || (eNB_UE_stats->dl_cqi > MAX_CQI_VALUE)), - eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE); - */ - if (nfapi_mode) { - eNB_UE_stats->dlsch_mcs1 = 10;//cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; - } - else { - eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; - } - eNB_UE_stats->dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; //cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); + /* + DevCheck(((eNB_UE_stats->dl_cqi < MIN_CQI_VALUE) || (eNB_UE_stats->dl_cqi > MAX_CQI_VALUE)), + eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE); + */ + if (nfapi_mode) { + eNB_UE_stats->dlsch_mcs1 = 10;//cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; + } + else { + eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; + } + eNB_UE_stats->dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; //cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); - // store stats - //UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->dl_cqi; + // store stats + //UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->dl_cqi; - // initializing the rb allocation indicator for each UE - for (j = 0; j < N_RBG[CC_id]; j++) { - UE_list-> - UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] - = 0; - } + // initializing the rb allocation indicator for each UE + for (j = 0; j < N_RBG[CC_id]; j++) { + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = 0; + } + LOG_D(MAC, + "[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n", + module_idP, frameP, UE_id, CC_id, rnti, harq_pid, round, + nb_available_rb, ue_sched_ctl->dl_cqi[CC_id], + eNB_UE_stats->dlsch_mcs1, + UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status); + + + + /* process retransmission */ + + if (round != 8) { + + // get freq_allocation + nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + TBS = get_TBS_DL(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid], + nb_rb); + + if (nb_rb <= nb_available_rb) { + if (cc[CC_id].tdd_Config != NULL) { + UE_list->UE_template[CC_id][UE_id].DAI++; + update_ul_dci(module_idP, CC_id, rnti, + UE_list->UE_template[CC_id][UE_id]. + DAI); LOG_D(MAC, - "[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n", - module_idP, frameP, UE_id, CC_id, rnti, harq_pid, round, - nb_available_rb, ue_sched_ctl->dl_cqi[CC_id], - eNB_UE_stats->dlsch_mcs1, - UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status); + "DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n", + CC_id, subframeP, UE_id, + UE_list->UE_template[CC_id][UE_id].DAI); + } + if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { + for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + } + } else { + nb_rb_temp = nb_rb; + j = 0; + while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { + if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { + if (UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]) + printf("WARN: rballoc_subband not free for retrans?\n"); + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - /* process retransmission */ - - if (round != 8) { - - // get freq_allocation - nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - TBS = - get_TBS_DL(UE_list-> - UE_template[CC_id][UE_id].oldmcs1[harq_pid], - nb_rb); - - if (nb_rb <= nb_available_rb) { - if (cc[CC_id].tdd_Config != NULL) { - UE_list->UE_template[CC_id][UE_id].DAI++; - update_ul_dci(module_idP, CC_id, rnti, - UE_list->UE_template[CC_id][UE_id]. - DAI); - LOG_D(MAC, - "DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n", - CC_id, subframeP, UE_id, - UE_list->UE_template[CC_id][UE_id].DAI); - } - - if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { - for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band - UE_list->UE_template[CC_id][UE_id]. - rballoc_subband[harq_pid][j] = - ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - } - } else { - nb_rb_temp = nb_rb; - j = 0; - - while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { - if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == - 1) { - if (UE_list-> - UE_template[CC_id] - [UE_id].rballoc_subband[harq_pid][j]) - printf - ("WARN: rballoc_subband not free for retrans?\n"); - UE_list-> - UE_template[CC_id] - [UE_id].rballoc_subband[harq_pid][j] = - ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - - if ((j == N_RBG[CC_id] - 1) && - ((N_RB_DL[CC_id] == 25) || - (N_RB_DL[CC_id] == 50))) { - nb_rb_temp = - nb_rb_temp - min_rb_unit[CC_id] + - 1; - } else { - nb_rb_temp = - nb_rb_temp - min_rb_unit[CC_id]; - } - } - - j = j + 1; - } - } - - nb_available_rb -= nb_rb; - /* - eNB->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; - eNB->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id]; - - for(j=0; jmu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; - } - */ - - switch (get_tmode(module_idP, CC_id, UE_id)) { - case 1: - case 2: - case 7: - default: - LOG_D(MAC,"retransmission DL_REQ: rnti:%x\n",rnti); - - 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_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + - sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - dci_format = NFAPI_DL_DCI_FORMAT_1; - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level = - get_aggregation(get_bw_index - (module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format1); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = - rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - harq_process = harq_pid; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // dont adjust power when retransmitting - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.new_data_indicator_1 = - UE_list->UE_template[CC_id][UE_id]. - oldNDI[harq_pid]; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = - UE_list->UE_template[CC_id][UE_id]. - oldmcs1[harq_pid]; - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.redundancy_version_1 = - round & 3; - - if (cc[CC_id].tdd_Config != NULL) { //TDD - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.downlink_assignment_index = - (UE_list->UE_template[CC_id][UE_id].DAI - - 1) & 3; - LOG_D(MAC, - "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n", - module_idP, CC_id, harq_pid, round, - (UE_list->UE_template[CC_id][UE_id].DAI - - 1), - UE_list-> - UE_template[CC_id][UE_id].oldmcs1 - [harq_pid]); - } else { - LOG_D(MAC, - "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n", - module_idP, CC_id, harq_pid, round, - UE_list-> - UE_template[CC_id][UE_id].oldmcs1 - [harq_pid]); - - } - if (!CCE_allocation_infeasible - (module_idP, CC_id, 1, subframeP, - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level, rnti)) { - dl_req->number_dci++; - dl_req->number_pdu++; - dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - - eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; - eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; - - fill_nfapi_dlsch_config(eNB, dl_req, TBS, -1 - /* retransmission, no pdu_index */ - , rnti, 0, // type 0 allocation from 7.1.6 in 36.213 - 0, // virtual_resource_block_assignment_flag, unused here - 0, // resource_block_coding, to be filled in later - getQm(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]), round & 3, // redundancy version - 1, // transport blocks - 0, // transport block to codeword swap flag - cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme - 1, // number of layers - 1, // number of subbands - // uint8_t codebook_index, - 4, // UE category capacity - UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0, // delta_power_offset for TM5 - 0, // ngap - 0, // nprb - cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode - 0, //number of PRBs treated as one subband, not used here - 0 // number of beamforming vectors, not used here - ); - - LOG_D(MAC, - "Filled NFAPI configuration for DCI/DLSCH %d, retransmission round %d\n", - eNB->pdu_index[CC_id], round); - - program_dlsch_acknak(module_idP, CC_id, UE_id, - frameP, subframeP, - dl_config_pdu-> - dci_dl_pdu.dci_dl_pdu_rel8. - cce_idx); - // No TX request for retransmission (check if null request for FAPI) - } else { - LOG_W(MAC, - "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d\%x, infeasible CCE allocation\n", - frameP, subframeP, UE_id, rnti); - } - } - - - add_ue_dlsch_info(module_idP, - CC_id, UE_id, subframeP, - S_DL_SCHEDULED); - - //eNB_UE_stats->dlsch_trials[round]++; - UE_list->eNB_UE_stats[CC_id][UE_id]. - num_retransmission += 1; - UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx = - nb_rb; - UE_list->eNB_UE_stats[CC_id][UE_id]. - total_rbs_used_retx += nb_rb; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = - eNB_UE_stats->dlsch_mcs1; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = - eNB_UE_stats->dlsch_mcs1; + if ((j == N_RBG[CC_id] - 1) && + ((N_RB_DL[CC_id] == 25) || + (N_RB_DL[CC_id] == 50))) { + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1; } else { - LOG_D(MAC, - "[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n", - module_idP, frameP, CC_id, UE_id); + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; } - } else { /* This is a potentially new SDU opportunity */ - - rlc_status.bytes_in_buffer = 0; - // Now check RLC information to compute number of required RBs - // get maximum TBS size for RLC request - TBS = - get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb); - // check first for RLC data on DCCH - // add the length for all the control elements (timing adv, drx, etc) : header + payload - - if (ue_sched_ctl->ta_timer == 0) { - ta_update = ue_sched_ctl->ta_update; - /* if we send TA then set timer to not send it for a while */ - if (ta_update != 31) - ue_sched_ctl->ta_timer = 20; - /* reset ta_update */ - ue_sched_ctl->ta_update = 31; - } else { - ta_update = 31; - } - - ta_len = (ta_update != 31) ? 2 : 0; - - header_len_dcch = 2; // 2 bytes DCCH SDU subheader - - if (TBS - ta_len - header_len_dcch > 0) { - rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, (TBS - ta_len - header_len_dcch)); // transport block set size - - sdu_lengths[0] = 0; - - if (rlc_status.bytes_in_buffer > 0) { // There is DCCH to transmit - LOG_D(MAC, - "[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", - module_idP, frameP, subframeP, CC_id, - TBS - header_len_dcch); - sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, TBS, //not used - (char *) - &dlsch_buffer - [0]); - - T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), T_INT(DCCH), - T_INT(sdu_lengths[0])); - - LOG_D(MAC, - "[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n", - module_idP, CC_id, sdu_lengths[0]); - sdu_length_total = sdu_lengths[0]; - sdu_lcids[0] = DCCH; - UE_list->eNB_UE_stats[CC_id][UE_id]. - num_pdu_tx[DCCH] += 1; - UE_list-> - eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH] - += sdu_lengths[0]; - num_sdus = 1; -#ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC, - "[eNB %d][DCCH] CC_id %d Got %d bytes :", - module_idP, CC_id, sdu_lengths[0]); - - for (j = 0; j < sdu_lengths[0]; j++) { - LOG_T(MAC, "%x ", dlsch_buffer[j]); - } - - LOG_T(MAC, "\n"); -#endif - } else { - header_len_dcch = 0; - sdu_length_total = 0; - } - } - // check for DCCH1 and update header information (assume 2 byte sub-header) - if (TBS - ta_len - header_len_dcch - sdu_length_total > 0) { - rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, (TBS - ta_len - header_len_dcch - sdu_length_total)); // transport block set size less allocations for timing advance and - // DCCH SDU - sdu_lengths[num_sdus] = 0; - - if (rlc_status.bytes_in_buffer > 0) { - LOG_D(MAC, - "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n", - module_idP, frameP, CC_id, - TBS - header_len_dcch - sdu_length_total); - sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, TBS, //not used - (char *) - &dlsch_buffer - [sdu_length_total]); - - T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), - T_INT(DCCH + 1), T_INT(sdu_lengths[num_sdus])); - - sdu_lcids[num_sdus] = DCCH1; - sdu_length_total += sdu_lengths[num_sdus]; - header_len_dcch += 2; - UE_list->eNB_UE_stats[CC_id][UE_id]. - num_pdu_tx[DCCH1] += 1; - UE_list-> - eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1] - += sdu_lengths[num_sdus]; - num_sdus++; -#ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC, - "[eNB %d][DCCH1] CC_id %d Got %d bytes :", - module_idP, CC_id, sdu_lengths[num_sdus]); - - for (j = 0; j < sdu_lengths[num_sdus]; j++) { - LOG_T(MAC, "%x ", dlsch_buffer[j]); - } - - LOG_T(MAC, "\n"); -#endif - - } - } - // assume the max dtch header size, and adjust it later - header_len_dtch = 0; - header_len_dtch_last = 0; // the header length of the last mac sdu - // lcid has to be sorted before the actual allocation (similar struct as ue_list). - for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { - // TBD: check if the lcid is active - - header_len_dtch += 3; - header_len_dtch_last = 3; - LOG_D(MAC, - "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", - module_idP, frameP, lcid, TBS, - TBS - ta_len - header_len_dcch - - sdu_length_total - header_len_dtch); - - if (TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch > 0) { // NN: > 2 ? - rlc_status = mac_rlc_status_ind(module_idP, - rnti, - module_idP, - frameP, - subframeP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - lcid, - TBS - ta_len - - header_len_dcch - - sdu_length_total - - header_len_dtch); - - - if (rlc_status.bytes_in_buffer > 0) { - - LOG_D(MAC, - "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n", - module_idP, frameP, - TBS - header_len_dcch - - sdu_length_total - header_len_dtch, lcid, - header_len_dtch); - sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, TBS, //not used - (char - *) - &dlsch_buffer - [sdu_length_total]); - T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), - T_INT(lcid), T_INT(sdu_lengths[num_sdus])); - - LOG_D(MAC, - "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", - module_idP, sdu_lengths[num_sdus], lcid); - sdu_lcids[num_sdus] = lcid; - sdu_length_total += sdu_lengths[num_sdus]; - 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[num_sdus]; - if (sdu_lengths[num_sdus] < 128) { - header_len_dtch--; - header_len_dtch_last--; - } - num_sdus++; - UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; - } // no data for this LCID - else { - header_len_dtch -= 3; - } - } // no TBS left - else { - header_len_dtch -= 3; - break; - } - } - if (header_len_dtch == 0) - header_len_dtch_last = 0; - // there is at least one SDU - // if (num_sdus > 0 ){ - if ((sdu_length_total + header_len_dcch + - header_len_dtch) > 0) { - - // Now compute number of required RBs for total sdu length - // Assume RAH format 2 - // adjust header lengths - header_len_dcch_tmp = header_len_dcch; - header_len_dtch_tmp = header_len_dtch; - if (header_len_dtch == 0) { - header_len_dcch = (header_len_dcch > 0) ? 1 : 0; //header_len_dcch; // remove length field - } else { - header_len_dtch_last -= 1; // now use it to find how many bytes has to be removed for the last MAC SDU - header_len_dtch = (header_len_dtch > 0) ? header_len_dtch - header_len_dtch_last : header_len_dtch; // remove length field for the last SDU - } - - mcs = eNB_UE_stats->dlsch_mcs1; - - if (mcs == 0) { - nb_rb = 4; // don't let the TBS get too small - } else { - nb_rb = min_rb_unit[CC_id]; - } - - TBS = get_TBS_DL(mcs, nb_rb); - - while (TBS < - (sdu_length_total + header_len_dcch + - header_len_dtch + ta_len)) { - nb_rb += min_rb_unit[CC_id]; // - - if (nb_rb > nb_available_rb) { // if we've gone beyond the maximum number of RBs - // (can happen if N_RB_DL is odd) - TBS = - get_TBS_DL(eNB_UE_stats->dlsch_mcs1, - nb_available_rb); - nb_rb = nb_available_rb; - break; - } - - TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rb); - } - - if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { - for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band - UE_list->UE_template[CC_id][UE_id]. - rballoc_subband[harq_pid][j] = - ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - } - } else { - nb_rb_temp = nb_rb; - j = 0; - - while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { - if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == - 1) { - UE_list-> - UE_template[CC_id] - [UE_id].rballoc_subband[harq_pid][j] = - ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - - if ((j == N_RBG[CC_id] - 1) && - ((N_RB_DL[CC_id] == 25) || - (N_RB_DL[CC_id] == 50))) { - nb_rb_temp = - nb_rb_temp - min_rb_unit[CC_id] + - 1; - } else { - nb_rb_temp = - nb_rb_temp - min_rb_unit[CC_id]; - } - } - - j = j + 1; - } - } - - // decrease mcs until TBS falls below required length - while ((TBS > - (sdu_length_total + header_len_dcch + - header_len_dtch + ta_len)) && (mcs > 0)) { - mcs--; - TBS = get_TBS_DL(mcs, nb_rb); - } - - // if we have decreased too much or we don't have enough RBs, increase MCS - while ((TBS < - (sdu_length_total + header_len_dcch + - header_len_dtch + ta_len)) - && (((ue_sched_ctl->dl_pow_off[CC_id] > 0) - && (mcs < 28)) - || ((ue_sched_ctl->dl_pow_off[CC_id] == 0) - && (mcs <= 15)))) { - mcs++; - TBS = get_TBS_DL(mcs, nb_rb); - } - - LOG_D(MAC, - "dlsch_mcs before and after the rate matching = (%d, %d)\n", - eNB_UE_stats->dlsch_mcs1, mcs); - -#ifdef DEBUG_eNB_SCHEDULER - LOG_D(MAC, - "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n", - module_idP, CC_id, mcs, TBS, nb_rb); - // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n", - // TBS, sdu_length_total, offset, TBS-sdu_length_total-offset); -#endif - - if ((TBS - header_len_dcch - header_len_dtch - - sdu_length_total - ta_len) <= 2) { - padding = - (TBS - header_len_dcch - header_len_dtch - - sdu_length_total - ta_len); - post_padding = 0; - } else { - padding = 0; - - // adjust the header len - if (header_len_dtch == 0) { - header_len_dcch = header_len_dcch_tmp; - } else { //if (( header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2))) - header_len_dtch = header_len_dtch_tmp; - } - - post_padding = TBS - sdu_length_total - header_len_dcch - header_len_dtch - ta_len; // 1 is for the postpadding header - } - - - 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); - - //#ifdef DEBUG_eNB_SCHEDULER - if (ta_update != 31) { - LOG_D(MAC, - "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_dcch %d, header_dtch %d\n", - module_idP, frameP, UE_id, CC_id, - sdu_length_total, num_sdus, sdu_lengths[0], - sdu_lcids[0], offset, ta_update, padding, - post_padding, mcs, TBS, nb_rb, - header_len_dcch, header_len_dtch); - } - //#endif -#ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n"); - - for (i = 0; i < 16; i++) { - LOG_T(MAC, "%x.", dlsch_buffer[i]); - } - - LOG_T(MAC, "\n"); -#endif - - // cycle through SDUs and place in dlsch_buffer - memcpy(&UE_list-> - DLSCH_pdu[CC_id][0][UE_id].payload[0][offset], - dlsch_buffer, sdu_length_total); - // memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); - - // fill remainder of DLSCH with random data - for (j = 0; j < (TBS - sdu_length_total - offset); j++) { - UE_list->DLSCH_pdu[CC_id][0][UE_id]. - payload[0][offset + sdu_length_total + j] = - (char) (taus() & 0xff); - } - - - if (opt_enabled == 1) { - trace_pdu(1, (uint8_t *) - UE_list->DLSCH_pdu[CC_id][0][UE_id]. - payload[0], TBS, module_idP, 3, - UE_RNTI(module_idP, UE_id), eNB->frame, - eNB->subframe, 0, 0); - LOG_D(OPT, - "[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", - module_idP, CC_id, frameP, - UE_RNTI(module_idP, UE_id), TBS); - } - - T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), - T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id]. - payload[0], TBS)); - - UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = - nb_rb; - - add_ue_dlsch_info(module_idP, - CC_id, UE_id, subframeP, - S_DL_SCHEDULED); - // store stats - eNB->eNB_stats[CC_id].dlsch_bytes_tx += - sdu_length_total; - eNB->eNB_stats[CC_id].dlsch_pdus_tx += 1; - - UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb; - UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used += - nb_rb; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = - eNB_UE_stats->dlsch_mcs1; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = mcs; - UE_list->eNB_UE_stats[CC_id][UE_id].TBS = TBS; - - UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes = - TBS - sdu_length_total; - UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes += - sdu_length_total; - UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes += - TBS; - UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus += - 1; - - if (cc[CC_id].tdd_Config != NULL) { // TDD - UE_list->UE_template[CC_id][UE_id].DAI++; - update_ul_dci(module_idP, CC_id, rnti, - UE_list->UE_template[CC_id][UE_id]. - DAI); - } - // do PUCCH power control - // this is the normalized RX power - eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; - - /* TODO: fix how we deal with power, unit is not dBm, it's special from nfapi */ - normalized_rx_power = ue_sched_ctl->pucch1_snr[CC_id]; - target_rx_power = 208; - - // this assumes accumulated tpc - // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out - int32_t framex10psubframe = - UE_list->UE_template[CC_id][UE_id]. - pucch_tpc_tx_frame * 10 + - UE_list->UE_template[CC_id][UE_id]. - pucch_tpc_tx_subframe; - if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || //normal case - ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) //frame wrap-around - if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) { - ue_sched_ctl->pucch1_cqi_update[CC_id] = 0; - - UE_list-> - UE_template[CC_id] - [UE_id].pucch_tpc_tx_frame = frameP; - UE_list-> - UE_template[CC_id] - [UE_id].pucch_tpc_tx_subframe = subframeP; - - if (normalized_rx_power > - (target_rx_power + 4)) { - tpc = 0; //-1 - tpc_accumulated--; - } else if (normalized_rx_power < - (target_rx_power - 4)) { - tpc = 2; //+1 - tpc_accumulated++; - } else { - tpc = 1; //0 - } - - LOG_D(MAC, - "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", - module_idP, frameP, subframeP, harq_pid, - tpc, tpc_accumulated, - normalized_rx_power, target_rx_power); - - } // Po_PUCCH has been updated - else { - tpc = 1; //0 - } // time to do TPC update - else { - tpc = 1; //0 - } - - 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_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = - NFAPI_DL_DCI_FORMAT_1; - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level = - get_aggregation(get_bw_index(module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format1); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - harq_process = harq_pid; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; // dont adjust power when retransmitting - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.new_data_indicator_1 = - 1 - - UE_list->UE_template[CC_id][UE_id]. - oldNDI[harq_pid]; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.redundancy_version_1 = 0; - //deactivate second codeword - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0; - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.redundancy_version_2 = 1; - if (cc[CC_id].tdd_Config != NULL) { //TDD - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.downlink_assignment_index = - (UE_list->UE_template[CC_id][UE_id].DAI - - 1) & 3; - LOG_D(MAC, - "[eNB %d] Initial transmission CC_id %d : harq_pid %d, dai %d, mcs %d\n", - module_idP, CC_id, harq_pid, - (UE_list->UE_template[CC_id][UE_id].DAI - 1), - mcs); - } else { - LOG_D(MAC, - "[eNB %d] Initial transmission CC_id %d : harq_pid %d, mcs %d\n", - module_idP, CC_id, harq_pid, mcs); - - } - LOG_D(MAC, "Checking feasibility pdu %d (new sdu)\n", - dl_req->number_pdu); - if (!CCE_allocation_infeasible - (module_idP, CC_id, 1, subframeP, - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level, rnti)) { - - - ue_sched_ctl->round[CC_id][harq_pid] = 0; - dl_req->number_dci++; - dl_req->number_pdu++; - dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - - eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; - eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; - - // Toggle NDI for next time - LOG_D(MAC, - "CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n", - CC_id, frameP, subframeP, UE_id, rnti, - harq_pid, - UE_list-> - UE_template[CC_id][UE_id].oldNDI[harq_pid]); - - UE_list->UE_template[CC_id][UE_id]. - oldNDI[harq_pid] = - 1 - - UE_list->UE_template[CC_id][UE_id]. - oldNDI[harq_pid]; - UE_list->UE_template[CC_id][UE_id]. - oldmcs1[harq_pid] = mcs; - UE_list->UE_template[CC_id][UE_id]. - oldmcs2[harq_pid] = 0; - AssertFatal(UE_list->UE_template[CC_id] - [UE_id].physicalConfigDedicated != - NULL, - "physicalConfigDedicated is NULL\n"); - AssertFatal(UE_list->UE_template[CC_id] - [UE_id]. - physicalConfigDedicated->pdsch_ConfigDedicated - != NULL, - "physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n"); - - fill_nfapi_dlsch_config(eNB, dl_req, TBS, eNB->pdu_index[CC_id], rnti, 0, // type 0 allocation from 7.1.6 in 36.213 - 0, // virtual_resource_block_assignment_flag, unused here - 0, // resource_block_coding, to be filled in later - getQm(mcs), 0, // redundancy version - 1, // transport blocks - 0, // transport block to codeword swap flag - cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme - 1, // number of layers - 1, // number of subbands - // uint8_t codebook_index, - 4, // UE category capacity - UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0, // delta_power_offset for TM5 - 0, // ngap - 0, // nprb - cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode - 0, //number of PRBs treated as one subband, not used here - 0 // number of beamforming vectors, not used here - ); - eNB->TX_req[CC_id].sfn_sf = - fill_nfapi_tx_req(&eNB-> - TX_req - [CC_id].tx_request_body, - (frameP * 10) + subframeP, - TBS, eNB->pdu_index[CC_id], - eNB-> - UE_list.DLSCH_pdu[CC_id][0][(unsigned char) - UE_id].payload + } + + j = j + 1; + } + } + + nb_available_rb -= nb_rb; + /* + eNB->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; + eNB->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id]; + + for(j=0; jmu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; + } + */ + + switch (get_tmode(module_idP, CC_id, UE_id)) { + case 1: + case 2: + case 7: + default: + LOG_D(MAC,"retransmission DL_REQ: rnti:%x\n",rnti); + + 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_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP, CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format1); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // dont adjust power when retransmitting + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = round & 3; + + if (cc[CC_id].tdd_Config != NULL) { //TDD + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (UE_list->UE_template[CC_id][UE_id].DAI - 1) & 3; + LOG_D(MAC, + "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n", + module_idP, CC_id, harq_pid, round, + (UE_list->UE_template[CC_id][UE_id].DAI - 1), + UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]); + } else { + LOG_D(MAC, + "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n", + module_idP, CC_id, harq_pid, round, + UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]); + + } + if (!CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, rnti)) { + dl_req->number_dci++; + dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + + eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; + eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; + + fill_nfapi_dlsch_config(eNB, dl_req, TBS, -1 + /* retransmission, no pdu_index */ + , rnti, 0, // type 0 allocation from 7.1.6 in 36.213 + 0, // virtual_resource_block_assignment_flag, unused here + 0, // resource_block_coding, to be filled in later + getQm(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]), round & 3, // redundancy version + 1, // transport blocks + 0, // transport block to codeword swap flag + cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme + 1, // number of layers + 1, // number of subbands + // uint8_t codebook_index, + 4, // UE category capacity + UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0, // delta_power_offset for TM5 + 0, // ngap + 0, // nprb + cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode + 0, //number of PRBs treated as one subband, not used here + 0 // number of beamforming vectors, not used here + ); + + LOG_D(MAC, + "Filled NFAPI configuration for DCI/DLSCH %d, retransmission round %d\n", + eNB->pdu_index[CC_id], round); + + program_dlsch_acknak(module_idP, CC_id, UE_id, + frameP, subframeP, + dl_config_pdu-> + dci_dl_pdu.dci_dl_pdu_rel8. + cce_idx); + // No TX request for retransmission (check if null request for FAPI) + } else { + LOG_W(MAC, + "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d\%x, infeasible CCE allocation\n", + frameP, subframeP, UE_id, rnti); + } + } + + + add_ue_dlsch_info(module_idP, + CC_id, UE_id, subframeP, + S_DL_SCHEDULED); + + //eNB_UE_stats->dlsch_trials[round]++; + UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx = nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_retx += nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = eNB_UE_stats->dlsch_mcs1; + } else { + LOG_D(MAC, + "[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n", + module_idP, frameP, CC_id, UE_id); + } + } else { /* This is a potentially new SDU opportunity */ + + rlc_status.bytes_in_buffer = 0; + // Now check RLC information to compute number of required RBs + // get maximum TBS size for RLC request + TBS = + get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb); + // check first for RLC data on DCCH + // add the length for all the control elements (timing adv, drx, etc) : header + payload + + if (ue_sched_ctl->ta_timer == 0) { + ta_update = ue_sched_ctl->ta_update; + /* if we send TA then set timer to not send it for a while */ + if (ta_update != 31) ue_sched_ctl->ta_timer = 20; + /* reset ta_update */ + ue_sched_ctl->ta_update = 31; + } else { + ta_update = 31; + } + + ta_len = (ta_update != 31) ? 2 : 0; + + header_len_dcch = 2; // 2 bytes DCCH SDU subheader + + if (TBS - ta_len - header_len_dcch > 0) { + rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, (TBS - ta_len - header_len_dcch)); // transport block set size + + sdu_lengths[0] = 0; + + if (rlc_status.bytes_in_buffer > 0) { // There is DCCH to transmit + LOG_D(MAC, + "[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", + module_idP, frameP, subframeP, CC_id, + TBS - header_len_dcch); + sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, TBS, //not used + (char *) + &dlsch_buffer [0]); - LOG_D(MAC, - "Filled NFAPI configuration for DCI/DLSCH/TXREQ %d, new SDU\n", - eNB->pdu_index[CC_id]); + T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), + T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), T_INT(DCCH), + T_INT(sdu_lengths[0])); - eNB->pdu_index[CC_id]++; - program_dlsch_acknak(module_idP, CC_id, UE_id, - frameP, subframeP, - dl_config_pdu-> - dci_dl_pdu.dci_dl_pdu_rel8. - cce_idx); + LOG_D(MAC, + "[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n", + module_idP, CC_id, sdu_lengths[0]); + sdu_length_total = sdu_lengths[0]; + sdu_lcids[0] = DCCH; + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH] += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH] += sdu_lengths[0]; + num_sdus = 1; +#ifdef DEBUG_eNB_SCHEDULER + LOG_T(MAC, + "[eNB %d][DCCH] CC_id %d Got %d bytes :", + module_idP, CC_id, sdu_lengths[0]); - } else { - LOG_W(MAC, - "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d/%x, infeasible CCE allocations\n", - frameP, subframeP, UE_id, rnti); - } - } else { // There is no data from RLC or MAC header, so don't schedule + for (j = 0; j < sdu_lengths[0]; j++) { + LOG_T(MAC, "%x ", dlsch_buffer[j]); + } + LOG_T(MAC, "\n"); +#endif + } else { + header_len_dcch = 0; + sdu_length_total = 0; + } + } + // check for DCCH1 and update header information (assume 2 byte sub-header) + if (TBS - ta_len - header_len_dcch - sdu_length_total > 0) { + rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, (TBS - ta_len - header_len_dcch - sdu_length_total)); // transport block set size less allocations for timing advance and + // DCCH SDU + sdu_lengths[num_sdus] = 0; + + if (rlc_status.bytes_in_buffer > 0) { + LOG_D(MAC, + "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n", + module_idP, frameP, CC_id, + TBS - header_len_dcch - sdu_length_total); + sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, TBS, //not used + (char *) + &dlsch_buffer + [sdu_length_total]); + + T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), + T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), + T_INT(DCCH + 1), T_INT(sdu_lengths[num_sdus])); + + sdu_lcids[num_sdus] = DCCH1; + sdu_length_total += sdu_lengths[num_sdus]; + header_len_dcch += 2; + UE_list->eNB_UE_stats[CC_id][UE_id]. + num_pdu_tx[DCCH1] += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1] += sdu_lengths[num_sdus]; + num_sdus++; +#ifdef DEBUG_eNB_SCHEDULER + LOG_T(MAC, + "[eNB %d][DCCH1] CC_id %d Got %d bytes :", + module_idP, CC_id, sdu_lengths[num_sdus]); + + for (j = 0; j < sdu_lengths[num_sdus]; j++) { + LOG_T(MAC, "%x ", dlsch_buffer[j]); + } + + LOG_T(MAC, "\n"); +#endif + + } + } + // assume the max dtch header size, and adjust it later + header_len_dtch = 0; + header_len_dtch_last = 0; // the header length of the last mac sdu + // lcid has to be sorted before the actual allocation (similar struct as ue_list). + for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { + // TBD: check if the lcid is active + + header_len_dtch += 3; + header_len_dtch_last = 3; + LOG_D(MAC, + "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", + module_idP, frameP, lcid, TBS, + TBS - ta_len - header_len_dcch - + sdu_length_total - header_len_dtch); + + if (TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch > 0) { // NN: > 2 ? + rlc_status = mac_rlc_status_ind(module_idP, + rnti, + module_idP, + frameP, + subframeP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + TBS - ta_len - + header_len_dcch - + sdu_length_total - + header_len_dtch); + + + if (rlc_status.bytes_in_buffer > 0) { + + LOG_D(MAC, + "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n", + module_idP, frameP, + TBS - header_len_dcch - + sdu_length_total - header_len_dtch, lcid, + header_len_dtch); + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, TBS, //not used + (char + *) + &dlsch_buffer + [sdu_length_total]); + T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), + T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), + T_INT(lcid), T_INT(sdu_lengths[num_sdus])); + + LOG_D(MAC, + "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", + module_idP, sdu_lengths[num_sdus], lcid); + sdu_lcids[num_sdus] = lcid; + sdu_length_total += sdu_lengths[num_sdus]; + 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[num_sdus]; + if (sdu_lengths[num_sdus] < 128) { + header_len_dtch--; + header_len_dtch_last--; + } + num_sdus++; + UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; + } // no data for this LCID + else { + header_len_dtch -= 3; + } + } // no TBS left + else { + header_len_dtch -= 3; + break; + } + } + if (header_len_dtch == 0) + header_len_dtch_last = 0; + // there is at least one SDU + // if (num_sdus > 0 ){ + if ((sdu_length_total + header_len_dcch + + header_len_dtch) > 0) { + + // Now compute number of required RBs for total sdu length + // Assume RAH format 2 + // adjust header lengths + header_len_dcch_tmp = header_len_dcch; + header_len_dtch_tmp = header_len_dtch; + if (header_len_dtch == 0) { + header_len_dcch = (header_len_dcch > 0) ? 1 : 0; //header_len_dcch; // remove length field + } else { + header_len_dtch_last -= 1; // now use it to find how many bytes has to be removed for the last MAC SDU + header_len_dtch = (header_len_dtch > 0) ? header_len_dtch - header_len_dtch_last : header_len_dtch; // remove length field for the last SDU + } + + mcs = eNB_UE_stats->dlsch_mcs1; + + if (mcs == 0) { + nb_rb = 4; // don't let the TBS get too small + } else { + nb_rb = min_rb_unit[CC_id]; + } + + TBS = get_TBS_DL(mcs, nb_rb); + + while (TBS < + (sdu_length_total + header_len_dcch + + header_len_dtch + ta_len)) { + nb_rb += min_rb_unit[CC_id]; // + + if (nb_rb > nb_available_rb) { // if we've gone beyond the maximum number of RBs + // (can happen if N_RB_DL is odd) + TBS = + get_TBS_DL(eNB_UE_stats->dlsch_mcs1, + nb_available_rb); + nb_rb = nb_available_rb; + break; + } + + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rb); + } + + if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { + for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + } + } else { + nb_rb_temp = nb_rb; + j = 0; + + while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { + if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + + if ((j == N_RBG[CC_id] - 1) && + ((N_RB_DL[CC_id] == 25) || + (N_RB_DL[CC_id] == 50))) { + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1; + } else { + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; } + } + + j = j + 1; + } + } + + // decrease mcs until TBS falls below required length + while ((TBS > (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && (mcs > 0)) { + mcs--; + TBS = get_TBS_DL(mcs, nb_rb); + } + + // if we have decreased too much or we don't have enough RBs, increase MCS + while ((TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) + && (((ue_sched_ctl->dl_pow_off[CC_id] > 0) + && (mcs < 28)) + || ((ue_sched_ctl->dl_pow_off[CC_id] == 0) + && (mcs <= 15)))) { + mcs++; + TBS = get_TBS_DL(mcs, nb_rb); + } + + LOG_D(MAC, + "dlsch_mcs before and after the rate matching = (%d, %d)\n", + eNB_UE_stats->dlsch_mcs1, mcs); + +#ifdef DEBUG_eNB_SCHEDULER + LOG_D(MAC, + "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n", + module_idP, CC_id, mcs, TBS, nb_rb); + // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n", + // TBS, sdu_length_total, offset, TBS-sdu_length_total-offset); +#endif + + if ((TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len) <= 2) { + padding = (TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len); + post_padding = 0; + } else { + padding = 0; + + // adjust the header len + if (header_len_dtch == 0) { + header_len_dcch = header_len_dcch_tmp; + } else { //if (( header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2))) + header_len_dtch = header_len_dtch_tmp; } - if (cc[CC_id].tdd_Config != NULL) { // TDD - set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP); - } + post_padding = TBS - sdu_length_total - header_len_dcch - header_len_dtch - ta_len; // 1 is for the postpadding header + } - } // UE_id loop - } // CC_id loop + + 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); + + //#ifdef DEBUG_eNB_SCHEDULER + if (ta_update != 31) { + LOG_D(MAC, + "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_dcch %d, header_dtch %d\n", + module_idP, frameP, UE_id, CC_id, + sdu_length_total, num_sdus, sdu_lengths[0], + sdu_lcids[0], offset, ta_update, padding, + post_padding, mcs, TBS, nb_rb, + header_len_dcch, header_len_dtch); + } + //#endif +#ifdef DEBUG_eNB_SCHEDULER + LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n"); + + for (i = 0; i < 16; i++) { + LOG_T(MAC, "%x.", dlsch_buffer[i]); + } + + LOG_T(MAC, "\n"); +#endif + + // cycle through SDUs and place in dlsch_buffer + memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset], + dlsch_buffer, sdu_length_total); + // memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); + + // fill remainder of DLSCH with random data + for (j = 0; j < (TBS - sdu_length_total - offset); j++) { + UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + sdu_length_total + j] = (char) (taus() & 0xff); + } + + + if (opt_enabled == 1) { + trace_pdu(1, (uint8_t *) + UE_list->DLSCH_pdu[CC_id][0][UE_id]. + payload[0], TBS, module_idP, 3, + UE_RNTI(module_idP, UE_id), eNB->frame, + eNB->subframe, 0, 0); + LOG_D(OPT, + "[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", + module_idP, CC_id, frameP, + UE_RNTI(module_idP, UE_id), TBS); + } + + T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), + T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), + T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id]. + payload[0], TBS)); + + UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb; + + add_ue_dlsch_info(module_idP, + CC_id, UE_id, subframeP, + S_DL_SCHEDULED); + // store stats + eNB->eNB_stats[CC_id].dlsch_bytes_tx += sdu_length_total; + eNB->eNB_stats[CC_id].dlsch_pdus_tx += 1; + + UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used += nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = mcs; + UE_list->eNB_UE_stats[CC_id][UE_id].TBS = TBS; + + UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes = TBS - sdu_length_total; + UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes += sdu_length_total; + UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes += TBS; + UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus += 1; + + if (cc[CC_id].tdd_Config != NULL) { // TDD + UE_list->UE_template[CC_id][UE_id].DAI++; + update_ul_dci(module_idP, CC_id, rnti, + UE_list->UE_template[CC_id][UE_id]. + DAI); + } + // do PUCCH power control + // this is the normalized RX power + eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; + + /* TODO: fix how we deal with power, unit is not dBm, it's special from nfapi */ + normalized_rx_power = ue_sched_ctl->pucch1_snr[CC_id]; + target_rx_power = 208; + + // this assumes accumulated tpc + // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out + int32_t framex10psubframe = UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame * 10 + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe; + if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || //normal case + ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) //frame wrap-around + if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) { + ue_sched_ctl->pucch1_cqi_update[CC_id] = 0; + + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame = frameP; + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe = subframeP; + + if (normalized_rx_power > (target_rx_power + 4)) { + tpc = 0; //-1 + tpc_accumulated--; + } else if (normalized_rx_power < (target_rx_power - 4)) { + tpc = 2; //+1 + tpc_accumulated++; + } else { + tpc = 1; //0 + } + + LOG_D(MAC, + "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", + module_idP, frameP, subframeP, harq_pid, + tpc, tpc_accumulated, + normalized_rx_power, target_rx_power); + + } // Po_PUCCH has been updated + else { + tpc = 1; //0 + } // time to do TPC update + else { + tpc = 1; //0 + } + + 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_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP, CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format1); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; // dont adjust power when retransmitting + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; + //deactivate second codeword + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1; + if (cc[CC_id].tdd_Config != NULL) { //TDD + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (UE_list->UE_template[CC_id][UE_id].DAI - 1) & 3; + LOG_D(MAC, + "[eNB %d] Initial transmission CC_id %d : harq_pid %d, dai %d, mcs %d\n", + module_idP, CC_id, harq_pid, + (UE_list->UE_template[CC_id][UE_id].DAI - 1), + mcs); + } else { + LOG_D(MAC, + "[eNB %d] Initial transmission CC_id %d : harq_pid %d, mcs %d\n", + module_idP, CC_id, harq_pid, mcs); + + } + LOG_D(MAC, "Checking feasibility pdu %d (new sdu)\n", + dl_req->number_pdu); + if (!CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, + dl_config_pdu->dci_dl_pdu. + dci_dl_pdu_rel8.aggregation_level, rnti)) { + + + ue_sched_ctl->round[CC_id][harq_pid] = 0; + dl_req->number_dci++; + dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + + eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; + eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; + + // Toggle NDI for next time + LOG_D(MAC, + "CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n", + CC_id, frameP, subframeP, UE_id, rnti, + harq_pid, + UE_list-> + UE_template[CC_id][UE_id].oldNDI[harq_pid]); + + UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid] = 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid] = mcs; + UE_list->UE_template[CC_id][UE_id].oldmcs2[harq_pid] = 0; + AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != + NULL, + "physicalConfigDedicated is NULL\n"); + AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated != NULL, + "physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n"); + + fill_nfapi_dlsch_config(eNB, dl_req, TBS, eNB->pdu_index[CC_id], rnti, 0, // type 0 allocation from 7.1.6 in 36.213 + 0, // virtual_resource_block_assignment_flag, unused here + 0, // resource_block_coding, to be filled in later + getQm(mcs), 0, // redundancy version + 1, // transport blocks + 0, // transport block to codeword swap flag + cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme + 1, // number of layers + 1, // number of subbands + // uint8_t codebook_index, + 4, // UE category capacity + UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0, // delta_power_offset for TM5 + 0, // ngap + 0, // nprb + cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode + 0, //number of PRBs treated as one subband, not used here + 0 // number of beamforming vectors, not used here + ); + eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB-> + TX_req + [CC_id].tx_request_body, + (frameP * 10) + subframeP, + TBS, eNB->pdu_index[CC_id], + eNB-> + UE_list.DLSCH_pdu[CC_id][0][(unsigned char) + UE_id].payload + [0]); + + LOG_D(MAC, + "Filled NFAPI configuration for DCI/DLSCH/TXREQ %d, new SDU\n", + eNB->pdu_index[CC_id]); + + eNB->pdu_index[CC_id]++; + program_dlsch_acknak(module_idP, CC_id, UE_id, + frameP, subframeP, + dl_config_pdu-> + dci_dl_pdu.dci_dl_pdu_rel8. + cce_idx); + + } else { + LOG_W(MAC, + "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d/%x, infeasible CCE allocations\n", + frameP, subframeP, UE_id, rnti); + } + } else { // There is no data from RLC or MAC header, so don't schedule + + } + } + + if (cc[CC_id].tdd_Config != NULL) { // TDD + set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP); + } + + } // UE_id loop + } // CC_id loop - fill_DLSCH_dci(module_idP, frameP, subframeP, mbsfn_flag); + fill_DLSCH_dci(module_idP, frameP, subframeP, mbsfn_flag); - stop_meas(&eNB->schedule_dlsch); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT); + stop_meas(&eNB->schedule_dlsch); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT); } @@ -1531,111 +1396,84 @@ fill_DLSCH_dci(module_id_t module_idP, //------------------------------------------------------------------------------ { - // loop over all allocated UEs and compute frequency allocations for PDSCH - int UE_id = -1; - uint8_t /* first_rb, */ nb_rb = 3; - rnti_t rnti; - //unsigned char *vrb_map; - uint8_t rballoc_sub[25]; - //uint8_t number_of_subbands=13; + // loop over all allocated UEs and compute frequency allocations for PDSCH + int UE_id = -1; + uint8_t /* first_rb, */ nb_rb = 3; + rnti_t rnti; + //unsigned char *vrb_map; + uint8_t rballoc_sub[25]; + //uint8_t number_of_subbands=13; - //unsigned char round; - unsigned char harq_pid; - int i; - int CC_id; - eNB_MAC_INST *eNB = RC.mac[module_idP]; - UE_list_t *UE_list = &eNB->UE_list; - int N_RBG; - int N_RB_DL; - COMMON_channels_t *cc; + //unsigned char round; + unsigned char harq_pid; + int i; + int CC_id; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + UE_list_t *UE_list = &eNB->UE_list; + int N_RBG; + int N_RB_DL; + COMMON_channels_t *cc; - start_meas(&eNB->fill_DLSCH_dci); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_IN); + start_meas(&eNB->fill_DLSCH_dci); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_IN); - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - LOG_D(MAC, "Doing fill DCI for CC_id %d\n", CC_id); + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + LOG_D(MAC, "Doing fill DCI for CC_id %d\n", CC_id); - if (mbsfn_flagP[CC_id] > 0) - continue; + if (mbsfn_flagP[CC_id] > 0) + continue; - cc = &eNB->common_channels[CC_id]; - N_RBG = to_rbg(cc->mib->message.dl_Bandwidth); - N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); + cc = &eNB->common_channels[CC_id]; + N_RBG = to_rbg(cc->mib->message.dl_Bandwidth); + N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); - // UE specific DCIs - for (UE_id = UE_list->head; UE_id >= 0; - UE_id = UE_list->next[UE_id]) { - LOG_T(MAC, "CC_id %d, UE_id: %d => status %d\n", CC_id, UE_id, - eNB_dlsch_info[module_idP][CC_id][UE_id].status); + // UE specific DCIs + for (UE_id = UE_list->head; UE_id >= 0; + UE_id = UE_list->next[UE_id]) { + LOG_T(MAC, "CC_id %d, UE_id: %d => status %d\n", CC_id, UE_id, + eNB_dlsch_info[module_idP][CC_id][UE_id].status); - if (eNB_dlsch_info[module_idP][CC_id][UE_id].status == - S_DL_SCHEDULED) { + if (eNB_dlsch_info[module_idP][CC_id][UE_id].status == S_DL_SCHEDULED) { - // clear scheduling flag - eNB_dlsch_info[module_idP][CC_id][UE_id].status = - S_DL_WAITING; - rnti = UE_RNTI(module_idP, UE_id); - if (cc->tdd_Config) - harq_pid = ((frameP * 10) + subframeP) % 10; - else - harq_pid = ((frameP * 10) + subframeP) & 7; - nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + // clear scheduling flag + eNB_dlsch_info[module_idP][CC_id][UE_id].status = S_DL_WAITING; + rnti = UE_RNTI(module_idP, UE_id); + if (cc->tdd_Config) harq_pid = ((frameP * 10) + subframeP) % 10; + else harq_pid = ((frameP * 10) + subframeP) & 7; + nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - - - /// Synchronizing rballoc with rballoc_sub - for (i = 0; i < N_RBG; i++) { - rballoc_sub[i] = - UE_list-> - UE_template[CC_id][UE_id].rballoc_subband[harq_pid] - [i]; - } - - nfapi_dl_config_request_t *DL_req = - &RC.mac[module_idP]->DL_req[0]; - nfapi_dl_config_request_pdu_t *dl_config_pdu; - - for (i = 0; - i < DL_req[CC_id].dl_config_request_body.number_pdu; - i++) { - dl_config_pdu = - &DL_req[CC_id]. - dl_config_request_body.dl_config_pdu_list[i]; - if ((dl_config_pdu->pdu_type == - NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) - && (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - rnti == rnti) - && (dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.dci_format != 1)) { - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.resource_block_coding = - allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG, - rballoc_sub); - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.resource_allocation_type = 0; - } else - if ((dl_config_pdu->pdu_type == - NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) - && (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - rnti == rnti) - && (dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.resource_allocation_type == - 0)) { - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.resource_block_coding = - allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG, - rballoc_sub); - } - } - } + /// Synchronizing rballoc with rballoc_sub + for (i = 0; i < N_RBG; i++) { + rballoc_sub[i] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][i]; } + nfapi_dl_config_request_t *DL_req = &RC.mac[module_idP]->DL_req[0]; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + + for (i = 0; + i < DL_req[CC_id].dl_config_request_body.number_pdu; + i++) { + dl_config_pdu = &DL_req[CC_id].dl_config_request_body.dl_config_pdu_list[i]; + if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) + && (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == rnti) + && (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format != 1)) { + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG,rballoc_sub); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0; + } else + if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) + && (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == rnti) + && (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type == 0)) { + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding =allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG,rballoc_sub); + } + } + } } - stop_meas(&eNB->fill_DLSCH_dci); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_OUT); + } + + stop_meas(&eNB->fill_DLSCH_dci); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_OUT); } //------------------------------------------------------------------------------ @@ -1645,37 +1483,35 @@ unsigned char *get_dlsch_sdu(module_id_t module_idP, //------------------------------------------------------------------------------ { - int UE_id; - eNB_MAC_INST *eNB = RC.mac[module_idP]; + int UE_id; + eNB_MAC_INST *eNB = RC.mac[module_idP]; - if (rntiP == SI_RNTI) { - LOG_D(MAC, "[eNB %d] CC_id %d Frame %d Get DLSCH sdu for BCCH \n", - module_idP, CC_id, frameP); + if (rntiP == SI_RNTI) { + LOG_D(MAC, "[eNB %d] CC_id %d Frame %d Get DLSCH sdu for BCCH \n", + module_idP, CC_id, frameP); - return ((unsigned char *) &eNB->common_channels[CC_id]. - BCCH_pdu.payload[0]); - } + return ((unsigned char *) &eNB->common_channels[CC_id].BCCH_pdu.payload[0]); + } - if (rntiP==P_RNTI) { - LOG_D(MAC,"[eNB %d] CC_id %d Frame %d Get PCH sdu for PCCH \n", module_idP, CC_id, frameP); + if (rntiP==P_RNTI) { + LOG_D(MAC,"[eNB %d] CC_id %d Frame %d Get PCH sdu for PCCH \n", module_idP, CC_id, frameP); - return((unsigned char *)&eNB->common_channels[CC_id].PCCH_pdu.payload[0]); - } + return((unsigned char *)&eNB->common_channels[CC_id].PCCH_pdu.payload[0]); + } UE_id = find_UE_id(module_idP,rntiP); - if (UE_id != -1) { - LOG_D(MAC, - "[eNB %d] Frame %d: CC_id %d Get DLSCH sdu for rnti %x => UE_id %d\n", - module_idP, frameP, CC_id, rntiP, UE_id); - return ((unsigned char *) &eNB-> - UE_list.DLSCH_pdu[CC_id][TBindex][UE_id].payload[0]); - } else { - LOG_E(MAC, - "[eNB %d] Frame %d: CC_id %d UE with RNTI %x does not exist\n", - module_idP, frameP, CC_id, rntiP); - return NULL; - } + if (UE_id != -1) { + LOG_D(MAC, + "[eNB %d] Frame %d: CC_id %d Get DLSCH sdu for rnti %x => UE_id %d\n", + module_idP, frameP, CC_id, rntiP, UE_id); + return ((unsigned char *) &eNB->UE_list.DLSCH_pdu[CC_id][TBindex][UE_id].payload[0]); + } else { + LOG_E(MAC, + "[eNB %d] Frame %d: CC_id %d UE with RNTI %x does not exist\n", + module_idP, frameP, CC_id, rntiP); + return NULL; + } } @@ -1687,27 +1523,25 @@ update_ul_dci(module_id_t module_idP, //------------------------------------------------------------------------------ { - nfapi_hi_dci0_request_t *HI_DCI0_req = - &RC.mac[module_idP]->HI_DCI0_req[CC_idP]; - nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = - &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[0]; - COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_idP]; - int i; + nfapi_hi_dci0_request_t *HI_DCI0_req = + &RC.mac[module_idP]->HI_DCI0_req[CC_idP]; + nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = + &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[0]; + COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_idP]; + int i; - if (cc->tdd_Config != NULL) { // TDD - for (i = 0; - i < - HI_DCI0_req->hi_dci0_request_body.number_of_dci + - HI_DCI0_req->hi_dci0_request_body.number_of_dci; i++) { + if (cc->tdd_Config != NULL) { // TDD + for (i = 0; + i hi_dci0_request_body.number_of_dci + HI_DCI0_req->hi_dci0_request_body.number_of_dci; + i++) { - if ((hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) && - (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti == rntiP)) - hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.dl_assignment_index = - (daiP - 1) & 3; + if ((hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) && + (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti == rntiP)) + hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.dl_assignment_index = (daiP - 1) & 3; - } } + } } @@ -1718,64 +1552,64 @@ set_ue_dai(sub_frame_t subframeP, UE_list_t * UE_list) //------------------------------------------------------------------------------ { - switch (tdd_config) { - case 0: - if ((subframeP == 0) || (subframeP == 1) || (subframeP == 3) - || (subframeP == 5) || (subframeP == 6) || (subframeP == 8)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } - - break; - - case 1: - if ((subframeP == 0) || (subframeP == 4) || (subframeP == 5) - || (subframeP == 9)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } - - break; - - case 2: - if ((subframeP == 4) || (subframeP == 5)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } - - break; - - case 3: - if ((subframeP == 5) || (subframeP == 7) || (subframeP == 9)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } - - break; - - case 4: - if ((subframeP == 0) || (subframeP == 6)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } - - break; - - case 5: - if (subframeP == 9) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } - - break; - - case 6: - if ((subframeP == 0) || (subframeP == 1) || (subframeP == 5) - || (subframeP == 6) || (subframeP == 9)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } - - break; - - default: - UE_list->UE_template[CC_id][UE_id].DAI = 0; - LOG_N(MAC, "unknow TDD config %d\n", tdd_config); - break; + switch (tdd_config) { + case 0: + if ((subframeP == 0) || (subframeP == 1) || (subframeP == 3) + || (subframeP == 5) || (subframeP == 6) || (subframeP == 8)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; } + + break; + + case 1: + if ((subframeP == 0) || (subframeP == 4) || (subframeP == 5) + || (subframeP == 9)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } + + break; + + case 2: + if ((subframeP == 4) || (subframeP == 5)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } + + break; + + case 3: + if ((subframeP == 5) || (subframeP == 7) || (subframeP == 9)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } + + break; + + case 4: + if ((subframeP == 0) || (subframeP == 6)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } + + break; + + case 5: + if (subframeP == 9) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } + + break; + + case 6: + if ((subframeP == 0) || (subframeP == 1) || (subframeP == 5) + || (subframeP == 6) || (subframeP == 9)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } + + break; + + default: + UE_list->UE_template[CC_id][UE_id].DAI = 0; + LOG_N(MAC, "unknow TDD config %d\n", tdd_config); + break; + } } void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) @@ -1796,22 +1630,22 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) #ifdef FORMAT1C int gap_index = 0; /* indicate which gap(1st or 2nd) is used (0:1st) */ const int GAP_MAP [9][2] = { - {-1, 0}, /* N_RB_DL [6-10] -1: |N_RB/2| 0: N/A*/ - {4, 0}, /* N_RB_DL [11] */ - {8, 0}, /* N_RB_DL [12-19] */ - {12, 0}, /* N_RB_DL [20-26] */ - {18, 0}, /* N_RB_DL [27-44] */ - {27, 0}, /* N_RB_DL [45-49] */ - {27, 9}, /* N_RB_DL [50-63] */ - {32, 16}, /* N_RB_DL [64-79] */ - {48, 16} /* N_RB_DL [80-110] */ - }; + {-1, 0}, /* N_RB_DL [6-10] -1: |N_RB/2| 0: N/A*/ + {4, 0}, /* N_RB_DL [11] */ + {8, 0}, /* N_RB_DL [12-19] */ + {12, 0}, /* N_RB_DL [20-26] */ + {18, 0}, /* N_RB_DL [27-44] */ + {27, 0}, /* N_RB_DL [45-49] */ + {27, 9}, /* N_RB_DL [50-63] */ + {32, 16}, /* N_RB_DL [64-79] */ + {48, 16} /* N_RB_DL [80-110] */ + }; uint8_t n_rb_step = 0; uint8_t n_gap = 0; uint8_t n_vrb_dl = 0; uint8_t Lcrbs = 0; uint16_t rb_bit = 168; /* RB bit number value is unsure */ - #endif +#endif start_meas(&eNB->schedule_pch); @@ -1825,298 +1659,298 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) continue; } if (frameP % UE_PF_PO[CC_id][i].T == UE_PF_PO[CC_id][i].PF_min && subframeP == UE_PF_PO[CC_id][i].PO) { - pcch_sdu_length = mac_rrc_data_req(module_idP, + pcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, PCCH,1, &cc->PCCH_pdu.payload[0], i); // used for ue index - if (pcch_sdu_length == 0) { - LOG_D(MAC,"[eNB %d] Frame %d subframe %d: PCCH not active(size = 0 byte)\n", module_idP,frameP, subframeP); - continue; - } - LOG_D(MAC,"[eNB %d] Frame %d subframe %d: PCCH->PCH CC_id %d UE_id %d, Received %d bytes \n", module_idP, frameP, subframeP, CC_id,i, pcch_sdu_length); + if (pcch_sdu_length == 0) { + LOG_D(MAC,"[eNB %d] Frame %d subframe %d: PCCH not active(size = 0 byte)\n", module_idP,frameP, subframeP); + continue; + } + LOG_D(MAC,"[eNB %d] Frame %d subframe %d: PCCH->PCH CC_id %d UE_id %d, Received %d bytes \n", module_idP, frameP, subframeP, CC_id,i, pcch_sdu_length); #ifdef FORMAT1C - //NO SIB - if ((subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) || - (subframeP == 5 && ((frameP % 2) != 0 && (frameP % 8) != 1))) { - switch (n_rb_dl) { + //NO SIB + if ((subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) || + (subframeP == 5 && ((frameP % 2) != 0 && (frameP % 8) != 1))) { + switch (n_rb_dl) { #if 0 - case 6: - n_gap = n_rb_dl/2; /* expect: 3 */ - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));; /* expect: 6 */ - first_rb = 0; - break; - case 15: - n_gap = GAP_MAP[2][0]; /* expect: 8 */ - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 14 */ - first_rb = 6; - break; + case 6: + n_gap = n_rb_dl/2; /* expect: 3 */ + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));; /* expect: 6 */ + first_rb = 0; + break; + case 15: + n_gap = GAP_MAP[2][0]; /* expect: 8 */ + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 14 */ + first_rb = 6; + break; #endif - case 25: - n_gap = GAP_MAP[3][0]; /* expect: 12 */ - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 24 */ - first_rb = 10; - break; - case 50: - n_gap = GAP_MAP[6][gap_index]; /* expect: 27 or 9 */ - if (gap_index > 0) { - n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* 36 */ - } else { - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 46 */ - } - first_rb = 24; - break; - case 100: - n_gap = GAP_MAP[8][gap_index]; /* expect: 48 or 16 */ - if (gap_index > 0) { - n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* expect: 96 */ - } else { - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 96 */ - } - first_rb = 48; - break; - } - } else if (subframeP == 5 && ((frameP % 2) == 0 || (frameP % 8) == 1)) { // SIB + paging - switch (n_rb_dl) { + case 25: + n_gap = GAP_MAP[3][0]; /* expect: 12 */ + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 24 */ + first_rb = 10; + break; + case 50: + n_gap = GAP_MAP[6][gap_index]; /* expect: 27 or 9 */ + if (gap_index > 0) { + n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* 36 */ + } else { + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 46 */ + } + first_rb = 24; + break; + case 100: + n_gap = GAP_MAP[8][gap_index]; /* expect: 48 or 16 */ + if (gap_index > 0) { + n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* expect: 96 */ + } else { + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 96 */ + } + first_rb = 48; + break; + } + } else if (subframeP == 5 && ((frameP % 2) == 0 || (frameP % 8) == 1)) { // SIB + paging + switch (n_rb_dl) { #if 0 - case 6: - n_gap = n_rb_dl/2; /* expect: 3 */ - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));; /* expect: 6 */ - first_rb = 0; - break; - case 15: - n_gap = GAP_MAP[2][0]; /* expect: 8 */ - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 14 */ - first_rb = 10; - break; + case 6: + n_gap = n_rb_dl/2; /* expect: 3 */ + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));; /* expect: 6 */ + first_rb = 0; + break; + case 15: + n_gap = GAP_MAP[2][0]; /* expect: 8 */ + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 14 */ + first_rb = 10; + break; #endif - case 25: - n_gap = GAP_MAP[3][0]; /* expect: 12 */ - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 24 */ - first_rb = 14; - break; - case 50: - n_gap = GAP_MAP[6][gap_index]; /* expect: 27 or 9 */ - if (gap_index > 0) { - n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* 36 */ - } else { - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 46 */ - } - first_rb = 28; - break; - case 100: - n_gap = GAP_MAP[8][gap_index]; /* expect: 48 or 16 */ - if (gap_index > 0) { - n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* expect: 96 */ - } else { - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 96 */ - } - first_rb = 52; - break; - } - } - /* Get MCS for length of PCH */ - if (pcch_sdu_length <= TBStable1C[0]) { - mcs=0; - } else if (pcch_sdu_length <= TBStable1C[1]) { - mcs=1; - } else if (pcch_sdu_length <= TBStable1C[2]) { - mcs=2; - } else if (pcch_sdu_length <= TBStable1C[3]) { - mcs=3; - } else if (pcch_sdu_length <= TBStable1C[4]) { - mcs=4; - } else if (pcch_sdu_length <= TBStable1C[5]) { - mcs=5; - } else if (pcch_sdu_length <= TBStable1C[6]) { - mcs=6; - } else if (pcch_sdu_length <= TBStable1C[7]) { - mcs=7; - } else if (pcch_sdu_length <= TBStable1C[8]) { - mcs=8; - } else if (pcch_sdu_length <= TBStable1C[9]) { - mcs=9; - } else { - /* unexpected: pcch sdb size is over max value*/ - LOG_E(MAC,"[eNB %d] Frame %d : PCCH->PCH CC_id %d, Received %d bytes is over max length(256) \n", - module_idP, frameP,CC_id, pcch_sdu_length); - return; - } - rb_num = TBStable1C[mcs] / rb_bit + ( (TBStable1C[mcs] % rb_bit == 0)? 0: 1) + 1; - /* calculate N_RB_STEP and Lcrbs */ - if (n_rb_dl < 50) { - n_rb_step = 2; - Lcrbs = rb_num / 2 + ((rb_num % 2 == 0) ? 0:2); - } else { - n_rb_step = 4; - Lcrbs = rb_num / 4 + ((rb_num % 4 == 0) ? 0:4); - } - for(i = 0;i < Lcrbs ;i++){ - vrb_map[first_rb+i] = 1; - } + case 25: + n_gap = GAP_MAP[3][0]; /* expect: 12 */ + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 24 */ + first_rb = 14; + break; + case 50: + n_gap = GAP_MAP[6][gap_index]; /* expect: 27 or 9 */ + if (gap_index > 0) { + n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* 36 */ + } else { + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 46 */ + } + first_rb = 28; + break; + case 100: + n_gap = GAP_MAP[8][gap_index]; /* expect: 48 or 16 */ + if (gap_index > 0) { + n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* expect: 96 */ + } else { + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 96 */ + } + first_rb = 52; + break; + } + } + /* Get MCS for length of PCH */ + if (pcch_sdu_length <= TBStable1C[0]) { + mcs=0; + } else if (pcch_sdu_length <= TBStable1C[1]) { + mcs=1; + } else if (pcch_sdu_length <= TBStable1C[2]) { + mcs=2; + } else if (pcch_sdu_length <= TBStable1C[3]) { + mcs=3; + } else if (pcch_sdu_length <= TBStable1C[4]) { + mcs=4; + } else if (pcch_sdu_length <= TBStable1C[5]) { + mcs=5; + } else if (pcch_sdu_length <= TBStable1C[6]) { + mcs=6; + } else if (pcch_sdu_length <= TBStable1C[7]) { + mcs=7; + } else if (pcch_sdu_length <= TBStable1C[8]) { + mcs=8; + } else if (pcch_sdu_length <= TBStable1C[9]) { + mcs=9; + } else { + /* unexpected: pcch sdb size is over max value*/ + LOG_E(MAC,"[eNB %d] Frame %d : PCCH->PCH CC_id %d, Received %d bytes is over max length(256) \n", + module_idP, frameP,CC_id, pcch_sdu_length); + return; + } + rb_num = TBStable1C[mcs] / rb_bit + ( (TBStable1C[mcs] % rb_bit == 0)? 0: 1) + 1; + /* calculate N_RB_STEP and Lcrbs */ + if (n_rb_dl < 50) { + n_rb_step = 2; + Lcrbs = rb_num / 2 + ((rb_num % 2 == 0) ? 0:2); + } else { + n_rb_step = 4; + Lcrbs = rb_num / 4 + ((rb_num % 4 == 0) ? 0:4); + } + for(i = 0;i < Lcrbs ;i++){ + vrb_map[first_rb+i] = 1; + } #else - //NO SIB - if ((subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) || - (subframeP == 5 && ((frameP % 2) != 0 && (frameP % 8) != 1))) { - switch (n_rb_dl) { - case 25: - first_rb = 10; - break; - case 50: - first_rb = 24; - break; - case 100: - first_rb = 48; - break; - } - } else if (subframeP == 5 && ((frameP % 2) == 0 || (frameP % 8) == 1)) { // SIB + paging - switch (n_rb_dl) { - case 25: - first_rb = 14; - break; - case 50: - first_rb = 28; - break; - case 100: - first_rb = 52; - break; - } - } + //NO SIB + if ((subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) || + (subframeP == 5 && ((frameP % 2) != 0 && (frameP % 8) != 1))) { + switch (n_rb_dl) { + case 25: + first_rb = 10; + break; + case 50: + first_rb = 24; + break; + case 100: + first_rb = 48; + break; + } + } else if (subframeP == 5 && ((frameP % 2) == 0 || (frameP % 8) == 1)) { // SIB + paging + switch (n_rb_dl) { + case 25: + first_rb = 14; + break; + case 50: + first_rb = 28; + break; + case 100: + first_rb = 52; + break; + } + } - vrb_map[first_rb] = 1; - vrb_map[first_rb+1] = 1; - vrb_map[first_rb+2] = 1; - vrb_map[first_rb+3] = 1; - /* Get MCS for length of PCH */ - if (pcch_sdu_length <= get_TBS_DL(0,3)) { - mcs=0; - } else if (pcch_sdu_length <= get_TBS_DL(1,3)) { - mcs=1; - } else if (pcch_sdu_length <= get_TBS_DL(2,3)) { - mcs=2; - } else if (pcch_sdu_length <= get_TBS_DL(3,3)) { - mcs=3; - } else if (pcch_sdu_length <= get_TBS_DL(4,3)) { - mcs=4; - } else if (pcch_sdu_length <= get_TBS_DL(5,3)) { - mcs=5; - } else if (pcch_sdu_length <= get_TBS_DL(6,3)) { - mcs=6; - } else if (pcch_sdu_length <= get_TBS_DL(7,3)) { - mcs=7; - } else if (pcch_sdu_length <= get_TBS_DL(8,3)) { - mcs=8; - } else if (pcch_sdu_length <= get_TBS_DL(9,3)) { - mcs=9; - } + vrb_map[first_rb] = 1; + vrb_map[first_rb+1] = 1; + vrb_map[first_rb+2] = 1; + vrb_map[first_rb+3] = 1; + /* Get MCS for length of PCH */ + if (pcch_sdu_length <= get_TBS_DL(0,3)) { + mcs=0; + } else if (pcch_sdu_length <= get_TBS_DL(1,3)) { + mcs=1; + } else if (pcch_sdu_length <= get_TBS_DL(2,3)) { + mcs=2; + } else if (pcch_sdu_length <= get_TBS_DL(3,3)) { + mcs=3; + } else if (pcch_sdu_length <= get_TBS_DL(4,3)) { + mcs=4; + } else if (pcch_sdu_length <= get_TBS_DL(5,3)) { + mcs=5; + } else if (pcch_sdu_length <= get_TBS_DL(6,3)) { + mcs=6; + } else if (pcch_sdu_length <= get_TBS_DL(7,3)) { + mcs=7; + } else if (pcch_sdu_length <= get_TBS_DL(8,3)) { + mcs=8; + } else if (pcch_sdu_length <= get_TBS_DL(9,3)) { + mcs=9; + } #endif - 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_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_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_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu)); #ifdef FORMAT1C - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1C; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.ngap = n_gap; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1C; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.ngap = n_gap; #else - 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.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.new_data_indicator_1 = 1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_rb_dl,first_rb,4); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0; + 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.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.new_data_indicator_1 = 1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_rb_dl,first_rb,4); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0; #endif - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFE; // P-RNTI - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // P-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.mcs_1 = mcs; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFE; // P-RNTI + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // P-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.mcs_1 = mcs; - // 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; + // 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; - if (!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, P_RNTI)) { - LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for P_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 = 0xFFFE; + if (!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, P_RNTI)) { + LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for P_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 = 0xFFFE; #ifdef FORMAT1C - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 3; // format 1C - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 3; // format 1C + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step); #else - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_rb_dl,first_rb,4); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_rb_dl,first_rb,4); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized #endif - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 1; - 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++; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 1; + 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++; - eNB->TX_req[CC_id].sfn_sf = (frameP<<4)+subframeP; - 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 = pcch_sdu_length; - TX_req->pdu_index = eNB->pdu_index[CC_id]++; - TX_req->num_segments = 1; - TX_req->segments[0].segment_length = pcch_sdu_length; - TX_req->segments[0].segment_data = cc[CC_id].PCCH_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/1C for Paging\n",module_idP, CC_id, frameP, subframeP); - continue; + eNB->TX_req[CC_id].sfn_sf = (frameP<<4)+subframeP; + 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 = pcch_sdu_length; + TX_req->pdu_index = eNB->pdu_index[CC_id]++; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = pcch_sdu_length; + TX_req->segments[0].segment_data = cc[CC_id].PCCH_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/1C for Paging\n",module_idP, CC_id, frameP, subframeP); + continue; + } + + if (opt_enabled == 1) { + trace_pdu(1, + &eNB->common_channels[CC_id].PCCH_pdu.payload[0], + pcch_sdu_length, + 0xffff, + PCCH, + P_RNTI, + eNB->frame, + eNB->subframe, + 0, + 0); + LOG_D(OPT,"[eNB %d][PCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", + module_idP, frameP, CC_id, 0xffff, pcch_sdu_length); + } + eNB->eNB_stats[CC_id].total_num_pcch_pdu+=1; + eNB->eNB_stats[CC_id].pcch_buffer=pcch_sdu_length; + eNB->eNB_stats[CC_id].total_pcch_buffer+=pcch_sdu_length; + eNB->eNB_stats[CC_id].pcch_mcs=mcs; + //paging first_rb log + LOG_D(MAC,"[eNB %d] Frame %d subframe %d PCH: paging_ue_index %d pcch_sdu_length %d mcs %d first_rb %d\n", + module_idP, frameP, subframeP, UE_PF_PO[CC_id][i].ue_index_value, pcch_sdu_length, mcs, first_rb); + + pthread_mutex_lock(&ue_pf_po_mutex); + memset(&UE_PF_PO[CC_id][i], 0, sizeof(UE_PF_PO_t)); + pthread_mutex_unlock(&ue_pf_po_mutex); } - - if (opt_enabled == 1) { - trace_pdu(1, - &eNB->common_channels[CC_id].PCCH_pdu.payload[0], - pcch_sdu_length, - 0xffff, - PCCH, - P_RNTI, - eNB->frame, - eNB->subframe, - 0, - 0); - LOG_D(OPT,"[eNB %d][PCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", - module_idP, frameP, CC_id, 0xffff, pcch_sdu_length); - } - eNB->eNB_stats[CC_id].total_num_pcch_pdu+=1; - eNB->eNB_stats[CC_id].pcch_buffer=pcch_sdu_length; - eNB->eNB_stats[CC_id].total_pcch_buffer+=pcch_sdu_length; - eNB->eNB_stats[CC_id].pcch_mcs=mcs; - //paging first_rb log - LOG_D(MAC,"[eNB %d] Frame %d subframe %d PCH: paging_ue_index %d pcch_sdu_length %d mcs %d first_rb %d\n", - module_idP, frameP, subframeP, UE_PF_PO[CC_id][i].ue_index_value, pcch_sdu_length, mcs, first_rb); - - pthread_mutex_lock(&ue_pf_po_mutex); - memset(&UE_PF_PO[CC_id][i], 0, sizeof(UE_PF_PO_t)); - pthread_mutex_unlock(&ue_pf_po_mutex); - } } } /* this might be misleading when pcch is inactive */ diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index f841d9d55a..5cdd9d8771 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -72,9 +72,9 @@ extern uint8_t nfapi_mode; // This table holds the allowable PRB sizes for ULSCH transmissions uint8_t rb_table[34] = - { 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, + { 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80, 81, 90, 96, 100 -}; + }; void rx_sdu(const module_id_t enb_mod_idP, @@ -86,746 +86,625 @@ rx_sdu(const module_id_t enb_mod_idP, const uint16_t sdu_lenP, const uint16_t timing_advance, const uint8_t ul_cqi) { - int current_rnti = rntiP; - unsigned char rx_ces[MAX_NUM_CE], num_ce, num_sdu, i, *payload_ptr; - unsigned char rx_lcids[NB_RB_MAX]; - unsigned short rx_lengths[NB_RB_MAX]; - int UE_id = find_UE_id(enb_mod_idP, current_rnti); - int RA_id; - int ii, j; - eNB_MAC_INST *mac = RC.mac[enb_mod_idP]; - int harq_pid = - subframe2harqpid(&mac->common_channels[CC_idP], frameP, subframeP); + int current_rnti = rntiP; + unsigned char rx_ces[MAX_NUM_CE], num_ce, num_sdu, i, *payload_ptr; + unsigned char rx_lcids[NB_RB_MAX]; + unsigned short rx_lengths[NB_RB_MAX]; + int UE_id = find_UE_id(enb_mod_idP, current_rnti); + int RA_id; + int ii, j; + eNB_MAC_INST *mac = RC.mac[enb_mod_idP]; + int harq_pid = + subframe2harqpid(&mac->common_channels[CC_idP], frameP, subframeP); - UE_list_t *UE_list = &mac->UE_list; - int crnti_rx = 0; - int old_buffer_info; - RA_t *ra = - (RA_t *) & RC.mac[enb_mod_idP]->common_channels[CC_idP].ra[0]; - int first_rb = 0; + UE_list_t *UE_list = &mac->UE_list; + int crnti_rx = 0; + int old_buffer_info; + RA_t *ra = + (RA_t *) & RC.mac[enb_mod_idP]->common_channels[CC_idP].ra[0]; + int first_rb = 0; - start_meas(&mac->rx_ulsch_sdu); + start_meas(&mac->rx_ulsch_sdu); - if ((UE_id > NUMBER_OF_UE_MAX) || (UE_id == -1)) - for (ii = 0; ii < NB_RB_MAX; ii++) { - rx_lengths[ii] = 0; - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 1); - if (opt_enabled == 1) { - trace_pdu(0, sduP, sdu_lenP, 0, 3, current_rnti, frameP, subframeP, - 0, 0); - LOG_D(OPT, "[eNB %d][ULSCH] Frame %d rnti %x with size %d\n", - enb_mod_idP, frameP, current_rnti, sdu_lenP); + if ((UE_id > NUMBER_OF_UE_MAX) || (UE_id == -1)) + for (ii = 0; ii < NB_RB_MAX; ii++) { + rx_lengths[ii] = 0; } - if (UE_id != -1) { - LOG_D(MAC, - "[eNB %d][PUSCH %d] CC_id %d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n", - enb_mod_idP, harq_pid, CC_idP, - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid], - current_rnti, UE_id, ul_cqi); - - AssertFatal(UE_list->UE_sched_ctrl[UE_id]. - round_UL[CC_idP][harq_pid] < 8, "round >= 8\n"); - if (sduP != NULL) { - UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_scheduled &= - (~(1 << harq_pid)); - /* Update with smoothing: 3/4 of old value and 1/4 of new. - * This is the logic that was done in the function - * lte_est_timing_advance_pusch, maybe it's not necessary? - * maybe it's even not correct at all? - */ - UE_list->UE_sched_ctrl[UE_id].ta_update = - (UE_list->UE_sched_ctrl[UE_id].ta_update * 3 + - timing_advance) / 4; - UE_list->UE_sched_ctrl[UE_id].pusch_snr[CC_idP] = ul_cqi; - UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors = 0; - first_rb = - UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid]; - - if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) { - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0; - mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, - subframeP, UE_RNTI(enb_mod_idP, - UE_id)); - } - } else { // we've got an error - LOG_D(MAC, - "[eNB %d][PUSCH %d] CC_id %d ULSCH in error in round %d, ul_cqi %d\n", - enb_mod_idP, harq_pid, CC_idP, - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid], - ul_cqi); - - // AssertFatal(1==0,"ulsch in error\n"); - if (UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] == - 3) { - UE_list->UE_sched_ctrl[UE_id].ul_scheduled &= - (~(1 << harq_pid)); - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = - 0; - if (UE_list->UE_sched_ctrl[UE_id]. - ul_consecutive_errors++ == 10) - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 1; - } else - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]++; - return; - - } - } else if ((RA_id = find_RA_id(enb_mod_idP, CC_idP, current_rnti)) != -1) { // Check if this is an RA process for the rnti - AssertFatal(mac->common_channels[CC_idP]. - radioResourceConfigCommon->rach_ConfigCommon. - maxHARQ_Msg3Tx > 1, - "maxHARQ %d should be greater than 1\n", - (int) mac->common_channels[CC_idP]. - radioResourceConfigCommon->rach_ConfigCommon. - maxHARQ_Msg3Tx); - - LOG_D(MAC, - "[eNB %d][PUSCH %d] CC_id %d [RAPROC Msg3] Received ULSCH sdu round %d from PHY (rnti %x, RA_id %d) ul_cqi %d\n", - enb_mod_idP, harq_pid, CC_idP, ra[RA_id].msg3_round, - current_rnti, RA_id, ul_cqi); - - first_rb = ra->msg3_first_rb; - - if (sduP == NULL) { // we've got an error on Msg3 - LOG_D(MAC, - "[eNB %d] CC_id %d, RA %d ULSCH in error in round %d/%d\n", - enb_mod_idP, CC_idP, RA_id, - ra[RA_id].msg3_round, - (int) mac->common_channels[CC_idP]. - radioResourceConfigCommon->rach_ConfigCommon. - maxHARQ_Msg3Tx); - if (ra[RA_id].msg3_round == - mac->common_channels[CC_idP].radioResourceConfigCommon-> - rach_ConfigCommon.maxHARQ_Msg3Tx - 1) { - cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); - } - - else { - first_rb = - UE_list->UE_template[CC_idP][UE_id]. - first_rb_ul[harq_pid]; - ra[RA_id].msg3_round++; - // prepare handling of retransmission - ra[RA_id].Msg3_frame = (ra[RA_id].Msg3_frame + ((ra[RA_id].Msg3_subframe > 1) ? 1 : 0)) % 1024; - ra[RA_id].Msg3_subframe = (ra[RA_id].Msg3_subframe + 8) % 10; - add_msg3(enb_mod_idP, CC_idP, &ra[RA_id], frameP, - subframeP); - } - return; - } - } else { - LOG_W(MAC, - "Cannot find UE or RA corresponding to ULSCH rnti %x, dropping it\n", - current_rnti); - return; - } - payload_ptr = - parse_ulsch_header(sduP, &num_ce, &num_sdu, rx_ces, rx_lcids, - rx_lengths, sdu_lenP); - - T(T_ENB_MAC_UE_UL_PDU, T_INT(enb_mod_idP), T_INT(CC_idP), - T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), - T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu)); - T(T_ENB_MAC_UE_UL_PDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), - T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), - T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu), - T_BUFFER(sduP, sdu_lenP)); - - mac->eNB_stats[CC_idP].ulsch_bytes_rx = sdu_lenP; - mac->eNB_stats[CC_idP].total_ulsch_bytes_rx += sdu_lenP; - mac->eNB_stats[CC_idP].total_ulsch_pdus_rx += 1; - - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = 0; - - // control element - for (i = 0; i < num_ce; i++) { - - T(T_ENB_MAC_UE_UL_CE, T_INT(enb_mod_idP), T_INT(CC_idP), - T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), - T_INT(rx_ces[i])); - - switch (rx_ces[i]) { // implement and process BSR + CRNTI + - case POWER_HEADROOM: - if (UE_id != -1) { - UE_list->UE_template[CC_idP][UE_id].phr_info = - (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET; - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d : Received PHR PH = %d (db)\n", - enb_mod_idP, CC_idP, rx_ces[i], - UE_list->UE_template[CC_idP][UE_id].phr_info); - UE_list->UE_template[CC_idP][UE_id].phr_info_configured = - 1; - UE_list->UE_sched_ctrl[UE_id].phr_received = 1; - } - payload_ptr += sizeof(POWER_HEADROOM_CMD); - break; - - case CRNTI: - { - int old_rnti = - (((uint16_t) payload_ptr[0]) << 8) + payload_ptr[1]; - int old_UE_id = find_UE_id(enb_mod_idP, old_rnti); - LOG_D(MAC, - "[eNB %d] Frame %d, Subframe %d CC_id %d MAC CE_LCID %d (ce %d/%d): CRNTI %x (UE_id %d) in Msg3\n", - enb_mod_idP, frameP, subframeP, CC_idP, rx_ces[i], i, - num_ce, old_rnti, old_UE_id); - /* receiving CRNTI means that the current rnti has to go away */ - cancel_ra_proc(enb_mod_idP, CC_idP, frameP, - current_rnti); - if (old_UE_id != -1) { - /* TODO: if the UE did random access (followed by a MAC uplink with - * CRNTI) because none of its scheduling request was granted, then - * according to 36.321 5.4.4 the UE's MAC will notify RRC to release - * PUCCH/SRS. According to 36.331 5.3.13 the UE will then apply - * default configuration for CQI reporting and scheduling requests, - * which basically means that the CQI requests won't work anymore and - * that the UE won't do any scheduling request anymore as long as the - * eNB doesn't reconfigure the UE. - * We have to take care of this. As the code is, nothing is done and - * the UE state in the eNB is wrong. - */ - UE_id = old_UE_id; - UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; - if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) { - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0; - mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, - subframeP, old_rnti); - } - current_rnti = old_rnti; - } - crnti_rx = 1; - payload_ptr += 2; - break; - } - - case TRUNCATED_BSR: - case SHORT_BSR: - { - uint8_t lcgid; - lcgid = (payload_ptr[0] >> 6); - - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", - enb_mod_idP, CC_idP, rx_ces[i], lcgid, - payload_ptr[0] & 0x3f); - - if (crnti_rx == 1) - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", - enb_mod_idP, CC_idP, rx_ces[i], lcgid, - payload_ptr[0] & 0x3f); - if (UE_id != -1) { - - UE_list->UE_template[CC_idP][UE_id].bsr_info[lcgid] = - (payload_ptr[0] & 0x3f); - - // update buffer info - - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[lcgid] = - BSR_TABLE[UE_list->UE_template[CC_idP][UE_id]. - bsr_info[lcgid]]; - - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[lcgid]; - - RC.eNB[enb_mod_idP][CC_idP]-> - pusch_stats_bsr[UE_id][(frameP * 10) + subframeP] - = (payload_ptr[0] & 0x3f); - if (UE_id == UE_list->head) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME - (VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR, - RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr - [UE_id][(frameP * 10) + subframeP]); - if (UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[lcgid] - == 0) { - UE_list->UE_template[CC_idP] - [UE_id].ul_buffer_creation_time[lcgid] = - frameP; - } - if (mac_eNB_get_rrc_status - (enb_mod_idP, - UE_RNTI(enb_mod_idP, UE_id)) < RRC_CONNECTED) - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d : ul_total_buffer = %d (lcg increment %d)\n", - enb_mod_idP, CC_idP, rx_ces[i], - UE_list->UE_template[CC_idP][UE_id]. - ul_total_buffer, - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[lcgid]); - } else { - - } - payload_ptr += 1; //sizeof(SHORT_BSR); // fixme - } - break; - - case LONG_BSR: - if (UE_id != -1) { - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] = - ((payload_ptr[0] & 0xFC) >> 2); - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] = - ((payload_ptr[0] & 0x03) << 4) | - ((payload_ptr[1] & 0xF0) >> 4); - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] = - ((payload_ptr[1] & 0x0F) << 2) | - ((payload_ptr[2] & 0xC0) >> 6); - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] = - (payload_ptr[2] & 0x3F); - - // update buffer info - old_buffer_info = - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID0]; - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID0] = - BSR_TABLE[UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID0]]; - - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer += - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID0]; - if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= - old_buffer_info) - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= - old_buffer_info; - else - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = - 0; - - old_buffer_info = - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID1]; - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID1] = - BSR_TABLE[UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID1]]; - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer += - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID1]; - if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= - old_buffer_info) - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= - old_buffer_info; - else - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = - 0; - - old_buffer_info = - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID2]; - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID2] = - BSR_TABLE[UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID2]]; - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer += - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID2]; - if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= - old_buffer_info) - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= - old_buffer_info; - else - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = - 0; - - old_buffer_info = - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID3]; - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID3] = - BSR_TABLE[UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID3]]; - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer += - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID3]; - if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= - old_buffer_info) - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= - old_buffer_info; - else - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = - 0; - - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = " - "%u LCGID2 = %u LCGID3 = %u\n", enb_mod_idP, CC_idP, - rx_ces[i], - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0], - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1], - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2], - UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID3]); - if (crnti_rx == 1) - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = " - "%u LCGID2 = %u LCGID3 = %u\n", enb_mod_idP, - CC_idP, rx_ces[i], - UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID0], - UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID1], - UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID2], - UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID3]); - - if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] == - 0) { - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[LCGID0] = 0; - } else if (UE_list->UE_template[CC_idP] - [UE_id].ul_buffer_creation_time[LCGID0] == 0) { - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[LCGID0] = frameP; - } - - if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] == - 0) { - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[LCGID1] = 0; - } else if (UE_list->UE_template[CC_idP] - [UE_id].ul_buffer_creation_time[LCGID1] == 0) { - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[LCGID1] = frameP; - } - - if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] == - 0) { - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[LCGID2] = 0; - } else if (UE_list->UE_template[CC_idP] - [UE_id].ul_buffer_creation_time[LCGID2] == 0) { - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[LCGID2] = frameP; - } - - if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] == - 0) { - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[LCGID3] = 0; - } else if (UE_list->UE_template[CC_idP] - [UE_id].ul_buffer_creation_time[LCGID3] == 0) { - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[LCGID3] = frameP; - - } - } - - payload_ptr += 3; ////sizeof(LONG_BSR); - break; - - default: - LOG_E(MAC, - "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", - enb_mod_idP, CC_idP, rx_ces[i]); - break; - } - } - - for (i = 0; i < num_sdu; i++) { - LOG_D(MAC, "SDU Number %d MAC Subheader SDU_LCID %d, length %d\n", - i, rx_lcids[i], rx_lengths[i]); - - T(T_ENB_MAC_UE_UL_SDU, T_INT(enb_mod_idP), T_INT(CC_idP), - T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), - T_INT(rx_lcids[i]), T_INT(rx_lengths[i])); - T(T_ENB_MAC_UE_UL_SDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), - T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), - T_INT(rx_lcids[i]), T_INT(rx_lengths[i]), T_BUFFER(payload_ptr, - rx_lengths - [i])); - - switch (rx_lcids[i]) { - case CCCH: - if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) { - LOG_E(MAC, - "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d, sdu_len %d), dropping packet\n", - enb_mod_idP, CC_idP, frameP, rx_lengths[i], - CCCH_PAYLOAD_SIZE_MAX, sdu_lenP); - break; - } - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d, Received CCCH: %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n", - enb_mod_idP, CC_idP, frameP, payload_ptr[0], - payload_ptr[1], payload_ptr[2], payload_ptr[3], - payload_ptr[4], payload_ptr[5], current_rnti); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 1); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 0); - for (ii = 0; ii < NB_RA_PROC_MAX; ii++) { - RA_t *ra = &mac->common_channels[CC_idP].ra[ii]; - - LOG_D(MAC, - "[mac %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), state %d\n", - enb_mod_idP, CC_idP, ii, ra->rnti, - current_rnti, ra->state); - - if ((ra->rnti == current_rnti) && (ra->state != IDLE)) { - - //payload_ptr = parse_ulsch_header(msg3,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,msg3_len); - - if (UE_id < 0) { - memcpy(&ra->cont_res_id[0], payload_ptr, 6); - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %ld\n", - enb_mod_idP, CC_idP, frameP, rx_lengths[i], - payload_ptr - sduP); - - if ((UE_id = - add_new_ue(enb_mod_idP, CC_idP, - mac->common_channels[CC_idP]. - ra[ii].rnti, harq_pid -#ifdef Rel14 - , - mac->common_channels[CC_idP]. - ra[ii].rach_resource_type -#endif - )) == -1) { - AssertFatal(1 == 0, - "[MAC][eNB] Max user count reached\n"); - // kill RA procedure - } else - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n", - enb_mod_idP, CC_idP, frameP, ra->rnti, - UE_id); - } else { - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n", - enb_mod_idP, CC_idP, frameP, UE_id, - rx_lengths[i], payload_ptr - sduP); - // kill RA procedure - } - - mac_rrc_data_ind(enb_mod_idP, - CC_idP, - frameP, subframeP, - current_rnti, - CCCH, - (uint8_t *) payload_ptr, - rx_lengths[i], - 0); - - - if (num_ce > 0) { // handle msg3 which is not RRCConnectionRequest - // process_ra_message(msg3,num_ce,rx_lcids,rx_ces); - } - // prepare transmission of Msg4 - ra->state = MSG4; - - - - // Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, // Check if this is ok for BL/CE, or if the rule is different - ra->Msg4_frame = frameP + ((subframeP > 5) ? 1 : 0); - ra->Msg4_subframe = (subframeP + 4) % 10; - - } // if process is active - } // loop on RA processes - - break; - - case DCCH: - case DCCH1: - // if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){ - - -#if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_T(MAC, "offset: %d\n", - (unsigned char) ((unsigned char *) payload_ptr - sduP)); - for (j = 0; j < 32; j++) { - LOG_T(MAC, "%x ", payload_ptr[j]); - } - LOG_T(MAC, "\n"); -#endif - - if (UE_id != -1) { - // adjust buffer occupancy of the correponding logical channel group - if (UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[UE_list->UE_template[CC_idP] - [UE_id].lcgidmap[rx_lcids[i]]] >= - rx_lengths[i]) - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[UE_list->UE_template[CC_idP] - [UE_id].lcgidmap[rx_lcids[i]]] -= - rx_lengths[i]; - else - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[UE_list->UE_template[CC_idP] - [UE_id].lcgidmap[rx_lcids[i]]] = 0; - - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DCCH, received %d bytes form UE %d on LCID %d \n", - enb_mod_idP, CC_idP, frameP, rx_lengths[i], UE_id, - rx_lcids[i]); - - mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); //(unsigned int*)crc_status); - UE_list->eNB_UE_stats[CC_idP][UE_id]. - num_pdu_rx[rx_lcids[i]] += 1; - UE_list->eNB_UE_stats[CC_idP][UE_id]. - num_bytes_rx[rx_lcids[i]] - += rx_lengths[i]; - - - } - - /* UE_id != -1 */ - // } - break; - - // all the DRBS - case DTCH: - default: - -#if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_T(MAC, "offset: %d\n", - (unsigned char) ((unsigned char *) payload_ptr - sduP)); - for (j = 0; j < 32; j++) { - LOG_T(MAC, "%x ", payload_ptr[j]); - } - LOG_T(MAC, "\n"); -#endif - if (rx_lcids[i] < NB_RB_MAX) { - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d\n", - enb_mod_idP, CC_idP, frameP, rx_lengths[i], UE_id, - rx_lcids[i]); - - if (UE_id != -1) { - // adjust buffer occupancy of the correponding logical channel group - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d, removing from LCGID %ld, %d\n", - enb_mod_idP, CC_idP, frameP, rx_lengths[i], - UE_id, rx_lcids[i], - UE_list->UE_template[CC_idP][UE_id]. - lcgidmap[rx_lcids[i]], - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[UE_list->UE_template[CC_idP] - [UE_id].lcgidmap[rx_lcids[i]]]); - - if (UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[UE_list->UE_template[CC_idP] - [UE_id].lcgidmap[rx_lcids[i]]] - >= rx_lengths[i]) - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[UE_list->UE_template[CC_idP] - [UE_id].lcgidmap[rx_lcids[i]]] - -= rx_lengths[i]; - else - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info - [UE_list->UE_template[CC_idP][UE_id].lcgidmap - [rx_lcids[i]]] = 0; - if ((rx_lengths[i] < SCH_PAYLOAD_SIZE_MAX) - && (rx_lengths[i] > 0)) { // MAX SIZE OF transport block - mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); //(unsigned int*)crc_status); - - UE_list->eNB_UE_stats[CC_idP][UE_id]. - num_pdu_rx[rx_lcids[i]] += 1; - UE_list->eNB_UE_stats[CC_idP][UE_id]. - num_bytes_rx[rx_lcids[i]] += rx_lengths[i]; - //clear uplane_inactivity_timer - UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; - } else { /* rx_length[i] */ - UE_list->eNB_UE_stats[CC_idP][UE_id]. - num_errors_rx += 1; - LOG_E(MAC, - "[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ", - enb_mod_idP, CC_idP, frameP, rx_lcids[i], - UE_id); - } - } else { /*(UE_id != -1 */ - LOG_E(MAC, - "[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ", - enb_mod_idP, CC_idP, frameP, rx_lcids[i], UE_id); - } - } - - break; - } - - payload_ptr += rx_lengths[i]; - } - - // Program ACK for PHICH + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 1); + if (opt_enabled == 1) { + trace_pdu(0, sduP, sdu_lenP, 0, 3, current_rnti, frameP, subframeP, + 0, 0); + LOG_D(OPT, "[eNB %d][ULSCH] Frame %d rnti %x with size %d\n", + enb_mod_idP, frameP, current_rnti, sdu_lenP); + } + + if (UE_id != -1) { LOG_D(MAC, - "Programming PHICH ACK for rnti %x harq_pid %d (first_rb %d)\n", - current_rnti, harq_pid, first_rb); - nfapi_hi_dci0_request_t *hi_dci0_req = &mac->HI_DCI0_req[CC_idP]; - nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body; - nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = - &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; - memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t)); - hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; - hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu); - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG; - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = first_rb; - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0; - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 1; - hi_dci0_req_body->number_of_hi++; - hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP,subframeP, 0); - hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; - hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP,subframeP, 4); - hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; + "[eNB %d][PUSCH %d] CC_id %d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n", + enb_mod_idP, harq_pid, CC_idP, + UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid], + current_rnti, UE_id, ul_cqi); - /* NN--> FK: we could either check the payload, or use a phy helper to detect a false msg3 */ - if ((num_sdu == 0) && (num_ce == 0)) { - if (UE_id != -1) - UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx += 1; - /* - if (msg3_flagP != NULL) { - if( *msg3_flagP == 1 ) { - LOG_N(MAC,"[eNB %d] CC_id %d frame %d : false msg3 detection: signal phy to canceling RA and remove the UE\n", enb_mod_idP, CC_idP, frameP); - *msg3_flagP=0; - } - } */ - } else { - if (UE_id != -1) { - UE_list->eNB_UE_stats[CC_idP][UE_id].pdu_bytes_rx = sdu_lenP; - UE_list->eNB_UE_stats[CC_idP][UE_id].total_pdu_bytes_rx += - sdu_lenP; - UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_pdus_rx += 1; + AssertFatal(UE_list->UE_sched_ctrl[UE_id]. + round_UL[CC_idP][harq_pid] < 8, "round >= 8\n"); + if (sduP != NULL) { + UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0; + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; + UE_list->UE_sched_ctrl[UE_id].ul_scheduled &= (~(1 << harq_pid)); + /* Update with smoothing: 3/4 of old value and 1/4 of new. + * This is the logic that was done in the function + * lte_est_timing_advance_pusch, maybe it's not necessary? + * maybe it's even not correct at all? + */ + UE_list->UE_sched_ctrl[UE_id].ta_update = (UE_list->UE_sched_ctrl[UE_id].ta_update * 3 + timing_advance) / 4; + UE_list->UE_sched_ctrl[UE_id].pusch_snr[CC_idP] = ul_cqi; + UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors = 0; + first_rb = UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid]; + + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) { + UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0; + mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, + subframeP, UE_RNTI(enb_mod_idP, + UE_id)); + } + } else { // we've got an error + LOG_D(MAC, + "[eNB %d][PUSCH %d] CC_id %d ULSCH in error in round %d, ul_cqi %d\n", + enb_mod_idP, harq_pid, CC_idP, + UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid], + ul_cqi); + + // AssertFatal(1==0,"ulsch in error\n"); + if (UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] == 3) { + UE_list->UE_sched_ctrl[UE_id].ul_scheduled &= (~(1 << harq_pid)); + UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = 0; + if (UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors++ == 10) + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 1; + } else + UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]++; + return; + + } + } else if ((RA_id = find_RA_id(enb_mod_idP, CC_idP, current_rnti)) != -1) { // Check if this is an RA process for the rnti + AssertFatal(mac->common_channels[CC_idP]. + radioResourceConfigCommon->rach_ConfigCommon. + maxHARQ_Msg3Tx > 1, + "maxHARQ %d should be greater than 1\n", + (int) mac->common_channels[CC_idP]. + radioResourceConfigCommon->rach_ConfigCommon. + maxHARQ_Msg3Tx); + + LOG_D(MAC, + "[eNB %d][PUSCH %d] CC_id %d [RAPROC Msg3] Received ULSCH sdu round %d from PHY (rnti %x, RA_id %d) ul_cqi %d\n", + enb_mod_idP, harq_pid, CC_idP, ra[RA_id].msg3_round, + current_rnti, RA_id, ul_cqi); + + first_rb = ra->msg3_first_rb; + + if (sduP == NULL) { // we've got an error on Msg3 + LOG_D(MAC, + "[eNB %d] CC_id %d, RA %d ULSCH in error in round %d/%d\n", + enb_mod_idP, CC_idP, RA_id, + ra[RA_id].msg3_round, + (int) mac->common_channels[CC_idP]. + radioResourceConfigCommon->rach_ConfigCommon. + maxHARQ_Msg3Tx); + if (ra[RA_id].msg3_round == mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx - 1) { + cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); + } + + else { + first_rb = UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid]; + ra[RA_id].msg3_round++; + // prepare handling of retransmission + ra[RA_id].Msg3_frame = (ra[RA_id].Msg3_frame + ((ra[RA_id].Msg3_subframe > 1) ? 1 : 0)) % 1024; + ra[RA_id].Msg3_subframe = (ra[RA_id].Msg3_subframe + 8) % 10; + add_msg3(enb_mod_idP, CC_idP, &ra[RA_id], frameP, subframeP); + } + return; + } + } else { + LOG_W(MAC, + "Cannot find UE or RA corresponding to ULSCH rnti %x, dropping it\n", + current_rnti); + return; + } + payload_ptr = parse_ulsch_header(sduP, &num_ce, &num_sdu, rx_ces, rx_lcids, rx_lengths, sdu_lenP); + + T(T_ENB_MAC_UE_UL_PDU, T_INT(enb_mod_idP), T_INT(CC_idP), + T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), + T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu)); + T(T_ENB_MAC_UE_UL_PDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), + T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), + T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu), + T_BUFFER(sduP, sdu_lenP)); + + mac->eNB_stats[CC_idP].ulsch_bytes_rx = sdu_lenP; + mac->eNB_stats[CC_idP].total_ulsch_bytes_rx += sdu_lenP; + mac->eNB_stats[CC_idP].total_ulsch_pdus_rx += 1; + + UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = 0; + + // control element + for (i = 0; i < num_ce; i++) { + + T(T_ENB_MAC_UE_UL_CE, T_INT(enb_mod_idP), T_INT(CC_idP), + T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), + T_INT(rx_ces[i])); + + switch (rx_ces[i]) { // implement and process BSR + CRNTI + + case POWER_HEADROOM: + if (UE_id != -1) { + UE_list->UE_template[CC_idP][UE_id].phr_info = + (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET; + LOG_D(MAC, + "[eNB %d] CC_id %d MAC CE_LCID %d : Received PHR PH = %d (db)\n", + enb_mod_idP, CC_idP, rx_ces[i], + UE_list->UE_template[CC_idP][UE_id].phr_info); + UE_list->UE_template[CC_idP][UE_id].phr_info_configured = + 1; + UE_list->UE_sched_ctrl[UE_id].phr_received = 1; + } + payload_ptr += sizeof(POWER_HEADROOM_CMD); + break; + + case CRNTI: + { + int old_rnti = + (((uint16_t) payload_ptr[0]) << 8) + payload_ptr[1]; + int old_UE_id = find_UE_id(enb_mod_idP, old_rnti); + LOG_D(MAC, + "[eNB %d] Frame %d, Subframe %d CC_id %d MAC CE_LCID %d (ce %d/%d): CRNTI %x (UE_id %d) in Msg3\n", + enb_mod_idP, frameP, subframeP, CC_idP, rx_ces[i], i, + num_ce, old_rnti, old_UE_id); + /* receiving CRNTI means that the current rnti has to go away */ + cancel_ra_proc(enb_mod_idP, CC_idP, frameP, + current_rnti); + if (old_UE_id != -1) { + /* TODO: if the UE did random access (followed by a MAC uplink with + * CRNTI) because none of its scheduling request was granted, then + * according to 36.321 5.4.4 the UE's MAC will notify RRC to release + * PUCCH/SRS. According to 36.331 5.3.13 the UE will then apply + * default configuration for CQI reporting and scheduling requests, + * which basically means that the CQI requests won't work anymore and + * that the UE won't do any scheduling request anymore as long as the + * eNB doesn't reconfigure the UE. + * We have to take care of this. As the code is, nothing is done and + * the UE state in the eNB is wrong. + */ + UE_id = old_UE_id; + UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0; + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) { + UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0; + mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, + subframeP, old_rnti); + } + current_rnti = old_rnti; } + crnti_rx = 1; + payload_ptr += 2; + break; + } + + case TRUNCATED_BSR: + case SHORT_BSR: + { + uint8_t lcgid; + lcgid = (payload_ptr[0] >> 6); + + LOG_D(MAC, + "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", + enb_mod_idP, CC_idP, rx_ces[i], lcgid, + payload_ptr[0] & 0x3f); + + if (crnti_rx == 1) + LOG_D(MAC, + "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", + enb_mod_idP, CC_idP, rx_ces[i], lcgid, + payload_ptr[0] & 0x3f); + if (UE_id != -1) { + + UE_list->UE_template[CC_idP][UE_id].bsr_info[lcgid] = (payload_ptr[0] & 0x3f); + + // update buffer info + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid] = BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[lcgid]]; + + UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid]; + + RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP * 10) + subframeP] = (payload_ptr[0] & 0x3f); + if (UE_id == UE_list->head) + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR, + RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr + [UE_id][(frameP * 10) + subframeP]); + if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] = frameP; + } + if (mac_eNB_get_rrc_status(enb_mod_idP,UE_RNTI(enb_mod_idP, UE_id)) < RRC_CONNECTED) + LOG_D(MAC, + "[eNB %d] CC_id %d MAC CE_LCID %d : ul_total_buffer = %d (lcg increment %d)\n", + enb_mod_idP, CC_idP, rx_ces[i], + UE_list->UE_template[CC_idP][UE_id]. + ul_total_buffer, + UE_list->UE_template[CC_idP][UE_id]. + ul_buffer_info[lcgid]); + } else { + + } + payload_ptr += 1; //sizeof(SHORT_BSR); // fixme + } + break; + + case LONG_BSR: + if (UE_id != -1) { + UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] = ((payload_ptr[0] & 0xFC) >> 2); + UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] = ((payload_ptr[0] & 0x03) << 4) | ((payload_ptr[1] & 0xF0) >> 4); + UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] = ((payload_ptr[1] & 0x0F) << 2) | ((payload_ptr[2] & 0xC0) >> 6); + UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] = (payload_ptr[2] & 0x3F); + + // update buffer info + old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0]; + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] = BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0]]; + + UE_list->UE_template[CC_idP][UE_id].ul_total_buffer += UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0]; + if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info) + UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info; + else + UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0; + + old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1]; + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1] = BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1]]; + UE_list->UE_template[CC_idP][UE_id].ul_total_buffer += UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1]; + if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info) UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= + old_buffer_info; + else + UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0; + + old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2]; + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2] = BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2]]; + UE_list->UE_template[CC_idP][UE_id].ul_total_buffer += UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2]; + if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info) + UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info; + else + UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0; + + old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]; + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3] = BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3]]; + UE_list->UE_template[CC_idP][UE_id].ul_total_buffer += UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]; + if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info) + UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info; + else + UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0; + + LOG_D(MAC, + "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = " + "%u LCGID2 = %u LCGID3 = %u\n", enb_mod_idP, CC_idP, + rx_ces[i], + UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0], + UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1], + UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2], + UE_list->UE_template[CC_idP][UE_id]. + bsr_info[LCGID3]); + if (crnti_rx == 1) + LOG_D(MAC, + "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = " + "%u LCGID2 = %u LCGID3 = %u\n", enb_mod_idP, + CC_idP, rx_ces[i], + UE_list->UE_template[CC_idP][UE_id]. + bsr_info[LCGID0], + UE_list->UE_template[CC_idP][UE_id]. + bsr_info[LCGID1], + UE_list->UE_template[CC_idP][UE_id]. + bsr_info[LCGID2], + UE_list->UE_template[CC_idP][UE_id]. + bsr_info[LCGID3]); + + if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] = 0; + } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] = frameP; + } + + if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] = 0; + } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] = frameP; + } + + if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] = 0; + } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] = frameP; + } + + if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] = 0; + } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] = frameP; + + } + } + + payload_ptr += 3; ////sizeof(LONG_BSR); + break; + + default: + LOG_E(MAC, + "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", + enb_mod_idP, CC_idP, rx_ces[i]); + break; + } + } + + for (i = 0; i < num_sdu; i++) { + LOG_D(MAC, "SDU Number %d MAC Subheader SDU_LCID %d, length %d\n", + i, rx_lcids[i], rx_lengths[i]); + + T(T_ENB_MAC_UE_UL_SDU, T_INT(enb_mod_idP), T_INT(CC_idP), + T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), + T_INT(rx_lcids[i]), T_INT(rx_lengths[i])); + T(T_ENB_MAC_UE_UL_SDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), + T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), + T_INT(rx_lcids[i]), T_INT(rx_lengths[i]), T_BUFFER(payload_ptr, + rx_lengths + [i])); + + switch (rx_lcids[i]) { + case CCCH: + if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) { + LOG_E(MAC, + "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d, sdu_len %d), dropping packet\n", + enb_mod_idP, CC_idP, frameP, rx_lengths[i], + CCCH_PAYLOAD_SIZE_MAX, sdu_lenP); + break; + } + LOG_D(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d, Received CCCH: %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n", + enb_mod_idP, CC_idP, frameP, payload_ptr[0], + payload_ptr[1], payload_ptr[2], payload_ptr[3], + payload_ptr[4], payload_ptr[5], current_rnti); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 1); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 0); + for (ii = 0; ii < NB_RA_PROC_MAX; ii++) { + RA_t *ra = &mac->common_channels[CC_idP].ra[ii]; + + LOG_D(MAC, + "[mac %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), state %d\n", + enb_mod_idP, CC_idP, ii, ra->rnti, + current_rnti, ra->state); + + if ((ra->rnti == current_rnti) && (ra->state != IDLE)) { + + //payload_ptr = parse_ulsch_header(msg3,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,msg3_len); + + if (UE_id < 0) { + memcpy(&ra->cont_res_id[0], payload_ptr, 6); + LOG_D(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %ld\n", + enb_mod_idP, CC_idP, frameP, rx_lengths[i], + payload_ptr - sduP); + + if ((UE_id = add_new_ue(enb_mod_idP, CC_idP, + mac->common_channels[CC_idP]. + ra[ii].rnti, harq_pid +#ifdef Rel14 + , + mac->common_channels[CC_idP]. + ra[ii].rach_resource_type +#endif + )) == -1) { + AssertFatal(1 == 0, + "[MAC][eNB] Max user count reached\n"); + // kill RA procedure + } else + LOG_D(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n", + enb_mod_idP, CC_idP, frameP, ra->rnti, + UE_id); + } else { + LOG_D(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n", + enb_mod_idP, CC_idP, frameP, UE_id, + rx_lengths[i], payload_ptr - sduP); + // kill RA procedure + } + + mac_rrc_data_ind(enb_mod_idP, + CC_idP, + frameP, subframeP, + current_rnti, + CCCH, + (uint8_t *) payload_ptr, + rx_lengths[i], + 0); + + + if (num_ce > 0) { // handle msg3 which is not RRCConnectionRequest + // process_ra_message(msg3,num_ce,rx_lcids,rx_ces); + } + // prepare transmission of Msg4 + ra->state = MSG4; + + + + // Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, // Check if this is ok for BL/CE, or if the rule is different + ra->Msg4_frame = frameP + ((subframeP > 5) ? 1 : 0); + ra->Msg4_subframe = (subframeP + 4) % 10; + + } // if process is active + } // loop on RA processes + + break; + + case DCCH: + case DCCH1: + // if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){ + + +#if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_T(MAC, "offset: %d\n", + (unsigned char) ((unsigned char *) payload_ptr - sduP)); + for (j = 0; j < 32; j++) { + LOG_T(MAC, "%x ", payload_ptr[j]); + } + LOG_T(MAC, "\n"); +#endif + + if (UE_id != -1) { + // adjust buffer occupancy of the correponding logical channel group + if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; + else + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0; + + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DCCH, received %d bytes form UE %d on LCID %d \n", + enb_mod_idP, CC_idP, frameP, rx_lengths[i], UE_id, + rx_lcids[i]); + + mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); //(unsigned int*)crc_status); + UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1; + UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i]; + + + } + + /* UE_id != -1 */ + // } + break; + + // all the DRBS + case DTCH: + default: + +#if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_T(MAC, "offset: %d\n", + (unsigned char) ((unsigned char *) payload_ptr - sduP)); + for (j = 0; j < 32; j++) { + LOG_T(MAC, "%x ", payload_ptr[j]); + } + LOG_T(MAC, "\n"); +#endif + if (rx_lcids[i] < NB_RB_MAX) { + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d\n", + enb_mod_idP, CC_idP, frameP, rx_lengths[i], UE_id, + rx_lcids[i]); + + if (UE_id != -1) { + // adjust buffer occupancy of the correponding logical channel group + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d, removing from LCGID %ld, %d\n", + enb_mod_idP, CC_idP, frameP, rx_lengths[i], + UE_id, rx_lcids[i], + UE_list->UE_template[CC_idP][UE_id]. + lcgidmap[rx_lcids[i]], + UE_list->UE_template[CC_idP][UE_id]. + ul_buffer_info[UE_list->UE_template[CC_idP] + [UE_id].lcgidmap[rx_lcids[i]]]); + + if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; + else + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0; + if ((rx_lengths[i] < SCH_PAYLOAD_SIZE_MAX) && (rx_lengths[i] > 0)) { // MAX SIZE OF transport block + mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); //(unsigned int*)crc_status); + + UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1; + UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i]; + //clear uplane_inactivity_timer + UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; + } else { /* rx_length[i] */ + UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx += 1; + LOG_E(MAC, + "[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ", + enb_mod_idP, CC_idP, frameP, rx_lcids[i], + UE_id); + } + } else { /*(UE_id != -1 */ + LOG_E(MAC, + "[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ", + enb_mod_idP, CC_idP, frameP, rx_lcids[i], UE_id); + } + } + + break; } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 0); - stop_meas(&mac->rx_ulsch_sdu); + payload_ptr += rx_lengths[i]; + } + + // Program ACK for PHICH + LOG_D(MAC, + "Programming PHICH ACK for rnti %x harq_pid %d (first_rb %d)\n", + current_rnti, harq_pid, first_rb); + nfapi_hi_dci0_request_t *hi_dci0_req = &mac->HI_DCI0_req[CC_idP]; + nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body; + nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = + &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; + memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t)); + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; + hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu); + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = first_rb; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 1; + hi_dci0_req_body->number_of_hi++; + hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP,subframeP, 0); + hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; + hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP,subframeP, 4); + hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; + + /* NN--> FK: we could either check the payload, or use a phy helper to detect a false msg3 */ + if ((num_sdu == 0) && (num_ce == 0)) { + if (UE_id != -1) + UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx += 1; + /* + if (msg3_flagP != NULL) { + if( *msg3_flagP == 1 ) { + LOG_N(MAC,"[eNB %d] CC_id %d frame %d : false msg3 detection: signal phy to canceling RA and remove the UE\n", enb_mod_idP, CC_idP, frameP); + *msg3_flagP=0; + } + } */ + } else { + if (UE_id != -1) { + UE_list->eNB_UE_stats[CC_idP][UE_id].pdu_bytes_rx = sdu_lenP; + UE_list->eNB_UE_stats[CC_idP][UE_id].total_pdu_bytes_rx += sdu_lenP; + UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_pdus_rx += 1; + } + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 0); + stop_meas(&mac->rx_ulsch_sdu); } uint32_t bytes_to_bsr_index(int32_t nbytes) { - uint32_t i = 0; + uint32_t i = 0; - if (nbytes < 0) { - return (0); - } + if (nbytes < 0) { + return (0); + } - while ((i < BSR_TABLE_SIZE) && (BSR_TABLE[i] <= nbytes)) { - i++; - } + while ((i < BSR_TABLE_SIZE) && (BSR_TABLE[i] <= nbytes)) { + i++; + } - return (i - 1); + return (i - 1); } void add_ue_ulsch_info(module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframeP, UE_ULSCH_STATUS status) { - eNB_ulsch_info[module_idP][CC_id][UE_id].rnti = - UE_RNTI(module_idP, UE_id); - eNB_ulsch_info[module_idP][CC_id][UE_id].subframe = subframeP; - eNB_ulsch_info[module_idP][CC_id][UE_id].status = status; + eNB_ulsch_info[module_idP][CC_id][UE_id].rnti = UE_RNTI(module_idP, UE_id); + eNB_ulsch_info[module_idP][CC_id][UE_id].subframe = subframeP; + eNB_ulsch_info[module_idP][CC_id][UE_id].status = status; - eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++; + eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++; } unsigned char *parse_ulsch_header(unsigned char *mac_header, @@ -836,77 +715,76 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header, unsigned short *rx_lengths, unsigned short tb_length) { - unsigned char not_done = 1, num_ces = 0, num_sdus = - 0, lcid, num_sdu_cnt; - unsigned char *mac_header_ptr = mac_header; - unsigned short length, ce_len = 0; + unsigned char not_done = 1, num_ces = 0, num_sdus = + 0, lcid, num_sdu_cnt; + unsigned char *mac_header_ptr = mac_header; + unsigned short length, ce_len = 0; - while (not_done == 1) { + while (not_done == 1) { - if (((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E == 0) { - not_done = 0; - } - - lcid = ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID; - - if (lcid < EXTENDED_POWER_HEADROOM) { - if (not_done == 0) { // last MAC SDU, length is implicit - mac_header_ptr++; - length = - tb_length - (mac_header_ptr - mac_header) - ce_len; - - for (num_sdu_cnt = 0; num_sdu_cnt < num_sdus; - num_sdu_cnt++) { - length -= rx_lengths[num_sdu_cnt]; - } - } else { - if (((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F == 0) { - length = ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L; - mac_header_ptr += 2; //sizeof(SCH_SUBHEADER_SHORT); - } else { // F = 1 - length = - ((((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB & - 0x7f) << 8) | (((SCH_SUBHEADER_LONG *) - mac_header_ptr)->L_LSB & 0xff); - mac_header_ptr += 3; //sizeof(SCH_SUBHEADER_LONG); - } - } - - LOG_D(MAC, - "[eNB] sdu %d lcid %d tb_length %d length %d (offset now %ld)\n", - num_sdus, lcid, tb_length, length, - mac_header_ptr - mac_header); - rx_lcids[num_sdus] = lcid; - rx_lengths[num_sdus] = length; - num_sdus++; - } else { // This is a control element subheader POWER_HEADROOM, BSR and CRNTI - if (lcid == SHORT_PADDING) { - mac_header_ptr++; - } else { - rx_ces[num_ces] = lcid; - num_ces++; - mac_header_ptr++; - - if (lcid == LONG_BSR) { - ce_len += 3; - } else if (lcid == CRNTI) { - ce_len += 2; - } else if ((lcid == POWER_HEADROOM) - || (lcid == TRUNCATED_BSR) - || (lcid == SHORT_BSR)) { - ce_len++; - } else { - LOG_E(MAC, "unknown CE %d \n", lcid); - AssertFatal(1 == 0, "unknown CE"); - } - } - } + if (((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E == 0) { + not_done = 0; } - *num_ce = num_ces; - *num_sdu = num_sdus; + lcid = ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID; - return (mac_header_ptr); + if (lcid < EXTENDED_POWER_HEADROOM) { + if (not_done == 0) { // last MAC SDU, length is implicit + mac_header_ptr++; + length = tb_length - (mac_header_ptr - mac_header) - ce_len; + + for (num_sdu_cnt = 0; num_sdu_cnt < num_sdus; + num_sdu_cnt++) { + length -= rx_lengths[num_sdu_cnt]; + } + } else { + if (((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F == 0) { + length = ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L; + mac_header_ptr += 2; //sizeof(SCH_SUBHEADER_SHORT); + } else { // F = 1 + length = + ((((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB & + 0x7f) << 8) | (((SCH_SUBHEADER_LONG *) + mac_header_ptr)->L_LSB & 0xff); + mac_header_ptr += 3; //sizeof(SCH_SUBHEADER_LONG); + } + } + + LOG_D(MAC, + "[eNB] sdu %d lcid %d tb_length %d length %d (offset now %ld)\n", + num_sdus, lcid, tb_length, length, + mac_header_ptr - mac_header); + rx_lcids[num_sdus] = lcid; + rx_lengths[num_sdus] = length; + num_sdus++; + } else { // This is a control element subheader POWER_HEADROOM, BSR and CRNTI + if (lcid == SHORT_PADDING) { + mac_header_ptr++; + } else { + rx_ces[num_ces] = lcid; + num_ces++; + mac_header_ptr++; + + if (lcid == LONG_BSR) { + ce_len += 3; + } else if (lcid == CRNTI) { + ce_len += 2; + } else if ((lcid == POWER_HEADROOM) + || (lcid == TRUNCATED_BSR) + || (lcid == SHORT_BSR)) { + ce_len++; + } else { + LOG_E(MAC, "unknown CE %d \n", lcid); + AssertFatal(1 == 0, "unknown CE"); + } + } + } + } + + *num_ce = num_ces; + *num_sdu = num_sdus; + + return (mac_header_ptr); } /* This function is called by PHY layer when it schedules some @@ -921,16 +799,16 @@ set_msg3_subframe(module_id_t Mod_id, int subframe, int rnti, int Msg3_frame, int Msg3_subframe) { - eNB_MAC_INST *mac = RC.mac[Mod_id]; - int i; - for (i = 0; i < NB_RA_PROC_MAX; i++) { - if (mac->common_channels[CC_id].ra[i].state != IDLE && - mac->common_channels[CC_id].ra[i].rnti == rnti) { - mac->common_channels[CC_id].ra[i].Msg3_subframe = - Msg3_subframe; - break; - } + eNB_MAC_INST *mac = RC.mac[Mod_id]; + int i; + for (i = 0; i < NB_RA_PROC_MAX; i++) { + if (mac->common_channels[CC_id].ra[i].state != IDLE && + mac->common_channels[CC_id].ra[i].rnti == rnti) { + mac->common_channels[CC_id].ra[i].Msg3_subframe = + Msg3_subframe; + break; } + } } @@ -938,118 +816,118 @@ void schedule_ulsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { - uint16_t first_rb[MAX_NUM_CCs], i; - int CC_id; - eNB_MAC_INST *mac = RC.mac[module_idP]; - COMMON_channels_t *cc; + uint16_t first_rb[MAX_NUM_CCs], i; + int CC_id; + eNB_MAC_INST *mac = RC.mac[module_idP]; + COMMON_channels_t *cc; - start_meas(&mac->schedule_ulsch); + start_meas(&mac->schedule_ulsch); - int sched_subframe = (subframeP + 4) % 10; + int sched_subframe = (subframeP + 4) % 10; - cc = &mac->common_channels[0]; - int tdd_sfa; - // for TDD: check subframes where we have to act and return if nothing should be done now - if (cc->tdd_Config) { - tdd_sfa = cc->tdd_Config->subframeAssignment; - switch (subframeP) { - case 0: - if ((tdd_sfa == 0) || (tdd_sfa == 3) || (tdd_sfa == 6)) - sched_subframe = 4; - else - return; - break; - case 1: - if ((tdd_sfa == 0) || (tdd_sfa == 1)) - sched_subframe = 7; - else if (tdd_sfa == 6) - sched_subframe = 8; - break; - default: - return; + cc = &mac->common_channels[0]; + int tdd_sfa; + // for TDD: check subframes where we have to act and return if nothing should be done now + if (cc->tdd_Config) { + tdd_sfa = cc->tdd_Config->subframeAssignment; + switch (subframeP) { + case 0: + if ((tdd_sfa == 0) || (tdd_sfa == 3) || (tdd_sfa == 6)) + sched_subframe = 4; + else + return; + break; + case 1: + if ((tdd_sfa == 0) || (tdd_sfa == 1)) + sched_subframe = 7; + else if (tdd_sfa == 6) + sched_subframe = 8; + break; + default: + return; - case 2: // Don't schedule UL in subframe 2 for TDD - return; - case 3: - if (tdd_sfa == 2) - sched_subframe = 7; - else - return; - break; - case 4: - if (tdd_sfa == 1) - sched_subframe = 8; - else - return; - break; - case 5: - if (tdd_sfa == 0) - sched_subframe = 9; - else if (tdd_sfa == 6) - sched_subframe = 3; - else - return; - break; - case 6: - if (tdd_sfa == 1) - sched_subframe = 2; - else if (tdd_sfa == 6) - sched_subframe = 3; - else - return; - break; - case 7: - return; - case 8: - if ((tdd_sfa >= 2) || (tdd_sfa <= 5)) - sched_subframe = 2; - else - return; - break; - case 9: - if ((tdd_sfa == 1) || (tdd_sfa == 3) || (tdd_sfa == 4)) - sched_subframe = 3; - else if (tdd_sfa == 6) - sched_subframe = 4; - else - return; - break; - } + case 2: // Don't schedule UL in subframe 2 for TDD + return; + case 3: + if (tdd_sfa == 2) + sched_subframe = 7; + else + return; + break; + case 4: + if (tdd_sfa == 1) + sched_subframe = 8; + else + return; + break; + case 5: + if (tdd_sfa == 0) + sched_subframe = 9; + else if (tdd_sfa == 6) + sched_subframe = 3; + else + return; + break; + case 6: + if (tdd_sfa == 1) + sched_subframe = 2; + else if (tdd_sfa == 6) + sched_subframe = 3; + else + return; + break; + case 7: + return; + case 8: + if ((tdd_sfa >= 2) || (tdd_sfa <= 5)) + sched_subframe = 2; + else + return; + break; + case 9: + if ((tdd_sfa == 1) || (tdd_sfa == 3) || (tdd_sfa == 4)) + sched_subframe = 3; + else if (tdd_sfa == 6) + sched_subframe = 4; + else + return; + break; } - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + } + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - //leave out first RB for PUCCH - first_rb[CC_id] = 1; + //leave out first RB for PUCCH + first_rb[CC_id] = 1; - // UE data info; - // check which UE has data to transmit - // function to decide the scheduling - // e.g. scheduling_rslt = Greedy(granted_UEs, nb_RB) + // UE data info; + // check which UE has data to transmit + // function to decide the scheduling + // e.g. scheduling_rslt = Greedy(granted_UEs, nb_RB) - // default function for default scheduling - // + // default function for default scheduling + // - // output of scheduling, the UE numbers in RBs, where it is in the code??? - // check if RA (Msg3) is active in this subframeP, if so skip the PRBs used for Msg3 - // Msg3 is using 1 PRB so we need to increase first_rb accordingly - // not sure about the break (can there be more than 1 active RA procedure?) + // output of scheduling, the UE numbers in RBs, where it is in the code??? + // check if RA (Msg3) is active in this subframeP, if so skip the PRBs used for Msg3 + // Msg3 is using 1 PRB so we need to increase first_rb accordingly + // not sure about the break (can there be more than 1 active RA procedure?) - for (i = 0; i < NB_RA_PROC_MAX; i++) { - if ((cc->ra[i].state == WAITMSG3) && - (cc->ra[i].Msg3_subframe == sched_subframe)) { - first_rb[CC_id]++; - // cc->ray[i].Msg3_subframe = -1; - break; - } - } + for (i = 0; i < NB_RA_PROC_MAX; i++) { + if ((cc->ra[i].state == WAITMSG3) && + (cc->ra[i].Msg3_subframe == sched_subframe)) { + first_rb[CC_id]++; + // cc->ray[i].Msg3_subframe = -1; + break; + } } + } - schedule_ulsch_rnti(module_idP, frameP, subframeP, sched_subframe, - first_rb); + schedule_ulsch_rnti(module_idP, frameP, subframeP, sched_subframe, + first_rb); - stop_meas(&mac->schedule_ulsch); + stop_meas(&mac->schedule_ulsch); } void @@ -1058,501 +936,467 @@ schedule_ulsch_rnti(module_id_t module_idP, sub_frame_t subframeP, unsigned char sched_subframeP, uint16_t * first_rb) { - int UE_id; - uint8_t aggregation = 2; - rnti_t rnti = -1; - uint8_t round = 0; - uint8_t harq_pid = 0; - uint8_t status = 0; - uint8_t rb_table_index = -1; - uint32_t cqi_req, cshift, ndi, tpc; - int32_t normalized_rx_power; - int32_t target_rx_power = -90; - static int32_t tpc_accumulated = 0; - int n; - int CC_id = 0; - int drop_ue = 0; - int N_RB_UL; - eNB_MAC_INST *mac = RC.mac[module_idP]; - COMMON_channels_t *cc = mac->common_channels; - UE_list_t *UE_list = &mac->UE_list; - UE_TEMPLATE *UE_template; - UE_sched_ctrl *UE_sched_ctrl; - int sched_frame = frameP; - int rvidx_tab[4] = { 0, 2, 3, 1 }; + int UE_id; + uint8_t aggregation = 2; + rnti_t rnti = -1; + uint8_t round = 0; + uint8_t harq_pid = 0; + uint8_t status = 0; + uint8_t rb_table_index = -1; + uint32_t cqi_req, cshift, ndi, tpc; + int32_t normalized_rx_power; + int32_t target_rx_power = -90; + static int32_t tpc_accumulated = 0; + int n; + int CC_id = 0; + int drop_ue = 0; + int N_RB_UL; + eNB_MAC_INST *mac = RC.mac[module_idP]; + COMMON_channels_t *cc = mac->common_channels; + UE_list_t *UE_list = &mac->UE_list; + UE_TEMPLATE *UE_template; + UE_sched_ctrl *UE_sched_ctrl; + int sched_frame = frameP; + int rvidx_tab[4] = { 0, 2, 3, 1 }; - if (sched_subframeP < subframeP) - sched_frame++; + if (sched_subframeP < subframeP) + sched_frame++; - nfapi_hi_dci0_request_t *hi_dci0_req = &mac->HI_DCI0_req[CC_id]; - nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body; - nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu; + nfapi_hi_dci0_request_t *hi_dci0_req = &mac->HI_DCI0_req[CC_id]; + nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body; + nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu; - nfapi_ul_config_request_t *ul_req_tmp = &mac->UL_req_tmp[CC_id][sched_subframeP]; - nfapi_ul_config_request_body_t *ul_req_tmp_body = &ul_req_tmp->ul_config_request_body; + nfapi_ul_config_request_t *ul_req_tmp = &mac->UL_req_tmp[CC_id][sched_subframeP]; + nfapi_ul_config_request_body_t *ul_req_tmp_body = &ul_req_tmp->ul_config_request_body; - //LOG_D(MAC, "entering ulsch preprocesor\n"); - ulsch_scheduler_pre_processor(module_idP, frameP, subframeP, first_rb); + //LOG_D(MAC, "entering ulsch preprocesor\n"); + ulsch_scheduler_pre_processor(module_idP, frameP, subframeP, first_rb); - //LOG_D(MAC, "exiting ulsch preprocesor\n"); + //LOG_D(MAC, "exiting ulsch preprocesor\n"); - hi_dci0_req->sfn_sf = (frameP << 4) + subframeP; + hi_dci0_req->sfn_sf = (frameP << 4) + subframeP; - // loop over all active UEs - for (UE_id = UE_list->head_ul; UE_id >= 0; - UE_id = UE_list->next_ul[UE_id]) { + // loop over all active UEs + for (UE_id = UE_list->head_ul; UE_id >= 0; + UE_id = UE_list->next_ul[UE_id]) { - // don't schedule if Msg4 is not received yet - if (UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id]. - configured == FALSE) { - LOG_D(MAC, - "[eNB %d] frame %d subfarme %d, UE %d: not configured, skipping UE scheduling \n", - module_idP, frameP, subframeP, UE_id); - continue; - } + // don't schedule if Msg4 is not received yet + if (UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id]. + configured == FALSE) { + LOG_D(MAC, + "[eNB %d] frame %d subfarme %d, UE %d: not configured, skipping UE scheduling \n", + module_idP, frameP, subframeP, UE_id); + continue; + } - rnti = UE_RNTI(module_idP, UE_id); + rnti = UE_RNTI(module_idP, UE_id); - if (rnti == NOT_A_RNTI) { - LOG_W(MAC, "[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n", - module_idP, frameP, subframeP, UE_id); - continue; - } + if (rnti == NOT_A_RNTI) { + LOG_W(MAC, "[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n", + module_idP, frameP, subframeP, UE_id); + continue; + } - drop_ue = 0; - /* let's drop the UE if get_eNB_UE_stats returns NULL when calling it with any of the UE's active UL CCs */ - /* TODO: refine? + drop_ue = 0; + /* let's drop the UE if get_eNB_UE_stats returns NULL when calling it with any of the UE's active UL CCs */ + /* TODO: refine? - for (n=0; nnumactiveULCCs[UE_id]; n++) { - CC_id = UE_list->ordered_ULCCids[n][UE_id]; + for (n=0; nnumactiveULCCs[UE_id]; n++) { + CC_id = UE_list->ordered_ULCCids[n][UE_id]; - if (mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti) == NULL) { - LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: no PHY context\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id); - drop_ue = 1; - break; - } - } */ - if (drop_ue == 1) { -/* we can't come here, ulsch_scheduler_pre_processor won't put in the list a UE with no PHY context */ - abort(); - /* TODO: this is a hack. Sometimes the UE has no PHY context but - * is still present in the MAC with 'ul_failure_timer' = 0 and - * 'ul_out_of_sync' = 0. It seems wrong and the UE stays there forever. Let's - * start an UL out of sync procedure in this case. - * The root cause of this problem has to be found and corrected. - * In the meantime, this hack... - */ - if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 0 && - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0) { - LOG_W(MAC, - "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: UE in weird state, let's put it 'out of sync'\n", - module_idP, frameP, subframeP, UE_id, rnti, CC_id); - // inform RRC of failure and clear timer - 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; + if (mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti) == NULL) { + LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: no PHY context\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id); + drop_ue = 1; + break; + } + } */ + if (drop_ue == 1) { + /* we can't come here, ulsch_scheduler_pre_processor won't put in the list a UE with no PHY context */ + abort(); + /* TODO: this is a hack. Sometimes the UE has no PHY context but + * is still present in the MAC with 'ul_failure_timer' = 0 and + * 'ul_out_of_sync' = 0. It seems wrong and the UE stays there forever. Let's + * start an UL out of sync procedure in this case. + * The root cause of this problem has to be found and corrected. + * In the meantime, this hack... + */ + if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 0 && + UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0) { + LOG_W(MAC, + "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: UE in weird state, let's put it 'out of sync'\n", + module_idP, frameP, subframeP, UE_id, rnti, CC_id); + // inform RRC of failure and clear timer + 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; + } + continue; + } + // loop over all active UL CC_ids for this UE + for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { + // This is the actual CC_id in the list + CC_id = UE_list->ordered_ULCCids[n][UE_id]; + N_RB_UL = to_prb(cc[CC_id].ul_Bandwidth); + + /* + aggregation=get_aggregation(get_bw_index(module_idP,CC_id), + eNB_UE_stats->dl_cqi, + format0); + */ + + if (CCE_allocation_infeasible + (module_idP, CC_id, 1, subframeP, aggregation, rnti)) { + LOG_W(MAC, + "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: not enough nCCE\n", + module_idP, frameP, subframeP, UE_id, rnti, CC_id); + continue; // break; + } + + /* be sure that there are some free RBs */ + if (first_rb[CC_id] >= N_RB_UL - 1) { + LOG_W(MAC, + "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n", + module_idP, frameP, subframeP, UE_id, rnti, CC_id); + continue; + } + // if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel + + UE_template = &UE_list->UE_template[CC_id][UE_id]; + UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id]; + harq_pid = subframe2harqpid(&cc[CC_id], sched_frame, sched_subframeP); + round = UE_sched_ctrl->round_UL[CC_id][harq_pid]; + AssertFatal(round < 8, "round %d > 7 for UE %d/%x\n", round, + UE_id, rnti); + LOG_D(MAC, + "[eNB %d] frame %d subframe %d (sched_frame %d, sched_subframe %d), Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n", + module_idP, frameP, subframeP, sched_frame, sched_subframeP, harq_pid, UE_id, rnti, + CC_id, aggregation, N_RB_UL); + + RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * + 10) + + subframeP] = + UE_template->ul_total_buffer; + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO,RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * + 10) + + subframeP]); + if (UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0 || round > 0) // || ((frameP%10)==0)) + // if there is information on bsr of DCCH, DTCH or if there is UL_SR, or if there is a packet to retransmit, or we want to schedule a periodic feedback every 10 frames + { + LOG_D(MAC, + "[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n", + module_idP, harq_pid, frameP, subframeP, UE_id, rnti, + round, UE_template->ul_SR, + UE_sched_ctrl->ul_inactivity_timer, + UE_sched_ctrl->ul_failure_timer, + UE_sched_ctrl->cqi_req_timer); + // reset the scheduling request + UE_template->ul_SR = 0; + status = mac_eNB_get_rrc_status(module_idP, rnti); + if (status < RRC_CONNECTED) + cqi_req = 0; + else if (UE_sched_ctrl->cqi_req_timer > 30) { + if (nfapi_mode) { + cqi_req = 0; + } else { + cqi_req = 1; } - continue; - } - // loop over all active UL CC_ids for this UE - for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { - // This is the actual CC_id in the list - CC_id = UE_list->ordered_ULCCids[n][UE_id]; - N_RB_UL = to_prb(cc[CC_id].ul_Bandwidth); + UE_sched_ctrl->cqi_req_timer = 0; + } else + cqi_req = 0; - /* - aggregation=get_aggregation(get_bw_index(module_idP,CC_id), - eNB_UE_stats->dl_cqi, - format0); - */ + //power control + //compute the expected ULSCH RX power (for the stats) - if (CCE_allocation_infeasible - (module_idP, CC_id, 1, subframeP, aggregation, rnti)) { - LOG_W(MAC, - "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: not enough nCCE\n", - module_idP, frameP, subframeP, UE_id, rnti, CC_id); - continue; // break; - } + // this is the normalized RX power and this should be constant (regardless of mcs + normalized_rx_power = UE_sched_ctrl->pusch_snr[CC_id]; + target_rx_power = 178; - /* be sure that there are some free RBs */ - if (first_rb[CC_id] >= N_RB_UL - 1) { - LOG_W(MAC, - "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n", - module_idP, frameP, subframeP, UE_id, rnti, CC_id); - continue; - } - // if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel - - UE_template = &UE_list->UE_template[CC_id][UE_id]; - UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id]; - harq_pid = - subframe2harqpid(&cc[CC_id], sched_frame, sched_subframeP); - round = UE_sched_ctrl->round_UL[CC_id][harq_pid]; - AssertFatal(round < 8, "round %d > 7 for UE %d/%x\n", round, - UE_id, rnti); - LOG_D(MAC, - "[eNB %d] frame %d subframe %d (sched_frame %d, sched_subframe %d), Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n", - module_idP, frameP, subframeP, sched_frame, sched_subframeP, harq_pid, UE_id, rnti, - CC_id, aggregation, N_RB_UL); - - RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * - 10) + - subframeP] = - UE_template->ul_total_buffer; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME - (VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO, - RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * - 10) + - subframeP]); - if (UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0 || round > 0) // || ((frameP%10)==0)) - // if there is information on bsr of DCCH, DTCH or if there is UL_SR, or if there is a packet to retransmit, or we want to schedule a periodic feedback every 10 frames + // this assumes accumulated tpc + // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out + int32_t framex10psubframe = UE_template->pusch_tpc_tx_frame * 10 + UE_template->pusch_tpc_tx_subframe; + if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || //normal case + ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) //frame wrap-around { - LOG_D(MAC, - "[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n", - module_idP, harq_pid, frameP, subframeP, UE_id, rnti, - round, UE_template->ul_SR, - UE_sched_ctrl->ul_inactivity_timer, - UE_sched_ctrl->ul_failure_timer, - UE_sched_ctrl->cqi_req_timer); - // reset the scheduling request - UE_template->ul_SR = 0; - status = mac_eNB_get_rrc_status(module_idP, rnti); - if (status < RRC_CONNECTED) - cqi_req = 0; - else if (UE_sched_ctrl->cqi_req_timer > 30) { - if (nfapi_mode) { - cqi_req = 0; - } else { - cqi_req = 1; - } - UE_sched_ctrl->cqi_req_timer = 0; - } else - cqi_req = 0; + UE_template->pusch_tpc_tx_frame = frameP; + UE_template->pusch_tpc_tx_subframe = subframeP; + if (normalized_rx_power > (target_rx_power + 4)) { + tpc = 0; //-1 + tpc_accumulated--; + } else if (normalized_rx_power < (target_rx_power - 4)) { + tpc = 2; //+1 + tpc_accumulated++; + } else { + tpc = 1; //0 + } + } else { + tpc = 1; //0 + } + //tpc = 1; + if (tpc != 1) { + LOG_D(MAC, + "[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", + module_idP, frameP, subframeP, harq_pid, tpc, + tpc_accumulated, normalized_rx_power, + target_rx_power); + } + // new transmission + if (round == 0) { - //power control - //compute the expected ULSCH RX power (for the stats) + ndi = 1 - UE_template->oldNDI_UL[harq_pid]; + UE_template->oldNDI_UL[harq_pid] = ndi; + UE_list->eNB_UE_stats[CC_id][UE_id]. + normalized_rx_power = normalized_rx_power; + UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power = target_rx_power; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1 = UE_template->pre_assigned_mcs_ul; + UE_template->mcs_UL[harq_pid] = UE_template->pre_assigned_mcs_ul; //cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS + if (UE_template->pre_allocated_rb_table_index_ul >= 0) { + rb_table_index = + UE_template->pre_allocated_rb_table_index_ul; + } else { + UE_template->mcs_UL[harq_pid] = 10; //cmin (10, openair_daq_vars.target_ue_ul_mcs); + rb_table_index = 5; // for PHR + } - // this is the normalized RX power and this should be constant (regardless of mcs - normalized_rx_power = UE_sched_ctrl->pusch_snr[CC_id]; - target_rx_power = 178; - - // this assumes accumulated tpc - // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out - int32_t framex10psubframe = - UE_template->pusch_tpc_tx_frame * 10 + - UE_template->pusch_tpc_tx_subframe; - if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || //normal case - ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) //frame wrap-around - { - UE_template->pusch_tpc_tx_frame = frameP; - UE_template->pusch_tpc_tx_subframe = subframeP; - if (normalized_rx_power > (target_rx_power + 4)) { - tpc = 0; //-1 - tpc_accumulated--; - } else if (normalized_rx_power < (target_rx_power - 4)) { - tpc = 2; //+1 - tpc_accumulated++; - } else { - tpc = 1; //0 - } - } else { - tpc = 1; //0 - } - //tpc = 1; - if (tpc != 1) { - LOG_D(MAC, - "[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", - module_idP, frameP, subframeP, harq_pid, tpc, - tpc_accumulated, normalized_rx_power, - target_rx_power); - } - // new transmission - if (round == 0) { - - ndi = 1 - UE_template->oldNDI_UL[harq_pid]; - UE_template->oldNDI_UL[harq_pid] = ndi; - UE_list->eNB_UE_stats[CC_id][UE_id]. - normalized_rx_power = normalized_rx_power; - UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power = - target_rx_power; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1 = - UE_template->pre_assigned_mcs_ul; - UE_template->mcs_UL[harq_pid] = UE_template->pre_assigned_mcs_ul; //cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS - if (UE_template->pre_allocated_rb_table_index_ul >= 0) { - rb_table_index = - UE_template->pre_allocated_rb_table_index_ul; - } else { - UE_template->mcs_UL[harq_pid] = 10; //cmin (10, openair_daq_vars.target_ue_ul_mcs); - rb_table_index = 5; // for PHR - } - - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = - UE_template->mcs_UL[harq_pid]; - // buffer_occupancy = UE_template->ul_total_buffer; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = UE_template->mcs_UL[harq_pid]; + // buffer_occupancy = UE_template->ul_total_buffer; - while (((rb_table[rb_table_index] > - (N_RB_UL - 1 - first_rb[CC_id])) - || (rb_table[rb_table_index] > 45)) - && (rb_table_index > 0)) { - rb_table_index--; - } + while (((rb_table[rb_table_index] > + (N_RB_UL - 1 - first_rb[CC_id])) + || (rb_table[rb_table_index] > 45)) + && (rb_table_index > 0)) { + rb_table_index--; + } - UE_template->TBS_UL[harq_pid] = - get_TBS_UL(UE_template->mcs_UL[harq_pid], - rb_table[rb_table_index]); - UE_list->eNB_UE_stats[CC_id][UE_id]. - total_rbs_used_rx += rb_table[rb_table_index]; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = - UE_template->TBS_UL[harq_pid]; - // buffer_occupancy -= TBS; + UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid], + rb_table[rb_table_index]); + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += rb_table[rb_table_index]; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = UE_template->TBS_UL[harq_pid]; + // buffer_occupancy -= TBS; - T(T_ENB_MAC_UE_UL_SCHEDULE, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), - T_INT(UE_template->mcs_UL[harq_pid]), - T_INT(first_rb[CC_id]), - T_INT(rb_table[rb_table_index]), - T_INT(UE_template->TBS_UL[harq_pid]), T_INT(ndi)); + T(T_ENB_MAC_UE_UL_SCHEDULE, T_INT(module_idP), + T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), + T_INT(UE_template->mcs_UL[harq_pid]), + T_INT(first_rb[CC_id]), + T_INT(rb_table[rb_table_index]), + T_INT(UE_template->TBS_UL[harq_pid]), T_INT(ndi)); - if (mac_eNB_get_rrc_status(module_idP, rnti) < - RRC_CONNECTED) - LOG_D(MAC, - "[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n", - module_idP, harq_pid, rnti, CC_id, frameP, - subframeP, UE_id, - UE_template->mcs_UL[harq_pid], - first_rb[CC_id], rb_table[rb_table_index], - rb_table_index, - UE_template->TBS_UL[harq_pid], harq_pid); + if (mac_eNB_get_rrc_status(module_idP, rnti) < RRC_CONNECTED) + LOG_D(MAC, + "[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n", + module_idP, harq_pid, rnti, CC_id, frameP, + subframeP, UE_id, + UE_template->mcs_UL[harq_pid], + first_rb[CC_id], rb_table[rb_table_index], + rb_table_index, + UE_template->TBS_UL[harq_pid], harq_pid); - // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB) - //store for possible retransmission - UE_template->nb_rb_ul[harq_pid] = - rb_table[rb_table_index]; - UE_template->first_rb_ul[harq_pid] = first_rb[CC_id]; + // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB) + //store for possible retransmission + UE_template->nb_rb_ul[harq_pid] = rb_table[rb_table_index]; + UE_template->first_rb_ul[harq_pid] = first_rb[CC_id]; - UE_sched_ctrl->ul_scheduled |= (1 << harq_pid); - if (UE_id == UE_list->head) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME - (VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED, - UE_sched_ctrl->ul_scheduled); + UE_sched_ctrl->ul_scheduled |= (1 << harq_pid); + if (UE_id == UE_list->head) + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED, + UE_sched_ctrl->ul_scheduled); - // adjust total UL buffer status by TBS, wait for UL sdus to do final update - LOG_D(MAC, - "[eNB %d] CC_id %d UE %d/%x : adjusting ul_total_buffer, old %d, TBS %d\n", - module_idP, CC_id, UE_id, rnti, - UE_template->ul_total_buffer, - UE_template->TBS_UL[harq_pid]); - if (UE_template->ul_total_buffer > - UE_template->TBS_UL[harq_pid]) - UE_template->ul_total_buffer -= - UE_template->TBS_UL[harq_pid]; - else - UE_template->ul_total_buffer = 0; - LOG_D(MAC, "ul_total_buffer, new %d\n", - UE_template->ul_total_buffer); - // Cyclic shift for DM RS - cshift = 0; // values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1) - // save it for a potential retransmission - UE_template->cshift[harq_pid] = cshift; + // adjust total UL buffer status by TBS, wait for UL sdus to do final update + LOG_D(MAC, + "[eNB %d] CC_id %d UE %d/%x : adjusting ul_total_buffer, old %d, TBS %d\n", + module_idP, CC_id, UE_id, rnti, + UE_template->ul_total_buffer, + UE_template->TBS_UL[harq_pid]); + if (UE_template->ul_total_buffer > UE_template->TBS_UL[harq_pid]) + UE_template->ul_total_buffer -= UE_template->TBS_UL[harq_pid]; + else + UE_template->ul_total_buffer = 0; + LOG_D(MAC, "ul_total_buffer, new %d\n", + UE_template->ul_total_buffer); + // Cyclic shift for DM RS + cshift = 0; // values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1) + // save it for a potential retransmission + UE_template->cshift[harq_pid] = cshift; - hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; - memset((void *) hi_dci0_pdu, 0, - sizeof(nfapi_hi_dci0_request_pdu_t)); - hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; - hi_dci0_pdu->pdu_size = - 2 + sizeof(nfapi_hi_dci0_dci_pdu); - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format = - NFAPI_UL_DCI_FORMAT_0; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = - aggregation; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power = - 6000; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8. - resource_block_start = first_rb[CC_id]; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8. - number_of_resource_block = - rb_table[rb_table_index]; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 = - UE_template->mcs_UL[harq_pid]; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8. - cyclic_shift_2_for_drms = cshift; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8. - frequency_hopping_enabled_flag = 0; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8. - new_data_indication_1 = ndi; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc = tpc; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request = - cqi_req; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = - UE_template->DAI_ul[sched_subframeP]; + hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; + memset((void *) hi_dci0_pdu, 0,sizeof(nfapi_hi_dci0_request_pdu_t)); + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; + hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_dci_pdu); + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format = NFAPI_UL_DCI_FORMAT_0; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power = 6000; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.resource_block_start = first_rb[CC_id]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.number_of_resource_block = rb_table[rb_table_index]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 = UE_template->mcs_UL[harq_pid]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = cshift; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.frequency_hopping_enabled_flag = 0; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.new_data_indication_1 = ndi; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc = tpc; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request = cqi_req; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = UE_template->DAI_ul[sched_subframeP]; - hi_dci0_req_body->number_of_dci++; - hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP, subframeP, 4); - hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; + hi_dci0_req_body->number_of_dci++; + hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP, subframeP, 4); + hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; - hi_dci0_req->sfn_sf = frameP<<4|subframeP; // sfnsf_add_subframe(sched_frame, sched_subframeP, 0); // sunday! - hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; + hi_dci0_req->sfn_sf = frameP<<4|subframeP; // sfnsf_add_subframe(sched_frame, sched_subframeP, 0); // sunday! + hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; - LOG_D(MAC, - "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", - harq_pid, frameP, subframeP, UE_id, rnti, - sched_frame, sched_subframeP); + LOG_D(MAC, + "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", + harq_pid, frameP, subframeP, UE_id, rnti, + sched_frame, sched_subframeP); - // Add UL_config PDUs - fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_tmp_body->number_of_pdus], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, first_rb[CC_id], // resource_block_start - rb_table[rb_table_index], // number_of_resource_blocks - UE_template->mcs_UL[harq_pid], cshift, // cyclic_shift_2_for_drms - 0, // frequency_hopping_enabled_flag - 0, // frequency_hopping_bits - ndi, // new_data_indication - 0, // redundancy_version - harq_pid, // harq_process_number - 0, // ul_tx_mode - 0, // current_tx_nb - 0, // n_srs - get_TBS_UL - (UE_template-> - mcs_UL[harq_pid], - rb_table - [rb_table_index])); + // Add UL_config PDUs + fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_tmp_body->number_of_pdus], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, first_rb[CC_id], // resource_block_start + rb_table[rb_table_index], // number_of_resource_blocks + UE_template->mcs_UL[harq_pid], cshift, // cyclic_shift_2_for_drms + 0, // frequency_hopping_enabled_flag + 0, // frequency_hopping_bits + ndi, // new_data_indication + 0, // redundancy_version + harq_pid, // harq_process_number + 0, // ul_tx_mode + 0, // current_tx_nb + 0, // n_srs + get_TBS_UL + (UE_template-> + mcs_UL[harq_pid], + rb_table + [rb_table_index])); #ifdef Rel14 - if (UE_template->rach_resource_type > 0) { // This is a BL/CE UE allocation - fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_tmp_body->number_of_pdus], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions - 1, //repetition_number - (frameP * - 10) + - subframeP); - } + if (UE_template->rach_resource_type > 0) { // This is a BL/CE UE allocation + fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_tmp_body->number_of_pdus], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions + 1, //repetition_number + (frameP * + 10) + + subframeP); + } #endif - ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST; - ul_req_tmp_body->number_of_pdus++; - ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - mac->ul_handle++; + ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_req_tmp_body->number_of_pdus++; + ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + mac->ul_handle++; - uint16_t ul_sched_frame = sched_frame; - uint16_t ul_sched_subframeP = sched_subframeP; + uint16_t ul_sched_frame = sched_frame; + uint16_t ul_sched_subframeP = sched_subframeP; - add_subframe(&ul_sched_frame, &ul_sched_subframeP, 2); - ul_req_tmp->sfn_sf = ul_sched_frame<<4|ul_sched_subframeP; + add_subframe(&ul_sched_frame, &ul_sched_subframeP, 2); + ul_req_tmp->sfn_sf = ul_sched_frame<<4|ul_sched_subframeP; - add_ue_ulsch_info(module_idP, - CC_id, UE_id, subframeP, - S_UL_SCHEDULED); + add_ue_ulsch_info(module_idP, + CC_id, UE_id, subframeP, + S_UL_SCHEDULED); - //LOG_D(MAC, "[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", module_idP, CC_id, frameP, subframeP, UE_id); - LOG_D(MAC,"[PUSCH %d] SFN/SF:%04d%d UL_CFG:SFN/SF:%04d%d CQI:%d for UE %d/%x\n", harq_pid,frameP,subframeP,ul_sched_frame,ul_sched_subframeP,cqi_req,UE_id,rnti); + //LOG_D(MAC, "[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", module_idP, CC_id, frameP, subframeP, UE_id); + LOG_D(MAC,"[PUSCH %d] SFN/SF:%04d%d UL_CFG:SFN/SF:%04d%d CQI:%d for UE %d/%x\n", harq_pid,frameP,subframeP,ul_sched_frame,ul_sched_subframeP,cqi_req,UE_id,rnti); - // increment first rb for next UE allocation - first_rb[CC_id] += rb_table[rb_table_index]; - } else { // round > 0 => retransmission - T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, - T_INT(module_idP), T_INT(CC_id), T_INT(rnti), - T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), - T_INT(UE_template->mcs_UL[harq_pid]), - T_INT(first_rb[CC_id]), - T_INT(rb_table[rb_table_index]), T_INT(round)); + // increment first rb for next UE allocation + first_rb[CC_id] += rb_table[rb_table_index]; + } else { // round > 0 => retransmission + T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, + T_INT(module_idP), T_INT(CC_id), T_INT(rnti), + T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), + T_INT(UE_template->mcs_UL[harq_pid]), + T_INT(first_rb[CC_id]), + T_INT(rb_table[rb_table_index]), T_INT(round)); - // fill in NAK information + // fill in NAK information - hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; - memset((void *) hi_dci0_pdu, 0, - sizeof(nfapi_hi_dci0_request_pdu_t)); - hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; - hi_dci0_pdu->pdu_size = - 2 + sizeof(nfapi_hi_dci0_hi_pdu); - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG; - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = - UE_template->first_rb_ul[harq_pid]; - hi_dci0_pdu->hi_pdu.hi_pdu_rel8. - cyclic_shift_2_for_drms = - UE_template->cshift[harq_pid]; - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 0; - hi_dci0_req_body->number_of_hi++; - hi_dci0_req_body->sfnsf = sfnsf_add_subframe(sched_frame, sched_subframeP, 0); - hi_dci0_req->sfn_sf = frameP<<4|subframeP; - hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; + hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; + memset((void *) hi_dci0_pdu, 0, + sizeof(nfapi_hi_dci0_request_pdu_t)); + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; + hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu); + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = UE_template->first_rb_ul[harq_pid]; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = UE_template->cshift[harq_pid]; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 0; + hi_dci0_req_body->number_of_hi++; + hi_dci0_req_body->sfnsf = sfnsf_add_subframe(sched_frame, sched_subframeP, 0); + hi_dci0_req->sfn_sf = frameP<<4|subframeP; + hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; - LOG_D(MAC, - "[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) UE %d (mcs %d, first rb %d, nb_rb %d, TBS %d, round %d)\n", - module_idP, harq_pid, rnti, CC_id, frameP, - subframeP, UE_id, UE_template->mcs_UL[harq_pid], - UE_template->first_rb_ul[harq_pid], - UE_template->nb_rb_ul[harq_pid], - UE_template->TBS_UL[harq_pid], round); - // Add UL_config PDUs - LOG_D(MAC, - "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", - harq_pid, frameP, subframeP, UE_id, rnti, - sched_frame, sched_subframeP); - fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_tmp_body->number_of_pdus], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, UE_template->first_rb_ul[harq_pid], // resource_block_start - UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks - UE_template->mcs_UL[harq_pid], cshift, // cyclic_shift_2_for_drms - 0, // frequency_hopping_enabled_flag - 0, // frequency_hopping_bits - UE_template->oldNDI_UL[harq_pid], // new_data_indication - rvidx_tab[round & 3], // redundancy_version - harq_pid, // harq_process_number - 0, // ul_tx_mode - 0, // current_tx_nb - 0, // n_srs - UE_template-> - TBS_UL[harq_pid]); + LOG_D(MAC, + "[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) UE %d (mcs %d, first rb %d, nb_rb %d, TBS %d, round %d)\n", + module_idP, harq_pid, rnti, CC_id, frameP, + subframeP, UE_id, UE_template->mcs_UL[harq_pid], + UE_template->first_rb_ul[harq_pid], + UE_template->nb_rb_ul[harq_pid], + UE_template->TBS_UL[harq_pid], round); + // Add UL_config PDUs + LOG_D(MAC, + "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", + harq_pid, frameP, subframeP, UE_id, rnti, + sched_frame, sched_subframeP); + fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_tmp_body->number_of_pdus], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, UE_template->first_rb_ul[harq_pid], // resource_block_start + UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks + UE_template->mcs_UL[harq_pid], cshift, // cyclic_shift_2_for_drms + 0, // frequency_hopping_enabled_flag + 0, // frequency_hopping_bits + UE_template->oldNDI_UL[harq_pid], // new_data_indication + rvidx_tab[round & 3], // redundancy_version + harq_pid, // harq_process_number + 0, // ul_tx_mode + 0, // current_tx_nb + 0, // n_srs + UE_template-> + TBS_UL[harq_pid]); #ifdef Rel14 - if (UE_template->rach_resource_type > 0) { // This is a BL/CE UE allocation - fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_tmp_body->number_of_pdus], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions - 1, //repetition_number - (frameP * - 10) + - subframeP); - } + if (UE_template->rach_resource_type > 0) { // This is a BL/CE UE allocation + fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_tmp_body->number_of_pdus], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions + 1, //repetition_number + (frameP * + 10) + + subframeP); + } #endif - ul_req_tmp_body->number_of_pdus++; - mac->ul_handle++; + ul_req_tmp_body->number_of_pdus++; + mac->ul_handle++; - ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - ul_req_tmp->sfn_sf = sched_frame<<4|sched_subframeP; - ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_req_tmp->sfn_sf = sched_frame<<4|sched_subframeP; + ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST; - LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d cqi_req %d\n", - harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP,cqi_req); - } /* - else if (round > 0) { //we schedule a retransmission + LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d cqi_req %d\n", + harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP,cqi_req); + } /* + else if (round > 0) { //we schedule a retransmission - ndi = UE_template->oldNDI_UL[harq_pid]; + ndi = UE_template->oldNDI_UL[harq_pid]; - if ((round&3)==0) { - mcs = openair_daq_vars.target_ue_ul_mcs; - } else { - mcs = rvidx_tab[round&3] + 28; //not correct for round==4! + if ((round&3)==0) { + mcs = openair_daq_vars.target_ue_ul_mcs; + } else { + mcs = rvidx_tab[round&3] + 28; //not correct for round==4! - } + } - LOG_I(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE retransmission (mcs %d, first rb %d, nb_rb %d, harq_pid %d, round %d)\n", - module_idP,UE_id,rnti,CC_id,frameP,subframeP,mcs, - first_rb[CC_id],UE_template->nb_rb_ul[harq_pid], - harq_pid, round); + LOG_I(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE retransmission (mcs %d, first rb %d, nb_rb %d, harq_pid %d, round %d)\n", + module_idP,UE_id,rnti,CC_id,frameP,subframeP,mcs, + first_rb[CC_id],UE_template->nb_rb_ul[harq_pid], + harq_pid, round); - rballoc = mac_xface->computeRIV(frame_parms->N_RB_UL, - first_rb[CC_id], - UE_template->nb_rb_ul[harq_pid]); - first_rb[CC_id]+=UE_template->nb_rb_ul[harq_pid]; // increment for next UE allocation + rballoc = mac_xface->computeRIV(frame_parms->N_RB_UL, + first_rb[CC_id], + UE_template->nb_rb_ul[harq_pid]); + first_rb[CC_id]+=UE_template->nb_rb_ul[harq_pid]; // increment for next UE allocation - UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission_rx+=1; - UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx_rx=UE_template->nb_rb_ul[harq_pid]; - UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=UE_template->nb_rb_ul[harq_pid]; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=mcs; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs; - } - */ + UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission_rx+=1; + UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx_rx=UE_template->nb_rb_ul[harq_pid]; + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=UE_template->nb_rb_ul[harq_pid]; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=mcs; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs; + } + */ - } // UE_is_to_be_scheduled - } // loop over UE_id - } // loop of CC_id + } // UE_is_to_be_scheduled + } // loop over UE_id + } // loop of CC_id }