From 1fac8d696320c22e45f0d68e283fb948ea6235b4 Mon Sep 17 00:00:00 2001 From: mjoang <m.joa-ng@northeastern.edu> Date: Sat, 9 Oct 2021 13:07:23 -0400 Subject: [PATCH] Revert "run astyle to change format" This reverts commit 721594102a4f2fbcdbc5941ff11cc49a27952b46. --- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 3286 +++++++++--------- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 769 ++-- 2 files changed, 2107 insertions(+), 1948 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 506c71e452..8adc552bd2 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -97,46 +97,47 @@ static const int sequence_cyclic_shift_2_harq_ack_bits[4] /* TS 38.211 Table 6.4.1.3.3.2-1: DM-RS positions for PUCCH format 3 and 4 */ static const int nb_symbols_excluding_dmrs[11][2][2] = { - /* No additional DMRS Additional DMRS */ - /* PUCCH length No hopping hopping No hopping hopping */ - /* index 0 1 0 1 */ - /* 4 */ {{ 3, 2 }, { 3, 2 }}, - /* 5 */ {{ 3, 3 }, { 3, 3 }}, - /* 6 */ {{ 4, 4 }, { 4, 4 }}, - /* 7 */ {{ 5, 5 }, { 5, 5 }}, - /* 8 */ {{ 6, 6 }, { 6, 6 }}, - /* 9 */ {{ 7, 7 }, { 7, 7 }}, - /* 10 */ {{ 8, 8 }, { 6, 6 }}, - /* 11 */ {{ 9, 9 }, { 7, 7 }}, - /* 12 */ {{ 10, 10 }, { 8, 8 }}, - /* 13 */ {{ 11, 11 }, { 9, 9 }}, - /* 14 */ {{ 12, 12 }, { 10, 10 }}, +/* No additional DMRS Additional DMRS */ +/* PUCCH length No hopping hopping No hopping hopping */ +/* index 0 1 0 1 */ +/* 4 */ {{ 3 , 2 } , { 3 , 2 }}, +/* 5 */ {{ 3 , 3 } , { 3 , 3 }}, +/* 6 */ {{ 4 , 4 } , { 4 , 4 }}, +/* 7 */ {{ 5 , 5 } , { 5 , 5 }}, +/* 8 */ {{ 6 , 6 } , { 6 , 6 }}, +/* 9 */ {{ 7 , 7 } , { 7 , 7 }}, +/* 10 */ {{ 8 , 8 } , { 6 , 6 }}, +/* 11 */ {{ 9 , 9 } , { 7 , 7 }}, +/* 12 */ {{ 10 , 10 } , { 8 , 8 }}, +/* 13 */ {{ 11 , 11 } , { 9 , 9 }}, +/* 14 */ {{ 12 , 12 } , { 10 , 10 }}, }; /* TS 36.213 Table 9.2.1-1: PUCCH resource sets before dedicated PUCCH resource configuration */ const initial_pucch_resource_t initial_pucch_resource[16] = { - /* format first symbol Number of symbols PRB offset nb index for set of initial CS */ - /* 0 */ { 0, 12, 2, 0, 2, { 0, 3, 0, 0 } }, - /* 1 */ { 0, 12, 2, 0, 3, { 0, 4, 8, 0 } }, - /* 2 */ { 0, 12, 2, 3, 3, { 0, 4, 8, 0 } }, - /* 3 */ { 1, 10, 4, 0, 2, { 0, 6, 0, 0 } }, - /* 4 */ { 1, 10, 4, 0, 4, { 0, 3, 6, 9 } }, - /* 5 */ { 1, 10, 4, 2, 4, { 0, 3, 6, 9 } }, - /* 6 */ { 1, 10, 4, 4, 4, { 0, 3, 6, 9 } }, - /* 7 */ { 1, 4, 10, 0, 2, { 0, 6, 0, 0 } }, - /* 8 */ { 1, 4, 10, 0, 4, { 0, 3, 6, 9 } }, - /* 9 */ { 1, 4, 10, 2, 4, { 0, 3, 6, 9 } }, - /* 10 */ { 1, 4, 10, 4, 4, { 0, 3, 6, 9 } }, - /* 11 */ { 1, 0, 14, 0, 2, { 0, 6, 0, 0 } }, - /* 12 */ { 1, 0, 14, 0, 4, { 0, 3, 6, 9 } }, - /* 13 */ { 1, 0, 14, 2, 4, { 0, 3, 6, 9 } }, - /* 14 */ { 1, 0, 14, 4, 4, { 0, 3, 6, 9 } }, - /* 15 */ { 1, 0, 14, 0, 4, { 0, 3, 6, 9 } }, +/* format first symbol Number of symbols PRB offset nb index for set of initial CS */ +/* 0 */ { 0, 12, 2, 0, 2, { 0, 3, 0, 0 } }, +/* 1 */ { 0, 12, 2, 0, 3, { 0, 4, 8, 0 } }, +/* 2 */ { 0, 12, 2, 3, 3, { 0, 4, 8, 0 } }, +/* 3 */ { 1, 10, 4, 0, 2, { 0, 6, 0, 0 } }, +/* 4 */ { 1, 10, 4, 0, 4, { 0, 3, 6, 9 } }, +/* 5 */ { 1, 10, 4, 2, 4, { 0, 3, 6, 9 } }, +/* 6 */ { 1, 10, 4, 4, 4, { 0, 3, 6, 9 } }, +/* 7 */ { 1, 4, 10, 0, 2, { 0, 6, 0, 0 } }, +/* 8 */ { 1, 4, 10, 0, 4, { 0, 3, 6, 9 } }, +/* 9 */ { 1, 4, 10, 2, 4, { 0, 3, 6, 9 } }, +/* 10 */ { 1, 4, 10, 4, 4, { 0, 3, 6, 9 } }, +/* 11 */ { 1, 0, 14, 0, 2, { 0, 6, 0, 0 } }, +/* 12 */ { 1, 0, 14, 0, 4, { 0, 3, 6, 9 } }, +/* 13 */ { 1, 0, 14, 2, 4, { 0, 3, 6, 9 } }, +/* 14 */ { 1, 0, 14, 4, 4, { 0, 3, 6, 9 } }, +/* 15 */ { 1, 0, 14, 0, 4, { 0, 3, 6, 9 } }, }; void nr_ue_init_mac(module_id_t module_idP) { int i; + NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); // default values as deined in 38.331 sec 9.2.2 LOG_I(NR_MAC, "[UE%d] Applying default macMainConfig\n", module_idP); @@ -145,45 +146,45 @@ void nr_ue_init_mac(module_id_t module_idP) { NR_BSR_Config__retxBSR_Timer_sf10240; mac->scheduling_info.periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_infinity; - // mac->scheduling_info.periodicPHR_Timer = - // NR_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; - // mac->scheduling_info.prohibitPHR_Timer = - // NR_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; - // mac->scheduling_info.PathlossChange_db = - // NR_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; - // mac->PHR_state = - // NR_MAC_MainConfig__phr_Config_PR_setup; +// mac->scheduling_info.periodicPHR_Timer = +// NR_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; +// mac->scheduling_info.prohibitPHR_Timer = +// NR_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; +// mac->scheduling_info.PathlossChange_db = +// NR_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; +// mac->PHR_state = +// NR_MAC_MainConfig__phr_Config_PR_setup; mac->scheduling_info.SR_COUNTER = 0; mac->scheduling_info.sr_ProhibitTimer = 0; mac->scheduling_info.sr_ProhibitTimer_Running = 0; - // mac->scheduling_info.maxHARQ_Tx = - // NR_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; - // mac->scheduling_info.ttiBundling = 0; - // mac->scheduling_info.extendedBSR_Sizes_r10 = 0; - // mac->scheduling_info.extendedPHR_r10 = 0; - // mac->scheduling_info.drx_config = NULL; - // mac->scheduling_info.phr_config = NULL; +// mac->scheduling_info.maxHARQ_Tx = +// NR_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; +// mac->scheduling_info.ttiBundling = 0; +// mac->scheduling_info.extendedBSR_Sizes_r10 = 0; +// mac->scheduling_info.extendedPHR_r10 = 0; +// mac->scheduling_info.drx_config = NULL; +// mac->scheduling_info.phr_config = NULL; // set init value 0xFFFF, make sure periodic timer and retx time counters are NOT active, after bsr transmission set the value configured by the NW. mac->scheduling_info.periodicBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING; mac->scheduling_info.retxBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING; mac->BSR_reporting_active = BSR_TRIGGER_NONE; - // mac->scheduling_info.periodicPHR_SF = - // nr_get_sf_perioidicPHR_Timer(mac-> - // scheduling_info.periodicPHR_Timer); - // mac->scheduling_info.prohibitPHR_SF = - // nr_get_sf_prohibitPHR_Timer(mac-> - // scheduling_info.prohibitPHR_Timer); - // mac->scheduling_info.PathlossChange_db = - // nr_get_db_dl_PathlossChange(mac-> - // scheduling_info.PathlossChange); - // mac->PHR_reporting_active = 0; +// mac->scheduling_info.periodicPHR_SF = +// nr_get_sf_perioidicPHR_Timer(mac-> +// scheduling_info.periodicPHR_Timer); +// mac->scheduling_info.prohibitPHR_SF = +// nr_get_sf_prohibitPHR_Timer(mac-> +// scheduling_info.prohibitPHR_Timer); +// mac->scheduling_info.PathlossChange_db = +// nr_get_db_dl_PathlossChange(mac-> +// scheduling_info.PathlossChange); +// mac->PHR_reporting_active = 0; for (i = 0; i < NR_MAX_NUM_LCID; i++) { LOG_D(NR_MAC, "[UE%d] Applying default logical channel config for LCGID %d\n", - module_idP, i); + module_idP, i); mac->scheduling_info.Bj[i] = -1; mac->scheduling_info.bucket_size[i] = -1; @@ -196,47 +197,53 @@ void nr_ue_init_mac(module_id_t module_idP) { mac->scheduling_info.LCID_status[i] = LCID_EMPTY; mac->scheduling_info.LCID_buffer_remain[i] = 0; - - for (int i=0; i<NR_MAX_HARQ_PROCESSES; i++) mac->first_ul_tx[i]=1; + for (int i=0;i<NR_MAX_HARQ_PROCESSES;i++) mac->first_ul_tx[i]=1; } } -int get_rnti_type(NR_UE_MAC_INST_t *mac, uint16_t rnti) { - RA_config_t *ra = &mac->ra; - int rnti_type; - - if (rnti == ra->ra_rnti) { - rnti_type = NR_RNTI_RA; - } else if (rnti == ra->t_crnti && (ra->ra_state == WAIT_RAR || ra->ra_state == WAIT_CONTENTION_RESOLUTION) ) { - rnti_type = NR_RNTI_TC; - } else if (rnti == mac->crnti) { - rnti_type = NR_RNTI_C; - } else if (rnti == 0xFFFE) { - rnti_type = NR_RNTI_P; - } else if (rnti == 0xFFFF) { - rnti_type = NR_RNTI_SI; - } else { - AssertFatal(1 == 0, "In %s: Not identified/handled rnti %d \n", __FUNCTION__, rnti); - } +int get_rnti_type(NR_UE_MAC_INST_t *mac, uint16_t rnti){ + + RA_config_t *ra = &mac->ra; + int rnti_type; + + if (rnti == ra->ra_rnti) { + rnti_type = NR_RNTI_RA; + } else if (rnti == ra->t_crnti && (ra->ra_state == WAIT_RAR || ra->ra_state == WAIT_CONTENTION_RESOLUTION) ) { + rnti_type = NR_RNTI_TC; + } else if (rnti == mac->crnti) { + rnti_type = NR_RNTI_C; + } else if (rnti == 0xFFFE) { + rnti_type = NR_RNTI_P; + } else if (rnti == 0xFFFF) { + rnti_type = NR_RNTI_SI; + } else { + AssertFatal(1 == 0, "In %s: Not identified/handled rnti %d \n", __FUNCTION__, rnti); + } + + LOG_D(MAC, "In %s: returning rnti_type %s \n", __FUNCTION__, rnti_types[rnti_type]); + + return rnti_type; - LOG_D(MAC, "In %s: returning rnti_type %s \n", __FUNCTION__, rnti_types[rnti_type]); - return rnti_type; } int8_t nr_ue_decode_mib(module_id_t module_id, int cc_id, uint8_t gNB_index, - uint8_t extra_bits, // 8bits 38.212 c7.1.1 + uint8_t extra_bits, // 8bits 38.212 c7.1.1 uint32_t ssb_length, uint32_t ssb_index, void *pduP, uint16_t ssb_start_subcarrier, - uint16_t cell_id) { + uint16_t cell_id) +{ LOG_I(MAC,"[L2][MAC] decode mib\n"); + NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); mac->physCellId = cell_id; + nr_mac_rrc_data_ind_ue( module_id, cc_id, gNB_index, 0, 0, 0, NR_BCCH_BCH, (uint8_t *) pduP, 3 ); // fixed 3 bytes MIB PDU + AssertFatal(mac->mib != NULL, "nr_ue_decode_mib() mac->mib == NULL\n"); //if(mac->mib != NULL){ uint16_t frame = (mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused); @@ -245,26 +252,24 @@ int8_t nr_ue_decode_mib(module_id_t module_id, for (int i=0; i<4; i++) frame_number_4lsb |= ((extra_bits>>i)&1)<<(3-i); - uint8_t ssb_subcarrier_offset_msb = ( extra_bits >> 5 ) & 0x1; // extra bits[5] + uint8_t ssb_subcarrier_offset_msb = ( extra_bits >> 5 ) & 0x1; // extra bits[5] uint8_t ssb_subcarrier_offset = (uint8_t)mac->mib->ssb_SubcarrierOffset; + frame = frame << 4; frame = frame | frame_number_4lsb; - - if(ssb_length == 64) { + if(ssb_length == 64){ mac->frequency_range = FR2; - for (int i=0; i<3; i++) ssb_index += (((extra_bits>>(7-i))&0x01)<<(3+i)); - } else { + }else{ mac->frequency_range = FR1; - - if(ssb_subcarrier_offset_msb) { + if(ssb_subcarrier_offset_msb){ ssb_subcarrier_offset = ssb_subcarrier_offset | 0x10; } } #ifdef DEBUG_MIB - uint8_t half_frame_bit = ( extra_bits >> 4 ) & 0x1; // extra bits[4] + uint8_t half_frame_bit = ( extra_bits >> 4 ) & 0x1; // extra bits[4] LOG_I(MAC,"system frame number(6 MSB bits): %d\n", mac->mib->systemFrameNumber.buf[0]); LOG_I(MAC,"system frame number(with LSB): %d\n", (int)frame); LOG_I(MAC,"subcarrier spacing (0=15or60, 1=30or120): %d\n", (int)mac->mib->subCarrierSpacingCommon); @@ -277,14 +282,17 @@ int8_t nr_ue_decode_mib(module_id_t module_id, LOG_I(MAC,"half frame bit(extra bits): %d\n", (int)half_frame_bit); LOG_I(MAC,"ssb index(extra bits): %d\n", (int)ssb_index); #endif + //storing ssb index in the mac structure mac->mib_ssb = ssb_index; mac->ssb_subcarrier_offset = ssb_subcarrier_offset; + uint8_t scs_ssb; uint32_t band; uint16_t ssb_start_symbol; if (get_softmodem_params()->sa == 1) { + scs_ssb = get_softmodem_params()->numerology; band = mac->nr_band; ssb_start_symbol = get_ssb_start_symbol(band,scs_ssb,ssb_index); @@ -298,7 +306,8 @@ int8_t nr_ue_decode_mib(module_id_t module_id, ssb_index, ssb_start_subcarrier, mac->frequency_range); - } else { + } + else { NR_ServingCellConfigCommon_t *scc = mac->scc; scs_ssb = *scc->ssbSubcarrierSpacing; band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; @@ -307,6 +316,7 @@ int8_t nr_ue_decode_mib(module_id_t module_id, mac->dl_config_request.sfn = frame; mac->dl_config_request.slot = ssb_start_symbol/14; + return 0; } @@ -319,14 +329,14 @@ int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id, if(ack_nack) { LOG_D(NR_MAC, "Decoding NR-BCCH-DL-SCH-Message (SIB1 or SI)\n"); nr_mac_rrc_data_ind_ue(module_id, cc_id, gNB_index, 0, 0, 0, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len); - } else + } + else LOG_E(NR_MAC, "Got NACK on NR-BCCH-DL-SCH-Message (SIB1 or SI)\n"); - return 0; } // TODO: change to UE parameter, scs: 15KHz, slot duration: 1ms -uint32_t get_ssb_frame(uint32_t test) { +uint32_t get_ssb_frame(uint32_t test){ return test; } @@ -335,16 +345,18 @@ uint32_t get_ssb_frame(uint32_t test) { * These tables and functions are going to be called by function nr_ue_process_dci */ int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, - fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu, - uint16_t n_RB_ULBWP, - uint16_t n_RB_DLBWP, - uint16_t riv - ) { + fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu, + uint16_t n_RB_ULBWP, + uint16_t n_RB_DLBWP, + uint16_t riv + ){ + /* * TS 38.214 subclause 5.1.2.2 Resource allocation in frequency domain (downlink) * when the scheduling grant is received with DCI format 1_0, then downlink resource allocation type 1 is used */ - if(dlsch_config_pdu != NULL) { + if(dlsch_config_pdu != NULL){ + /* * TS 38.214 subclause 5.1.2.2.1 Downlink resource allocation type 0 */ @@ -365,9 +377,9 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *p LOG_D(MAC,"DLSCH n_RB_DLBWP = %i\n", n_RB_DLBWP); LOG_D(MAC,"DLSCH number_rbs = %i\n", dlsch_config_pdu->number_rbs); LOG_D(MAC,"DLSCH start_rb = %i\n", dlsch_config_pdu->start_rb); - } - if(pusch_config_pdu != NULL) { + } + if(pusch_config_pdu != NULL){ /* * TS 38.214 subclause 6.1.2.2 Resource allocation in frequency domain (uplink) */ @@ -377,6 +389,7 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *p /* * TS 38.214 subclause 6.1.2.2.2 Uplink resource allocation type 1 */ + pusch_config_pdu->rb_size = NRRIV2BW(riv,n_RB_ULBWP); pusch_config_pdu->rb_start = NRRIV2PRBOFFSET(riv,n_RB_ULBWP); @@ -386,30 +399,31 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *p LOG_W(MAC, "Frequency domain assignment values are invalid! #RBs: %d, Start RB: %d, n_RB_ULBWP: %d \n",pusch_config_pdu->rb_size, pusch_config_pdu->rb_start, n_RB_ULBWP); return -1; } - LOG_D(MAC,"ULSCH riv = %i\n", riv); LOG_D(MAC,"ULSCH n_RB_DLBWP = %i\n", n_RB_ULBWP); LOG_D(MAC,"ULSCH number_rbs = %i\n", pusch_config_pdu->rb_size); LOG_D(MAC,"ULSCH start_rb = %i\n", pusch_config_pdu->rb_start); } - return 0; } int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, - nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, - fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu, - uint8_t time_domain_ind, - int default_abc, - bool use_default) { + nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, + fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu, + uint8_t time_domain_ind, + int default_abc, + bool use_default){ + int dmrs_typeA_pos = (mac->scc != NULL) ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position; - // uint8_t k_offset=0; + +// uint8_t k_offset=0; int sliv_S=0; int sliv_L=0; uint8_t mu_pusch = 1; + // definition table j Table 6.1.2.1.1-4 uint8_t j = (mu_pusch==3)?3:(mu_pusch==2)?2:1; - uint8_t table_6_1_2_1_1_2_time_dom_res_alloc_A[16][3]= { // for PUSCH from TS 38.214 subclause 6.1.2.1.1 + uint8_t table_6_1_2_1_1_2_time_dom_res_alloc_A[16][3]={ // for PUSCH from TS 38.214 subclause 6.1.2.1.1 {j, 0,14}, // row index 1 {j, 0,12}, // row index 2 {j, 0,10}, // row index 3 @@ -449,9 +463,8 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, /* * TS 38.214 subclause 5.1.2.1 Resource allocation in time domain (downlink) */ - if(dlsch_config_pdu != NULL) { + if(dlsch_config_pdu != NULL){ NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList = NULL; - if (mac->DLbwp[0] && mac->DLbwp[0]->bwp_Dedicated && mac->DLbwp[0]->bwp_Dedicated->pdsch_Config && @@ -463,6 +476,7 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, pdsch_TimeDomainAllocationList = mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; if (pdsch_TimeDomainAllocationList && use_default==false) { + if (time_domain_ind >= pdsch_TimeDomainAllocationList->list.count) { LOG_E(MAC, "time_domain_ind %d >= pdsch->TimeDomainAllocationList->list.count %d\n", time_domain_ind, pdsch_TimeDomainAllocationList->list.count); @@ -476,40 +490,44 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, SLIV2SL(startSymbolAndLength,&S,&L); dlsch_config_pdu->start_symbol=S; dlsch_config_pdu->number_symbols=L; + LOG_D(MAC,"SLIV = %i\n", startSymbolAndLength); LOG_D(MAC,"start_symbol = %i\n", dlsch_config_pdu->start_symbol); LOG_D(MAC,"number_symbols = %i\n", dlsch_config_pdu->number_symbols); - } else { // Default configuration from tables + + } + else {// Default configuration from tables + get_info_from_tda_tables(default_abc, time_domain_ind, dmrs_typeA_pos, 1, // normal CP &sliv_S, &sliv_L); + dlsch_config_pdu->number_symbols = sliv_L; dlsch_config_pdu->start_symbol = sliv_S; } - } /* - - * TS 38.214 subclause 6.1.2.1 Resource allocation in time domain (uplink) - */ - - if(pusch_config_pdu != NULL) { + } /* + * TS 38.214 subclause 6.1.2.1 Resource allocation in time domain (uplink) + */ + if(pusch_config_pdu != NULL){ NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL; - if (mac->ULbwp[0] && mac->ULbwp[0]->bwp_Dedicated && mac->ULbwp[0]->bwp_Dedicated->pusch_Config && mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup && mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList) { pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList->choice.setup; - } else if (mac->ULbwp[0] && - mac->ULbwp[0]->bwp_Common && - mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon && - mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup && - mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) { + } + else if (mac->ULbwp[0] && + mac->ULbwp[0]->bwp_Common && + mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon && + mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup && + mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) { pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - } else pusch_TimeDomainAllocationList = mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; + } + else pusch_TimeDomainAllocationList = mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; if (pusch_TimeDomainAllocationList && use_default==false) { if (time_domain_ind >= pusch_TimeDomainAllocationList->list.count) { @@ -519,16 +537,17 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, pusch_config_pdu->nr_of_symbols=0; return -1; } - + LOG_D(NR_MAC,"Filling Time-Domain Allocation from pusch_TimeDomainAllocationList\n"); int startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[time_domain_ind]->startSymbolAndLength; int S,L; SLIV2SL(startSymbolAndLength,&S,&L); pusch_config_pdu->start_symbol_index=S; pusch_config_pdu->nr_of_symbols=L; - } else { + } + else { LOG_D(NR_MAC,"Filling Time-Domain Allocation from tables\n"); - // k_offset = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][0]; +// k_offset = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][0]; sliv_S = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind][1]; sliv_L = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind][2]; // k_offset = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][0]; @@ -537,33 +556,32 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, pusch_config_pdu->nr_of_symbols = sliv_L; pusch_config_pdu->start_symbol_index = sliv_S; } - LOG_D(NR_MAC,"start_symbol = %i\n", pusch_config_pdu->start_symbol_index); LOG_D(NR_MAC,"number_symbols = %i\n", pusch_config_pdu->nr_of_symbols); } - return 0; } int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci) { + NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); dci_pdu_rel15_t *def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[dci->dci_format]; + LOG_D(MAC,"Received dci indication (rnti %x,dci format %d,n_CCE %d,payloadSize %d,payload %llx)\n", - dci->rnti,dci->dci_format,dci->n_CCE,dci->payloadSize,*(unsigned long long *)dci->payloadBits); + dci->rnti,dci->dci_format,dci->n_CCE,dci->payloadSize,*(unsigned long long*)dci->payloadBits); int8_t ret = nr_extract_dci_info(mac, dci->dci_format, dci->payloadSize, dci->rnti, (uint64_t *)dci->payloadBits, def_dci_pdu_rel15); - if ((ret&1) == 1) return -1; else if (ret == 2) { dci->dci_format = NR_UL_DCI_FORMAT_0_0; def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[dci->dci_format]; } - int8_t ret_proc = nr_ue_process_dci(module_id, cc_id, gNB_index, frame, slot, def_dci_pdu_rel15, dci); memset(def_dci_pdu_rel15, 0, sizeof(dci_pdu_rel15_t)); return ret_proc; } int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, frame_t frame, int slot, dci_pdu_rel15_t *dci, fapi_nr_dci_indication_pdu_t *dci_ind) { + uint16_t rnti = dci_ind->rnti; uint8_t dci_format = dci_ind->dci_format; int ret = 0; @@ -576,697 +594,681 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request; uint8_t is_Msg3 = 0; int default_abc = 1; - uint16_t n_RB_DLBWP; + uint16_t n_RB_DLBWP; if (mac->DLbwp[0]) n_RB_DLBWP = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); else if (mac->scc_SIB) n_RB_DLBWP = NRRIV2BW(mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth,MAX_BWP_SIZE); else n_RB_DLBWP = mac->type0_PDCCH_CSS_config.num_rbs; LOG_D(MAC, "In %s: Processing received DCI format %s (DL BWP %d)\n", __FUNCTION__, dci_formats[dci_format], n_RB_DLBWP); - switch(dci_format) { - case NR_UL_DCI_FORMAT_0_0: { - /* - * with CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI - * 0 IDENTIFIER_DCI_FORMATS: - * 10 FREQ_DOM_RESOURCE_ASSIGNMENT_UL: PUSCH hopping with resource allocation type 1 not considered - * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 6.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - * 17 FREQ_HOPPING_FLAG: 0 bit if only resource allocation type 0 - * 24 MCS: - * 25 NDI: - * 26 RV: - * 27 HARQ_PROCESS_NUMBER: - * 32 TPC_PUSCH: - * 49 PADDING_NR_DCI: (Note 2) If DCI format 0_0 is monitored in common search space - * 50 SUL_IND_0_0: - */ - // Calculate the slot in which ULSCH should be scheduled. This is current slot + K2, - // where K2 is the offset between the slot in which UL DCI is received and the slot - // in which ULSCH should be scheduled. K2 is configured in RRC configuration. - // todo: - // - SUL_IND_0_0 - // Schedule PUSCH - ret = nr_ue_pusch_scheduler(mac, is_Msg3, frame, slot, &frame_tx, &slot_tx, dci->time_domain_assignment.val); - - if (ret != -1) { - // Get UL config request corresponding slot_tx - fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx); - - if (!ul_config) { - LOG_W(MAC, "In %s: ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n", __FUNCTION__, frame, slot); - return -1; - } - - AssertFatal(ul_config->number_pdus<FAPI_NR_UL_CONFIG_LIST_NUM, "ul_config->number_pdus %d out of bounds\n",ul_config->number_pdus); - nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu; - fill_ul_config(ul_config, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH); - // Config PUSCH PDU - ret = nr_config_pusch_pdu(mac, pusch_config_pdu, dci, NULL, rnti, &dci_format); - } - - break; - } - - case NR_UL_DCI_FORMAT_0_1: { - /* - * with CRC scrambled by C-RNTI or CS-RNTI or SP-CSI-RNTI or new-RNTI - * 0 IDENTIFIER_DCI_FORMATS: - * 1 CARRIER_IND - * 2 SUL_IND_0_1 - * 7 BANDWIDTH_PART_IND - * 10 FREQ_DOM_RESOURCE_ASSIGNMENT_UL: PUSCH hopping with resource allocation type 1 not considered - * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 6.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - * 17 FREQ_HOPPING_FLAG: 0 bit if only resource allocation type 0 - * 24 MCS: - * 25 NDI: - * 26 RV: - * 27 HARQ_PROCESS_NUMBER: - * 29 FIRST_DAI - * 30 SECOND_DAI - * 32 TPC_PUSCH: - * 36 SRS_RESOURCE_IND: - * 37 PRECOD_NBR_LAYERS: - * 38 ANTENNA_PORTS: - * 40 SRS_REQUEST: - * 42 CSI_REQUEST: - * 43 CBGTI - * 45 PTRS_DMRS - * 46 BETA_OFFSET_IND - * 47 DMRS_SEQ_INI - * 48 UL_SCH_IND - * 49 PADDING_NR_DCI: (Note 2) If DCI format 0_0 is monitored in common search space - */ - // TODO: - // - FIRST_DAI - // - SECOND_DAI - // - SRS_RESOURCE_IND - // Schedule PUSCH - ret = nr_ue_pusch_scheduler(mac, is_Msg3, frame, slot, &frame_tx, &slot_tx, dci->time_domain_assignment.val); - - if (ret != -1) { - // Get UL config request corresponding slot_tx - fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx); - - if (!ul_config) { - LOG_W(MAC, "In %s: ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n", __FUNCTION__, frame, slot); - return -1; - } - - nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu; - fill_ul_config(ul_config, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH); - // Config PUSCH PDU - ret = nr_config_pusch_pdu(mac, pusch_config_pdu, dci, NULL, rnti, &dci_format); - } - - break; - } - - case NR_DL_DCI_FORMAT_1_0: { - /* - * with CRC scrambled by C-RNTI or CS-RNTI or new-RNTI - * 0 IDENTIFIER_DCI_FORMATS: - * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: - * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 - * 24 MCS: - * 25 NDI: - * 26 RV: - * 27 HARQ_PROCESS_NUMBER: - * 28 DAI_: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI - * 33 TPC_PUCCH: - * 34 PUCCH_RESOURCE_IND: - * 35 PDSCH_TO_HARQ_FEEDBACK_TIME_IND: - * 55 RESERVED_NR_DCI - * with CRC scrambled by P-RNTI - * 8 SHORT_MESSAGE_IND - * 9 SHORT_MESSAGES - * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: - * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 - * 24 MCS: - * 31 TB_SCALING - * 55 RESERVED_NR_DCI - * with CRC scrambled by SI-RNTI - * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: - * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 - * 24 MCS: - * 26 RV: - * 55 RESERVED_NR_DCI - * with CRC scrambled by RA-RNTI - * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: - * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 - * 24 MCS: - * 31 TB_SCALING - * 55 RESERVED_NR_DCI - * with CRC scrambled by TC-RNTI - * 0 IDENTIFIER_DCI_FORMATS: - * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: - * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 - * 24 MCS: - * 25 NDI: - * 26 RV: - * 27 HARQ_PROCESS_NUMBER: - * 28 DAI_: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI - * 33 TPC_PUCCH: - */ - dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.rnti = rnti; - fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu_1_0 = &dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.dlsch_config_rel15; - NR_PDSCH_Config_t *pdsch_config= (mac->DLbwp[0]) ? mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup : NULL; - uint16_t BWPSize = n_RB_DLBWP; - - if(rnti == SI_RNTI) { - NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config = mac->type0_PDCCH_CSS_config; - default_abc = type0_PDCCH_CSS_config.type0_pdcch_ss_mux_pattern; - dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH; - dlsch_config_pdu_1_0->BWPSize = mac->type0_PDCCH_CSS_config.num_rbs; - dlsch_config_pdu_1_0->BWPStart = mac->type0_PDCCH_CSS_config.cset_start_rb; - dlsch_config_pdu_1_0->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon; - - if (pdsch_config) pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NULL; // For PDSCH with mapping type A, the UE shall assume dmrs-AdditionalPosition='pos2' - - BWPSize = dlsch_config_pdu_1_0->BWPSize; - } else { - if (ra->RA_window_cnt >= 0 && rnti == ra->ra_rnti) { - dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH; - } else { - dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH; - } + switch(dci_format){ + case NR_UL_DCI_FORMAT_0_0: { + /* + * with CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI + * 0 IDENTIFIER_DCI_FORMATS: + * 10 FREQ_DOM_RESOURCE_ASSIGNMENT_UL: PUSCH hopping with resource allocation type 1 not considered + * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 6.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, + * 17 FREQ_HOPPING_FLAG: 0 bit if only resource allocation type 0 + * 24 MCS: + * 25 NDI: + * 26 RV: + * 27 HARQ_PROCESS_NUMBER: + * 32 TPC_PUSCH: + * 49 PADDING_NR_DCI: (Note 2) If DCI format 0_0 is monitored in common search space + * 50 SUL_IND_0_0: + */ + // Calculate the slot in which ULSCH should be scheduled. This is current slot + K2, + // where K2 is the offset between the slot in which UL DCI is received and the slot + // in which ULSCH should be scheduled. K2 is configured in RRC configuration. + // todo: + // - SUL_IND_0_0 - if( (ra->RA_window_cnt >= 0 && rnti == ra->ra_rnti) || (rnti == ra->t_crnti) ) { - if (mac->scc == NULL) { - dlsch_config_pdu_1_0->BWPSize = NRRIV2BW(mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - } else { - dlsch_config_pdu_1_0->BWPSize = NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - } + // Schedule PUSCH + ret = nr_ue_pusch_scheduler(mac, is_Msg3, frame, slot, &frame_tx, &slot_tx, dci->time_domain_assignment.val); - if (!get_softmodem_params()->sa) { // NSA mode is not using the Initial BWP - dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - pdsch_config = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup; - BWPSize = dlsch_config_pdu_1_0->BWPSize; - } - } else if (mac->DLbwp[0]) { - dlsch_config_pdu_1_0->BWPSize = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - dlsch_config_pdu_1_0->SubcarrierSpacing = mac->DLbwp[0]->bwp_Common->genericParameters.subcarrierSpacing; - pdsch_config = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup; - } else if (mac->scc_SIB) { - dlsch_config_pdu_1_0->BWPSize = NRRIV2BW(mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - dlsch_config_pdu_1_0->SubcarrierSpacing = mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.subcarrierSpacing; - pdsch_config = NULL; - } - } - - /* IDENTIFIER_DCI_FORMATS */ - /* FREQ_DOM_RESOURCE_ASSIGNMENT_DL */ - if (nr_ue_process_dci_freq_dom_resource_assignment(NULL,dlsch_config_pdu_1_0,0,BWPSize,dci->frequency_domain_assignment.val) < 0) { - LOG_W(MAC, "[%d.%d] Invalid frequency_domain_assignment. Possibly due to false DCI. Ignoring DCI!\n", frame, slot); - return -1; - } + if (ret != -1){ - /* TIME_DOM_RESOURCE_ASSIGNMENT */ - if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_0,dci->time_domain_assignment.val,default_abc,rnti==SI_RNTI) < 0) { - LOG_W(MAC, "[%d.%d] Invalid time_domain_assignment. Possibly due to false DCI. Ignoring DCI!\n", frame, slot); - return -1; - } + // Get UL config request corresponding slot_tx + fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx); - NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList = NULL; - - if (mac->DLbwp[0] && - mac->DLbwp[0]->bwp_Dedicated && - mac->DLbwp[0]->bwp_Dedicated->pdsch_Config && - mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList) - pdsch_TimeDomainAllocationList = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList->choice.setup; - else if (mac->DLbwp[0] && mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList) - pdsch_TimeDomainAllocationList = mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - else if (mac->scc_SIB && mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon->choice.setup) - pdsch_TimeDomainAllocationList = mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - - int mappingtype = pdsch_TimeDomainAllocationList ? pdsch_TimeDomainAllocationList->list.array[dci->time_domain_assignment.val]->mappingType : ((dlsch_config_pdu_1_0->start_symbol <= 3)? typeA: typeB); - /* dmrs symbol positions*/ - dlsch_config_pdu_1_0->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config, - mac->mib->dmrs_TypeA_Position, - dlsch_config_pdu_1_0->number_symbols, - dlsch_config_pdu_1_0->start_symbol, - mappingtype); - dlsch_config_pdu_1_0->dmrsConfigType = (mac->DLbwp[0] != NULL) ? - (mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1) : 0; - - /* number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214 version 15.9.0 Release 15 */ - if (dlsch_config_pdu_1_0->number_symbols == 2) - dlsch_config_pdu_1_0->n_dmrs_cdm_groups = 1; - else - dlsch_config_pdu_1_0->n_dmrs_cdm_groups = 2; - - /* VRB_TO_PRB_MAPPING */ - dlsch_config_pdu_1_0->vrb_to_prb_mapping = (dci->vrb_to_prb_mapping.val == 0) ? vrb_to_prb_mapping_non_interleaved:vrb_to_prb_mapping_interleaved; - /* MCS TABLE INDEX */ - dlsch_config_pdu_1_0->mcs_table = (pdsch_config) ? ((pdsch_config->mcs_Table) ? (*pdsch_config->mcs_Table + 1) : 0) : 0; - /* MCS */ - dlsch_config_pdu_1_0->mcs = dci->mcs; - - // Basic sanity check for MCS value to check for a false or erroneous DCI - if (dlsch_config_pdu_1_0->mcs > 28) { - LOG_W(MAC, "[%d.%d] MCS value %d out of bounds! Possibly due to false DCI. Ignoring DCI!\n", frame, slot, dlsch_config_pdu_1_0->mcs); + if (!ul_config) { + LOG_W(MAC, "In %s: ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n", __FUNCTION__, frame, slot); return -1; } - /* NDI (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI)*/ - dlsch_config_pdu_1_0->ndi = dci->ndi; - /* RV (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI)*/ - dlsch_config_pdu_1_0->rv = dci->rv; - /* HARQ_PROCESS_NUMBER (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI)*/ - dlsch_config_pdu_1_0->harq_process_nbr = dci->harq_pid; - - /* TB_SCALING (only if CRC scrambled by P-RNTI or RA-RNTI) */ - // according to TS 38.214 Table 5.1.3.2-3 - if (dci->tb_scaling == 0) dlsch_config_pdu_1_0->scaling_factor_S = 1; - - if (dci->tb_scaling == 1) dlsch_config_pdu_1_0->scaling_factor_S = 0.5; - - if (dci->tb_scaling == 2) dlsch_config_pdu_1_0->scaling_factor_S = 0.25; - - if (dci->tb_scaling == 3) dlsch_config_pdu_1_0->scaling_factor_S = 0; // value not defined in table + AssertFatal(ul_config->number_pdus<FAPI_NR_UL_CONFIG_LIST_NUM, "ul_config->number_pdus %d out of bounds\n",ul_config->number_pdus); + nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu; - /* TPC_PUCCH (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI)*/ - // according to TS 38.213 Table 7.2.1-1 - if (dci->tpc == 0) dlsch_config_pdu_1_0->accumulated_delta_PUCCH = -1; + fill_ul_config(ul_config, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH); - if (dci->tpc == 1) dlsch_config_pdu_1_0->accumulated_delta_PUCCH = 0; + // Config PUSCH PDU + ret = nr_config_pusch_pdu(mac, pusch_config_pdu, dci, NULL, rnti, &dci_format); - if (dci->tpc == 2) dlsch_config_pdu_1_0->accumulated_delta_PUCCH = 1; + } + + break; + } - if (dci->tpc == 3) dlsch_config_pdu_1_0->accumulated_delta_PUCCH = 3; + case NR_UL_DCI_FORMAT_0_1: { + /* + * with CRC scrambled by C-RNTI or CS-RNTI or SP-CSI-RNTI or new-RNTI + * 0 IDENTIFIER_DCI_FORMATS: + * 1 CARRIER_IND + * 2 SUL_IND_0_1 + * 7 BANDWIDTH_PART_IND + * 10 FREQ_DOM_RESOURCE_ASSIGNMENT_UL: PUSCH hopping with resource allocation type 1 not considered + * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 6.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, + * 17 FREQ_HOPPING_FLAG: 0 bit if only resource allocation type 0 + * 24 MCS: + * 25 NDI: + * 26 RV: + * 27 HARQ_PROCESS_NUMBER: + * 29 FIRST_DAI + * 30 SECOND_DAI + * 32 TPC_PUSCH: + * 36 SRS_RESOURCE_IND: + * 37 PRECOD_NBR_LAYERS: + * 38 ANTENNA_PORTS: + * 40 SRS_REQUEST: + * 42 CSI_REQUEST: + * 43 CBGTI + * 45 PTRS_DMRS + * 46 BETA_OFFSET_IND + * 47 DMRS_SEQ_INI + * 48 UL_SCH_IND + * 49 PADDING_NR_DCI: (Note 2) If DCI format 0_0 is monitored in common search space + */ + // TODO: + // - FIRST_DAI + // - SECOND_DAI + // - SRS_RESOURCE_IND - // Sanity check for pucch_resource_indicator value received to check for false DCI. - valid = 0; + // Schedule PUSCH + ret = nr_ue_pusch_scheduler(mac, is_Msg3, frame, slot, &frame_tx, &slot_tx, dci->time_domain_assignment.val); - if (mac->ULbwp[0] && - mac->ULbwp[0]->bwp_Dedicated && - mac->ULbwp[0]->bwp_Dedicated->pucch_Config && - mac->ULbwp[0]->bwp_Dedicated->pucch_Config->choice.setup&& - mac->ULbwp[0]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList) { - pucch_res_set_cnt = mac->ULbwp[0]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.count; + if (ret != -1){ - for (int id = 0; id < pucch_res_set_cnt; id++) { - if (dci->pucch_resource_indicator < mac->ULbwp[0]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[id]->resourceList.list.count) { - valid = 1; - break; - } - } - } else if (mac->cg && - mac->cg->spCellConfig && - mac->cg->spCellConfig->spCellConfigDedicated && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup->resourceSetToAddModList) { - pucch_res_set_cnt = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup->resourceSetToAddModList->list.count; - - for (int id = 0; id < pucch_res_set_cnt; id++) { - if (dci->pucch_resource_indicator < - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup->resourceSetToAddModList->list.array[id]->resourceList.list.count) { - valid = 1; - break; - } - } - } else valid=1; + // Get UL config request corresponding slot_tx + fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx); - if (!valid) { - LOG_W(MAC, "[%d.%d] pucch_resource_indicator value %d is out of bounds. Possibly due to false DCI. Ignoring DCI!\n", frame, slot, dci->pucch_resource_indicator); + if (!ul_config) { + LOG_W(MAC, "In %s: ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n", __FUNCTION__, frame, slot); return -1; } - // set the harq status at MAC for feedback - set_harq_status(mac,dci->pucch_resource_indicator, - dci->harq_pid, - dlsch_config_pdu_1_0->accumulated_delta_PUCCH, - 1+dci->pdsch_to_harq_feedback_timing_indicator.val, - dci->dai[0].val, - dci_ind->n_CCE,dci_ind->N_CCE, - frame,slot); - LOG_D(MAC,"(nr_ue_procedures.c) rnti = %x dl_config->number_pdus = %d\n", - dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.rnti, - dl_config->number_pdus); - LOG_D(MAC,"(nr_ue_procedures.c) frequency_domain_resource_assignment=%d \t number_rbs=%d \t start_rb=%d\n", - dci->frequency_domain_assignment.val, - dlsch_config_pdu_1_0->number_rbs, - dlsch_config_pdu_1_0->start_rb); - LOG_D(MAC,"(nr_ue_procedures.c) time_domain_resource_assignment=%d \t number_symbols=%d \t start_symbol=%d\n", - dci->time_domain_assignment.val, - dlsch_config_pdu_1_0->number_symbols, - dlsch_config_pdu_1_0->start_symbol); - LOG_D(MAC, - "(nr_ue_procedures.c) vrb_to_prb_mapping=%d \n>>> mcs=%d\n>>> ndi=%d\n>>> rv=%d\n>>> harq_process_nbr=%d\n>>> dai=%d\n>>> scaling_factor_S=%f\n>>> tpc_pucch=%d\n>>> pucch_res_ind=%d\n>>> pdsch_to_harq_feedback_time_ind=%d\n", - dlsch_config_pdu_1_0->vrb_to_prb_mapping, - dlsch_config_pdu_1_0->mcs, - dlsch_config_pdu_1_0->ndi, - dlsch_config_pdu_1_0->rv, - dlsch_config_pdu_1_0->harq_process_nbr, - dci->dai[0].val, - dlsch_config_pdu_1_0->scaling_factor_S, - dlsch_config_pdu_1_0->accumulated_delta_PUCCH, - dci->pucch_resource_indicator, - 1+dci->pdsch_to_harq_feedback_timing_indicator.val); - // dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP = n_RB_DLBWP; - LOG_D(MAC,"(nr_ue_procedures.c) pdu_type=%d\n\n",dl_config->dl_config_list[dl_config->number_pdus].pdu_type); - dl_config->number_pdus = dl_config->number_pdus + 1; - break; - } - - case NR_DL_DCI_FORMAT_1_1: { - /* - * with CRC scrambled by C-RNTI or CS-RNTI or new-RNTI - * 0 IDENTIFIER_DCI_FORMATS: - * 1 CARRIER_IND: - * 7 BANDWIDTH_PART_IND: - * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: - * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 - * 14 PRB_BUNDLING_SIZE_IND: - * 15 RATE_MATCHING_IND: - * 16 ZP_CSI_RS_TRIGGER: - * 18 TB1_MCS: - * 19 TB1_NDI: - * 20 TB1_RV: - * 21 TB2_MCS: - * 22 TB2_NDI: - * 23 TB2_RV: - * 27 HARQ_PROCESS_NUMBER: - * 28 DAI_: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI - * 33 TPC_PUCCH: - * 34 PUCCH_RESOURCE_IND: - * 35 PDSCH_TO_HARQ_FEEDBACK_TIME_IND: - * 38 ANTENNA_PORTS: - * 39 TCI: - * 40 SRS_REQUEST: - * 43 CBGTI: - * 44 CBGFI: - * 47 DMRS_SEQ_INI: - */ - if (dci->bwp_indicator.val != 1) { - LOG_W(MAC, "[%d.%d] bwp_indicator != 1! Possibly due to false DCI. Ignoring DCI!\n", frame, slot); - return -1; - } + nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu; - config_bwp_ue(mac, &dci->bwp_indicator.val, &dci_format); - NR_BWP_Id_t dl_bwp_id = mac->DL_BWP_Id; - NR_PDSCH_Config_t *pdsch_config=mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup; - dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH; - dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.rnti = rnti; - fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu_1_1 = &dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.dlsch_config_rel15; - dlsch_config_pdu_1_1->BWPSize = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - dlsch_config_pdu_1_1->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - dlsch_config_pdu_1_1->SubcarrierSpacing = mac->DLbwp[0]->bwp_Common->genericParameters.subcarrierSpacing; - - /* IDENTIFIER_DCI_FORMATS */ - /* CARRIER_IND */ - /* BANDWIDTH_PART_IND */ - // dlsch_config_pdu_1_1->bandwidth_part_ind = dci->bandwidth_part_ind; - /* FREQ_DOM_RESOURCE_ASSIGNMENT_DL */ - if (nr_ue_process_dci_freq_dom_resource_assignment(NULL,dlsch_config_pdu_1_1,0,n_RB_DLBWP,dci->frequency_domain_assignment.val) < 0) { - LOG_W(MAC, "[%d.%d] Invalid frequency_domain_assignment. Possibly due to false DCI. Ignoring DCI!\n", frame, slot); - return -1; - } + fill_ul_config(ul_config, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH); - /* TIME_DOM_RESOURCE_ASSIGNMENT */ - if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_1,dci->time_domain_assignment.val,0,false) < 0) { - LOG_W(MAC, "[%d.%d] Invalid time_domain_assignment. Possibly due to false DCI. Ignoring DCI!\n", frame, slot); - return -1; - } + // Config PUSCH PDU + ret = nr_config_pusch_pdu(mac, pusch_config_pdu, dci, NULL, rnti, &dci_format); - NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList = NULL; - - if (mac->DLbwp[0] && - mac->DLbwp[0]->bwp_Dedicated && - mac->DLbwp[0]->bwp_Dedicated->pdsch_Config && - mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList) - pdsch_TimeDomainAllocationList = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList->choice.setup; - else if (mac->DLbwp[0] && mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList) - pdsch_TimeDomainAllocationList = mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - else if (mac->scc_SIB && mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon->choice.setup) - pdsch_TimeDomainAllocationList = mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - - int mappingtype = pdsch_TimeDomainAllocationList ? pdsch_TimeDomainAllocationList->list.array[dci->time_domain_assignment.val]->mappingType : ((dlsch_config_pdu_1_1->start_symbol <= 3)? typeA: typeB); - /* dmrs symbol positions*/ - dlsch_config_pdu_1_1->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config, - mac->scc->dmrs_TypeA_Position, - dlsch_config_pdu_1_1->number_symbols, - dlsch_config_pdu_1_1->start_symbol, - mappingtype); - dlsch_config_pdu_1_1->dmrsConfigType = mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? NFAPI_NR_DMRS_TYPE1 : - NFAPI_NR_DMRS_TYPE2; - /* TODO: fix number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214, - using tables 7.3.1.2.2-1, 7.3.1.2.2-2, 7.3.1.2.2-3, 7.3.1.2.2-4 of 3GPP TS 38.212 */ - dlsch_config_pdu_1_1->n_dmrs_cdm_groups = 1; - - /* VRB_TO_PRB_MAPPING */ - if ((pdsch_config->resourceAllocation == 1) && (pdsch_config->vrb_ToPRB_Interleaver != NULL)) - dlsch_config_pdu_1_1->vrb_to_prb_mapping = (dci->vrb_to_prb_mapping.val == 0) ? vrb_to_prb_mapping_non_interleaved:vrb_to_prb_mapping_interleaved; - - /* PRB_BUNDLING_SIZE_IND */ - dlsch_config_pdu_1_1->prb_bundling_size_ind = dci->prb_bundling_size_indicator.val; - /* RATE_MATCHING_IND */ - dlsch_config_pdu_1_1->rate_matching_ind = dci->rate_matching_indicator.val; - /* ZP_CSI_RS_TRIGGER */ - dlsch_config_pdu_1_1->zp_csi_rs_trigger = dci->zp_csi_rs_trigger.val; - /* MCS (for transport block 1)*/ - dlsch_config_pdu_1_1->mcs = dci->mcs; - - // Basic sanity check for MCS value to check for a false or erroneous DCI - if (dlsch_config_pdu_1_1->mcs > 28) { - LOG_W(MAC, "[%d.%d] MCS value %d out of bounds! Possibly due to false DCI. Ignoring DCI!\n", frame, slot, dlsch_config_pdu_1_1->mcs); - return -1; - } + } + break; + } - /* NDI (for transport block 1)*/ - dlsch_config_pdu_1_1->ndi = dci->ndi; - /* RV (for transport block 1)*/ - dlsch_config_pdu_1_1->rv = dci->rv; - /* MCS (for transport block 2)*/ - dlsch_config_pdu_1_1->tb2_mcs = dci->mcs2.val; + case NR_DL_DCI_FORMAT_1_0: { + /* + * with CRC scrambled by C-RNTI or CS-RNTI or new-RNTI + * 0 IDENTIFIER_DCI_FORMATS: + * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: + * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, + * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 + * 24 MCS: + * 25 NDI: + * 26 RV: + * 27 HARQ_PROCESS_NUMBER: + * 28 DAI_: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI + * 33 TPC_PUCCH: + * 34 PUCCH_RESOURCE_IND: + * 35 PDSCH_TO_HARQ_FEEDBACK_TIME_IND: + * 55 RESERVED_NR_DCI + * with CRC scrambled by P-RNTI + * 8 SHORT_MESSAGE_IND + * 9 SHORT_MESSAGES + * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: + * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, + * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 + * 24 MCS: + * 31 TB_SCALING + * 55 RESERVED_NR_DCI + * with CRC scrambled by SI-RNTI + * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: + * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, + * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 + * 24 MCS: + * 26 RV: + * 55 RESERVED_NR_DCI + * with CRC scrambled by RA-RNTI + * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: + * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, + * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 + * 24 MCS: + * 31 TB_SCALING + * 55 RESERVED_NR_DCI + * with CRC scrambled by TC-RNTI + * 0 IDENTIFIER_DCI_FORMATS: + * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: + * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, + * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 + * 24 MCS: + * 25 NDI: + * 26 RV: + * 27 HARQ_PROCESS_NUMBER: + * 28 DAI_: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI + * 33 TPC_PUCCH: + */ - // Basic sanity check for MCS value to check for a false or erroneous DCI - if (dlsch_config_pdu_1_1->tb2_mcs > 28) { - LOG_W(MAC, "[%d.%d] MCS value %d out of bounds! Possibly due to false DCI. Ignoring DCI!\n", frame, slot, dlsch_config_pdu_1_1->tb2_mcs); - return -1; + dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.rnti = rnti; + fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu_1_0 = &dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.dlsch_config_rel15; + + NR_PDSCH_Config_t *pdsch_config= (mac->DLbwp[0]) ? mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup : NULL; + uint16_t BWPSize = n_RB_DLBWP; + + if(rnti == SI_RNTI) { + NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config = mac->type0_PDCCH_CSS_config; + default_abc = type0_PDCCH_CSS_config.type0_pdcch_ss_mux_pattern; + dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH; + dlsch_config_pdu_1_0->BWPSize = mac->type0_PDCCH_CSS_config.num_rbs; + dlsch_config_pdu_1_0->BWPStart = mac->type0_PDCCH_CSS_config.cset_start_rb; + dlsch_config_pdu_1_0->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon; + if (pdsch_config) pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NULL; // For PDSCH with mapping type A, the UE shall assume dmrs-AdditionalPosition='pos2' + BWPSize = dlsch_config_pdu_1_0->BWPSize; + } else { + if (ra->RA_window_cnt >= 0 && rnti == ra->ra_rnti){ + dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH; + } else { + dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH; } + if( (ra->RA_window_cnt >= 0 && rnti == ra->ra_rnti) || (rnti == ra->t_crnti) ) { + if (mac->scc == NULL) { + dlsch_config_pdu_1_0->BWPSize = NRRIV2BW(mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + } + else { + dlsch_config_pdu_1_0->BWPSize = NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + } + if (!get_softmodem_params()->sa) { // NSA mode is not using the Initial BWP + dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + pdsch_config = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup; + BWPSize = dlsch_config_pdu_1_0->BWPSize; + } + } else if (mac->DLbwp[0]) { + dlsch_config_pdu_1_0->BWPSize = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + dlsch_config_pdu_1_0->SubcarrierSpacing = mac->DLbwp[0]->bwp_Common->genericParameters.subcarrierSpacing; + pdsch_config = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup; + } else if (mac->scc_SIB) { + dlsch_config_pdu_1_0->BWPSize = NRRIV2BW(mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + dlsch_config_pdu_1_0->SubcarrierSpacing = mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.subcarrierSpacing; + pdsch_config = NULL; + } + } - /* NDI (for transport block 2)*/ - dlsch_config_pdu_1_1->tb2_ndi = dci->ndi2.val; - /* RV (for transport block 2)*/ - dlsch_config_pdu_1_1->tb2_rv = dci->rv2.val; - /* HARQ_PROCESS_NUMBER */ - dlsch_config_pdu_1_1->harq_process_nbr = dci->harq_pid; - - /* TPC_PUCCH */ - // according to TS 38.213 Table 7.2.1-1 - if (dci->tpc == 0) dlsch_config_pdu_1_1->accumulated_delta_PUCCH = -1; - - if (dci->tpc == 1) dlsch_config_pdu_1_1->accumulated_delta_PUCCH = 0; - - if (dci->tpc == 2) dlsch_config_pdu_1_1->accumulated_delta_PUCCH = 1; + /* IDENTIFIER_DCI_FORMATS */ + /* FREQ_DOM_RESOURCE_ASSIGNMENT_DL */ + if (nr_ue_process_dci_freq_dom_resource_assignment(NULL,dlsch_config_pdu_1_0,0,BWPSize,dci->frequency_domain_assignment.val) < 0) { + LOG_W(MAC, "[%d.%d] Invalid frequency_domain_assignment. Possibly due to false DCI. Ignoring DCI!\n", frame, slot); + return -1; + } + /* TIME_DOM_RESOURCE_ASSIGNMENT */ + if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_0,dci->time_domain_assignment.val,default_abc,rnti==SI_RNTI) < 0) { + LOG_W(MAC, "[%d.%d] Invalid time_domain_assignment. Possibly due to false DCI. Ignoring DCI!\n", frame, slot); + return -1; + } - if (dci->tpc == 3) dlsch_config_pdu_1_1->accumulated_delta_PUCCH = 3; + NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList = NULL; + if (mac->DLbwp[0] && + mac->DLbwp[0]->bwp_Dedicated && + mac->DLbwp[0]->bwp_Dedicated->pdsch_Config && + mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList) + pdsch_TimeDomainAllocationList = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList->choice.setup; + else if (mac->DLbwp[0] && mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList) + pdsch_TimeDomainAllocationList = mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; + else if (mac->scc_SIB && mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon->choice.setup) + pdsch_TimeDomainAllocationList = mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - // Sanity check for pucch_resource_indicator value received to check for false DCI. - valid = 0; + int mappingtype = pdsch_TimeDomainAllocationList ? pdsch_TimeDomainAllocationList->list.array[dci->time_domain_assignment.val]->mappingType : ((dlsch_config_pdu_1_0->start_symbol <= 3)? typeA: typeB); + + /* dmrs symbol positions*/ + dlsch_config_pdu_1_0->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config, + mac->mib->dmrs_TypeA_Position, + dlsch_config_pdu_1_0->number_symbols, + dlsch_config_pdu_1_0->start_symbol, + mappingtype); + dlsch_config_pdu_1_0->dmrsConfigType = (mac->DLbwp[0] != NULL) ? + (mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1) : 0; + /* number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214 version 15.9.0 Release 15 */ + if (dlsch_config_pdu_1_0->number_symbols == 2) + dlsch_config_pdu_1_0->n_dmrs_cdm_groups = 1; + else + dlsch_config_pdu_1_0->n_dmrs_cdm_groups = 2; + /* VRB_TO_PRB_MAPPING */ + dlsch_config_pdu_1_0->vrb_to_prb_mapping = (dci->vrb_to_prb_mapping.val == 0) ? vrb_to_prb_mapping_non_interleaved:vrb_to_prb_mapping_interleaved; + /* MCS TABLE INDEX */ + dlsch_config_pdu_1_0->mcs_table = (pdsch_config) ? ((pdsch_config->mcs_Table) ? (*pdsch_config->mcs_Table + 1) : 0) : 0; + /* MCS */ + dlsch_config_pdu_1_0->mcs = dci->mcs; + // Basic sanity check for MCS value to check for a false or erroneous DCI + if (dlsch_config_pdu_1_0->mcs > 28) { + LOG_W(MAC, "[%d.%d] MCS value %d out of bounds! Possibly due to false DCI. Ignoring DCI!\n", frame, slot, dlsch_config_pdu_1_0->mcs); + return -1; + } + /* NDI (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI)*/ + dlsch_config_pdu_1_0->ndi = dci->ndi; + /* RV (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI)*/ + dlsch_config_pdu_1_0->rv = dci->rv; + /* HARQ_PROCESS_NUMBER (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI)*/ + dlsch_config_pdu_1_0->harq_process_nbr = dci->harq_pid; + /* TB_SCALING (only if CRC scrambled by P-RNTI or RA-RNTI) */ + // according to TS 38.214 Table 5.1.3.2-3 + if (dci->tb_scaling == 0) dlsch_config_pdu_1_0->scaling_factor_S = 1; + if (dci->tb_scaling == 1) dlsch_config_pdu_1_0->scaling_factor_S = 0.5; + if (dci->tb_scaling == 2) dlsch_config_pdu_1_0->scaling_factor_S = 0.25; + if (dci->tb_scaling == 3) dlsch_config_pdu_1_0->scaling_factor_S = 0; // value not defined in table + /* TPC_PUCCH (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI)*/ + // according to TS 38.213 Table 7.2.1-1 + if (dci->tpc == 0) dlsch_config_pdu_1_0->accumulated_delta_PUCCH = -1; + if (dci->tpc == 1) dlsch_config_pdu_1_0->accumulated_delta_PUCCH = 0; + if (dci->tpc == 2) dlsch_config_pdu_1_0->accumulated_delta_PUCCH = 1; + if (dci->tpc == 3) dlsch_config_pdu_1_0->accumulated_delta_PUCCH = 3; + // Sanity check for pucch_resource_indicator value received to check for false DCI. + valid = 0; + if (mac->ULbwp[0] && + mac->ULbwp[0]->bwp_Dedicated && + mac->ULbwp[0]->bwp_Dedicated->pucch_Config && + mac->ULbwp[0]->bwp_Dedicated->pucch_Config->choice.setup&& + mac->ULbwp[0]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList) { pucch_res_set_cnt = mac->ULbwp[0]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.count; - for (int id = 0; id < pucch_res_set_cnt; id++) { - if (dci->pucch_resource_indicator < mac->ULbwp[0]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[id]->resourceList.list.count) { + if (dci->pucch_resource_indicator < mac->ULbwp[0]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[id]->resourceList.list.count) { + valid = 1; + break; + } + } + } + else if (mac->cg && + mac->cg->spCellConfig && + mac->cg->spCellConfig->spCellConfigDedicated && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup->resourceSetToAddModList){ + pucch_res_set_cnt = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup->resourceSetToAddModList->list.count; + for (int id = 0; id < pucch_res_set_cnt; id++) { + if (dci->pucch_resource_indicator < mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup->resourceSetToAddModList->list.array[id]->resourceList.list.count) { valid = 1; break; } } + } else valid=1; + if (!valid) { + LOG_W(MAC, "[%d.%d] pucch_resource_indicator value %d is out of bounds. Possibly due to false DCI. Ignoring DCI!\n", frame, slot, dci->pucch_resource_indicator); + return -1; + } - if (!valid) { - LOG_W(MAC, "[%d.%d] pucch_resource_indicator value %d is out of bounds. Possibly due to false DCI. Ignoring DCI!\n", frame, slot, dci->pucch_resource_indicator); - return -1; - } + // set the harq status at MAC for feedback + set_harq_status(mac,dci->pucch_resource_indicator, + dci->harq_pid, + dlsch_config_pdu_1_0->accumulated_delta_PUCCH, + 1+dci->pdsch_to_harq_feedback_timing_indicator.val, + dci->dai[0].val, + dci_ind->n_CCE,dci_ind->N_CCE, + frame,slot); + + LOG_D(MAC,"(nr_ue_procedures.c) rnti = %x dl_config->number_pdus = %d\n", + dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.rnti, + dl_config->number_pdus); + LOG_D(MAC,"(nr_ue_procedures.c) frequency_domain_resource_assignment=%d \t number_rbs=%d \t start_rb=%d\n", + dci->frequency_domain_assignment.val, + dlsch_config_pdu_1_0->number_rbs, + dlsch_config_pdu_1_0->start_rb); + LOG_D(MAC,"(nr_ue_procedures.c) time_domain_resource_assignment=%d \t number_symbols=%d \t start_symbol=%d\n", + dci->time_domain_assignment.val, + dlsch_config_pdu_1_0->number_symbols, + dlsch_config_pdu_1_0->start_symbol); + LOG_D(MAC,"(nr_ue_procedures.c) vrb_to_prb_mapping=%d \n>>> mcs=%d\n>>> ndi=%d\n>>> rv=%d\n>>> harq_process_nbr=%d\n>>> dai=%d\n>>> scaling_factor_S=%f\n>>> tpc_pucch=%d\n>>> pucch_res_ind=%d\n>>> pdsch_to_harq_feedback_time_ind=%d\n", + dlsch_config_pdu_1_0->vrb_to_prb_mapping, + dlsch_config_pdu_1_0->mcs, + dlsch_config_pdu_1_0->ndi, + dlsch_config_pdu_1_0->rv, + dlsch_config_pdu_1_0->harq_process_nbr, + dci->dai[0].val, + dlsch_config_pdu_1_0->scaling_factor_S, + dlsch_config_pdu_1_0->accumulated_delta_PUCCH, + dci->pucch_resource_indicator, + 1+dci->pdsch_to_harq_feedback_timing_indicator.val); + + // dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP = n_RB_DLBWP; + + LOG_D(MAC,"(nr_ue_procedures.c) pdu_type=%d\n\n",dl_config->dl_config_list[dl_config->number_pdus].pdu_type); + + dl_config->number_pdus = dl_config->number_pdus + 1; + + break; + } - /* ANTENNA_PORTS */ - uint8_t n_codewords = 1; // FIXME!!! - long *max_length = NULL; - long *dmrs_type = NULL; + case NR_DL_DCI_FORMAT_1_1: { + /* + * with CRC scrambled by C-RNTI or CS-RNTI or new-RNTI + * 0 IDENTIFIER_DCI_FORMATS: + * 1 CARRIER_IND: + * 7 BANDWIDTH_PART_IND: + * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: + * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, + * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 + * 14 PRB_BUNDLING_SIZE_IND: + * 15 RATE_MATCHING_IND: + * 16 ZP_CSI_RS_TRIGGER: + * 18 TB1_MCS: + * 19 TB1_NDI: + * 20 TB1_RV: + * 21 TB2_MCS: + * 22 TB2_NDI: + * 23 TB2_RV: + * 27 HARQ_PROCESS_NUMBER: + * 28 DAI_: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI + * 33 TPC_PUCCH: + * 34 PUCCH_RESOURCE_IND: + * 35 PDSCH_TO_HARQ_FEEDBACK_TIME_IND: + * 38 ANTENNA_PORTS: + * 39 TCI: + * 40 SRS_REQUEST: + * 43 CBGTI: + * 44 CBGFI: + * 47 DMRS_SEQ_INI: + */ - if (pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA) { - max_length = pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->maxLength; - dmrs_type = pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type; - } + if (dci->bwp_indicator.val != 1) { + LOG_W(MAC, "[%d.%d] bwp_indicator != 1! Possibly due to false DCI. Ignoring DCI!\n", frame, slot); + return -1; + } + config_bwp_ue(mac, &dci->bwp_indicator.val, &dci_format); + NR_BWP_Id_t dl_bwp_id = mac->DL_BWP_Id; + NR_PDSCH_Config_t *pdsch_config=mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup; + + dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH; + dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.rnti = rnti; + + fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu_1_1 = &dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.dlsch_config_rel15; + + dlsch_config_pdu_1_1->BWPSize = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + dlsch_config_pdu_1_1->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + dlsch_config_pdu_1_1->SubcarrierSpacing = mac->DLbwp[0]->bwp_Common->genericParameters.subcarrierSpacing; + + /* IDENTIFIER_DCI_FORMATS */ + /* CARRIER_IND */ + /* BANDWIDTH_PART_IND */ + // dlsch_config_pdu_1_1->bandwidth_part_ind = dci->bandwidth_part_ind; + /* FREQ_DOM_RESOURCE_ASSIGNMENT_DL */ + if (nr_ue_process_dci_freq_dom_resource_assignment(NULL,dlsch_config_pdu_1_1,0,n_RB_DLBWP,dci->frequency_domain_assignment.val) < 0) { + LOG_W(MAC, "[%d.%d] Invalid frequency_domain_assignment. Possibly due to false DCI. Ignoring DCI!\n", frame, slot); + return -1; + } + /* TIME_DOM_RESOURCE_ASSIGNMENT */ + if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_1,dci->time_domain_assignment.val,0,false) < 0) { + LOG_W(MAC, "[%d.%d] Invalid time_domain_assignment. Possibly due to false DCI. Ignoring DCI!\n", frame, slot); + return -1; + } - if (pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeB) { - max_length = pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->maxLength; - dmrs_type = pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type; - } + NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList = NULL; + if (mac->DLbwp[0] && + mac->DLbwp[0]->bwp_Dedicated && + mac->DLbwp[0]->bwp_Dedicated->pdsch_Config && + mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList) + pdsch_TimeDomainAllocationList = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList->choice.setup; + else if (mac->DLbwp[0] && mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList) + pdsch_TimeDomainAllocationList = mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; + else if (mac->scc_SIB && mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon->choice.setup) + pdsch_TimeDomainAllocationList = mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - if ((dmrs_type == NULL) && (max_length == NULL)) { - // Table 7.3.1.2.2-1: Antenna port(s) (1000 + DMRS port), dmrs-Type=1, maxLength=1 - dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_1[dci->antenna_ports.val][0]; - dlsch_config_pdu_1_1->dmrs_ports[0] = table_7_3_2_3_3_1[dci->antenna_ports.val][1]; - dlsch_config_pdu_1_1->dmrs_ports[1] = table_7_3_2_3_3_1[dci->antenna_ports.val][2]; - dlsch_config_pdu_1_1->dmrs_ports[2] = table_7_3_2_3_3_1[dci->antenna_ports.val][3]; - dlsch_config_pdu_1_1->dmrs_ports[3] = table_7_3_2_3_3_1[dci->antenna_ports.val][4]; + int mappingtype = pdsch_TimeDomainAllocationList ? pdsch_TimeDomainAllocationList->list.array[dci->time_domain_assignment.val]->mappingType : ((dlsch_config_pdu_1_1->start_symbol <= 3)? typeA: typeB); + + /* dmrs symbol positions*/ + dlsch_config_pdu_1_1->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config, + mac->scc->dmrs_TypeA_Position, + dlsch_config_pdu_1_1->number_symbols, + dlsch_config_pdu_1_1->start_symbol, + mappingtype); + + dlsch_config_pdu_1_1->dmrsConfigType = mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? NFAPI_NR_DMRS_TYPE1 : NFAPI_NR_DMRS_TYPE2; + + /* TODO: fix number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214, + using tables 7.3.1.2.2-1, 7.3.1.2.2-2, 7.3.1.2.2-3, 7.3.1.2.2-4 of 3GPP TS 38.212 */ + dlsch_config_pdu_1_1->n_dmrs_cdm_groups = 1; + /* VRB_TO_PRB_MAPPING */ + if ((pdsch_config->resourceAllocation == 1) && (pdsch_config->vrb_ToPRB_Interleaver != NULL)) + dlsch_config_pdu_1_1->vrb_to_prb_mapping = (dci->vrb_to_prb_mapping.val == 0) ? vrb_to_prb_mapping_non_interleaved:vrb_to_prb_mapping_interleaved; + /* PRB_BUNDLING_SIZE_IND */ + dlsch_config_pdu_1_1->prb_bundling_size_ind = dci->prb_bundling_size_indicator.val; + /* RATE_MATCHING_IND */ + dlsch_config_pdu_1_1->rate_matching_ind = dci->rate_matching_indicator.val; + /* ZP_CSI_RS_TRIGGER */ + dlsch_config_pdu_1_1->zp_csi_rs_trigger = dci->zp_csi_rs_trigger.val; + /* MCS (for transport block 1)*/ + dlsch_config_pdu_1_1->mcs = dci->mcs; + // Basic sanity check for MCS value to check for a false or erroneous DCI + if (dlsch_config_pdu_1_1->mcs > 28) { + LOG_W(MAC, "[%d.%d] MCS value %d out of bounds! Possibly due to false DCI. Ignoring DCI!\n", frame, slot, dlsch_config_pdu_1_1->mcs); + return -1; + } + /* NDI (for transport block 1)*/ + dlsch_config_pdu_1_1->ndi = dci->ndi; + /* RV (for transport block 1)*/ + dlsch_config_pdu_1_1->rv = dci->rv; + /* MCS (for transport block 2)*/ + dlsch_config_pdu_1_1->tb2_mcs = dci->mcs2.val; + // Basic sanity check for MCS value to check for a false or erroneous DCI + if (dlsch_config_pdu_1_1->tb2_mcs > 28) { + LOG_W(MAC, "[%d.%d] MCS value %d out of bounds! Possibly due to false DCI. Ignoring DCI!\n", frame, slot, dlsch_config_pdu_1_1->tb2_mcs); + return -1; + } + /* NDI (for transport block 2)*/ + dlsch_config_pdu_1_1->tb2_ndi = dci->ndi2.val; + /* RV (for transport block 2)*/ + dlsch_config_pdu_1_1->tb2_rv = dci->rv2.val; + /* HARQ_PROCESS_NUMBER */ + dlsch_config_pdu_1_1->harq_process_nbr = dci->harq_pid; + /* TPC_PUCCH */ + // according to TS 38.213 Table 7.2.1-1 + if (dci->tpc == 0) dlsch_config_pdu_1_1->accumulated_delta_PUCCH = -1; + if (dci->tpc == 1) dlsch_config_pdu_1_1->accumulated_delta_PUCCH = 0; + if (dci->tpc == 2) dlsch_config_pdu_1_1->accumulated_delta_PUCCH = 1; + if (dci->tpc == 3) dlsch_config_pdu_1_1->accumulated_delta_PUCCH = 3; + + // Sanity check for pucch_resource_indicator value received to check for false DCI. + valid = 0; + pucch_res_set_cnt = mac->ULbwp[0]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.count; + for (int id = 0; id < pucch_res_set_cnt; id++) { + if (dci->pucch_resource_indicator < mac->ULbwp[0]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[id]->resourceList.list.count) { + valid = 1; + break; } + } + if (!valid) { + LOG_W(MAC, "[%d.%d] pucch_resource_indicator value %d is out of bounds. Possibly due to false DCI. Ignoring DCI!\n", frame, slot, dci->pucch_resource_indicator); + return -1; + } - if ((dmrs_type == NULL) && (max_length != NULL)) { - // Table 7.3.1.2.2-2: Antenna port(s) (1000 + DMRS port), dmrs-Type=1, maxLength=2 - if (n_codewords == 1) { - dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_2_oneCodeword[dci->antenna_ports.val][0]; - dlsch_config_pdu_1_1->dmrs_ports[0] = table_7_3_2_3_3_2_oneCodeword[dci->antenna_ports.val][1]; - dlsch_config_pdu_1_1->dmrs_ports[1] = table_7_3_2_3_3_2_oneCodeword[dci->antenna_ports.val][2]; - dlsch_config_pdu_1_1->dmrs_ports[2] = table_7_3_2_3_3_2_oneCodeword[dci->antenna_ports.val][3]; - dlsch_config_pdu_1_1->dmrs_ports[3] = table_7_3_2_3_3_2_oneCodeword[dci->antenna_ports.val][4]; - dlsch_config_pdu_1_1->n_front_load_symb = table_7_3_2_3_3_2_oneCodeword[dci->antenna_ports.val][5]; - } - - if (n_codewords == 2) { - dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][0]; - dlsch_config_pdu_1_1->dmrs_ports[0] = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][1]; - dlsch_config_pdu_1_1->dmrs_ports[1] = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][2]; - dlsch_config_pdu_1_1->dmrs_ports[2] = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][3]; - dlsch_config_pdu_1_1->dmrs_ports[3] = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][4]; - dlsch_config_pdu_1_1->dmrs_ports[4] = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][5]; - dlsch_config_pdu_1_1->dmrs_ports[5] = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][6]; - dlsch_config_pdu_1_1->dmrs_ports[6] = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][7]; - dlsch_config_pdu_1_1->dmrs_ports[7] = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][8]; - dlsch_config_pdu_1_1->n_front_load_symb = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][9]; - } + /* ANTENNA_PORTS */ + uint8_t n_codewords = 1; // FIXME!!! + long *max_length = NULL; + long *dmrs_type = NULL; + if (pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA) { + max_length = pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->maxLength; + dmrs_type = pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type; + } + if (pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeB) { + max_length = pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->maxLength; + dmrs_type = pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type; + } + if ((dmrs_type == NULL) && (max_length == NULL)){ + // Table 7.3.1.2.2-1: Antenna port(s) (1000 + DMRS port), dmrs-Type=1, maxLength=1 + dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_1[dci->antenna_ports.val][0]; + dlsch_config_pdu_1_1->dmrs_ports[0] = table_7_3_2_3_3_1[dci->antenna_ports.val][1]; + dlsch_config_pdu_1_1->dmrs_ports[1] = table_7_3_2_3_3_1[dci->antenna_ports.val][2]; + dlsch_config_pdu_1_1->dmrs_ports[2] = table_7_3_2_3_3_1[dci->antenna_ports.val][3]; + dlsch_config_pdu_1_1->dmrs_ports[3] = table_7_3_2_3_3_1[dci->antenna_ports.val][4]; + } + if ((dmrs_type == NULL) && (max_length != NULL)){ + // Table 7.3.1.2.2-2: Antenna port(s) (1000 + DMRS port), dmrs-Type=1, maxLength=2 + if (n_codewords == 1) { + dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_2_oneCodeword[dci->antenna_ports.val][0]; + dlsch_config_pdu_1_1->dmrs_ports[0] = table_7_3_2_3_3_2_oneCodeword[dci->antenna_ports.val][1]; + dlsch_config_pdu_1_1->dmrs_ports[1] = table_7_3_2_3_3_2_oneCodeword[dci->antenna_ports.val][2]; + dlsch_config_pdu_1_1->dmrs_ports[2] = table_7_3_2_3_3_2_oneCodeword[dci->antenna_ports.val][3]; + dlsch_config_pdu_1_1->dmrs_ports[3] = table_7_3_2_3_3_2_oneCodeword[dci->antenna_ports.val][4]; + dlsch_config_pdu_1_1->n_front_load_symb = table_7_3_2_3_3_2_oneCodeword[dci->antenna_ports.val][5]; } - - if ((dmrs_type != NULL) && (max_length == NULL)) { - // Table 7.3.1.2.2-3: Antenna port(s) (1000 + DMRS port), dmrs-Type=2, maxLength=1 - if (n_codewords == 1) { - dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_3_oneCodeword[dci->antenna_ports.val][0]; - dlsch_config_pdu_1_1->dmrs_ports[0] = table_7_3_2_3_3_3_oneCodeword[dci->antenna_ports.val][1]; - dlsch_config_pdu_1_1->dmrs_ports[1] = table_7_3_2_3_3_3_oneCodeword[dci->antenna_ports.val][2]; - dlsch_config_pdu_1_1->dmrs_ports[2] = table_7_3_2_3_3_3_oneCodeword[dci->antenna_ports.val][3]; - dlsch_config_pdu_1_1->dmrs_ports[3] = table_7_3_2_3_3_3_oneCodeword[dci->antenna_ports.val][4]; - } - - if (n_codewords == 2) { - dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][0]; - dlsch_config_pdu_1_1->dmrs_ports[0] = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][1]; - dlsch_config_pdu_1_1->dmrs_ports[1] = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][2]; - dlsch_config_pdu_1_1->dmrs_ports[2] = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][3]; - dlsch_config_pdu_1_1->dmrs_ports[3] = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][4]; - dlsch_config_pdu_1_1->dmrs_ports[4] = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][5]; - dlsch_config_pdu_1_1->dmrs_ports[5] = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][6]; - } + if (n_codewords == 2) { + dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][0]; + dlsch_config_pdu_1_1->dmrs_ports[0] = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][1]; + dlsch_config_pdu_1_1->dmrs_ports[1] = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][2]; + dlsch_config_pdu_1_1->dmrs_ports[2] = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][3]; + dlsch_config_pdu_1_1->dmrs_ports[3] = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][4]; + dlsch_config_pdu_1_1->dmrs_ports[4] = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][5]; + dlsch_config_pdu_1_1->dmrs_ports[5] = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][6]; + dlsch_config_pdu_1_1->dmrs_ports[6] = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][7]; + dlsch_config_pdu_1_1->dmrs_ports[7] = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][8]; + dlsch_config_pdu_1_1->n_front_load_symb = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][9]; } - - if ((dmrs_type != NULL) && (max_length != NULL)) { - // Table 7.3.1.2.2-4: Antenna port(s) (1000 + DMRS port), dmrs-Type=2, maxLength=2 - if (n_codewords == 1) { - dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_4_oneCodeword[dci->antenna_ports.val][0]; - dlsch_config_pdu_1_1->dmrs_ports[0] = table_7_3_2_3_3_4_oneCodeword[dci->antenna_ports.val][1]; - dlsch_config_pdu_1_1->dmrs_ports[1] = table_7_3_2_3_3_4_oneCodeword[dci->antenna_ports.val][2]; - dlsch_config_pdu_1_1->dmrs_ports[2] = table_7_3_2_3_3_4_oneCodeword[dci->antenna_ports.val][3]; - dlsch_config_pdu_1_1->dmrs_ports[3] = table_7_3_2_3_3_4_oneCodeword[dci->antenna_ports.val][4]; - dlsch_config_pdu_1_1->n_front_load_symb = table_7_3_2_3_3_4_oneCodeword[dci->antenna_ports.val][5]; - } - - if (n_codewords == 2) { - dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][0]; - dlsch_config_pdu_1_1->dmrs_ports[0] = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][1]; - dlsch_config_pdu_1_1->dmrs_ports[1] = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][2]; - dlsch_config_pdu_1_1->dmrs_ports[2] = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][3]; - dlsch_config_pdu_1_1->dmrs_ports[3] = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][4]; - dlsch_config_pdu_1_1->dmrs_ports[4] = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][5]; - dlsch_config_pdu_1_1->dmrs_ports[5] = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][6]; - dlsch_config_pdu_1_1->dmrs_ports[6] = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][7]; - dlsch_config_pdu_1_1->dmrs_ports[7] = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][8]; - dlsch_config_pdu_1_1->n_front_load_symb = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][9]; - } + } + if ((dmrs_type != NULL) && (max_length == NULL)){ + // Table 7.3.1.2.2-3: Antenna port(s) (1000 + DMRS port), dmrs-Type=2, maxLength=1 + if (n_codewords == 1) { + dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_3_oneCodeword[dci->antenna_ports.val][0]; + dlsch_config_pdu_1_1->dmrs_ports[0] = table_7_3_2_3_3_3_oneCodeword[dci->antenna_ports.val][1]; + dlsch_config_pdu_1_1->dmrs_ports[1] = table_7_3_2_3_3_3_oneCodeword[dci->antenna_ports.val][2]; + dlsch_config_pdu_1_1->dmrs_ports[2] = table_7_3_2_3_3_3_oneCodeword[dci->antenna_ports.val][3]; + dlsch_config_pdu_1_1->dmrs_ports[3] = table_7_3_2_3_3_3_oneCodeword[dci->antenna_ports.val][4]; } - - /* TCI */ - if (mac->dl_config_request.dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.tci_present_in_dci == 1) { - // 0 bit if higher layer parameter tci-PresentInDCI is not enabled - // otherwise 3 bits as defined in Subclause 5.1.5 of [6, TS38.214] - dlsch_config_pdu_1_1->tci_state = dci->transmission_configuration_indication.val; + if (n_codewords == 2) { + dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][0]; + dlsch_config_pdu_1_1->dmrs_ports[0] = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][1]; + dlsch_config_pdu_1_1->dmrs_ports[1] = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][2]; + dlsch_config_pdu_1_1->dmrs_ports[2] = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][3]; + dlsch_config_pdu_1_1->dmrs_ports[3] = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][4]; + dlsch_config_pdu_1_1->dmrs_ports[4] = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][5]; + dlsch_config_pdu_1_1->dmrs_ports[5] = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][6]; } - - /* SRS_REQUEST */ - // if SUL is supported in the cell, there is an additional bit in this field and the value of this bit represents table 7.1.1.1-1 TS 38.212 FIXME!!! - dlsch_config_pdu_1_1->srs_config.aperiodicSRS_ResourceTrigger = (dci->srs_request.val & 0x11); // as per Table 7.3.1.1.2-24 TS 38.212 - /* CBGTI */ - dlsch_config_pdu_1_1->cbgti = dci->cbgti.val; - /* CBGFI */ - dlsch_config_pdu_1_1->codeBlockGroupFlushIndicator = dci->cbgfi.val; - /* DMRS_SEQ_INI */ - //FIXME!!! - // dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP = n_RB_DLBWP; - /* PDSCH_TO_HARQ_FEEDBACK_TIME_IND */ - // according to TS 38.213 Table 9.2.3-1 - NR_BWP_Id_t ul_bwp_id = mac->UL_BWP_Id; - uint8_t feedback_ti = - mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->dl_DataToUL_ACK->list.array[dci->pdsch_to_harq_feedback_timing_indicator.val][0]; - // set the harq status at MAC for feedback - set_harq_status(mac,dci->pucch_resource_indicator, - dci->harq_pid, - dlsch_config_pdu_1_1->accumulated_delta_PUCCH, - feedback_ti, - dci->dai[0].val, - dci_ind->n_CCE,dci_ind->N_CCE, - frame,slot); - dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH; - LOG_D(MAC,"(nr_ue_procedures.c) pdu_type=%d\n\n",dl_config->dl_config_list[dl_config->number_pdus].pdu_type); - dl_config->number_pdus = dl_config->number_pdus + 1; - /* TODO same calculation for MCS table as done in UL */ - dlsch_config_pdu_1_1->mcs_table = (pdsch_config->mcs_Table) ? (*pdsch_config->mcs_Table + 1) : 0; - - /*PTRS configuration */ - if(mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS != NULL) { - valid_ptrs_setup = set_dl_ptrs_values(mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup, - dlsch_config_pdu_1_1->number_rbs, dlsch_config_pdu_1_1->mcs, dlsch_config_pdu_1_1->mcs_table, - &dlsch_config_pdu_1_1->PTRSFreqDensity,&dlsch_config_pdu_1_1->PTRSTimeDensity, - &dlsch_config_pdu_1_1->PTRSPortIndex,&dlsch_config_pdu_1_1->nEpreRatioOfPDSCHToPTRS, - &dlsch_config_pdu_1_1->PTRSReOffset, dlsch_config_pdu_1_1->number_symbols); - - if(valid_ptrs_setup==true) { - dlsch_config_pdu_1_1->pduBitmap |= 0x1; - LOG_D(MAC, "DL PTRS values: PTRS time den: %d, PTRS freq den: %d\n", dlsch_config_pdu_1_1->PTRSTimeDensity, dlsch_config_pdu_1_1->PTRSFreqDensity); - } + } + if ((dmrs_type != NULL) && (max_length != NULL)){ + // Table 7.3.1.2.2-4: Antenna port(s) (1000 + DMRS port), dmrs-Type=2, maxLength=2 + if (n_codewords == 1) { + dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_4_oneCodeword[dci->antenna_ports.val][0]; + dlsch_config_pdu_1_1->dmrs_ports[0] = table_7_3_2_3_3_4_oneCodeword[dci->antenna_ports.val][1]; + dlsch_config_pdu_1_1->dmrs_ports[1] = table_7_3_2_3_3_4_oneCodeword[dci->antenna_ports.val][2]; + dlsch_config_pdu_1_1->dmrs_ports[2] = table_7_3_2_3_3_4_oneCodeword[dci->antenna_ports.val][3]; + dlsch_config_pdu_1_1->dmrs_ports[3] = table_7_3_2_3_3_4_oneCodeword[dci->antenna_ports.val][4]; + dlsch_config_pdu_1_1->n_front_load_symb = table_7_3_2_3_3_4_oneCodeword[dci->antenna_ports.val][5]; + } + if (n_codewords == 2) { + dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][0]; + dlsch_config_pdu_1_1->dmrs_ports[0] = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][1]; + dlsch_config_pdu_1_1->dmrs_ports[1] = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][2]; + dlsch_config_pdu_1_1->dmrs_ports[2] = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][3]; + dlsch_config_pdu_1_1->dmrs_ports[3] = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][4]; + dlsch_config_pdu_1_1->dmrs_ports[4] = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][5]; + dlsch_config_pdu_1_1->dmrs_ports[5] = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][6]; + dlsch_config_pdu_1_1->dmrs_ports[6] = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][7]; + dlsch_config_pdu_1_1->dmrs_ports[7] = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][8]; + dlsch_config_pdu_1_1->n_front_load_symb = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][9]; + } + } + /* TCI */ + if (mac->dl_config_request.dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.tci_present_in_dci == 1){ + // 0 bit if higher layer parameter tci-PresentInDCI is not enabled + // otherwise 3 bits as defined in Subclause 5.1.5 of [6, TS38.214] + dlsch_config_pdu_1_1->tci_state = dci->transmission_configuration_indication.val; + } + /* SRS_REQUEST */ + // if SUL is supported in the cell, there is an additional bit in this field and the value of this bit represents table 7.1.1.1-1 TS 38.212 FIXME!!! + dlsch_config_pdu_1_1->srs_config.aperiodicSRS_ResourceTrigger = (dci->srs_request.val & 0x11); // as per Table 7.3.1.1.2-24 TS 38.212 + /* CBGTI */ + dlsch_config_pdu_1_1->cbgti = dci->cbgti.val; + /* CBGFI */ + dlsch_config_pdu_1_1->codeBlockGroupFlushIndicator = dci->cbgfi.val; + /* DMRS_SEQ_INI */ + //FIXME!!! + + // dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP = n_RB_DLBWP; + + /* PDSCH_TO_HARQ_FEEDBACK_TIME_IND */ + // according to TS 38.213 Table 9.2.3-1 + NR_BWP_Id_t ul_bwp_id = mac->UL_BWP_Id; + uint8_t feedback_ti = + mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->dl_DataToUL_ACK->list.array[dci->pdsch_to_harq_feedback_timing_indicator.val][0]; + + // set the harq status at MAC for feedback + set_harq_status(mac,dci->pucch_resource_indicator, + dci->harq_pid, + dlsch_config_pdu_1_1->accumulated_delta_PUCCH, + feedback_ti, + dci->dai[0].val, + dci_ind->n_CCE,dci_ind->N_CCE, + frame,slot); + + dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH; + LOG_D(MAC,"(nr_ue_procedures.c) pdu_type=%d\n\n",dl_config->dl_config_list[dl_config->number_pdus].pdu_type); + + dl_config->number_pdus = dl_config->number_pdus + 1; + /* TODO same calculation for MCS table as done in UL */ + dlsch_config_pdu_1_1->mcs_table = (pdsch_config->mcs_Table) ? (*pdsch_config->mcs_Table + 1) : 0; + /*PTRS configuration */ + if(mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS != NULL) { + valid_ptrs_setup = set_dl_ptrs_values(mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup, + dlsch_config_pdu_1_1->number_rbs, dlsch_config_pdu_1_1->mcs, dlsch_config_pdu_1_1->mcs_table, + &dlsch_config_pdu_1_1->PTRSFreqDensity,&dlsch_config_pdu_1_1->PTRSTimeDensity, + &dlsch_config_pdu_1_1->PTRSPortIndex,&dlsch_config_pdu_1_1->nEpreRatioOfPDSCHToPTRS, + &dlsch_config_pdu_1_1->PTRSReOffset, dlsch_config_pdu_1_1->number_symbols); + if(valid_ptrs_setup==true) { + dlsch_config_pdu_1_1->pduBitmap |= 0x1; + LOG_D(MAC, "DL PTRS values: PTRS time den: %d, PTRS freq den: %d\n", dlsch_config_pdu_1_1->PTRSTimeDensity, dlsch_config_pdu_1_1->PTRSFreqDensity); } - - break; } - case NR_DL_DCI_FORMAT_2_0: - break; + break; + } - case NR_DL_DCI_FORMAT_2_1: - break; + case NR_DL_DCI_FORMAT_2_0: + break; - case NR_DL_DCI_FORMAT_2_2: - break; + case NR_DL_DCI_FORMAT_2_1: + break; - case NR_DL_DCI_FORMAT_2_3: - break; + case NR_DL_DCI_FORMAT_2_2: + break; - default: - break; + case NR_DL_DCI_FORMAT_2_3: + break; + + default: + break; } - if(rnti == SI_RNTI) { + + if(rnti == SI_RNTI){ + // }else if(rnti == mac->ra_rnti){ - } else if(rnti == P_RNTI) { - } else { // c-rnti - /// check if this is pdcch order + + }else if(rnti == P_RNTI){ + + }else{ // c-rnti + + /// check if this is pdcch order //dci->random_access_preamble_index; //dci->ss_pbch_index; //dci->prach_mask_index; + /// else normal DL-SCH grant } return ret; + } void set_harq_status(NR_UE_MAC_INST_t *mac, @@ -1279,7 +1281,9 @@ void set_harq_status(NR_UE_MAC_INST_t *mac, int N_CCE, frame_t frame, int slot) { + NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[harq_id]; + current_harq->active = true; current_harq->ack_received = false; current_harq->pucch_resource_indicator = pucch_id; @@ -1291,10 +1295,12 @@ void set_harq_status(NR_UE_MAC_INST_t *mac, // FIXME k0 != 0 currently not taken into consideration current_harq->dl_frame = frame; current_harq->dl_slot = slot; + } void update_harq_status(nr_downlink_indication_t *dl_info, int pdu_id) { + NR_UE_MAC_INST_t *mac = get_mac_inst(dl_info->module_id); uint8_t harq_pid = dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.harq_pid; NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[harq_pid]; @@ -1302,7 +1308,8 @@ void update_harq_status(nr_downlink_indication_t *dl_info, int pdu_id) { if (current_harq->active) { current_harq->ack = dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.ack_nack; current_harq->ack_received = true; - } else { + } + else { //shouldn't get here LOG_E(MAC, "Trying to process acknack for an inactive harq process (%d)\n", harq_pid); } @@ -1315,6 +1322,7 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch, fapi_nr_ul_config_pucch_pdu *pucch_pdu, int O_SR, int O_ACK, int O_CSI) { + int O_CRC = 0; //FIXME uint16_t O_uci = O_CSI + O_ACK; NR_BWP_Id_t bwp_id = mac->UL_BWP_Id; @@ -1323,38 +1331,39 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, long *id0 = NULL; int scs; NR_BWP_UplinkCommon_t *initialUplinkBWP; - if (mac->scc) initialUplinkBWP = mac->scc->uplinkConfigCommon->initialUplinkBWP; else initialUplinkBWP = &mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP; - NR_BWP_Uplink_t *ubwp = mac->ULbwp[0]; - if (mac->cg && ubwp && mac->cg->spCellConfig && mac->cg->spCellConfig->spCellConfigDedicated && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) { scs = ubwp->bwp_Common->genericParameters.subcarrierSpacing; - } else + } + else scs = initialUplinkBWP->genericParameters.subcarrierSpacing; int subframe_number = slot / (nr_slots_per_frame[scs]/10); nb_pucch_format_4_in_subframes[subframe_number] = 0; + pucch_pdu->rnti = rnti; // configure pucch from Table 9.2.1-1 if (pucch->initial_pucch_id > -1 && pucch->pucch_resource == NULL) { + pucch_pdu->format_type = initial_pucch_resource[pucch->initial_pucch_id].format; pucch_pdu->start_symbol_index = initial_pucch_resource[pucch->initial_pucch_id].startingSymbolIndex; pucch_pdu->nr_of_symbols = initial_pucch_resource[pucch->initial_pucch_id].nrofSymbols; + pucch_pdu->bwp_size = NRRIV2BW(mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE); pucch_pdu->bwp_start = NRRIV2PRBOFFSET(mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + pucch_pdu->prb_size = 1; // format 0 or 1 int RB_BWP_offset; - if (pucch->initial_pucch_id == 15) RB_BWP_offset = pucch_pdu->bwp_size>>2; else @@ -1362,15 +1371,14 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, int N_CS = initial_pucch_resource[pucch->initial_pucch_id].nb_CS_indexes; pucch_pdu->prb_start = RB_BWP_offset + (pucch->initial_pucch_id/N_CS); - if (pucch->initial_pucch_id>>3 == 0) { pucch_pdu->second_hop_prb = pucch_pdu->bwp_size - 1 - RB_BWP_offset - (pucch->initial_pucch_id/N_CS); pucch_pdu->initial_cyclic_shift = initial_pucch_resource[pucch->initial_pucch_id].initial_CS_indexes[pucch->initial_pucch_id%N_CS]; - } else { + } + else { pucch_pdu->second_hop_prb = pucch_pdu->bwp_size - 1 - RB_BWP_offset - ((pucch->initial_pucch_id - 8)/N_CS); pucch_pdu->initial_cyclic_shift = initial_pucch_resource[pucch->initial_pucch_id].initial_CS_indexes[(pucch->initial_pucch_id - 8)%N_CS]; } - pucch_pdu->freq_hop_flag = 1; pucch_pdu->time_domain_occ_idx = 0; @@ -1379,7 +1387,8 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, pucch_pdu->mcs = sequence_cyclic_shift_1_harq_ack_bit[pucch->ack_payload & 0x1]; /* only harq of 1 bit */ else pucch_pdu->mcs = sequence_cyclic_shift_2_harq_ack_bits[pucch->ack_payload & 0x3]; /* only harq with 2 bits */ - } else { /* SR + eventually ack are transmitted TS 36.213 9.2.5.1 UE procedure for multiplexing HARQ-ACK or CSI and SR */ + } + else { /* SR + eventually ack are transmitted TS 36.213 9.2.5.1 UE procedure for multiplexing HARQ-ACK or CSI and SR */ if (pucch->sr_payload == 1) { /* positive scheduling request */ if (O_ACK == 1) pucch_pdu->mcs = sequence_cyclic_shift_1_harq_ack_bit_positive_sr[pucch->ack_payload & 0x1]; /* positive SR and harq of 1 bit */ @@ -1392,27 +1401,29 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, // TODO verify if SR can be transmitted in this mode pucch_pdu->payload = (pucch->sr_payload << O_ACK) | pucch->ack_payload; - } else if (pucch->pucch_resource != NULL) { + + } + else if (pucch->pucch_resource != NULL) { + NR_PUCCH_Resource_t *pucchres = pucch->pucch_resource; if (mac->cg && mac->cg->physicalCellGroupConfig && (mac->cg->physicalCellGroupConfig->harq_ACK_SpatialBundlingPUCCH != NULL || - mac->cg->physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook != 1)) { - LOG_E(PHY,"PUCCH Unsupported cell group configuration : at line %d in function %s of file %s \n", LINE_FILE, __func__, FILE_NAME); + mac->cg->physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook != 1)) { + LOG_E(PHY,"PUCCH Unsupported cell group configuration : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); return; - } else if (mac->cg && - mac->cg->spCellConfig && - mac->cg->spCellConfig->spCellConfigDedicated && - mac->cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig && - mac->cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup && - mac->cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->codeBlockGroupTransmission != NULL) { - LOG_E(MAC,"PUCCH Unsupported code block group for serving cell config : at line %d in function %s of file %s \n", LINE_FILE, __func__, FILE_NAME); + } + else if (mac->cg && + mac->cg->spCellConfig && + mac->cg->spCellConfig->spCellConfigDedicated && + mac->cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig && + mac->cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup && + mac->cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->codeBlockGroupTransmission != NULL) { + LOG_E(MAC,"PUCCH Unsupported code block group for serving cell config : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); return; } - NR_PUCCH_Config_t *pucch_Config; - if (bwp_id>0 && mac->ULbwp[bwp_id-1] && mac->ULbwp[bwp_id-1]->bwp_Dedicated && @@ -1420,60 +1431,55 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup) { NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup; pusch_id = pusch_Config->dataScramblingIdentityPUSCH; - if (pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA != NULL) id0 = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup->transformPrecodingDisabled->scramblingID0; else if (pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB != NULL) id0 = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->transformPrecodingDisabled->scramblingID0; else *id0 = mac->physCellId; - pucch_Config = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup; pucch_pdu->bwp_size = NRRIV2BW(mac->ULbwp[bwp_id-1]->bwp_Common->genericParameters.locationAndBandwidth,MAX_BWP_SIZE); pucch_pdu->bwp_start = NRRIV2PRBOFFSET(mac->ULbwp[bwp_id-1]->bwp_Common->genericParameters.locationAndBandwidth,MAX_BWP_SIZE); - } else if (bwp_id==0 && - mac->cg && - mac->cg->spCellConfig && - mac->cg->spCellConfig->spCellConfigDedicated && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) { + } + else if (bwp_id==0 && + mac->cg && + mac->cg->spCellConfig && + mac->cg->spCellConfig->spCellConfigDedicated && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) { pucch_Config = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup; pucch_pdu->bwp_size = NRRIV2BW(mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth,MAX_BWP_SIZE); pucch_pdu->bwp_start = NRRIV2PRBOFFSET(mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth,MAX_BWP_SIZE); - } else AssertFatal(1==0,"no pucch_Config\n"); + } + else AssertFatal(1==0,"no pucch_Config\n"); NR_PUCCH_ConfigCommon_t *pucch_ConfigCommon; - if (mac->scc) pucch_ConfigCommon = mac->scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup; else pucch_ConfigCommon = mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pucch_ConfigCommon->choice.setup; - if (pucch_ConfigCommon->hoppingId != NULL) pucch_pdu->hopping_id = *pucch_ConfigCommon->hoppingId; else pucch_pdu->hopping_id = mac->physCellId; - switch (pucch_ConfigCommon->pucch_GroupHopping) { + switch (pucch_ConfigCommon->pucch_GroupHopping){ case 0 : - // if neither, both disabled - pucch_pdu->group_hop_flag = 0; - pucch_pdu->sequence_hop_flag = 0; - break; - - case 1 : - // if enable, group enabled - pucch_pdu->group_hop_flag = 1; - pucch_pdu->sequence_hop_flag = 0; - break; - - case 2 : - // if disable, sequence disabled - pucch_pdu->group_hop_flag = 0; - pucch_pdu->sequence_hop_flag = 1; - break; - - default: - AssertFatal(1==0,"Group hopping flag undefined (0,1,2) \n"); + // if neither, both disabled + pucch_pdu->group_hop_flag = 0; + pucch_pdu->sequence_hop_flag = 0; + break; + case 1 : + // if enable, group enabled + pucch_pdu->group_hop_flag = 1; + pucch_pdu->sequence_hop_flag = 0; + break; + case 2 : + // if disable, sequence disabled + pucch_pdu->group_hop_flag = 0; + pucch_pdu->sequence_hop_flag = 1; + break; + default: + AssertFatal(1==0,"Group hopping flag undefined (0,1,2) \n"); } pucch_pdu->prb_start = pucchres->startingPRB; @@ -1482,10 +1488,9 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, pucch_pdu->prb_size = 1; // format 0 or 1 if ((O_SR+O_CSI+O_SR) > (sizeof(uint64_t)*8)) { - LOG_E(MAC,"PUCCH number of UCI bits exceeds payload size : at line %d in function %s of file %s \n", LINE_FILE, __func__, FILE_NAME); + LOG_E(MAC,"PUCCH number of UCI bits exceeds payload size : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); return; } - pucch_pdu->payload = (pucch->csi_part1_payload << (O_ACK + O_SR)) | (pucch->sr_payload << O_ACK) | pucch->ack_payload; switch(pucchres->format.present) { @@ -1494,13 +1499,13 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, pucch_pdu->initial_cyclic_shift = pucchres->format.choice.format0->initialCyclicShift; pucch_pdu->nr_of_symbols = pucchres->format.choice.format0->nrofSymbols; pucch_pdu->start_symbol_index = pucchres->format.choice.format0->startingSymbolIndex; - if (O_SR == 0 || pucch->sr_payload == 0) { /* only ack is transmitted TS 36.213 9.2.3 UE procedure for reporting HARQ-ACK */ if (O_ACK == 1) pucch_pdu->mcs = sequence_cyclic_shift_1_harq_ack_bit[pucch->ack_payload & 0x1]; /* only harq of 1 bit */ else pucch_pdu->mcs = sequence_cyclic_shift_2_harq_ack_bits[pucch->ack_payload & 0x3]; /* only harq with 2 bits */ - } else { /* SR + eventually ack are transmitted TS 36.213 9.2.5.1 UE procedure for multiplexing HARQ-ACK or CSI and SR */ + } + else { /* SR + eventually ack are transmitted TS 36.213 9.2.5.1 UE procedure for multiplexing HARQ-ACK or CSI and SR */ if (pucch->sr_payload == 1) { /* positive scheduling request */ if (O_ACK == 1) pucch_pdu->mcs = sequence_cyclic_shift_1_harq_ack_bit_positive_sr[pucch->ack_payload & 0x1]; /* positive SR and harq of 1 bit */ @@ -1510,9 +1515,7 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, pucch_pdu->mcs = 0; /* only positive SR */ } } - break; - case NR_PUCCH_Resource__format_PR_format1 : pucch_pdu->format_type = 1; pucch_pdu->initial_cyclic_shift = pucchres->format.choice.format1->initialCyclicShift; @@ -1520,7 +1523,6 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, pucch_pdu->start_symbol_index = pucchres->format.choice.format1->startingSymbolIndex; pucch_pdu->time_domain_occ_idx = pucchres->format.choice.format1->timeDomainOCC; break; - case NR_PUCCH_Resource__format_PR_format2 : pucch_pdu->format_type = 2; pucch_pdu->n_bit = O_uci+O_SR; @@ -1529,28 +1531,25 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, pucch_pdu->data_scrambling_id = pusch_id!= NULL ? *pusch_id : mac->physCellId; pucch_pdu->dmrs_scrambling_id = id0!= NULL ? *id0 : mac->physCellId; pucch_pdu->prb_size = compute_pucch_prb_size(2,pucchres->format.choice.format2->nrofPRBs, - O_uci+O_SR,O_CSI,pucch_Config->format2->choice.setup->maxCodeRate, - 2,pucchres->format.choice.format2->nrofSymbols,8); + O_uci+O_SR,O_CSI,pucch_Config->format2->choice.setup->maxCodeRate, + 2,pucchres->format.choice.format2->nrofSymbols,8); break; - case NR_PUCCH_Resource__format_PR_format3 : pucch_pdu->format_type = 3; pucch_pdu->n_bit = O_uci+O_SR; pucch_pdu->nr_of_symbols = pucchres->format.choice.format3->nrofSymbols; pucch_pdu->start_symbol_index = pucchres->format.choice.format3->startingSymbolIndex; pucch_pdu->data_scrambling_id = pusch_id!= NULL ? *pusch_id : mac->physCellId; - if (pucch_Config->format3 == NULL) { pucch_pdu->pi_2bpsk = 0; pucch_pdu->add_dmrs_flag = 0; - } else { + } + else { pucchfmt = pucch_Config->format3->choice.setup; pucch_pdu->pi_2bpsk = pucchfmt->pi2BPSK!= NULL ? 1 : 0; pucch_pdu->add_dmrs_flag = pucchfmt->additionalDMRS!= NULL ? 1 : 0; } - int f3_dmrs_symbols; - if (pucchres->format.choice.format3->nrofSymbols==4) f3_dmrs_symbols = 1<<pucch_pdu->freq_hop_flag; else { @@ -1559,12 +1558,10 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, else f3_dmrs_symbols = 2<<pucch_pdu->add_dmrs_flag; } - pucch_pdu->prb_size = compute_pucch_prb_size(3,pucchres->format.choice.format3->nrofPRBs, - O_uci+O_SR,O_CSI,pucch_Config->format3->choice.setup->maxCodeRate, - 2-pucch_pdu->pi_2bpsk,pucchres->format.choice.format3->nrofSymbols-f3_dmrs_symbols,12); + O_uci+O_SR,O_CSI,pucch_Config->format3->choice.setup->maxCodeRate, + 2-pucch_pdu->pi_2bpsk,pucchres->format.choice.format3->nrofSymbols-f3_dmrs_symbols,12); break; - case NR_PUCCH_Resource__format_PR_format4 : pucch_pdu->format_type = 4; pucch_pdu->nr_of_symbols = pucchres->format.choice.format4->nrofSymbols; @@ -1572,33 +1569,30 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, pucch_pdu->pre_dft_occ_len = pucchres->format.choice.format4->occ_Length; pucch_pdu->pre_dft_occ_idx = pucchres->format.choice.format4->occ_Index; pucch_pdu->data_scrambling_id = pusch_id!= NULL ? *pusch_id : mac->physCellId; - if (pucch_Config->format3 == NULL) { pucch_pdu->pi_2bpsk = 0; pucch_pdu->add_dmrs_flag = 0; - } else { + } + else { pucchfmt = pucch_Config->format3->choice.setup; pucch_pdu->pi_2bpsk = pucchfmt->pi2BPSK!= NULL ? 1 : 0; pucch_pdu->add_dmrs_flag = pucchfmt->additionalDMRS!= NULL ? 1 : 0; } - break; - default : AssertFatal(1==0,"Undefined PUCCH format \n"); } - pucch_pdu->pucch_tx_power = get_pucch_tx_power_ue(mac, - pucch_Config, - pucch, - pucch_pdu->format_type, - pucch_pdu->prb_size, - pucch_pdu->freq_hop_flag, - pucch_pdu->add_dmrs_flag, - pucch_pdu->nr_of_symbols, - subframe_number, - O_ACK, O_SR, - O_CSI, O_CRC); + pucch_Config, + pucch, + pucch_pdu->format_type, + pucch_pdu->prb_size, + pucch_pdu->freq_hop_flag, + pucch_pdu->add_dmrs_flag, + pucch_pdu->nr_of_symbols, + subframe_number, + O_ACK, O_SR, + O_CSI, O_CRC); } } @@ -1614,9 +1608,9 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, int subframe_number, int O_ACK, int O_SR, int O_CSI, int O_CRC) { + int PUCCH_POWER_DEFAULT = 0; int16_t P_O_NOMINAL_PUCCH; - if (mac->scc) P_O_NOMINAL_PUCCH = *mac->scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->p0_nominal; else P_O_NOMINAL_PUCCH = *mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pucch_ConfigCommon->choice.setup->p0_nominal; @@ -1629,20 +1623,22 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, int16_t G_b_f_c = 0; if (pucch_Config->spatialRelationInfoToAddModList != NULL) { /* FFS TODO NR */ - LOG_D(MAC,"PUCCH Spatial relation infos are not yet implemented : at line %d in function %s of file %s \n", LINE_FILE, __func__, __FILE__); + LOG_D(MAC,"PUCCH Spatial relation infos are not yet implemented : at line %d in function %s of file %s \n", LINE_FILE , __func__, __FILE__); return (PUCCH_POWER_DEFAULT); } if (power_config->p0_Set != NULL) { P_O_UE_PUCCH = power_config->p0_Set->list.array[0]->p0_PUCCH_Value; /* get from index 0 if no spatial relation set */ G_b_f_c = 0; - } else { + } + else { G_b_f_c = pucch->delta_pucch; - LOG_D(MAC,"PUCCH Transmit power control command not yet implemented for NR : at line %d in function %s of file %s \n", LINE_FILE, __func__, __FILE__); + LOG_D(MAC,"PUCCH Transmit power control command not yet implemented for NR : at line %d in function %s of file %s \n", LINE_FILE , __func__, __FILE__); return (PUCCH_POWER_DEFAULT); } int P_O_PUCCH = P_O_NOMINAL_PUCCH + P_O_UE_PUCCH; + int16_t delta_F_PUCCH; int DELTA_TF; uint16_t N_ref_PUCCH; @@ -1655,13 +1651,11 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, DELTA_TF = 10 * log10(N_ref_PUCCH/N_symb_PUCCH); delta_F_PUCCH = *power_config->deltaF_PUCCH_f0; break; - case 1: N_ref_PUCCH = 14; DELTA_TF = 10 * log10(N_ref_PUCCH/N_symb_PUCCH); delta_F_PUCCH = *power_config->deltaF_PUCCH_f1; break; - case 2: N_sc_ctrl_RB = 10; DELTA_TF = get_deltatf(nb_of_prbs, @@ -1674,7 +1668,6 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, O_CSI, O_CRC); delta_F_PUCCH = *power_config->deltaF_PUCCH_f2; break; - case 3: N_sc_ctrl_RB = 14; DELTA_TF = get_deltatf(nb_of_prbs, @@ -1687,7 +1680,6 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, O_CSI, O_CRC); delta_F_PUCCH = *power_config->deltaF_PUCCH_f3; break; - case 4: N_sc_ctrl_RB = 14/(nb_pucch_format_4_in_subframes[subframe_number]); DELTA_TF = get_deltatf(nb_of_prbs, @@ -1700,21 +1692,23 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, O_CSI, O_CRC); delta_F_PUCCH = *power_config->deltaF_PUCCH_f4; break; - - default: { - LOG_E(MAC,"PUCCH unknown pucch format : at line %d in function %s of file %s \n", LINE_FILE, __func__, __FILE__); + default: + { + LOG_E(MAC,"PUCCH unknown pucch format : at line %d in function %s of file %s \n", LINE_FILE , __func__, __FILE__); return (0); } } if (*power_config->twoPUCCH_PC_AdjustmentStates > 1) { - LOG_E(MAC,"PUCCH power control adjustment states with 2 states not yet implemented : at line %d in function %s of file %s \n", LINE_FILE, __func__, __FILE__); + LOG_E(MAC,"PUCCH power control adjustment states with 2 states not yet implemented : at line %d in function %s of file %s \n", LINE_FILE , __func__, __FILE__); return (PUCCH_POWER_DEFAULT); } int16_t pucch_power = P_O_PUCCH + delta_F_PUCCH + DELTA_TF + G_b_f_c; + NR_TST_PHY_PRINTF("PUCCH ( Tx power : %d dBm ) ( 10Log(...) : %d ) ( from Path Loss : %d ) ( delta_F_PUCCH : %d ) ( DELTA_TF : %d ) ( G_b_f_c : %d ) \n", pucch_power, contributor, PL, delta_F_PUCCH, DELTA_TF, G_b_f_c); + return (pucch_power); } @@ -1725,13 +1719,13 @@ int get_deltatf(uint16_t nb_of_prbs, int N_sc_ctrl_RB, int n_HARQ_ACK, int O_ACK, int O_SR, - int O_CSI, int O_CRC) { + int O_CSI, int O_CRC){ + int DELTA_TF; int O_UCI = O_ACK + O_SR + O_CSI + O_CRC; int N_symb = nb_symbols_excluding_dmrs[N_symb_PUCCH-4][add_dmrs_flag][freq_hop_flag]; float N_RE = nb_of_prbs * N_sc_ctrl_RB * N_symb; float K1 = 6; - if (O_UCI < 12) DELTA_TF = 10 * log10((double)(((K1 * (n_HARQ_ACK + O_SR + O_CSI))/N_RE))); else { @@ -1739,7 +1733,6 @@ int get_deltatf(uint16_t nb_of_prbs, float BPRE = O_UCI/N_RE; DELTA_TF = 10 * log10((double)(pow(2,(K2*BPRE)) - 1)); } - return DELTA_TF; } @@ -1794,17 +1787,18 @@ int find_pucch_resource_set(NR_UE_MAC_INST_t *mac, int uci_size) { pucch_resource_set_id = 0; return (pucch_resource_set_id); break; - } else { + } + else { pucch_resource_set_id = 1; return (pucch_resource_set_id); break; } } - pucch_resource_set_id++; } pucch_resource_set_id = MAX_NB_OF_PUCCH_RESOURCE_SETS; + return (pucch_resource_set_id); } @@ -1828,6 +1822,7 @@ int find_pucch_resource_set(NR_UE_MAC_INST_t *mac, int uci_size) { void select_pucch_resource(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch) { + NR_PUCCH_ResourceId_t *current_resource_id = NULL; NR_BWP_Id_t bwp_id = mac->UL_BWP_Id; int n_list; @@ -1850,53 +1845,48 @@ void select_pucch_resource(NR_UE_MAC_INST_t *mac, mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup && mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList && mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[0] == NULL) - ) { + ){ + /* see TS 38.213 9.2.1 PUCCH Resource Sets */ int delta_PRI = pucch->resource_indicator; int n_CCE_0 = pucch->n_CCE; int N_CCE_0 = pucch->N_CCE; - if (N_CCE_0 == 0) { - AssertFatal(1==0,"PUCCH No compatible pucch format found : at line %d in function %s of file %s \n", LINE_FILE, __func__, FILE_NAME); + AssertFatal(1==0,"PUCCH No compatible pucch format found : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); } - int r_PUCCH = ((2 * n_CCE_0)/N_CCE_0) + (2 * delta_PRI); pucch->initial_pucch_id = r_PUCCH; pucch->pucch_resource = NULL; - } else { + } + else { struct NR_PUCCH_Config__resourceSetToAddModList *resourceSetToAddModList = NULL; struct NR_PUCCH_Config__resourceToAddModList *resourceToAddModList = NULL; - if (bwp_id > 0 && mac->ULbwp[bwp_id-1]) { AssertFatal(mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList!=NULL, "mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList is null\n"); resourceSetToAddModList = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList; resourceToAddModList = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceToAddModList; - } else if (bwp_id == 0 && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup->resourceSetToAddModList!=NULL) { + } + else if (bwp_id == 0 && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup->resourceSetToAddModList!=NULL) { resourceSetToAddModList = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup->resourceSetToAddModList; resourceToAddModList = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup->resourceToAddModList; } n_list = resourceSetToAddModList->list.count; - if (pucch->resource_set_id > n_list) { LOG_E(MAC,"Invalid PUCCH resource set id %d\n",pucch->resource_set_id); pucch->pucch_resource = NULL; return; } - n_list = resourceSetToAddModList->list.array[pucch->resource_set_id]->resourceList.list.count; - if (pucch->resource_indicator > n_list) { LOG_E(MAC,"Invalid PUCCH resource id %d\n",pucch->resource_indicator); pucch->pucch_resource = NULL; return; } - current_resource_id = resourceSetToAddModList->list.array[pucch->resource_set_id]->resourceList.list.array[pucch->resource_indicator]; n_list = resourceToAddModList->list.count; int res_found = 0; - for (int i=0; i<n_list; i++) { if (resourceToAddModList->list.array[i]->pucch_ResourceId == *current_resource_id) { pucch->pucch_resource = resourceToAddModList->list.array[i]; @@ -1904,7 +1894,6 @@ void select_pucch_resource(NR_UE_MAC_INST_t *mac, break; } } - if (res_found == 0) { LOG_E(MAC,"Couldn't find PUCCH Resource\n"); pucch->pucch_resource = NULL; @@ -1943,6 +1932,8 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sched_t *pucch) { + + uint32_t ack_data[NR_DL_MAX_NB_CW][NR_DL_MAX_DAI] = {{0},{0}}; uint32_t dai[NR_DL_MAX_NB_CW][NR_DL_MAX_DAI] = {{0},{0}}; /* for serving cell */ uint32_t dai_total[NR_DL_MAX_NB_CW][NR_DL_MAX_DAI] = {{0},{0}}; /* for multiple cells */ @@ -1957,10 +1948,8 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac, NR_UE_HARQ_STATUS_t *current_harq; int sched_frame,sched_slot; NR_BWP_UplinkCommon_t *initialUplinkBWP; - if (mac->scc) initialUplinkBWP = mac->scc->uplinkConfigCommon->initialUplinkBWP; else initialUplinkBWP = &mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP; - int slots_per_frame,scs; if (mac->DLbwp[0] && @@ -1970,63 +1959,68 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac, mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI[0] == 2) { two_transport_blocks = TRUE; number_of_code_word = 2; - } else { + } + else { number_of_code_word = 1; } NR_BWP_Uplink_t *ubwp = mac->ULbwp[0]; - if (mac->cg && ubwp && mac->cg->spCellConfig && mac->cg->spCellConfig->spCellConfigDedicated && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) { scs = ubwp->bwp_Common->genericParameters.subcarrierSpacing; - } else + } + else scs = initialUplinkBWP->genericParameters.subcarrierSpacing; slots_per_frame = nr_slots_per_frame[scs]; /* look for dl acknowledgment which should be done on current uplink slot */ for (int code_word = 0; code_word < number_of_code_word; code_word++) { + for (int dl_harq_pid = 0; dl_harq_pid < 16; dl_harq_pid++) { + current_harq = &mac->dl_harq_info[dl_harq_pid]; if (current_harq->active) { + sched_slot = current_harq->dl_slot + current_harq->feedback_to_ul; sched_frame = current_harq->dl_frame; - - if (sched_slot>=slots_per_frame) { + if (sched_slot>=slots_per_frame){ sched_slot %= slots_per_frame; sched_frame++; } /* check if current tx slot should transmit downlink acknowlegment */ if (sched_frame == frame && sched_slot == slot) { + if (current_harq->dai > NR_DL_MAX_DAI) { - LOG_E(MAC,"PUCCH Downlink DAI has an invalid value : at line %d in function %s of file %s \n", LINE_FILE, __func__, FILE_NAME); - } else { + LOG_E(MAC,"PUCCH Downlink DAI has an invalid value : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); + } + else { + if ((pucch->resource_indicator != -1) && (pucch->resource_indicator != current_harq->pucch_resource_indicator)) LOG_E(MAC, "Value of pucch_resource_indicator %d not matching with what set before %d (Possibly due to a false DCI) \n", current_harq->pucch_resource_indicator,pucch->resource_indicator); - else { + else{ dai_current = current_harq->dai+1; // DCI DAI to counter DAI conversion if (dai_current == 0) { - LOG_E(MAC,"PUCCH Downlink dai is invalid : at line %d in function %s of file %s \n", LINE_FILE, __func__, FILE_NAME); + LOG_E(MAC,"PUCCH Downlink dai is invalid : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); return(0); } else if (dai_current > dai_max) { dai_max = dai_current; } number_harq_feedback++; - if (current_harq->ack_received) ack_data[code_word][dai_current - 1] = current_harq->ack; else ack_data[code_word][dai_current - 1] = 0; - dai[code_word][dai_current - 1] = dai_current; + pucch->resource_indicator = current_harq->pucch_resource_indicator; pucch->n_CCE = current_harq->n_CCE; pucch->N_CCE = current_harq->N_CCE; @@ -2044,8 +2038,9 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac, if (number_harq_feedback == 0) { pucch->n_HARQ_ACK = 0; return(0); - } else if (number_harq_feedback > (sizeof(uint32_t)*8)) { - LOG_E(MAC,"PUCCH number of ack bits exceeds payload size : at line %d in function %s of file %s \n", LINE_FILE, __func__, FILE_NAME); + } + else if (number_harq_feedback > (sizeof(uint32_t)*8)) { + LOG_E(MAC,"PUCCH number of ack bits exceeds payload size : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); return(0); } @@ -2054,7 +2049,6 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac, U_DAI_c = number_harq_feedback/number_of_code_word; N_m_c_rx = number_harq_feedback; int N_SPS_c = 0; /* FFS TODO_NR multicells and SPS are not supported at the moment */ - if (mac->cg != NULL && mac->cg->physicalCellGroupConfig != NULL && mac->cg->physicalCellGroupConfig->harq_ACK_SpatialBundlingPUCCH != NULL) { @@ -2078,7 +2072,6 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac, ack_data[code_word][i] = 0; /* nack data transport block which has been missed */ number_harq_feedback++; } - if (two_transport_blocks == TRUE) { dai_total[code_word][i] = dai[code_word][i]; /* for a single cell, dai_total is the same as dai of first cell */ } @@ -2095,6 +2088,7 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac, int O_bit_number_cw1 = 0; for (int m = 0; m < M ; m++) { + if (dai[0][m] <= V_temp) { j = j + 1; } @@ -2111,7 +2105,8 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac, if (two_transport_blocks == TRUE) { O_bit_number_cw0 = (8 * j) + 2*(V_temp - 1); - } else { + } + else { O_bit_number_cw0 = (4 * j) + (V_temp - 1); } @@ -2124,30 +2119,32 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac, if (two_transport_blocks == TRUE) { O_ACK = 2 * ( 4 * j + V_temp2); /* for two transport blocks */ - } else { + } + else { O_ACK = 4 * j + V_temp2; /* only one transport block */ } if (number_harq_feedback != O_ACK) { - LOG_E(MAC,"PUCCH Error for number of bits for acknowledgment : at line %d in function %s of file %s \n", LINE_FILE, __func__, FILE_NAME); + LOG_E(MAC,"PUCCH Error for number of bits for acknowledgment : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); return (0); } pucch->ack_payload = o_ACK; + return(number_harq_feedback); } bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, - PUCCH_sched_t *pucch, - frame_t frame, - int slot) { + PUCCH_sched_t *pucch, + frame_t frame, + int slot) { + NR_BWP_Id_t bwp_id = mac->UL_BWP_Id; NR_PUCCH_Config_t *pucch_Config = NULL; int scs; NR_BWP_Uplink_t *ubwp = mac->ULbwp[0]; NR_BWP_UplinkCommon_t *initialUplinkBWP; - if (mac->scc) initialUplinkBWP = mac->scc->uplinkConfigCommon->initialUplinkBWP; else initialUplinkBWP = &mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP; @@ -2157,7 +2154,8 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) { scs = ubwp->bwp_Common->genericParameters.subcarrierSpacing; - } else + } + else scs = initialUplinkBWP->genericParameters.subcarrierSpacing; const int n_slots_frame = nr_slots_per_frame[scs]; @@ -2168,55 +2166,52 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config && mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup) { pucch_Config = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup; - } else if (bwp_id==0 && - mac->cg && - mac->cg->spCellConfig && - mac->cg->spCellConfig->spCellConfigDedicated && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) { + } + else if (bwp_id==0 && + mac->cg && + mac->cg->spCellConfig && + mac->cg->spCellConfig->spCellConfigDedicated && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) { pucch_Config = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup; } - if(!pucch_Config || pucch_Config->schedulingRequestResourceToAddModList->list.count==0) return false; // SR not configured - for (int SR_resource_id =0; SR_resource_id < pucch_Config->schedulingRequestResourceToAddModList->list.count; SR_resource_id++) { + for (int SR_resource_id =0; SR_resource_id < pucch_Config->schedulingRequestResourceToAddModList->list.count;SR_resource_id++) { NR_SchedulingRequestResourceConfig_t *SchedulingRequestResourceConfig = pucch_Config->schedulingRequestResourceToAddModList->list.array[SR_resource_id]; - int SR_period; - int SR_offset; + int SR_period; int SR_offset; + find_period_offest_SR(SchedulingRequestResourceConfig,&SR_period,&SR_offset); int sfn_sf = frame * n_slots_frame + slot; if ((sfn_sf - SR_offset) % SR_period == 0) { LOG_D(MAC, "Scheduling Request active in frame %d slot %d \n", frame, slot); NR_PUCCH_ResourceId_t *PucchResourceId = SchedulingRequestResourceConfig->resource; + int found = -1; NR_PUCCH_ResourceSet_t *pucchresset = pucch_Config->resourceSetToAddModList->list.array[0]; // set with formats 0,1 int n_list = pucchresset->resourceList.list.count; - - for (int i=0; i<n_list; i++) { + for (int i=0; i<n_list; i++) { if (*pucchresset->resourceList.list.array[i] == *PucchResourceId ) { found = i; break; } } - if (found == -1) { LOG_E(MAC,"Couldn't find PUCCH resource for SR\n"); return false; } - pucch->resource_indicator = found; return true; } } - return false; } -int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, slot_t slot) { +int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, slot_t slot){ // no UL-SCH resources available for this tti && UE has a valid PUCCH resources for SR configuration for this tti DevCheck(module_idP < (int) NB_UE_INST, module_idP, NB_NR_UE_MAC_INST, 0); NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); @@ -2227,38 +2222,36 @@ int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, slot_t slot) { mac->scheduling_info.SR_COUNTER, (1 << (2 + - // mac-> - // physicalConfigDedicated->schedulingRequestConfig->choice. - // setup.dsr_TransMax)), +// mac-> +// physicalConfigDedicated->schedulingRequestConfig->choice. +// setup.dsr_TransMax)), dsr_TransMax)), mac->scheduling_info.SR_pending); // todo - - /* - if ((mac->scheduling_info.sr_ProhibitTimer_Running == 0)) { - mac->scheduling_info.SR_pending = 1; - LOG_D(NR_MAC, - "[UE %d] Frame %d slot %d send SR indication (SR_COUNTER/dsr_TransMax %d/%d), SR_pending %d, sr_ProhibitTimer_Running == 0\n", - module_idP, frameP, slot, - mac->scheduling_info.SR_COUNTER, - (1 << - (2 + - // mac-> - // physicalConfigDedicated->schedulingRequestConfig->choice. - // setup.dsr_TransMax)), - dsr_TransMax)), - mac->scheduling_info.SR_pending); // todo - return (0); - } - */ // todo - +/* + if ((mac->scheduling_info.sr_ProhibitTimer_Running == 0)) { + mac->scheduling_info.SR_pending = 1; + LOG_D(NR_MAC, + "[UE %d] Frame %d slot %d send SR indication (SR_COUNTER/dsr_TransMax %d/%d), SR_pending %d, sr_ProhibitTimer_Running == 0\n", + module_idP, frameP, slot, + mac->scheduling_info.SR_COUNTER, + (1 << + (2 + +// mac-> +// physicalConfigDedicated->schedulingRequestConfig->choice. +// setup.dsr_TransMax)), + dsr_TransMax)), + mac->scheduling_info.SR_pending); // todo + return (0); + } +*/ // todo if ((mac->scheduling_info.SR_pending == 1) && (mac->scheduling_info.SR_COUNTER < (1 << (2 + //mac-> //physicalConfigDedicated->schedulingRequestConfig->choice.setup. - //dsr_TransMax)))) { - dsr_TransMax)))) { + //dsr_TransMax)))) { + dsr_TransMax)))) { LOG_D(NR_MAC, "[UE %d] Frame %d slot %d PHY asks for SR (SR_COUNTER/dsr_TransMax %d/%d), SR_pending %d, increment SR_COUNTER\n", module_idP, frameP, slot, @@ -2281,7 +2274,6 @@ int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, slot_t slot) { mac->scheduling_info. sr_ProhibitTimer_Running = 0; } - //mac->ul_active =1; return (1); //instruct phy to signal SR } else { @@ -2308,26 +2300,28 @@ uint8_t nr_get_csi_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sched_t *pucch) { + NR_BWP_Id_t bwp_id = mac->UL_BWP_Id; NR_PUCCH_Config_t *pucch_Config = NULL; int csi_bits = 0; if(mac->cg && - mac->cg->spCellConfig && - mac->cg->spCellConfig->spCellConfigDedicated && - mac->cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig) { + mac->cg->spCellConfig && + mac->cg->spCellConfig->spCellConfigDedicated && + mac->cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig) { + NR_CSI_MeasConfig_t *csi_measconfig = mac->cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup; - for (int csi_report_id = 0; csi_report_id < csi_measconfig->csi_ReportConfigToAddModList->list.count; csi_report_id++) { + for (int csi_report_id = 0; csi_report_id < csi_measconfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){ NR_CSI_ReportConfig_t *csirep = csi_measconfig->csi_ReportConfigToAddModList->list.array[csi_report_id]; - if(csirep->reportConfigType.present == NR_CSI_ReportConfig__reportConfigType_PR_periodic) { + if(csirep->reportConfigType.present == NR_CSI_ReportConfig__reportConfigType_PR_periodic){ int period, offset; csi_period_offset(csirep, NULL, &period, &offset); + int scs; NR_BWP_Uplink_t *ubwp = mac->ULbwp[0]; NR_BWP_UplinkCommon_t *initialUplinkBWP; - if (mac->scc) initialUplinkBWP = mac->scc->uplinkConfigCommon->initialUplinkBWP; else initialUplinkBWP = &mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP; @@ -2344,36 +2338,38 @@ uint8_t nr_get_csi_measurements(NR_UE_MAC_INST_t *mac, mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config && mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup) { pucch_Config = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup; - } else if (bwp_id==0 && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) { + } + else if (bwp_id==0 && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) { pucch_Config = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup; } const int n_slots_frame = nr_slots_per_frame[scs]; - if (((n_slots_frame*frame + slot - offset)%period) == 0 && pucch_Config) { + NR_PUCCH_CSI_Resource_t *pucchcsires = csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.array[0]; NR_PUCCH_ResourceSet_t *pucchresset = pucch_Config->resourceSetToAddModList->list.array[1]; // set with formats >1 int n = pucchresset->resourceList.list.count; + int res_index; int found = -1; - for (res_index = 0; res_index < n; res_index++) { if (*pucchresset->resourceList.list.array[res_index] == pucchcsires->pucch_Resource) { found = res_index; break; } } - AssertFatal(found != -1, "CSI resource not found among PUCCH resources\n"); + pucch->resource_indicator = found; csi_bits = nr_get_csi_payload(mac, pucch, csi_measconfig); } - } else + } + else AssertFatal(1==0,"Only periodic CSI reporting is currently implemented\n"); } } @@ -2385,21 +2381,20 @@ uint8_t nr_get_csi_measurements(NR_UE_MAC_INST_t *mac, uint8_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch, NR_CSI_MeasConfig_t *csi_MeasConfig) { + int n_csi_bits = 0; + AssertFatal(csi_MeasConfig->csi_ReportConfigToAddModList->list.count>0,"No CSI Report configuration available\n"); - for (int csi_report_id=0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++) { + for (int csi_report_id=0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){ struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]; NR_CSI_ResourceConfigId_t csi_ResourceConfigId = csi_reportconfig->resourcesForChannelMeasurement; - switch(csi_reportconfig->reportQuantity.present) { case NR_CSI_ReportConfig__reportQuantity_PR_none: break; - case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP: n_csi_bits += get_ssb_rsrp_payload(mac,pucch,csi_reportconfig,csi_ResourceConfigId,csi_MeasConfig); break; - case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP: case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI: case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1: @@ -2407,12 +2402,10 @@ uint8_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac, case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI: case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI: AssertFatal(1==0,"Measurement report based on CSI-RS not availalble\n"); - default: AssertFatal(1==0,"Invalid CSI report quantity type %d\n",csi_reportconfig->reportQuantity.present); } } - return (n_csi_bits); } @@ -2422,6 +2415,7 @@ uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, struct NR_CSI_ReportConfig *csi_reportconfig, NR_CSI_ResourceConfigId_t csi_ResourceConfigId, NR_CSI_MeasConfig_t *csi_MeasConfig) { + int nb_ssb = 0; // nb of ssb in the resource int nb_meas = 0; // nb of ssb to report measurements on int bits = 0; @@ -2429,8 +2423,8 @@ uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, for (int csi_resourceidx = 0; csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_resourceidx++) { struct NR_CSI_ResourceConfig *csi_resourceconfig = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]; - if (csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId) { + if (csi_reportconfig->groupBasedBeamReporting.present == NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled) { if (csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS != NULL) nb_meas = *(csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS)+1; @@ -2441,7 +2435,8 @@ uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, for (int csi_ssb_idx = 0; csi_ssb_idx < csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.count; csi_ssb_idx++) { if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceSetId == - *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])) { + *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])){ + ///only one SSB resource set from spec 38.331 IE CSI-ResourceConfig nb_ssb = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceList.list.count; break; @@ -2456,9 +2451,11 @@ uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, LOG_E(MAC, "In current implementation only the SSB of synchronization is measured at PHY. This works only for a single SSB scenario\n"); int ssb_rsrp[2][nb_meas]; // the array contains index and RSRP of each SSB to be reported (nb_meas highest RSRPs) + //TODO replace the following 2 lines with a function to order the nb_meas highest SSB RSRPs ssb_rsrp[0][0] = mac->mib_ssb; ssb_rsrp[1][0] = mac->ssb_rsrp_dBm; + uint8_t ssbi; if (ssbri_bits > 0) { @@ -2474,21 +2471,20 @@ uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, bits += 7; // 7 bits for highest RSRP // from the second SSB, differential report - for (int i=1; i<nb_meas; i++) { + for (int i=1; i<nb_meas; i++){ ssbi = ssb_rsrp[0][i]; reverse_n_bits(&ssbi, ssbri_bits); temp_payload = ssbi; bits += ssbri_bits; + rsrp_idx = get_rsrp_diff_index(ssb_rsrp[1][0],ssb_rsrp[1][i]); reverse_n_bits(&rsrp_idx, 4); temp_payload |= (rsrp_idx<<bits); bits += 4; // 7 bits for highest RSRP } - break; // resorce found } } - pucch->csi_part1_payload = temp_payload; return bits; } @@ -2498,11 +2494,10 @@ uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, // according to Table 10.1.6.1-1 in 38.133 uint8_t get_rsrp_index(int rsrp) { - int index = rsrp + 157; + int index = rsrp + 157; if (rsrp>-44) index = 113; - if (rsrp<-140) index = 16; @@ -2513,46 +2508,47 @@ uint8_t get_rsrp_index(int rsrp) { // returns index from differential RSRP // according to Table 10.1.6.1-2 in 38.133 uint8_t get_rsrp_diff_index(int best_rsrp,int current_rsrp) { - int diff = best_rsrp-current_rsrp; + int diff = best_rsrp-current_rsrp; if (diff>30) return 15; else return (diff>>1); + } -void nr_ue_send_sdu(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id) { +void nr_ue_send_sdu(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id){ + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_IN); + LOG_D(MAC, "In %s [%d.%d] Handling DLSCH PDU...\n", __FUNCTION__, dl_info->frame, dl_info->slot); // Processing MAC PDU // it parses MAC CEs subheaders, MAC CEs, SDU subheaderds and SDUs - switch (dl_info->rx_ind->rx_indication_body[pdu_id].pdu_type) { + switch (dl_info->rx_ind->rx_indication_body[pdu_id].pdu_type){ case FAPI_NR_RX_PDU_TYPE_DLSCH: - nr_ue_process_mac_pdu(dl_info, ul_time_alignment, pdu_id); - break; - + nr_ue_process_mac_pdu(dl_info, ul_time_alignment, pdu_id); + break; case FAPI_NR_RX_PDU_TYPE_RAR: - nr_ue_process_rar(dl_info, ul_time_alignment, pdu_id); - break; - + nr_ue_process_rar(dl_info, ul_time_alignment, pdu_id); + break; default: - break; + break; } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT); + } // N_RB configuration according to 7.3.1.0 (DCI size alignment) of TS 38.212 -int get_n_rb(NR_UE_MAC_INST_t *mac, int rnti_type) { - int N_RB = 0, start_RB; +int get_n_rb(NR_UE_MAC_INST_t *mac, int rnti_type){ + int N_RB = 0, start_RB; switch(rnti_type) { case NR_RNTI_RA: case NR_RNTI_TC: case NR_RNTI_P: { NR_BWP_Id_t dl_bwp_id = mac->DL_BWP_Id; - if (mac->DLbwp[dl_bwp_id-1]->bwp_Common->pdcch_ConfigCommon->choice.setup->controlResourceSetZero) { uint8_t coreset_id = 0; // assuming controlResourceSetId is 0 for controlResourceSetZero NR_ControlResourceSet_t *coreset = mac->coreset[dl_bwp_id-1][coreset_id]; @@ -2560,20 +2556,17 @@ int get_n_rb(NR_UE_MAC_INST_t *mac, int rnti_type) { } else { N_RB = NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); } - break; } - case NR_RNTI_SI: N_RB = mac->type0_PDCCH_CSS_config.num_rbs; break; - case NR_RNTI_C: N_RB = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); break; } - return N_RB; + } uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, @@ -2582,12 +2575,14 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, uint16_t rnti, uint64_t *dci_pdu, dci_pdu_rel15_t *dci_pdu_rel15) { + int N_RB = 0; int pos = 0; int fsize = 0; + int rnti_type = get_rnti_type(mac, rnti); - int N_RB_UL = 0; + int N_RB_UL = 0; if(mac->scc_SIB) { N_RB_UL = NRRIV2BW(mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE); } else if(mac->ULbwp[0]) { @@ -2597,615 +2592,666 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, } LOG_D(MAC,"nr_extract_dci_info : dci_pdu %lx, size %d\n",*dci_pdu,dci_size); - switch(dci_format) { - case NR_DL_DCI_FORMAT_1_0: - switch(rnti_type) { - case NR_RNTI_RA: - if(mac->scc_SIB) { - N_RB = NRRIV2BW(mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - } else { - N_RB = get_n_rb(mac, rnti_type); - } - // Freq domain assignment - fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); - pos=fsize; - dci_pdu_rel15->frequency_domain_assignment.val = *dci_pdu>>(dci_size-pos)&((1<<fsize)-1); + case NR_DL_DCI_FORMAT_1_0: + switch(rnti_type) { + case NR_RNTI_RA: + if(mac->scc_SIB) { + N_RB = NRRIV2BW(mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + } else { + N_RB = get_n_rb(mac, rnti_type); + } + // Freq domain assignment + fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); + pos=fsize; + dci_pdu_rel15->frequency_domain_assignment.val = *dci_pdu>>(dci_size-pos)&((1<<fsize)-1); #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"frequency-domain assignment %d (%d bits) N_RB_BWP %d=> %d (0x%lx)\n",dci_pdu_rel15->frequency_domain_assignment.val,fsize,N_RB,dci_size-pos,*dci_pdu); + LOG_D(MAC,"frequency-domain assignment %d (%d bits) N_RB_BWP %d=> %d (0x%lx)\n",dci_pdu_rel15->frequency_domain_assignment.val,fsize,N_RB,dci_size-pos,*dci_pdu); #endif - // Time domain assignment - pos+=4; - dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu >> (dci_size-pos))&0xf; + // Time domain assignment + pos+=4; + dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu >> (dci_size-pos))&0xf; #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"time-domain assignment %d (4 bits)=> %d (0x%lx)\n",dci_pdu_rel15->time_domain_assignment.val,dci_size-pos,*dci_pdu); + LOG_D(MAC,"time-domain assignment %d (4 bits)=> %d (0x%lx)\n",dci_pdu_rel15->time_domain_assignment.val,dci_size-pos,*dci_pdu); #endif - // VRB to PRB mapping - pos++; - dci_pdu_rel15->vrb_to_prb_mapping.val = (*dci_pdu>>(dci_size-pos))&0x1; + // VRB to PRB mapping + + pos++; + dci_pdu_rel15->vrb_to_prb_mapping.val = (*dci_pdu>>(dci_size-pos))&0x1; #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"vrb to prb mapping %d (1 bits)=> %d (0x%lx)\n",dci_pdu_rel15->vrb_to_prb_mapping.val,dci_size-pos,*dci_pdu); + LOG_D(MAC,"vrb to prb mapping %d (1 bits)=> %d (0x%lx)\n",dci_pdu_rel15->vrb_to_prb_mapping.val,dci_size-pos,*dci_pdu); #endif - // MCS - pos+=5; - dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f; + // MCS + pos+=5; + dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f; #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"mcs %d (5 bits)=> %d (0x%lx)\n",dci_pdu_rel15->mcs,dci_size-pos,*dci_pdu); + LOG_D(MAC,"mcs %d (5 bits)=> %d (0x%lx)\n",dci_pdu_rel15->mcs,dci_size-pos,*dci_pdu); #endif - // TB scaling - pos+=2; - dci_pdu_rel15->tb_scaling = (*dci_pdu>>(dci_size-pos))&0x3; + // TB scaling + pos+=2; + dci_pdu_rel15->tb_scaling = (*dci_pdu>>(dci_size-pos))&0x3; #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"tb_scaling %d (2 bits)=> %d (0x%lx)\n",dci_pdu_rel15->tb_scaling,dci_size-pos,*dci_pdu); + LOG_D(MAC,"tb_scaling %d (2 bits)=> %d (0x%lx)\n",dci_pdu_rel15->tb_scaling,dci_size-pos,*dci_pdu); #endif - break; + break; - case NR_RNTI_C: - //Identifier for DCI formats - pos++; - dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1; + case NR_RNTI_C: - //switch to DCI_0_0 - if (dci_pdu_rel15->format_indicator == 0) { - dci_pdu_rel15 = &mac->def_dci_pdu_rel15[NR_UL_DCI_FORMAT_0_0]; - return 2+nr_extract_dci_info(mac, NR_UL_DCI_FORMAT_0_0, dci_size, rnti, dci_pdu, dci_pdu_rel15); - } + //Identifier for DCI formats + pos++; + dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1; + //switch to DCI_0_0 + if (dci_pdu_rel15->format_indicator == 0) { + dci_pdu_rel15 = &mac->def_dci_pdu_rel15[NR_UL_DCI_FORMAT_0_0]; + return 2+nr_extract_dci_info(mac, NR_UL_DCI_FORMAT_0_0, dci_size, rnti, dci_pdu, dci_pdu_rel15); + } #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"Format indicator %d (%d bits) N_RB_BWP %d => %d (0x%lx)\n",dci_pdu_rel15->format_indicator,1,N_RB,dci_size-pos,*dci_pdu); + LOG_D(MAC,"Format indicator %d (%d bits) N_RB_BWP %d => %d (0x%lx)\n",dci_pdu_rel15->format_indicator,1,N_RB,dci_size-pos,*dci_pdu); #endif - // check BWP id - if (mac->DLbwp[0]) N_RB=NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - else N_RB=NRRIV2BW(mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + // check BWP id + if (mac->DLbwp[0]) N_RB=NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + else N_RB=NRRIV2BW(mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - // Freq domain assignment (275rb >> fsize = 16) - fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); - pos+=fsize; - dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1); + // Freq domain assignment (275rb >> fsize = 16) + fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); + pos+=fsize; + dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1); + #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"Freq domain assignment %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->frequency_domain_assignment.val,fsize,dci_size-pos,*dci_pdu); + LOG_D(MAC,"Freq domain assignment %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->frequency_domain_assignment.val,fsize,dci_size-pos,*dci_pdu); #endif - uint16_t is_ra = 1; - - for (int i=0; i<fsize; i++) - if (!((dci_pdu_rel15->frequency_domain_assignment.val>>i)&1)) { - is_ra = 0; - break; - } - - if (is_ra) { //fsize are all 1 38.212 p86 - // ra_preamble_index 6 bits - pos+=6; - dci_pdu_rel15->ra_preamble_index = (*dci_pdu>>(dci_size-pos))&0x3f; - // UL/SUL indicator 1 bit - pos++; - dci_pdu_rel15->ul_sul_indicator.val = (*dci_pdu>>(dci_size-pos))&1; - // SS/PBCH index 6 bits - pos+=6; - dci_pdu_rel15->ss_pbch_index = (*dci_pdu>>(dci_size-pos))&0x3f; - // prach_mask_index 4 bits - pos+=4; - dci_pdu_rel15->prach_mask_index = (*dci_pdu>>(dci_size-pos))&0xf; - } //end if - else { - // Time domain assignment 4bit - pos+=4; - dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0xf; + + uint16_t is_ra = 1; + for (int i=0; i<fsize; i++) + if (!((dci_pdu_rel15->frequency_domain_assignment.val>>i)&1)) { + is_ra = 0; + break; + } + if (is_ra) //fsize are all 1 38.212 p86 + { + // ra_preamble_index 6 bits + pos+=6; + dci_pdu_rel15->ra_preamble_index = (*dci_pdu>>(dci_size-pos))&0x3f; + + // UL/SUL indicator 1 bit + pos++; + dci_pdu_rel15->ul_sul_indicator.val = (*dci_pdu>>(dci_size-pos))&1; + + // SS/PBCH index 6 bits + pos+=6; + dci_pdu_rel15->ss_pbch_index = (*dci_pdu>>(dci_size-pos))&0x3f; + + // prach_mask_index 4 bits + pos+=4; + dci_pdu_rel15->prach_mask_index = (*dci_pdu>>(dci_size-pos))&0xf; + + } //end if + else { + + // Time domain assignment 4bit + + pos+=4; + dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0xf; #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"Time domain assignment %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->time_domain_assignment.val,4,dci_size-pos,*dci_pdu); + LOG_D(MAC,"Time domain assignment %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->time_domain_assignment.val,4,dci_size-pos,*dci_pdu); #endif - // VRB to PRB mapping 1bit - pos++; - dci_pdu_rel15->vrb_to_prb_mapping.val = (*dci_pdu>>(dci_size-pos))&1; + + // VRB to PRB mapping 1bit + pos++; + dci_pdu_rel15->vrb_to_prb_mapping.val = (*dci_pdu>>(dci_size-pos))&1; #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"VRB to PRB %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->vrb_to_prb_mapping.val,1,dci_size-pos,*dci_pdu); + LOG_D(MAC,"VRB to PRB %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->vrb_to_prb_mapping.val,1,dci_size-pos,*dci_pdu); #endif - // MCS 5bit //bit over 32, so dci_pdu ++ - pos+=5; - dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f; + + // MCS 5bit //bit over 32, so dci_pdu ++ + pos+=5; + dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f; #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"MCS %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->mcs,5,dci_size-pos,*dci_pdu); + LOG_D(MAC,"MCS %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->mcs,5,dci_size-pos,*dci_pdu); #endif - // New data indicator 1bit - pos++; - dci_pdu_rel15->ndi = (*dci_pdu>>(dci_size-pos))&1; + + // New data indicator 1bit + pos++; + dci_pdu_rel15->ndi = (*dci_pdu>>(dci_size-pos))&1; #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"NDI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->ndi,1,dci_size-pos,*dci_pdu); -#endif - // Redundancy version 2bit - pos+=2; - dci_pdu_rel15->rv = (*dci_pdu>>(dci_size-pos))&0x3; + LOG_D(MAC,"NDI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->ndi,1,dci_size-pos,*dci_pdu); +#endif + + // Redundancy version 2bit + pos+=2; + dci_pdu_rel15->rv = (*dci_pdu>>(dci_size-pos))&0x3; #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"RV %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->rv,2,dci_size-pos,*dci_pdu); + LOG_D(MAC,"RV %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->rv,2,dci_size-pos,*dci_pdu); #endif - // HARQ process number 4bit - pos+=4; - dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf; + + // HARQ process number 4bit + pos+=4; + dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf; #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"HARQ_PID %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->harq_pid,4,dci_size-pos,*dci_pdu); + LOG_D(MAC,"HARQ_PID %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->harq_pid,4,dci_size-pos,*dci_pdu); #endif - // Downlink assignment index 2bit - pos+=2; - dci_pdu_rel15->dai[0].val = (*dci_pdu>>(dci_size-pos))&3; + + // Downlink assignment index 2bit + pos+=2; + dci_pdu_rel15->dai[0].val = (*dci_pdu>>(dci_size-pos))&3; #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"DAI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->dai[0].val,2,dci_size-pos,*dci_pdu); + LOG_D(MAC,"DAI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->dai[0].val,2,dci_size-pos,*dci_pdu); #endif - // TPC command for scheduled PUCCH 2bit - pos+=2; - dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&3; + + // TPC command for scheduled PUCCH 2bit + pos+=2; + dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&3; #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"TPC %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->tpc,2,dci_size-pos,*dci_pdu); + LOG_D(MAC,"TPC %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->tpc,2,dci_size-pos,*dci_pdu); #endif - // PUCCH resource indicator 3bit - pos+=3; - dci_pdu_rel15->pucch_resource_indicator = (*dci_pdu>>(dci_size-pos))&0x7; + + // PUCCH resource indicator 3bit + pos+=3; + dci_pdu_rel15->pucch_resource_indicator = (*dci_pdu>>(dci_size-pos))&0x7; #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"PUCCH RI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->pucch_resource_indicator,3,dci_size-pos,*dci_pdu); + LOG_D(MAC,"PUCCH RI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->pucch_resource_indicator,3,dci_size-pos,*dci_pdu); #endif - // PDSCH-to-HARQ_feedback timing indicator 3bit - pos+=3; - dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val = (*dci_pdu>>(dci_size-pos))&0x7; + + // PDSCH-to-HARQ_feedback timing indicator 3bit + pos+=3; + dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val = (*dci_pdu>>(dci_size-pos))&0x7; #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"PDSCH to HARQ TI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val,3,dci_size-pos,*dci_pdu); + LOG_D(MAC,"PDSCH to HARQ TI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val,3,dci_size-pos,*dci_pdu); #endif - } //end else - - break; - - case NR_RNTI_P: - /* - // Short Messages Indicator â€E2 bits - for (int i=0; i<2; i++) - dci_pdu |= (((uint64_t)dci_pdu_rel15->short_messages_indicator>>(1-i))&1)<<(dci_size-pos++); - // Short Messages â€E8 bits - for (int i=0; i<8; i++) - *dci_pdu |= (((uint64_t)dci_pdu_rel15->short_messages>>(7-i))&1)<<(dci_size-pos++); - // Freq domain assignment 0-16 bit - fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); - for (int i=0; i<fsize; i++) - *dci_pdu |= (((uint64_t)dci_pdu_rel15->frequency_domain_assignment>>(fsize-i-1))&1)<<(dci_size-pos++); - // Time domain assignment 4 bit - for (int i=0; i<4; i++) - *dci_pdu |= (((uint64_t)dci_pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_size-pos++); - // VRB to PRB mapping 1 bit - *dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping.val&1)<<(dci_size-pos++); - // MCS 5 bit - for (int i=0; i<5; i++) - *dci_pdu |= (((uint64_t)dci_pdu_rel15->mcs>>(4-i))&1)<<(dci_size-pos++); - - // TB scaling 2 bit - for (int i=0; i<2; i++) - *dci_pdu |= (((uint64_t)dci_pdu_rel15->tb_scaling>>(1-i))&1)<<(dci_size-pos++); - */ - break; - - case NR_RNTI_SI: - N_RB = mac->type0_PDCCH_CSS_config.num_rbs; - // Freq domain assignment 0-16 bit - fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); - pos+=fsize; - dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1); - // Time domain assignment 4 bit - pos+=4; - dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0xf; - // VRB to PRB mapping 1 bit - pos++; - dci_pdu_rel15->vrb_to_prb_mapping.val = (*dci_pdu>>(dci_size-pos))&0x1; - // MCS 5bit //bit over 32, so dci_pdu ++ - pos+=5; - dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f; - // Redundancy version 2 bit - pos+=2; - dci_pdu_rel15->rv = (*dci_pdu>>(dci_size-pos))&3; - // System information indicator 1 bit - pos++; - dci_pdu_rel15->system_info_indicator = (*dci_pdu>>(dci_size-pos))&0x1; - LOG_D(MAC,"N_RB = %i\n", N_RB); - LOG_D(MAC,"dci_size = %i\n", dci_size); - LOG_D(MAC,"fsize = %i\n", fsize); - LOG_D(MAC,"dci_pdu_rel15->frequency_domain_assignment.val = %i\n", dci_pdu_rel15->frequency_domain_assignment.val); - LOG_D(MAC,"dci_pdu_rel15->time_domain_assignment.val = %i\n", dci_pdu_rel15->time_domain_assignment.val); - LOG_D(MAC,"dci_pdu_rel15->vrb_to_prb_mapping.val = %i\n", dci_pdu_rel15->vrb_to_prb_mapping.val); - LOG_D(MAC,"dci_pdu_rel15->mcs = %i\n", dci_pdu_rel15->mcs); - LOG_D(MAC,"dci_pdu_rel15->rv = %i\n", dci_pdu_rel15->rv); - LOG_D(MAC,"dci_pdu_rel15->system_info_indicator = %i\n", dci_pdu_rel15->system_info_indicator); - break; + + } //end else + break; - case NR_RNTI_TC: + case NR_RNTI_P: + /* + // Short Messages Indicator â€E2 bits + for (int i=0; i<2; i++) + dci_pdu |= (((uint64_t)dci_pdu_rel15->short_messages_indicator>>(1-i))&1)<<(dci_size-pos++); + // Short Messages â€E8 bits + for (int i=0; i<8; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->short_messages>>(7-i))&1)<<(dci_size-pos++); + // Freq domain assignment 0-16 bit + fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); + for (int i=0; i<fsize; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->frequency_domain_assignment>>(fsize-i-1))&1)<<(dci_size-pos++); + // Time domain assignment 4 bit + for (int i=0; i<4; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_size-pos++); + // VRB to PRB mapping 1 bit + *dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping.val&1)<<(dci_size-pos++); + // MCS 5 bit + for (int i=0; i<5; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->mcs>>(4-i))&1)<<(dci_size-pos++); + + // TB scaling 2 bit + for (int i=0; i<2; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->tb_scaling>>(1-i))&1)<<(dci_size-pos++); + */ + + break; + + case NR_RNTI_SI: + N_RB = mac->type0_PDCCH_CSS_config.num_rbs; + // Freq domain assignment 0-16 bit + fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); + pos+=fsize; + dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1); + + // Time domain assignment 4 bit + pos+=4; + dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0xf; + + // VRB to PRB mapping 1 bit + pos++; + dci_pdu_rel15->vrb_to_prb_mapping.val = (*dci_pdu>>(dci_size-pos))&0x1; + + // MCS 5bit //bit over 32, so dci_pdu ++ + pos+=5; + dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f; + + // Redundancy version 2 bit + pos+=2; + dci_pdu_rel15->rv = (*dci_pdu>>(dci_size-pos))&3; + + // System information indicator 1 bit + pos++; + dci_pdu_rel15->system_info_indicator = (*dci_pdu>>(dci_size-pos))&0x1; + + LOG_D(MAC,"N_RB = %i\n", N_RB); + LOG_D(MAC,"dci_size = %i\n", dci_size); + LOG_D(MAC,"fsize = %i\n", fsize); + LOG_D(MAC,"dci_pdu_rel15->frequency_domain_assignment.val = %i\n", dci_pdu_rel15->frequency_domain_assignment.val); + LOG_D(MAC,"dci_pdu_rel15->time_domain_assignment.val = %i\n", dci_pdu_rel15->time_domain_assignment.val); + LOG_D(MAC,"dci_pdu_rel15->vrb_to_prb_mapping.val = %i\n", dci_pdu_rel15->vrb_to_prb_mapping.val); + LOG_D(MAC,"dci_pdu_rel15->mcs = %i\n", dci_pdu_rel15->mcs); + LOG_D(MAC,"dci_pdu_rel15->rv = %i\n", dci_pdu_rel15->rv); + LOG_D(MAC,"dci_pdu_rel15->system_info_indicator = %i\n", dci_pdu_rel15->system_info_indicator); - // check BWP id - if (mac->DLbwp[0]) N_RB=NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - else N_RB=NRRIV2BW(mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + break; + + case NR_RNTI_TC: - // indicating a DL DCI format 1bit - pos++; - dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1; + // check BWP id + if (mac->DLbwp[0]) N_RB=NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + else N_RB=NRRIV2BW(mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - //switch to DCI_0_0 - if (dci_pdu_rel15->format_indicator == 0) { - dci_pdu_rel15 = &mac->def_dci_pdu_rel15[NR_UL_DCI_FORMAT_0_0]; - return 2+nr_extract_dci_info(mac, NR_UL_DCI_FORMAT_0_0, dci_size, rnti, dci_pdu, dci_pdu_rel15); - } + // indicating a DL DCI format 1bit + pos++; + dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1; - if (dci_pdu_rel15->format_indicator == 0) - return 1; // discard dci, format indicator not corresponding to dci_format - - // Freq domain assignment 0-16 bit - fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); - pos+=fsize; - dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1); - // Time domain assignment - 4 bits - pos+=4; - dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0xf; - // VRB to PRB mapping - 1 bit - pos++; - dci_pdu_rel15->vrb_to_prb_mapping.val = (*dci_pdu>>(dci_size-pos))&1; - // MCS 5bit //bit over 32, so dci_pdu ++ - pos+=5; - dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f; - // New data indicator - 1 bit - pos++; - dci_pdu_rel15->ndi = (*dci_pdu>>(dci_size-pos))&1; - // Redundancy version - 2 bits - pos+=2; - dci_pdu_rel15->rv = (*dci_pdu>>(dci_size-pos))&3; - // HARQ process number - 4 bits - pos+=4; - dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf; - // Downlink assignment index - 2 bits - pos+=2; - dci_pdu_rel15->dai[0].val = (*dci_pdu>>(dci_size-pos))&3; - // TPC command for scheduled PUCCH - 2 bits - pos+=2; - dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&3; - // PUCCH resource indicator - 3 bits - pos+=3; - dci_pdu_rel15->pucch_resource_indicator = (*dci_pdu>>(dci_size-pos))&7; - // PDSCH-to-HARQ_feedback timing indicator - 3 bits - pos+=3; - dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val = (*dci_pdu>>(dci_size-pos))&7; - LOG_D(NR_MAC,"N_RB = %i\n", N_RB); - LOG_D(NR_MAC,"dci_size = %i\n", dci_size); - LOG_D(NR_MAC,"fsize = %i\n", fsize); - LOG_D(NR_MAC,"dci_pdu_rel15->format_indicator = %i\n", dci_pdu_rel15->format_indicator); - LOG_D(NR_MAC,"dci_pdu_rel15->frequency_domain_assignment.val = %i\n", dci_pdu_rel15->frequency_domain_assignment.val); - LOG_D(NR_MAC,"dci_pdu_rel15->time_domain_assignment.val = %i\n", dci_pdu_rel15->time_domain_assignment.val); - LOG_D(NR_MAC,"dci_pdu_rel15->vrb_to_prb_mapping.val = %i\n", dci_pdu_rel15->vrb_to_prb_mapping.val); - LOG_D(NR_MAC,"dci_pdu_rel15->mcs = %i\n", dci_pdu_rel15->mcs); - LOG_D(NR_MAC,"dci_pdu_rel15->rv = %i\n", dci_pdu_rel15->rv); - LOG_D(NR_MAC,"dci_pdu_rel15->harq_pid = %i\n", dci_pdu_rel15->harq_pid); - LOG_D(NR_MAC,"dci_pdu_rel15->dai[0].val = %i\n", dci_pdu_rel15->dai[0].val); - LOG_D(NR_MAC,"dci_pdu_rel15->tpc = %i\n", dci_pdu_rel15->tpc); - LOG_D(NR_MAC,"dci_pdu_rel15->pucch_resource_indicator = %i\n", dci_pdu_rel15->pucch_resource_indicator); - LOG_D(NR_MAC,"dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val = %i\n", dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val); - break; + //switch to DCI_0_0 + if (dci_pdu_rel15->format_indicator == 0) { + dci_pdu_rel15 = &mac->def_dci_pdu_rel15[NR_UL_DCI_FORMAT_0_0]; + return 2+nr_extract_dci_info(mac, NR_UL_DCI_FORMAT_0_0, dci_size, rnti, dci_pdu, dci_pdu_rel15); } - break; - - case NR_UL_DCI_FORMAT_0_0: - if (mac->ULbwp[0]) N_RB_UL=NRRIV2BW(mac->ULbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - else N_RB_UL=NRRIV2BW(mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + if (dci_pdu_rel15->format_indicator == 0) + return 1; // discard dci, format indicator not corresponding to dci_format + + // Freq domain assignment 0-16 bit + fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); + pos+=fsize; + dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1); + + // Time domain assignment - 4 bits + pos+=4; + dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0xf; + + // VRB to PRB mapping - 1 bit + pos++; + dci_pdu_rel15->vrb_to_prb_mapping.val = (*dci_pdu>>(dci_size-pos))&1; + + // MCS 5bit //bit over 32, so dci_pdu ++ + pos+=5; + dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f; + + // New data indicator - 1 bit + pos++; + dci_pdu_rel15->ndi = (*dci_pdu>>(dci_size-pos))&1; + + // Redundancy version - 2 bits + pos+=2; + dci_pdu_rel15->rv = (*dci_pdu>>(dci_size-pos))&3; + + // HARQ process number - 4 bits + pos+=4; + dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf; + + // Downlink assignment index - 2 bits + pos+=2; + dci_pdu_rel15->dai[0].val = (*dci_pdu>>(dci_size-pos))&3; + + // TPC command for scheduled PUCCH - 2 bits + pos+=2; + dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&3; + + // PUCCH resource indicator - 3 bits + pos+=3; + dci_pdu_rel15->pucch_resource_indicator = (*dci_pdu>>(dci_size-pos))&7; + + // PDSCH-to-HARQ_feedback timing indicator - 3 bits + pos+=3; + dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val = (*dci_pdu>>(dci_size-pos))&7; + + LOG_D(NR_MAC,"N_RB = %i\n", N_RB); + LOG_D(NR_MAC,"dci_size = %i\n", dci_size); + LOG_D(NR_MAC,"fsize = %i\n", fsize); + LOG_D(NR_MAC,"dci_pdu_rel15->format_indicator = %i\n", dci_pdu_rel15->format_indicator); + LOG_D(NR_MAC,"dci_pdu_rel15->frequency_domain_assignment.val = %i\n", dci_pdu_rel15->frequency_domain_assignment.val); + LOG_D(NR_MAC,"dci_pdu_rel15->time_domain_assignment.val = %i\n", dci_pdu_rel15->time_domain_assignment.val); + LOG_D(NR_MAC,"dci_pdu_rel15->vrb_to_prb_mapping.val = %i\n", dci_pdu_rel15->vrb_to_prb_mapping.val); + LOG_D(NR_MAC,"dci_pdu_rel15->mcs = %i\n", dci_pdu_rel15->mcs); + LOG_D(NR_MAC,"dci_pdu_rel15->rv = %i\n", dci_pdu_rel15->rv); + LOG_D(NR_MAC,"dci_pdu_rel15->harq_pid = %i\n", dci_pdu_rel15->harq_pid); + LOG_D(NR_MAC,"dci_pdu_rel15->dai[0].val = %i\n", dci_pdu_rel15->dai[0].val); + LOG_D(NR_MAC,"dci_pdu_rel15->tpc = %i\n", dci_pdu_rel15->tpc); + LOG_D(NR_MAC,"dci_pdu_rel15->pucch_resource_indicator = %i\n", dci_pdu_rel15->pucch_resource_indicator); + LOG_D(NR_MAC,"dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val = %i\n", dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val); - switch(rnti_type) { - case NR_RNTI_C: - //Identifier for DCI formats - pos++; - dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1; + break; + } + break; + + case NR_UL_DCI_FORMAT_0_0: + if (mac->ULbwp[0]) N_RB_UL=NRRIV2BW(mac->ULbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + else N_RB_UL=NRRIV2BW(mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + + switch(rnti_type) + { + case NR_RNTI_C: + //Identifier for DCI formats + pos++; + dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1; #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"Format indicator %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->format_indicator,1,dci_size-pos,*dci_pdu); + LOG_D(MAC,"Format indicator %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->format_indicator,1,dci_size-pos,*dci_pdu); #endif - - if (dci_pdu_rel15->format_indicator == 1) - return 1; // discard dci, format indicator not corresponding to dci_format - - fsize = (int)ceil( log2( (N_RB_UL*(N_RB_UL+1))>>1 ) ); - pos+=fsize; - dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1); + if (dci_pdu_rel15->format_indicator == 1) + return 1; // discard dci, format indicator not corresponding to dci_format + fsize = (int)ceil( log2( (N_RB_UL*(N_RB_UL+1))>>1 ) ); + pos+=fsize; + dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1); #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"Freq domain assignment %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->frequency_domain_assignment.val,fsize,dci_size-pos,*dci_pdu); + LOG_D(MAC,"Freq domain assignment %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->frequency_domain_assignment.val,fsize,dci_size-pos,*dci_pdu); #endif - // Time domain assignment 4bit - pos+=4; - dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0xf; + // Time domain assignment 4bit + pos+=4; + dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0xf; #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"time-domain assignment %d (4 bits)=> %d (0x%lx)\n",dci_pdu_rel15->time_domain_assignment.val,dci_size-pos,*dci_pdu); + LOG_D(MAC,"time-domain assignment %d (4 bits)=> %d (0x%lx)\n",dci_pdu_rel15->time_domain_assignment.val,dci_size-pos,*dci_pdu); #endif - // Frequency hopping flag â€E1 bit - pos++; - dci_pdu_rel15->frequency_hopping_flag.val= (*dci_pdu>>(dci_size-pos))&1; + // Frequency hopping flag â€E1 bit + pos++; + dci_pdu_rel15->frequency_hopping_flag.val= (*dci_pdu>>(dci_size-pos))&1; #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"frequency_hopping %d (1 bit)=> %d (0x%lx)\n",dci_pdu_rel15->frequency_hopping_flag.val,dci_size-pos,*dci_pdu); + LOG_D(MAC,"frequency_hopping %d (1 bit)=> %d (0x%lx)\n",dci_pdu_rel15->frequency_hopping_flag.val,dci_size-pos,*dci_pdu); #endif - // MCS 5 bit - pos+=5; - dci_pdu_rel15->mcs= (*dci_pdu>>(dci_size-pos))&0x1f; + // MCS 5 bit + pos+=5; + dci_pdu_rel15->mcs= (*dci_pdu>>(dci_size-pos))&0x1f; #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"mcs %d (5 bits)=> %d (0x%lx)\n",dci_pdu_rel15->mcs,dci_size-pos,*dci_pdu); + LOG_D(MAC,"mcs %d (5 bits)=> %d (0x%lx)\n",dci_pdu_rel15->mcs,dci_size-pos,*dci_pdu); #endif - // New data indicator 1bit - pos++; - dci_pdu_rel15->ndi= (*dci_pdu>>(dci_size-pos))&1; + // New data indicator 1bit + pos++; + dci_pdu_rel15->ndi= (*dci_pdu>>(dci_size-pos))&1; #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"NDI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->ndi,1,dci_size-pos,*dci_pdu); + LOG_D(MAC,"NDI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->ndi,1,dci_size-pos,*dci_pdu); #endif - // Redundancy version 2bit - pos+=2; - dci_pdu_rel15->rv= (*dci_pdu>>(dci_size-pos))&3; + // Redundancy version 2bit + pos+=2; + dci_pdu_rel15->rv= (*dci_pdu>>(dci_size-pos))&3; #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"RV %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->rv,2,dci_size-pos,*dci_pdu); + LOG_D(MAC,"RV %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->rv,2,dci_size-pos,*dci_pdu); #endif - // HARQ process number 4bit - pos+=4; - dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf; + // HARQ process number 4bit + pos+=4; + dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf; #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"HARQ_PID %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->harq_pid,4,dci_size-pos,*dci_pdu); + LOG_D(MAC,"HARQ_PID %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->harq_pid,4,dci_size-pos,*dci_pdu); #endif - // TPC command for scheduled PUSCH â€E2 bits - pos+=2; - dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&3; + // TPC command for scheduled PUSCH â€E2 bits + pos+=2; + dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&3; #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"TPC %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->tpc,2,dci_size-pos,*dci_pdu); + LOG_D(MAC,"TPC %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->tpc,2,dci_size-pos,*dci_pdu); #endif - // UL/SUL indicator â€E1 bit - /* commented for now (RK): need to get this from BWP descriptor - if (cfg->pucch_config.pucch_GroupHopping.value) - dci_pdu->= ((uint64_t)*dci_pdu>>(dci_size-pos)ul_sul_indicator&1)<<(dci_size-pos++); - */ - break; - - case NR_RNTI_TC: - //Identifier for DCI formats - pos++; - dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1; + // UL/SUL indicator â€E1 bit + /* commented for now (RK): need to get this from BWP descriptor + if (cfg->pucch_config.pucch_GroupHopping.value) + dci_pdu->= ((uint64_t)*dci_pdu>>(dci_size-pos)ul_sul_indicator&1)<<(dci_size-pos++); + */ + break; + + case NR_RNTI_TC: + //Identifier for DCI formats + pos++; + dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1; #ifdef DEBUG_EXTRACT_DCI - LOG_I(MAC,"Format indicator %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->format_indicator,1,dci_size-pos,*dci_pdu); + LOG_I(MAC,"Format indicator %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->format_indicator,1,dci_size-pos,*dci_pdu); #endif - - if (dci_pdu_rel15->format_indicator == 1) - return 1; // discard dci, format indicator not corresponding to dci_format - - fsize = (int)ceil( log2( (N_RB_UL*(N_RB_UL+1))>>1 ) ); - pos+=fsize; - dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1); + if (dci_pdu_rel15->format_indicator == 1) + return 1; // discard dci, format indicator not corresponding to dci_format + fsize = (int)ceil( log2( (N_RB_UL*(N_RB_UL+1))>>1 ) ); + pos+=fsize; + dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1); #ifdef DEBUG_EXTRACT_DCI - LOG_I(MAC,"Freq domain assignment %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->frequency_domain_assignment.val,fsize,dci_size-pos,*dci_pdu); + LOG_I(MAC,"Freq domain assignment %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->frequency_domain_assignment.val,fsize,dci_size-pos,*dci_pdu); #endif - // Time domain assignment 4bit - pos+=4; - dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0xf; + // Time domain assignment 4bit + pos+=4; + dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0xf; #ifdef DEBUG_EXTRACT_DCI - LOG_I(MAC,"time-domain assignment %d (4 bits)=> %d (0x%lx)\n",dci_pdu_rel15->time_domain_assignment.val,dci_size-pos,*dci_pdu); + LOG_I(MAC,"time-domain assignment %d (4 bits)=> %d (0x%lx)\n",dci_pdu_rel15->time_domain_assignment.val,dci_size-pos,*dci_pdu); #endif - // Frequency hopping flag â€E1 bit - pos++; - dci_pdu_rel15->frequency_hopping_flag.val= (*dci_pdu>>(dci_size-pos))&1; + // Frequency hopping flag â€E1 bit + pos++; + dci_pdu_rel15->frequency_hopping_flag.val= (*dci_pdu>>(dci_size-pos))&1; #ifdef DEBUG_EXTRACT_DCI - LOG_I(MAC,"frequency_hopping %d (1 bit)=> %d (0x%lx)\n",dci_pdu_rel15->frequency_hopping_flag.val,dci_size-pos,*dci_pdu); + LOG_I(MAC,"frequency_hopping %d (1 bit)=> %d (0x%lx)\n",dci_pdu_rel15->frequency_hopping_flag.val,dci_size-pos,*dci_pdu); #endif - // MCS 5 bit - pos+=5; - dci_pdu_rel15->mcs= (*dci_pdu>>(dci_size-pos))&0x1f; + // MCS 5 bit + pos+=5; + dci_pdu_rel15->mcs= (*dci_pdu>>(dci_size-pos))&0x1f; #ifdef DEBUG_EXTRACT_DCI - LOG_I(MAC,"mcs %d (5 bits)=> %d (0x%lx)\n",dci_pdu_rel15->mcs,dci_size-pos,*dci_pdu); + LOG_I(MAC,"mcs %d (5 bits)=> %d (0x%lx)\n",dci_pdu_rel15->mcs,dci_size-pos,*dci_pdu); #endif - // New data indicator 1bit - pos++; - dci_pdu_rel15->ndi= (*dci_pdu>>(dci_size-pos))&1; + // New data indicator 1bit + pos++; + dci_pdu_rel15->ndi= (*dci_pdu>>(dci_size-pos))&1; #ifdef DEBUG_EXTRACT_DCI - LOG_I(MAC,"NDI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->ndi,1,dci_size-pos,*dci_pdu); + LOG_I(MAC,"NDI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->ndi,1,dci_size-pos,*dci_pdu); #endif - // Redundancy version 2bit - pos+=2; - dci_pdu_rel15->rv= (*dci_pdu>>(dci_size-pos))&3; + // Redundancy version 2bit + pos+=2; + dci_pdu_rel15->rv= (*dci_pdu>>(dci_size-pos))&3; #ifdef DEBUG_EXTRACT_DCI - LOG_I(MAC,"RV %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->rv,2,dci_size-pos,*dci_pdu); + LOG_I(MAC,"RV %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->rv,2,dci_size-pos,*dci_pdu); #endif - // HARQ process number 4bit - pos+=4; - dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf; + // HARQ process number 4bit + pos+=4; + dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf; #ifdef DEBUG_EXTRACT_DCI - LOG_I(MAC,"HARQ_PID %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->harq_pid,4,dci_size-pos,*dci_pdu); + LOG_I(MAC,"HARQ_PID %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->harq_pid,4,dci_size-pos,*dci_pdu); #endif - // TPC command for scheduled PUSCH â€E2 bits - pos+=2; - dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&3; + // TPC command for scheduled PUSCH â€E2 bits + pos+=2; + dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&3; #ifdef DEBUG_EXTRACT_DCI - LOG_I(MAC,"TPC %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->tpc,2,dci_size-pos,*dci_pdu); + LOG_I(MAC,"TPC %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->tpc,2,dci_size-pos,*dci_pdu); #endif - break; + break; + } - - break; - - case NR_DL_DCI_FORMAT_1_1: - switch(rnti_type) { - case NR_RNTI_C: - //Identifier for DCI formats - pos++; - dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1; - - if (dci_pdu_rel15->format_indicator == 0) - return 1; // discard dci, format indicator not corresponding to dci_format - - // Carrier indicator - pos+=dci_pdu_rel15->carrier_indicator.nbits; - dci_pdu_rel15->carrier_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->carrier_indicator.nbits)-1); - // BWP Indicator - pos+=dci_pdu_rel15->bwp_indicator.nbits; - dci_pdu_rel15->bwp_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->bwp_indicator.nbits)-1); - // Frequency domain resource assignment - pos+=dci_pdu_rel15->frequency_domain_assignment.nbits; - dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->frequency_domain_assignment.nbits)-1); - // Time domain resource assignment - pos+=dci_pdu_rel15->time_domain_assignment.nbits; - dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->time_domain_assignment.nbits)-1); - // VRB-to-PRB mapping - pos+=dci_pdu_rel15->vrb_to_prb_mapping.nbits; - dci_pdu_rel15->vrb_to_prb_mapping.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->vrb_to_prb_mapping.nbits)-1); - // PRB bundling size indicator - pos+=dci_pdu_rel15->prb_bundling_size_indicator.nbits; - dci_pdu_rel15->prb_bundling_size_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->prb_bundling_size_indicator.nbits)-1); - // Rate matching indicator - pos+=dci_pdu_rel15->rate_matching_indicator.nbits; - dci_pdu_rel15->rate_matching_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->rate_matching_indicator.nbits)-1); - // ZP CSI-RS trigger - pos+=dci_pdu_rel15->zp_csi_rs_trigger.nbits; - dci_pdu_rel15->zp_csi_rs_trigger.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->zp_csi_rs_trigger.nbits)-1); - //TB1 - // MCS 5bit - pos+=5; - dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f; - // New data indicator 1bit - pos+=1; - dci_pdu_rel15->ndi = (*dci_pdu>>(dci_size-pos))&0x1; - // Redundancy version 2bit - pos+=2; - dci_pdu_rel15->rv = (*dci_pdu>>(dci_size-pos))&0x3; - //TB2 - // MCS 5bit - pos+=dci_pdu_rel15->mcs2.nbits; - dci_pdu_rel15->mcs2.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->mcs2.nbits)-1); - // New data indicator 1bit - pos+=dci_pdu_rel15->ndi2.nbits; - dci_pdu_rel15->ndi2.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->ndi2.nbits)-1); - // Redundancy version 2bit - pos+=dci_pdu_rel15->rv2.nbits; - dci_pdu_rel15->rv2.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->rv2.nbits)-1); - // HARQ process number 4bit - pos+=4; - dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf; - // Downlink assignment index - pos+=dci_pdu_rel15->dai[0].nbits; - dci_pdu_rel15->dai[0].val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->dai[0].nbits)-1); - // TPC command for scheduled PUCCH 2bit - pos+=2; - dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&0x3; - // PUCCH resource indicator 3bit - pos+=3; - dci_pdu_rel15->pucch_resource_indicator = (*dci_pdu>>(dci_size-pos))&0x3; - // PDSCH-to-HARQ_feedback timing indicator - pos+=dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.nbits; - dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.nbits)-1); - // Antenna ports - pos+=dci_pdu_rel15->antenna_ports.nbits; - dci_pdu_rel15->antenna_ports.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->antenna_ports.nbits)-1); - // TCI - pos+=dci_pdu_rel15->transmission_configuration_indication.nbits; - dci_pdu_rel15->transmission_configuration_indication.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->transmission_configuration_indication.nbits)-1); - // SRS request - pos+=dci_pdu_rel15->srs_request.nbits; - dci_pdu_rel15->srs_request.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->srs_request.nbits)-1); - // CBG transmission information - pos+=dci_pdu_rel15->cbgti.nbits; - dci_pdu_rel15->cbgti.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->cbgti.nbits)-1); - // CBG flushing out information - pos+=dci_pdu_rel15->cbgfi.nbits; - dci_pdu_rel15->cbgfi.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->cbgfi.nbits)-1); - // DMRS sequence init - pos+=1; - dci_pdu_rel15->dmrs_sequence_initialization.val = (*dci_pdu>>(dci_size-pos))&0x1; - break; + break; + + case NR_DL_DCI_FORMAT_1_1: + switch(rnti_type) + { + case NR_RNTI_C: + //Identifier for DCI formats + pos++; + dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1; + if (dci_pdu_rel15->format_indicator == 0) + return 1; // discard dci, format indicator not corresponding to dci_format + // Carrier indicator + pos+=dci_pdu_rel15->carrier_indicator.nbits; + dci_pdu_rel15->carrier_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->carrier_indicator.nbits)-1); + // BWP Indicator + pos+=dci_pdu_rel15->bwp_indicator.nbits; + dci_pdu_rel15->bwp_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->bwp_indicator.nbits)-1); + // Frequency domain resource assignment + pos+=dci_pdu_rel15->frequency_domain_assignment.nbits; + dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->frequency_domain_assignment.nbits)-1); + // Time domain resource assignment + pos+=dci_pdu_rel15->time_domain_assignment.nbits; + dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->time_domain_assignment.nbits)-1); + // VRB-to-PRB mapping + pos+=dci_pdu_rel15->vrb_to_prb_mapping.nbits; + dci_pdu_rel15->vrb_to_prb_mapping.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->vrb_to_prb_mapping.nbits)-1); + // PRB bundling size indicator + pos+=dci_pdu_rel15->prb_bundling_size_indicator.nbits; + dci_pdu_rel15->prb_bundling_size_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->prb_bundling_size_indicator.nbits)-1); + // Rate matching indicator + pos+=dci_pdu_rel15->rate_matching_indicator.nbits; + dci_pdu_rel15->rate_matching_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->rate_matching_indicator.nbits)-1); + // ZP CSI-RS trigger + pos+=dci_pdu_rel15->zp_csi_rs_trigger.nbits; + dci_pdu_rel15->zp_csi_rs_trigger.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->zp_csi_rs_trigger.nbits)-1); + //TB1 + // MCS 5bit + pos+=5; + dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f; + // New data indicator 1bit + pos+=1; + dci_pdu_rel15->ndi = (*dci_pdu>>(dci_size-pos))&0x1; + // Redundancy version 2bit + pos+=2; + dci_pdu_rel15->rv = (*dci_pdu>>(dci_size-pos))&0x3; + //TB2 + // MCS 5bit + pos+=dci_pdu_rel15->mcs2.nbits; + dci_pdu_rel15->mcs2.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->mcs2.nbits)-1); + // New data indicator 1bit + pos+=dci_pdu_rel15->ndi2.nbits; + dci_pdu_rel15->ndi2.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->ndi2.nbits)-1); + // Redundancy version 2bit + pos+=dci_pdu_rel15->rv2.nbits; + dci_pdu_rel15->rv2.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->rv2.nbits)-1); + // HARQ process number 4bit + pos+=4; + dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf; + // Downlink assignment index + pos+=dci_pdu_rel15->dai[0].nbits; + dci_pdu_rel15->dai[0].val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->dai[0].nbits)-1); + // TPC command for scheduled PUCCH 2bit + pos+=2; + dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&0x3; + // PUCCH resource indicator 3bit + pos+=3; + dci_pdu_rel15->pucch_resource_indicator = (*dci_pdu>>(dci_size-pos))&0x3; + // PDSCH-to-HARQ_feedback timing indicator + pos+=dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.nbits; + dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.nbits)-1); + // Antenna ports + pos+=dci_pdu_rel15->antenna_ports.nbits; + dci_pdu_rel15->antenna_ports.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->antenna_ports.nbits)-1); + // TCI + pos+=dci_pdu_rel15->transmission_configuration_indication.nbits; + dci_pdu_rel15->transmission_configuration_indication.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->transmission_configuration_indication.nbits)-1); + // SRS request + pos+=dci_pdu_rel15->srs_request.nbits; + dci_pdu_rel15->srs_request.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->srs_request.nbits)-1); + // CBG transmission information + pos+=dci_pdu_rel15->cbgti.nbits; + dci_pdu_rel15->cbgti.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->cbgti.nbits)-1); + // CBG flushing out information + pos+=dci_pdu_rel15->cbgfi.nbits; + dci_pdu_rel15->cbgfi.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->cbgfi.nbits)-1); + // DMRS sequence init + pos+=1; + dci_pdu_rel15->dmrs_sequence_initialization.val = (*dci_pdu>>(dci_size-pos))&0x1; + break; } - break; - case NR_UL_DCI_FORMAT_0_1: - switch(rnti_type) { - case NR_RNTI_C: - //Identifier for DCI formats - pos++; - dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1; - - if (dci_pdu_rel15->format_indicator == 1) - return 1; // discard dci, format indicator not corresponding to dci_format - - // Carrier indicator - pos+=dci_pdu_rel15->carrier_indicator.nbits; - dci_pdu_rel15->carrier_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->carrier_indicator.nbits)-1); - // UL/SUL Indicator - pos+=dci_pdu_rel15->ul_sul_indicator.nbits; - dci_pdu_rel15->ul_sul_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->ul_sul_indicator.nbits)-1); - // BWP Indicator - pos+=dci_pdu_rel15->bwp_indicator.nbits; - dci_pdu_rel15->bwp_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->bwp_indicator.nbits)-1); - // Freq domain assignment max 16 bit - fsize = (int)ceil( log2( (N_RB_UL*(N_RB_UL+1))>>1 ) ); - pos+=fsize; - dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1); - // Time domain assignment 4bit - //pos+=4; - pos+=dci_pdu_rel15->time_domain_assignment.nbits; - dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0x3; - // Not supported yet - skip for now - // Frequency hopping flag – 1 bit - //pos++; - //dci_pdu_rel15->frequency_hopping_flag.val= (*dci_pdu>>(dci_size-pos))&1; - // MCS 5 bit - pos+=5; - dci_pdu_rel15->mcs= (*dci_pdu>>(dci_size-pos))&0x1f; - // New data indicator 1bit - pos++; - dci_pdu_rel15->ndi= (*dci_pdu>>(dci_size-pos))&1; - // Redundancy version 2bit - pos+=2; - dci_pdu_rel15->rv= (*dci_pdu>>(dci_size-pos))&3; - // HARQ process number 4bit - pos+=4; - dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf; - // 1st Downlink assignment index - pos+=dci_pdu_rel15->dai[0].nbits; - dci_pdu_rel15->dai[0].val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->dai[0].nbits)-1); - // 2nd Downlink assignment index - pos+=dci_pdu_rel15->dai[1].nbits; - dci_pdu_rel15->dai[1].val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->dai[1].nbits)-1); - // TPC command for scheduled PUSCH – 2 bits - pos+=2; - dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&3; - // SRS resource indicator - pos+=dci_pdu_rel15->srs_resource_indicator.nbits; - dci_pdu_rel15->srs_resource_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->srs_resource_indicator.nbits)-1); - // Precoding info and n. of layers - pos+=dci_pdu_rel15->precoding_information.nbits; - dci_pdu_rel15->precoding_information.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->precoding_information.nbits)-1); - // Antenna ports - pos+=dci_pdu_rel15->antenna_ports.nbits; - dci_pdu_rel15->antenna_ports.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->antenna_ports.nbits)-1); - // SRS request - pos+=dci_pdu_rel15->srs_request.nbits; - dci_pdu_rel15->srs_request.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->srs_request.nbits)-1); - // CSI request - pos+=dci_pdu_rel15->csi_request.nbits; - dci_pdu_rel15->csi_request.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->csi_request.nbits)-1); - // CBG transmission information - pos+=dci_pdu_rel15->cbgti.nbits; - dci_pdu_rel15->cbgti.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->cbgti.nbits)-1); - // PTRS DMRS association - pos+=dci_pdu_rel15->ptrs_dmrs_association.nbits; - dci_pdu_rel15->ptrs_dmrs_association.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->ptrs_dmrs_association.nbits)-1); - // Beta offset indicator - pos+=dci_pdu_rel15->beta_offset_indicator.nbits; - dci_pdu_rel15->beta_offset_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->beta_offset_indicator.nbits)-1); - // DMRS sequence initialization - pos+=dci_pdu_rel15->dmrs_sequence_initialization.nbits; - dci_pdu_rel15->dmrs_sequence_initialization.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->dmrs_sequence_initialization.nbits)-1); - // UL-SCH indicator - pos+=1; - dci_pdu_rel15->ulsch_indicator = (*dci_pdu>>(dci_size-pos))&0x1; - // UL/SUL indicator – 1 bit - /* commented for now (RK): need to get this from BWP descriptor - if (cfg->pucch_config.pucch_GroupHopping.value) - dci_pdu->= ((uint64_t)*dci_pdu>>(dci_size-pos)ul_sul_indicator&1)<<(dci_size-pos++); - */ - break; + case NR_UL_DCI_FORMAT_0_1: + switch(rnti_type) + { + case NR_RNTI_C: + //Identifier for DCI formats + pos++; + dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1; + if (dci_pdu_rel15->format_indicator == 1) + return 1; // discard dci, format indicator not corresponding to dci_format + // Carrier indicator + pos+=dci_pdu_rel15->carrier_indicator.nbits; + dci_pdu_rel15->carrier_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->carrier_indicator.nbits)-1); + + // UL/SUL Indicator + pos+=dci_pdu_rel15->ul_sul_indicator.nbits; + dci_pdu_rel15->ul_sul_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->ul_sul_indicator.nbits)-1); + + // BWP Indicator + pos+=dci_pdu_rel15->bwp_indicator.nbits; + dci_pdu_rel15->bwp_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->bwp_indicator.nbits)-1); + + // Freq domain assignment max 16 bit + fsize = (int)ceil( log2( (N_RB_UL*(N_RB_UL+1))>>1 ) ); + pos+=fsize; + dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1); + + // Time domain assignment 4bit + //pos+=4; + pos+=dci_pdu_rel15->time_domain_assignment.nbits; + dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0x3; + + // Not supported yet - skip for now + // Frequency hopping flag – 1 bit + //pos++; + //dci_pdu_rel15->frequency_hopping_flag.val= (*dci_pdu>>(dci_size-pos))&1; + + // MCS 5 bit + pos+=5; + dci_pdu_rel15->mcs= (*dci_pdu>>(dci_size-pos))&0x1f; + + // New data indicator 1bit + pos++; + dci_pdu_rel15->ndi= (*dci_pdu>>(dci_size-pos))&1; + + // Redundancy version 2bit + pos+=2; + dci_pdu_rel15->rv= (*dci_pdu>>(dci_size-pos))&3; + + // HARQ process number 4bit + pos+=4; + dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf; + + // 1st Downlink assignment index + pos+=dci_pdu_rel15->dai[0].nbits; + dci_pdu_rel15->dai[0].val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->dai[0].nbits)-1); + + // 2nd Downlink assignment index + pos+=dci_pdu_rel15->dai[1].nbits; + dci_pdu_rel15->dai[1].val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->dai[1].nbits)-1); + + // TPC command for scheduled PUSCH – 2 bits + pos+=2; + dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&3; + + // SRS resource indicator + pos+=dci_pdu_rel15->srs_resource_indicator.nbits; + dci_pdu_rel15->srs_resource_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->srs_resource_indicator.nbits)-1); + + // Precoding info and n. of layers + pos+=dci_pdu_rel15->precoding_information.nbits; + dci_pdu_rel15->precoding_information.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->precoding_information.nbits)-1); + + // Antenna ports + pos+=dci_pdu_rel15->antenna_ports.nbits; + dci_pdu_rel15->antenna_ports.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->antenna_ports.nbits)-1); + + // SRS request + pos+=dci_pdu_rel15->srs_request.nbits; + dci_pdu_rel15->srs_request.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->srs_request.nbits)-1); + + // CSI request + pos+=dci_pdu_rel15->csi_request.nbits; + dci_pdu_rel15->csi_request.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->csi_request.nbits)-1); + + // CBG transmission information + pos+=dci_pdu_rel15->cbgti.nbits; + dci_pdu_rel15->cbgti.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->cbgti.nbits)-1); + + // PTRS DMRS association + pos+=dci_pdu_rel15->ptrs_dmrs_association.nbits; + dci_pdu_rel15->ptrs_dmrs_association.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->ptrs_dmrs_association.nbits)-1); + + // Beta offset indicator + pos+=dci_pdu_rel15->beta_offset_indicator.nbits; + dci_pdu_rel15->beta_offset_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->beta_offset_indicator.nbits)-1); + + // DMRS sequence initialization + pos+=dci_pdu_rel15->dmrs_sequence_initialization.nbits; + dci_pdu_rel15->dmrs_sequence_initialization.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->dmrs_sequence_initialization.nbits)-1); + + // UL-SCH indicator + pos+=1; + dci_pdu_rel15->ulsch_indicator = (*dci_pdu>>(dci_size-pos))&0x1; + + // UL/SUL indicator – 1 bit + /* commented for now (RK): need to get this from BWP descriptor + if (cfg->pucch_config.pucch_GroupHopping.value) + dci_pdu->= ((uint64_t)*dci_pdu>>(dci_size-pos)ul_sul_indicator&1)<<(dci_size-pos++); + */ + break; } - - break; - } - - return 0; + break; + } + + return 0; } /////////////////////////////////// @@ -3240,7 +3286,8 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, //////////////////////////////// void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, - int pdu_id) { + int pdu_id){ + uint8_t rx_lcid; uint16_t mac_ce_len; uint16_t mac_subheader_len; @@ -3256,26 +3303,25 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); RA_config_t *ra = &mac->ra; - if (!pduP) { + if (!pduP){ return; } LOG_D(MAC, "In %s [%d.%d]: processing PDU %d (with length %d) of %d total number of PDUs...\n", __FUNCTION__, frameP, slot, pdu_id, pdu_len, dl_info->rx_ind->number_pdus); - while (!done && pdu_len > 0) { + while (!done && pdu_len > 0){ mac_ce_len = 0x0000; mac_subheader_len = 0x0001; // default to fixed-length subheader = 1-oct mac_sdu_len = 0x0000; rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pduP)->LCID; - LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", rx_lcid, pdu_len); - switch(rx_lcid) { + LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", rx_lcid, pdu_len); + switch(rx_lcid){ // MAC CE case DL_SCH_LCID_CCCH: - // MSG4 RRC Setup 38.331 // variable length - if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F) { + if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){ mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pduP)->L1 & 0x7f) << 8) | ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pduP)->L2 & 0xff); mac_subheader_len = 3; @@ -3286,13 +3332,11 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, // Check if it is a valid CCCH message, we get all 00's messages very often int i = 0; - for(i=0; i<(mac_subheader_len+mac_sdu_len); i++) { if(pduP[i] != 0) { break; } } - if (i == (mac_subheader_len+mac_sdu_len)) { LOG_D(NR_MAC, "%s() Invalid CCCH message!, pdu_len: %d\n", __func__, pdu_len); done = 1; @@ -3301,140 +3345,118 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, if ( mac_sdu_len > 0 ) { LOG_D(NR_MAC,"DL_SCH_LCID_CCCH (e.g. RRCSetup) with payload len %d\n", mac_sdu_len); - for (int i = 0; i < mac_subheader_len; i++) { LOG_D(NR_MAC, "MAC header %d: 0x%x\n", i, pduP[i]); } - for (int i = 0; i < mac_sdu_len; i++) { LOG_D(NR_MAC, "%d: 0x%x\n", i, pduP[mac_subheader_len + i]); } - nr_mac_rrc_data_ind_ue(module_idP, CC_id, gNB_index, frameP, 0, mac->crnti, CCCH, pduP+mac_subheader_len, mac_sdu_len); } - break; - case DL_SCH_LCID_TCI_STATE_ACT_UE_SPEC_PDSCH: + // 38.321 Ch6.1.3.14 // varialbe length mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L; mac_subheader_len = 2; - - if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F) { + if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){ mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8; mac_subheader_len = 3; } - break; - case DL_SCH_LCID_APERIODIC_CSI_TRI_STATE_SUBSEL: // 38.321 Ch6.1.3.13 // varialbe length mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L; mac_subheader_len = 2; - - if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F) { + if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){ mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8; mac_subheader_len = 3; } - break; - case DL_SCH_LCID_SP_CSI_RS_CSI_IM_RES_SET_ACT: // 38.321 Ch6.1.3.12 // varialbe length mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L; mac_subheader_len = 2; - - if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F) { + if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){ mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8; mac_subheader_len = 3; } - break; - case DL_SCH_LCID_SP_SRS_ACTIVATION: // 38.321 Ch6.1.3.17 // varialbe length mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L; mac_subheader_len = 2; - - if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F) { + if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){ mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8; mac_subheader_len = 3; } - break; - case DL_SCH_LCID_RECOMMENDED_BITRATE: // 38.321 Ch6.1.3.20 mac_ce_len = 2; break; - case DL_SCH_LCID_SP_ZP_CSI_RS_RES_SET_ACT: // 38.321 Ch6.1.3.19 mac_ce_len = 2; break; - case DL_SCH_LCID_PUCCH_SPATIAL_RELATION_ACT: // 38.321 Ch6.1.3.18 mac_ce_len = 3; break; - case DL_SCH_LCID_SP_CSI_REP_PUCCH_ACT: // 38.321 Ch6.1.3.16 mac_ce_len = 2; break; - case DL_SCH_LCID_TCI_STATE_IND_UE_SPEC_PDCCH: // 38.321 Ch6.1.3.15 mac_ce_len = 2; break; - case DL_SCH_LCID_DUPLICATION_ACT: // 38.321 Ch6.1.3.11 mac_ce_len = 1; break; - case DL_SCH_LCID_SCell_ACT_4_OCT: // 38.321 Ch6.1.3.10 mac_ce_len = 4; break; - case DL_SCH_LCID_SCell_ACT_1_OCT: // 38.321 Ch6.1.3.10 mac_ce_len = 1; break; - case DL_SCH_LCID_L_DRX: // 38.321 Ch6.1.3.6 // fixed length but not yet specify. mac_ce_len = 0; break; - case DL_SCH_LCID_DRX: // 38.321 Ch6.1.3.5 // fixed length but not yet specify. mac_ce_len = 0; break; - case DL_SCH_LCID_TA_COMMAND: // 38.321 Ch6.1.3.4 mac_ce_len = 1; + /*uint8_t ta_command = ((NR_MAC_CE_TA *)pduP)[1].TA_COMMAND; uint8_t tag_id = ((NR_MAC_CE_TA *)pduP)[1].TAGID;*/ + ul_time_alignment->apply_ta = 1; ul_time_alignment->ta_command = ((NR_MAC_CE_TA *)pduP)[1].TA_COMMAND; ul_time_alignment->tag_id = ((NR_MAC_CE_TA *)pduP)[1].TAGID; + /* #ifdef DEBUG_HEADER_PARSING LOG_D(MAC, "[UE] CE %d : UE Timing Advance : %d\n", i, pduP[1]); #endif */ + LOG_D(MAC, "[%d.%d] Received TA_COMMAND %u TAGID %u CC_id %d\n", frameP, slot, ul_time_alignment->ta_command, ul_time_alignment->tag_id, CC_id); - break; + break; case DL_SCH_LCID_CON_RES_ID: // Clause 5.1.5 and 6.1.3.3 of 3GPP TS 38.321 version 16.2.1 Release 16 // MAC Header: 1 byte (R/R/LCID) @@ -3444,8 +3466,8 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, if(ra->ra_state == WAIT_CONTENTION_RESOLUTION) { LOG_I(MAC, "[UE %d][RAPROC] Frame %d : received contention resolution identity: 0x%02x%02x%02x%02x%02x%02x Terminating RA procedure\n", module_idP, frameP, pduP[1], pduP[2], pduP[3], pduP[4], pduP[5], pduP[6]); - bool ra_success = true; + bool ra_success = true; for(int i = 0; i<mac_ce_len; i++) { if(ra->cont_res_id[i] != pduP[i+1]) { ra_success = false; @@ -3455,52 +3477,49 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, if ( (ra->RA_active == 1) && ra_success) { nr_ra_succeeded(module_idP, frameP, slot); - } else if (!ra_success) { + } else if (!ra_success){ // TODO: Handle failure of RA procedure @ MAC layer // nr_ra_failed(module_idP, CC_id, prach_resources, frameP, slot); // prach_resources is a PHY structure ra->ra_state = RA_UE_IDLE; ra->RA_active = 0; } } - break; - case DL_SCH_LCID_PADDING: done = 1; // end of MAC PDU, can ignore the rest. break; - - // MAC SDU + // MAC SDU case DL_SCH_LCID_DCCH: - - // check if LCID is valid at current time. + // check if LCID is valid at current time. case DL_SCH_LCID_DCCH1: - - // check if LCID is valid at current time. + // check if LCID is valid at current time. default: - // check if LCID is valid at current time. - if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F) { + if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){ //mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8; mac_subheader_len = 3; mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pduP)->L1 & 0x7f) << 8) | ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pduP)->L2 & 0xff); + } else { mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L; mac_subheader_len = 2; } LOG_D(MAC, "[UE %d] Frame %d : DLSCH -> DL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, gNB_index, mac_sdu_len); -#if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP); - for (i = 0; i < 32; i++) - LOG_T(MAC, "%x.", (pduP + mac_subheader_len)[i]); + #if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP); - LOG_T(MAC, "\n"); -#endif + for (i = 0; i < 32; i++) + LOG_T(MAC, "%x.", (pduP + mac_subheader_len)[i]); + + LOG_T(MAC, "\n"); + #endif if (rx_lcid < NB_RB_MAX && rx_lcid >= DL_SCH_LCID_DCCH) { + mac_rlc_data_ind(module_idP, mac->crnti, gNB_index, @@ -3517,14 +3536,12 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, } break; + } + pduP += ( mac_subheader_len + mac_ce_len + mac_sdu_len ); + pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len ); + if (pdu_len < 0) + LOG_E(MAC, "[UE %d][%d.%d] nr_ue_process_mac_pdu, residual mac pdu length %d < 0!\n", module_idP, frameP, slot, pdu_len); } - - pduP += ( mac_subheader_len + mac_ce_len + mac_sdu_len ); - pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len ); - - if (pdu_len < 0) - LOG_E(MAC, "[UE %d][%d.%d] nr_ue_process_mac_pdu, residual mac pdu length %d < 0!\n", module_idP, frameP, slot, pdu_len); - } } /** @@ -3538,85 +3555,102 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, NR_UE_MAC_INST_t *mac, uint8_t power_headroom, // todo: NR_POWER_HEADROOM_CMD *power_headroom, - uint16_t *crnti, + uint16_t *crnti, NR_BSR_SHORT *truncated_bsr, NR_BSR_SHORT *short_bsr, NR_BSR_LONG *long_bsr) { + int mac_ce_len = 0; uint8_t mac_ce_size = 0; uint8_t *pdu = mac_ce; - if (power_headroom) { + // MAC CE fixed subheader ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0; ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->LCID = UL_SCH_LCID_SINGLE_ENTRY_PHR; mac_ce++; + // PHR MAC CE (1 octet) ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PH = power_headroom; ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->R1 = 0; ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PCMAX = 0; // todo ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->R2 = 0; + // update pointer and length mac_ce_size = sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE); mac_ce += mac_ce_size; mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED); LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : power_headroom pdu %p mac_ce %p b\n", - pdu, mac_ce); + pdu, mac_ce); } if (crnti && (!get_softmodem_params()->sa && get_softmodem_params()->do_ra && mac->ra.ra_state != RA_SUCCEEDED)) { + LOG_D(NR_MAC, "In %s: generating C-RNTI MAC CE with C-RNTI %x\n", __FUNCTION__, (*crnti)); + // MAC CE fixed subheader ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0; ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->LCID = UL_SCH_LCID_C_RNTI; mac_ce++; + // C-RNTI MAC CE (2 octets) *(uint16_t *) mac_ce = (*crnti); + // update pointer and length mac_ce_size = sizeof(uint16_t); mac_ce += mac_ce_size; mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED); + } if (truncated_bsr) { - // MAC CE fixed subheader + + // MAC CE fixed subheader ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0; ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->LCID = UL_SCH_LCID_S_TRUNCATED_BSR; mac_ce++; + // Short truncated BSR MAC CE (1 octet) ((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> Buffer_size = truncated_bsr->Buffer_size; ((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> LcgID = truncated_bsr->LcgID;; + // update pointer and length mac_ce_size = sizeof(NR_BSR_SHORT_TRUNCATED); mac_ce += mac_ce_size; mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED); LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : truncated_bsr Buffer_size %d LcgID %d pdu %p mac_ce %p\n", - truncated_bsr->Buffer_size, truncated_bsr->LcgID, pdu, mac_ce); + truncated_bsr->Buffer_size, truncated_bsr->LcgID, pdu, mac_ce); + } else if (short_bsr) { - // MAC CE fixed subheader + + // MAC CE fixed subheader ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0; ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->LCID = UL_SCH_LCID_S_BSR; mac_ce++; + // Short truncated BSR MAC CE (1 octet) ((NR_BSR_SHORT *) mac_ce)->Buffer_size = short_bsr->Buffer_size; ((NR_BSR_SHORT *) mac_ce)->LcgID = short_bsr->LcgID; + // update pointer and length mac_ce_size = sizeof(NR_BSR_SHORT); mac_ce += mac_ce_size; mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED); LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : short_bsr Buffer_size %d LcgID %d pdu %p mac_ce %p\n", - short_bsr->Buffer_size, short_bsr->LcgID, pdu, mac_ce); + short_bsr->Buffer_size, short_bsr->LcgID, pdu, mac_ce); } else if (long_bsr) { - // MAC CE variable subheader + + // MAC CE variable subheader // ch 6.1.3.1. TS 38.321 ((NR_MAC_SUBHEADER_SHORT *) mac_ce)->R = 0; ((NR_MAC_SUBHEADER_SHORT *) mac_ce)->F = 0; ((NR_MAC_SUBHEADER_SHORT *) mac_ce)->LCID = UL_SCH_LCID_L_BSR; + NR_MAC_SUBHEADER_SHORT *mac_pdu_subheader_ptr = (NR_MAC_SUBHEADER_SHORT *) mac_ce; mac_ce += 2; - // Could move to nr_get_sdu() - uint8_t *Buffer_size_ptr= (uint8_t *) mac_ce + 1; + // Could move to nr_get_sdu() + uint8_t *Buffer_size_ptr= (uint8_t*) mac_ce + 1; //int NR_BSR_LONG_SIZE = 1; if (long_bsr->Buffer_size0 == 0) { ((NR_BSR_LONG *) mac_ce)->LcgID0 = 0; @@ -3625,7 +3659,6 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, *Buffer_size_ptr++ = long_bsr->Buffer_size0; //NR_BSR_LONG_SIZE++; } - if (long_bsr->Buffer_size1 == 0) { ((NR_BSR_LONG *) mac_ce)->LcgID1 = 0; } else { @@ -3633,7 +3666,6 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, *Buffer_size_ptr++ = long_bsr->Buffer_size1; //NR_BSR_LONG_SIZE++; } - if (long_bsr->Buffer_size2 == 0) { ((NR_BSR_LONG *) mac_ce)->LcgID2 = 0; } else { @@ -3641,7 +3673,6 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, *Buffer_size_ptr++ = long_bsr->Buffer_size2; //NR_BSR_LONG_SIZE++; } - if (long_bsr->Buffer_size3 == 0) { ((NR_BSR_LONG *) mac_ce)->LcgID3 = 0; } else { @@ -3649,7 +3680,6 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, *Buffer_size_ptr++ = long_bsr->Buffer_size3; //NR_BSR_LONG_SIZE++; } - if (long_bsr->Buffer_size4 == 0) { ((NR_BSR_LONG *) mac_ce)->LcgID4 = 0; } else { @@ -3657,7 +3687,6 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, *Buffer_size_ptr++ = long_bsr->Buffer_size4; //NR_BSR_LONG_SIZE++; } - if (long_bsr->Buffer_size5 == 0) { ((NR_BSR_LONG *) mac_ce)->LcgID5 = 0; } else { @@ -3665,7 +3694,6 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, *Buffer_size_ptr++ = long_bsr->Buffer_size5; //NR_BSR_LONG_SIZE++; } - if (long_bsr->Buffer_size6 == 0) { ((NR_BSR_LONG *) mac_ce)->LcgID6 = 0; } else { @@ -3673,7 +3701,6 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, *Buffer_size_ptr++ = long_bsr->Buffer_size6; //NR_BSR_LONG_SIZE++; } - if (long_bsr->Buffer_size7 == 0) { ((NR_BSR_LONG *) mac_ce)->LcgID7 = 0; } else { @@ -3681,17 +3708,17 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, *Buffer_size_ptr++ = long_bsr->Buffer_size7; //NR_BSR_LONG_SIZE++; } - - ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_subheader_ptr)->L = mac_ce_size = (uint8_t *) Buffer_size_ptr - (uint8_t *) mac_ce; - LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : long_bsr size %d Lcgbit 0x%02x Buffer_size %d %d %d %d %d %d %d %d\n", mac_ce_size, *((uint8_t *) mac_ce), - ((NR_BSR_LONG *) mac_ce)->Buffer_size0, ((NR_BSR_LONG *) mac_ce)->Buffer_size1, ((NR_BSR_LONG *) mac_ce)->Buffer_size2, ((NR_BSR_LONG *) mac_ce)->Buffer_size3, - ((NR_BSR_LONG *) mac_ce)->Buffer_size4, ((NR_BSR_LONG *) mac_ce)->Buffer_size5, ((NR_BSR_LONG *) mac_ce)->Buffer_size6, ((NR_BSR_LONG *) mac_ce)->Buffer_size7); + ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_subheader_ptr)->L = mac_ce_size = (uint8_t*) Buffer_size_ptr - (uint8_t*) mac_ce; + LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : long_bsr size %d Lcgbit 0x%02x Buffer_size %d %d %d %d %d %d %d %d\n", mac_ce_size, *((uint8_t*) mac_ce), + ((NR_BSR_LONG *) mac_ce)->Buffer_size0, ((NR_BSR_LONG *) mac_ce)->Buffer_size1, ((NR_BSR_LONG *) mac_ce)->Buffer_size2, ((NR_BSR_LONG *) mac_ce)->Buffer_size3, + ((NR_BSR_LONG *) mac_ce)->Buffer_size4, ((NR_BSR_LONG *) mac_ce)->Buffer_size5, ((NR_BSR_LONG *) mac_ce)->Buffer_size6, ((NR_BSR_LONG *) mac_ce)->Buffer_size7); // update pointer and length mac_ce = Buffer_size_ptr; mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_SHORT); } return mac_ce_len; + } @@ -3728,7 +3755,8 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, // - b buffer // - ulsch power offset // - optimize: mu_pusch, j and table_6_1_2_1_1_2_time_dom_res_alloc_A are already defined in nr_ue_procedures -int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id) { +int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id){ + module_id_t mod_id = dl_info->module_id; frame_t frame = dl_info->frame; int slot = dl_info->slot; @@ -3752,11 +3780,11 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer; // RAR subheader pointer NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1); // RAR subPDU pointer uint8_t preamble_index = get_ra_PreambleIndex(mod_id, cc_id, gNB_id); //prach_resources->ra_PreambleIndex; + LOG_D(NR_MAC, "In %s:[%d.%d]: [UE %d][RAPROC] invoking MAC for received RAR (current preamble %d)\n", __FUNCTION__, frame, slot, mod_id, preamble_index); while (1) { n_subheaders++; - if (rarh->T == 1) { n_subPDUs++; LOG_I(NR_MAC, "[UE %d][RAPROC] Got RAPID RAR subPDU\n", mod_id); @@ -3764,7 +3792,6 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t ra->RA_backoff_indicator = table_7_2_1[((NR_RA_HEADER_BI *)rarh)->BI]; ra->RA_BI_found = 1; LOG_I(NR_MAC, "[UE %d][RAPROC] Got BI RAR subPDU %d ms\n", mod_id, ra->RA_backoff_indicator); - if ( ((NR_RA_HEADER_BI *)rarh)->E == 1) { rarh += sizeof(NR_RA_HEADER_BI); continue; @@ -3772,14 +3799,12 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t break; } } - if (rarh->RAPID == preamble_index) { LOG_I(NR_MAC, "[UE %d][RAPROC][%d.%d] Found RAR with the intended RAPID %d\n", mod_id, frame, slot, rarh->RAPID); rar = (NR_MAC_RAR *) (dlsch_buffer + n_subheaders + (n_subPDUs - 1) * sizeof(NR_MAC_RAR)); ra->RA_RAPID_found = 1; break; } - if (rarh->E == 0) { LOG_W(NR_MAC,"[UE %d][RAPROC][%d.%d] Received RAR preamble (%d) doesn't match the intended RAPID (%d)\n", mod_id, frame, slot, rarh->RAPID, preamble_index); break; @@ -3788,61 +3813,57 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t } } -#ifdef DEBUG_RAR + #ifdef DEBUG_RAR LOG_D(MAC, "[DEBUG_RAR] (%d,%d) number of RAR subheader %d; number of RAR pyloads %d\n", frame, slot, n_subheaders, n_subPDUs); LOG_D(MAC, "[DEBUG_RAR] Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n", *(uint8_t *) rarh, rar[0], rar[1], rar[2], rar[3], rar[4], rar[5], rarh->RAPID, preamble_index); -#endif + #endif if (ra->RA_RAPID_found) { + RAR_grant_t rar_grant; + unsigned char tpc_command; #ifdef DEBUG_RAR unsigned char csi_req; #endif + // TA command ul_time_alignment->apply_ta = 1; ul_time_alignment->ta_command = 31 + rar->TA2 + (rar->TA1 << 5); + #ifdef DEBUG_RAR // CSI csi_req = (unsigned char) (rar->UL_GRANT_4 & 0x01); #endif + // TPC tpc_command = (unsigned char) ((rar->UL_GRANT_4 >> 1) & 0x07); - - switch (tpc_command) { + switch (tpc_command){ case 0: ra->Msg3_TPC = -6; break; - case 1: ra->Msg3_TPC = -4; break; - case 2: ra->Msg3_TPC = -2; break; - case 3: ra->Msg3_TPC = 0; break; - case 4: ra->Msg3_TPC = 2; break; - case 5: ra->Msg3_TPC = 4; break; - case 6: ra->Msg3_TPC = 6; break; - case 7: ra->Msg3_TPC = 8; break; } - // MCS rar_grant.mcs = (unsigned char) (rar->UL_GRANT_4 >> 4); // time alloc @@ -3851,36 +3872,44 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t rar_grant.Msg3_f_alloc = (uint16_t) ((rar->UL_GRANT_3 >> 4) | (rar->UL_GRANT_2 << 4) | ((rar->UL_GRANT_1 & 0x03) << 12)); // frequency hopping rar_grant.freq_hopping = (unsigned char) (rar->UL_GRANT_1 >> 2); + #ifdef DEBUG_RAR LOG_I(NR_MAC, "rarh->E = 0x%x\n", rarh->E); LOG_I(NR_MAC, "rarh->T = 0x%x\n", rarh->T); LOG_I(NR_MAC, "rarh->RAPID = 0x%x (%i)\n", rarh->RAPID, rarh->RAPID); + LOG_I(NR_MAC, "rar->R = 0x%x\n", rar->R); LOG_I(NR_MAC, "rar->TA1 = 0x%x\n", rar->TA1); + LOG_I(NR_MAC, "rar->TA2 = 0x%x\n", rar->TA2); LOG_I(NR_MAC, "rar->UL_GRANT_1 = 0x%x\n", rar->UL_GRANT_1); + LOG_I(NR_MAC, "rar->UL_GRANT_2 = 0x%x\n", rar->UL_GRANT_2); LOG_I(NR_MAC, "rar->UL_GRANT_3 = 0x%x\n", rar->UL_GRANT_3); LOG_I(NR_MAC, "rar->UL_GRANT_4 = 0x%x\n", rar->UL_GRANT_4); + LOG_I(NR_MAC, "rar->TCRNTI_1 = 0x%x\n", rar->TCRNTI_1); LOG_I(NR_MAC, "rar->TCRNTI_2 = 0x%x\n", rar->TCRNTI_2); + LOG_I(NR_MAC, "In %s:[%d.%d]: [UE %d] Received RAR with t_alloc %d f_alloc %d ta_command %d mcs %d freq_hopping %d tpc_command %d t_crnti %x \n", - __FUNCTION__, - frame, - slot, - mod_id, - rar_grant.Msg3_t_alloc, - rar_grant.Msg3_f_alloc, - ul_time_alignment->ta_command, - rar_grant.mcs, - rar_grant.freq_hopping, - tpc_command, - ra->t_crnti); + __FUNCTION__, + frame, + slot, + mod_id, + rar_grant.Msg3_t_alloc, + rar_grant.Msg3_f_alloc, + ul_time_alignment->ta_command, + rar_grant.mcs, + rar_grant.freq_hopping, + tpc_command, + ra->t_crnti); #endif + // Schedule Msg3 ret = nr_ue_pusch_scheduler(mac, is_Msg3, frame, slot, &frame_tx, &slot_tx, rar_grant.Msg3_t_alloc); - if (ret != -1) { + if (ret != -1){ + fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx); uint16_t rnti = mac->crnti; @@ -3896,14 +3925,21 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t } nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu; + fill_ul_config(ul_config, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH); + // Config Msg3 PDU nr_config_pusch_pdu(mac, pusch_config_pdu, NULL, &rar_grant, rnti, NULL); + } + } else { + ra->t_crnti = 0; ul_time_alignment->ta_command = (0xffff); + } return ret; + } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 1a65d266c2..4f231b40ca 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -58,12 +58,15 @@ static prach_association_pattern_t prach_assoc_pattern; static ssb_list_info_t ssb_list; -void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type) { +void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type){ + ul_config->ul_config_list[ul_config->number_pdus].pdu_type = pdu_type; ul_config->slot = slot_tx; ul_config->sfn = frame_tx; ul_config->number_pdus++; + LOG_D(NR_MAC, "In %s: Set config request for UL transmission in [%d.%d], number of UL PDUs: %d\n", __FUNCTION__, ul_config->sfn, ul_config->slot, ul_config->number_pdus); + } void fill_scheduled_response(nr_scheduled_response_t *scheduled_response, @@ -74,7 +77,8 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response, int cc_id, frame_t frame, int slot, - int thread_id) { + int thread_id){ + scheduled_response->dl_config = dl_config; scheduled_response->ul_config = ul_config; scheduled_response->tx_request = tx_request; @@ -83,6 +87,7 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response, scheduled_response->frame = frame; scheduled_response->slot = slot; scheduled_response->thread_id = thread_id; + } /* @@ -94,16 +99,17 @@ long get_k2(NR_UE_MAC_INST_t *mac, uint8_t time_domain_ind) { // Get K2 from RRC configuration NR_PUSCH_Config_t *pusch_config=mac->ULbwp[0] ? mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup : NULL; NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL; - if (pusch_config && pusch_config->pusch_TimeDomainAllocationList) { pusch_TimeDomainAllocationList = pusch_config->pusch_TimeDomainAllocationList->choice.setup; - } else if (mac->ULbwp[0] && - mac->ULbwp[0]->bwp_Common&& - mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon&& - mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup && - mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) { + } + else if (mac->ULbwp[0] && + mac->ULbwp[0]->bwp_Common&& + mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon&& + mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup && + mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) { pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - } else if (mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) + } + else if (mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) pusch_TimeDomainAllocationList=mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; else AssertFatal(1==0,"need to fall back to default PUSCH time-domain allocations\n"); @@ -113,13 +119,13 @@ long get_k2(NR_UE_MAC_INST_t *mac, uint8_t time_domain_ind) { time_domain_ind, pusch_TimeDomainAllocationList->list.count); return -1; } - k2 = *pusch_TimeDomainAllocationList->list.array[time_domain_ind]->k2; } AssertFatal(k2 >= DURATION_RX_TO_TX, "Slot offset K2 (%ld) cannot be less than DURATION_RX_TO_TX (%d)\n", k2,DURATION_RX_TO_TX); + LOG_D(NR_MAC, "get_k2(): k2 is %ld\n", k2); return k2; } @@ -128,7 +134,8 @@ long get_k2(NR_UE_MAC_INST_t *mac, uint8_t time_domain_ind) { * This function returns the UL config corresponding to a given UL slot * from MAC instance . */ -fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot) { +fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot) +{ NR_TDD_UL_DL_ConfigCommon_t *tdd_config = mac->scc==NULL ? mac->scc_SIB->tdd_UL_DL_ConfigurationCommon : mac->scc->tdd_UL_DL_ConfigurationCommon; //Check if request to access ul_config is for a UL slot @@ -141,24 +148,27 @@ fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int sl // based on the TDD pattern (slot configuration period) and number of UL+mixed // slots in the period. TS 38.213 Sec 11.1 int mu = mac->ULbwp[0] ? - mac->ULbwp[0]->bwp_Common->genericParameters.subcarrierSpacing : - mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing; + mac->ULbwp[0]->bwp_Common->genericParameters.subcarrierSpacing : + mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing; NR_TDD_UL_DL_Pattern_t *tdd_pattern = &tdd_config->pattern1; const int num_slots_per_tdd = nr_slots_per_frame[mu] >> (7 - tdd_pattern->dl_UL_TransmissionPeriodicity); const int num_slots_ul = tdd_pattern->nrofUplinkSlots + (tdd_pattern->nrofUplinkSymbols!=0); int index = slot % num_slots_ul; + LOG_D(NR_MAC, "In %s slots per tdd %d, num_slots_ul %d, index %d\n", __FUNCTION__, - num_slots_per_tdd, - num_slots_ul, - index); + num_slots_per_tdd, + num_slots_ul, + index); + return &mac->ul_config_request[index]; } -void ul_layers_config(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, dci_pdu_rel15_t *dci) { +void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, dci_pdu_rel15_t *dci) { + NR_ServingCellConfigCommon_t *scc = mac->scc; NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup; - long transformPrecoder; + long transformPrecoder; if (pusch_Config->transformPrecoder) transformPrecoder = *pusch_Config->transformPrecoder; else { @@ -168,34 +178,36 @@ void ul_layers_config(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled; } + /* PRECOD_NBR_LAYERS */ if ((*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_nonCodebook)); - // 0 bits if the higher layer parameter txConfig = nonCodeBook - if ((*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook)) { + if ((*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook)){ + uint8_t n_antenna_port = 0; //FIXME!!! if (n_antenna_port == 1); // 1 antenna port and the higher layer parameter txConfig = codebook 0 bits - if (n_antenna_port == 4) { // 4 antenna port and the higher layer parameter txConfig = codebook + if (n_antenna_port == 4){ // 4 antenna port and the higher layer parameter txConfig = codebook // Table 7.3.1.1.2-2: transformPrecoder=disabled and maxRank = 2 or 3 or 4 if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) - && ((*pusch_Config->maxRank == 2) || - (*pusch_Config->maxRank == 3) || - (*pusch_Config->maxRank == 4))) { + && ((*pusch_Config->maxRank == 2) || + (*pusch_Config->maxRank == 3) || + (*pusch_Config->maxRank == 4))){ + if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) { pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][0]; pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][1]; } - if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_partialAndNonCoherent) { + if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_partialAndNonCoherent){ pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][2]; pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][3]; } - if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent) { + if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent){ pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][4]; pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][5]; } @@ -203,92 +215,100 @@ void ul_layers_config(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_conf // Table 7.3.1.1.2-3: transformPrecoder= enabled, or transformPrecoder=disabled and maxRank = 1 if (((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) - || (transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled)) - && (*pusch_Config->maxRank == 1)) { + || (transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled)) + && (*pusch_Config->maxRank == 1)){ + if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) { pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][6]; pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][7]; } - if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_partialAndNonCoherent) { + if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_partialAndNonCoherent){ pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][8]; pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][9]; } - if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent) { + if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent){ pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][10]; pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][11]; } } } - if (n_antenna_port == 4) { // 2 antenna port and the higher layer parameter txConfig = codebook + if (n_antenna_port == 4){ // 2 antenna port and the higher layer parameter txConfig = codebook // Table 7.3.1.1.2-4: transformPrecoder=disabled and maxRank = 2 - if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && (*pusch_Config->maxRank == 2)) { + if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && (*pusch_Config->maxRank == 2)){ + if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) { pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][12]; pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][13]; } - if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent) { + if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent){ pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][14]; pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][15]; } + } // Table 7.3.1.1.2-5: transformPrecoder= enabled, or transformPrecoder= disabled and maxRank = 1 if (((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) - || (transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled)) - && (*pusch_Config->maxRank == 1)) { + || (transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled)) + && (*pusch_Config->maxRank == 1)){ + if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_fullyAndPartialAndNonCoherent) { pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][16]; pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][17]; } - if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent) { + if (*pusch_Config->codebookSubset == NR_PUSCH_Config__codebookSubset_nonCoherent){ pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][18]; pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][19]; } + } } } /*-------------------- Changed to enable Transform precoding in RF SIM------------------------------------------------*/ - /*if (pusch_config_pdu->transform_precoding == transform_precoder_enabled) { - pusch_config_dedicated->transform_precoder = transform_precoder_enabled; + /*if (pusch_config_pdu->transform_precoding == transform_precoder_enabled) { - if(pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA != NULL) { + pusch_config_dedicated->transform_precoder = transform_precoder_enabled; - NR_DMRS_UplinkConfig_t *NR_DMRS_ulconfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup; + if(pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA != NULL) { - if (NR_DMRS_ulconfig->dmrs_Type == NULL) - pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.dmrs_type = 1; - if (NR_DMRS_ulconfig->maxLength == NULL) - pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.max_length = 1; + NR_DMRS_UplinkConfig_t *NR_DMRS_ulconfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup; - } else if(pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB != NULL) { + if (NR_DMRS_ulconfig->dmrs_Type == NULL) + pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.dmrs_type = 1; + if (NR_DMRS_ulconfig->maxLength == NULL) + pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.max_length = 1; - NR_DMRS_UplinkConfig_t *NR_DMRS_ulconfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup; + } else if(pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB != NULL) { - if (NR_DMRS_ulconfig->dmrs_Type == NULL) - pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_b.dmrs_type = 1; - if (NR_DMRS_ulconfig->maxLength == NULL) - pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_b.max_length = 1; + NR_DMRS_UplinkConfig_t *NR_DMRS_ulconfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup; - } - } else - pusch_config_dedicated->transform_precoder = transform_precoder_disabled;*/ + if (NR_DMRS_ulconfig->dmrs_Type == NULL) + pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_b.dmrs_type = 1; + if (NR_DMRS_ulconfig->maxLength == NULL) + pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_b.max_length = 1; + + } + } else + pusch_config_dedicated->transform_precoder = transform_precoder_disabled;*/ } // todo: this function shall be reviewed completely because of the many comments left by the author -void ul_ports_config(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, dci_pdu_rel15_t *dci) { +void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, dci_pdu_rel15_t *dci) { + /* ANTENNA_PORTS */ uint8_t rank = 0; // We need to initialize rank FIXME!!! + NR_ServingCellConfigCommon_t *scc = mac->scc; NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup; - long transformPrecoder; + long transformPrecoder; if (pusch_Config->transformPrecoder) transformPrecoder = *pusch_Config->transformPrecoder; else { @@ -297,46 +317,48 @@ void ul_ports_config(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_confi else transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled; } - long *max_length = NULL; long *dmrs_type = NULL; - if (pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA) { max_length = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup->maxLength; dmrs_type = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup->dmrs_Type; - } else { + } + else { max_length = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->maxLength; dmrs_type = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->dmrs_Type; } + if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) && - (dmrs_type == NULL) && (max_length == NULL)) { // tables 7.3.1.1.2-6 - pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC - pusch_config_pdu->dmrs_ports = dci->antenna_ports.val; //TBC + (dmrs_type == NULL) && (max_length == NULL)) { // tables 7.3.1.1.2-6 + pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC + pusch_config_pdu->dmrs_ports = dci->antenna_ports.val; //TBC } if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_enabled) && - (dmrs_type == NULL) && (max_length != NULL)) { // tables 7.3.1.1.2-7 + (dmrs_type == NULL) && (max_length != NULL)) { // tables 7.3.1.1.2-7 + pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC pusch_config_pdu->dmrs_ports = (dci->antenna_ports.val > 3)?(dci->antenna_ports.val-4):(dci->antenna_ports.val); //TBC //pusch_config_pdu->n_front_load_symb = (dci->antenna_ports > 3)?2:1; //FIXME } if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && - (dmrs_type == NULL) && (max_length == NULL)) { // tables 7.3.1.1.2-8/9/10/11 + (dmrs_type == NULL) && (max_length == NULL)) { // tables 7.3.1.1.2-8/9/10/11 + if (rank == 1) { pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?2:1; //TBC pusch_config_pdu->dmrs_ports = (dci->antenna_ports.val > 1)?(dci->antenna_ports.val-2):(dci->antenna_ports.val); //TBC } - if (rank == 2) { + if (rank == 2){ pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 0)?2:1; //TBC pusch_config_pdu->dmrs_ports = 0; //FIXME //pusch_config_pdu->dmrs_ports[0] = (dci->antenna_ports > 1)?(dci->antenna_ports > 2 ?0:2):0; //pusch_config_pdu->dmrs_ports[1] = (dci->antenna_ports > 1)?(dci->antenna_ports > 2 ?2:3):1; } - if (rank == 3) { + if (rank == 3){ pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC pusch_config_pdu->dmrs_ports = 0; //FIXME //pusch_config_pdu->dmrs_ports[0] = 0; @@ -344,7 +366,7 @@ void ul_ports_config(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_confi //pusch_config_pdu->dmrs_ports[2] = 2; } - if (rank == 4) { + if (rank == 4){ pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC pusch_config_pdu->dmrs_ports = 0; //FIXME //pusch_config_pdu->dmrs_ports[0] = 0; @@ -355,14 +377,15 @@ void ul_ports_config(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_confi } if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && - (dmrs_type == NULL) && (max_length != NULL)) { // tables 7.3.1.1.2-12/13/14/15 - if (rank == 1) { + (dmrs_type == NULL) && (max_length != NULL)) { // tables 7.3.1.1.2-12/13/14/15 + + if (rank == 1){ pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?2:1; //TBC pusch_config_pdu->dmrs_ports = (dci->antenna_ports.val > 1)?(dci->antenna_ports.val > 5 ?(dci->antenna_ports.val-6):(dci->antenna_ports.val-2)):dci->antenna_ports.val; //TBC //pusch_config_pdu->n_front_load_symb = (dci->antenna_ports.val > 6)?2:1; //FIXME } - if (rank == 2) { + if (rank == 2){ pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 0)?2:1; //TBC pusch_config_pdu->dmrs_ports = 0; //FIXME //pusch_config_pdu->dmrs_ports[0] = table_7_3_1_1_2_13[dci->antenna_ports.val][1]; @@ -370,7 +393,7 @@ void ul_ports_config(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_confi //pusch_config_pdu->n_front_load_symb = (dci->antenna_ports.val > 3)?2:1; // FIXME } - if (rank == 3) { + if (rank == 3){ pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC pusch_config_pdu->dmrs_ports = 0; //FIXME //pusch_config_pdu->dmrs_ports[0] = table_7_3_1_1_2_14[dci->antenna_ports.val][1]; @@ -379,7 +402,7 @@ void ul_ports_config(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_confi //pusch_config_pdu->n_front_load_symb = (dci->antenna_ports.val > 1)?2:1; //FIXME } - if (rank == 4) { + if (rank == 4){ pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC pusch_config_pdu->dmrs_ports = 0; //FIXME //pusch_config_pdu->dmrs_ports[0] = table_7_3_1_1_2_15[dci->antenna_ports.val][1]; @@ -391,21 +414,22 @@ void ul_ports_config(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_confi } if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && - (dmrs_type != NULL) && - (max_length == NULL)) { // tables 7.3.1.1.2-16/17/18/19 - if (rank == 1) { + (dmrs_type != NULL) && + (max_length == NULL)) { // tables 7.3.1.1.2-16/17/18/19 + + if (rank == 1){ pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?((dci->antenna_ports.val > 5)?3:2):1; //TBC pusch_config_pdu->dmrs_ports = (dci->antenna_ports.val > 1)?(dci->antenna_ports.val > 5 ?(dci->antenna_ports.val-6):(dci->antenna_ports.val-2)):dci->antenna_ports.val; //TBC } - if (rank == 2) { + if (rank == 2){ pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 0)?((dci->antenna_ports.val > 2)?3:2):1; //TBC pusch_config_pdu->dmrs_ports = 0; //FIXME //pusch_config_pdu->dmrs_ports[0] = table_7_3_1_1_2_17[dci->antenna_ports.val][1]; //pusch_config_pdu->dmrs_ports[1] = table_7_3_1_1_2_17[dci->antenna_ports.val][2]; } - if (rank == 3) { + if (rank == 3){ pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 0)?3:2; //TBC pusch_config_pdu->dmrs_ports = 0; //FIXME //pusch_config_pdu->dmrs_ports[0] = table_7_3_1_1_2_18[dci->antenna_ports.val][1]; @@ -413,7 +437,7 @@ void ul_ports_config(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_confi //pusch_config_pdu->dmrs_ports[2] = table_7_3_1_1_2_18[dci->antenna_ports.val][3]; } - if (rank == 4) { + if (rank == 4){ pusch_config_pdu->num_dmrs_cdm_grps_no_data = dci->antenna_ports.val + 2; //TBC pusch_config_pdu->dmrs_ports = 0; //FIXME //pusch_config_pdu->dmrs_ports[0] = 0; @@ -424,22 +448,23 @@ void ul_ports_config(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_confi } if ((transformPrecoder == NR_PUSCH_Config__transformPrecoder_disabled) && - (dmrs_type != NULL) && (max_length != NULL)) { // tables 7.3.1.1.2-20/21/22/23 - if (rank == 1) { + (dmrs_type != NULL) && (max_length != NULL)) { // tables 7.3.1.1.2-20/21/22/23 + + if (rank == 1){ pusch_config_pdu->num_dmrs_cdm_grps_no_data = table_7_3_1_1_2_20[dci->antenna_ports.val][0]; //TBC pusch_config_pdu->dmrs_ports = table_7_3_1_1_2_20[dci->antenna_ports.val][1]; //TBC //pusch_config_pdu->n_front_load_symb = table_7_3_1_1_2_20[dci->antenna_ports.val][2]; //FIXME } - if (rank == 2) { + if (rank == 2){ pusch_config_pdu->num_dmrs_cdm_grps_no_data = table_7_3_1_1_2_21[dci->antenna_ports.val][0]; //TBC pusch_config_pdu->dmrs_ports = 0; //FIXME //pusch_config_pdu->dmrs_ports[0] = table_7_3_1_1_2_21[dci->antenna_ports.val][1]; //pusch_config_pdu->dmrs_ports[1] = table_7_3_1_1_2_21[dci->antenna_ports.val][2]; //pusch_config_pdu->n_front_load_symb = table_7_3_1_1_2_21[dci->antenna_ports.val][3]; //FIXME - } + } - if (rank == 3) { + if (rank == 3){ pusch_config_pdu->num_dmrs_cdm_grps_no_data = table_7_3_1_1_2_22[dci->antenna_ports.val][0]; //TBC pusch_config_pdu->dmrs_ports = 0; //FIXME //pusch_config_pdu->dmrs_ports[0] = table_7_3_1_1_2_22[dci->antenna_ports.val][1]; @@ -448,7 +473,7 @@ void ul_ports_config(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_confi //pusch_config_pdu->n_front_load_symb = table_7_3_1_1_2_22[dci->antenna_ports.val][4]; //FIXME } - if (rank == 4) { + if (rank == 4){ pusch_config_pdu->num_dmrs_cdm_grps_no_data = table_7_3_1_1_2_23[dci->antenna_ports.val][0]; //TBC pusch_config_pdu->dmrs_ports = 0; //FIXME //pusch_config_pdu->dmrs_ports[0] = table_7_3_1_1_2_23[dci->antenna_ports.val][1]; @@ -473,23 +498,26 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, dci_pdu_rel15_t *dci, RAR_grant_t *rar_grant, uint16_t rnti, - uint8_t *dci_format) { + uint8_t *dci_format){ + int f_alloc; int mask; int StartSymbolIndex; int NrOfSymbols; uint8_t nb_dmrs_re_per_rb; + uint16_t l_prime_mask = 0; uint16_t number_dmrs_symbols = 0; int N_PRB_oh = 0; + int rnti_type = get_rnti_type(mac, rnti); + // Common configuration pusch_config_pdu->dmrs_config_type = pusch_dmrs_type1; pusch_config_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; pusch_config_pdu->nrOfLayers = 1; pusch_config_pdu->rnti = rnti; NR_BWP_UplinkCommon_t *initialUplinkBWP; - if (mac->scc) initialUplinkBWP = mac->scc->uplinkConfigCommon->initialUplinkBWP; else initialUplinkBWP = &mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP; @@ -497,38 +525,41 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, pusch_maxLength_t dmrslength = pusch_len1; if (rar_grant) { + // Note: for Msg3 or MsgA PUSCH transmission the N_PRB_oh is always set to 0 NR_BWP_Uplink_t *ubwp = mac->ULbwp[0]; NR_BWP_UplinkDedicated_t *ibwp; int scs,abwp_start,abwp_size,startSymbolAndLength,mappingtype; NR_PUSCH_Config_t *pusch_Config=NULL; - if (mac->cg && ubwp && mac->cg->spCellConfig && mac->cg->spCellConfig->spCellConfigDedicated && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) { + ibwp = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP; pusch_Config = ibwp->pusch_Config->choice.setup; startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[rar_grant->Msg3_t_alloc]->startSymbolAndLength; mappingtype = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[rar_grant->Msg3_t_alloc]->mappingType; + // active BWP start abwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); abwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); scs = ubwp->bwp_Common->genericParameters.subcarrierSpacing; - } else { + } + else { startSymbolAndLength = initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[rar_grant->Msg3_t_alloc]->startSymbolAndLength; mappingtype = initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[rar_grant->Msg3_t_alloc]->mappingType; + // active BWP start abwp_start = NRRIV2PRBOFFSET(initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); abwp_size = NRRIV2BW(initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); scs = initialUplinkBWP->genericParameters.subcarrierSpacing; } - int ibwp_start = NRRIV2PRBOFFSET(initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); int ibwp_size = NRRIV2BW(initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - // BWP start selection according to 8.3 of TS 38.213 + // BWP start selection according to 8.3 of TS 38.213 if ((ibwp_start < abwp_start) || (ibwp_size > abwp_size)) { pusch_config_pdu->bwp_start = abwp_start; pusch_config_pdu->bwp_size = abwp_size; @@ -545,35 +576,43 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, mask = (1 << (28 - (int)(ceil(log2((ibwp_size*(ibwp_size+1))>>1))))) - 1; f_alloc = rar_grant->Msg3_f_alloc & mask; - if (nr_ue_process_dci_freq_dom_resource_assignment(pusch_config_pdu, NULL, ibwp_size, 0, f_alloc) < 0) return -1; // virtual resource block to physical resource mapping for Msg3 PUSCH (6.3.1.7 in 38.211) //pusch_config_pdu->rb_start += ibwp_start - abwp_start; + // Time domain allocation SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols); pusch_config_pdu->start_symbol_index = StartSymbolIndex; pusch_config_pdu->nr_of_symbols = NrOfSymbols; + l_prime_mask = get_l_prime(NrOfSymbols, mappingtype, add_pos, dmrslength, StartSymbolIndex, mac->scc ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position); LOG_D(MAC, "MSG3 start_sym:%d NR Symb:%d mappingtype:%d , DMRS_MASK:%x\n", pusch_config_pdu->start_symbol_index, pusch_config_pdu->nr_of_symbols, mappingtype, l_prime_mask); -#ifdef DEBUG_MSG3 + + #ifdef DEBUG_MSG3 LOG_D(NR_MAC, "In %s BWP assignment (BWP (start %d, size %d) \n", __FUNCTION__, pusch_config_pdu->bwp_start, pusch_config_pdu->bwp_size); -#endif + #endif + // MCS pusch_config_pdu->mcs_index = rar_grant->mcs; // Frequency hopping pusch_config_pdu->frequency_hopping = rar_grant->freq_hopping; + // DM-RS configuration according to 6.2.2 UE DM-RS transmission procedure in 38.214 pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; pusch_config_pdu->dmrs_ports = 1; + // DMRS sequence initialization [TS 38.211, sec 6.4.1.1.1]. // Should match what is sent in DCI 0_1, otherwise set to 0. pusch_config_pdu->scid = 0; + // Transform precoding according to 6.1.3 UE procedure for applying transform precoding on PUSCH in 38.214 pusch_config_pdu->transform_precoding = get_transformPrecoding(initialUplinkBWP, pusch_Config, NULL, NULL, NR_RNTI_TC, 0); // TBR fix rnti and take out + // Resource allocation in frequency domain according to 6.1.2.2 in TS 38.214 pusch_config_pdu->resource_alloc = (mac->cg) ? pusch_Config->resourceAllocation : 1; + //// Completing PUSCH PDU pusch_config_pdu->mcs_table = 0; pusch_config_pdu->cyclic_prefix = 0; @@ -587,20 +626,23 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, pusch_config_pdu->pusch_data.harq_process_id = 0; pusch_config_pdu->pusch_data.new_data_indicator = 1; // new data pusch_config_pdu->pusch_data.num_cb = 0; + } else if (dci) { + int target_ss; bool valid_ptrs_setup = 0; uint16_t n_RB_ULBWP; - if (mac->ULbwp[0] && mac->ULbwp[0]->bwp_Common) { n_RB_ULBWP = NRRIV2BW(mac->ULbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); pusch_config_pdu->bwp_start = NRRIV2PRBOFFSET(mac->ULbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - } else { + } + else { pusch_config_pdu->bwp_start = NRRIV2PRBOFFSET(mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE); n_RB_ULBWP = NRRIV2BW(mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE); } pusch_config_pdu->bwp_size = n_RB_ULBWP; + NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[0] ? mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup : NULL; // Basic sanity check for MCS value to check for a false or erroneous DCI @@ -616,40 +658,46 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, /*DCI format-related configuration*/ if (*dci_format == NR_UL_DCI_FORMAT_0_0) { + target_ss = NR_SearchSpace__searchSpaceType_PR_common; + } else if (*dci_format == NR_UL_DCI_FORMAT_0_1) { + /* BANDWIDTH_PART_IND */ if (dci->bwp_indicator.val != 1) { LOG_W(NR_MAC, "bwp_indicator != 1! Possibly due to false DCI. Ignoring DCI!\n"); return -1; } - config_bwp_ue(mac, &dci->bwp_indicator.val, dci_format); target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; ul_layers_config(mac, pusch_config_pdu, dci); ul_ports_config(mac, pusch_config_pdu, dci); + } else { + LOG_E(NR_MAC, "In %s: UL grant from DCI format %d is not handled...\n", __FUNCTION__, *dci_format); return -1; + } NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL; - if (pusch_Config && pusch_Config->pusch_TimeDomainAllocationList) { pusch_TimeDomainAllocationList = pusch_Config->pusch_TimeDomainAllocationList->choice.setup; - } else if (mac->ULbwp[0] && - mac->ULbwp[0]->bwp_Common&& - mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon&& - mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup && - mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) { + } + else if (mac->ULbwp[0] && + mac->ULbwp[0]->bwp_Common&& + mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon&& + mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup && + mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) { pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - } else if (mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) + } + else if (mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) pusch_TimeDomainAllocationList=mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; else AssertFatal(1==0,"need to fall back to default PUSCH time-domain allocations\n"); int mappingtype = pusch_TimeDomainAllocationList->list.array[dci->time_domain_assignment.val]->mappingType; - NR_DMRS_UplinkConfig_t *NR_DMRS_ulconfig = NULL; + NR_DMRS_UplinkConfig_t *NR_DMRS_ulconfig = NULL; if(pusch_Config) { NR_DMRS_ulconfig = (mappingtype == NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeA) ? pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup : pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup; @@ -658,9 +706,10 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, /* TRANSFORM PRECODING ------------------------------------------------------------------------------------------*/ if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled) { + pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; - uint32_t n_RS_Id = 0; + uint32_t n_RS_Id = 0; if (NR_DMRS_ulconfig->transformPrecodingEnabled->nPUSCH_Identity != NULL) n_RS_Id = *NR_DMRS_ulconfig->transformPrecodingEnabled->nPUSCH_Identity; else @@ -671,30 +720,29 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, // V as specified in section 6.4.1.1.1.2 in 38.211 V = 0 if sequence hopping and group hopping are disabled if ((NR_DMRS_ulconfig->transformPrecodingEnabled->sequenceGroupHopping == NULL) && - (NR_DMRS_ulconfig->transformPrecodingEnabled->sequenceHopping == NULL)) - pusch_config_pdu->dfts_ofdm.low_papr_sequence_number = 0; + (NR_DMRS_ulconfig->transformPrecodingEnabled->sequenceHopping == NULL)) + pusch_config_pdu->dfts_ofdm.low_papr_sequence_number = 0; else AssertFatal(1==0,"SequenceGroupHopping or sequenceHopping are NOT Supported\n"); LOG_D(NR_MAC,"TRANSFORM PRECODING IS ENABLED. CDM groups: %d, U: %d \n", pusch_config_pdu->num_dmrs_cdm_grps_no_data, - pusch_config_pdu->dfts_ofdm.low_papr_group_number); + pusch_config_pdu->dfts_ofdm.low_papr_group_number); } /* TRANSFORM PRECODING --------------------------------------------------------------------------------------------------------*/ /* IDENTIFIER_DCI_FORMATS */ /* FREQ_DOM_RESOURCE_ASSIGNMENT_UL */ - if (nr_ue_process_dci_freq_dom_resource_assignment(pusch_config_pdu, NULL, n_RB_ULBWP, 0, dci->frequency_domain_assignment.val) < 0) { + if (nr_ue_process_dci_freq_dom_resource_assignment(pusch_config_pdu, NULL, n_RB_ULBWP, 0, dci->frequency_domain_assignment.val) < 0){ return -1; } - /* TIME_DOM_RESOURCE_ASSIGNMENT */ if (nr_ue_process_dci_time_dom_resource_assignment(mac, pusch_config_pdu, NULL, dci->time_domain_assignment.val,0,false) < 0) { return -1; } /* FREQ_HOPPING_FLAG */ - if ((pusch_Config!=NULL) && (pusch_Config->frequencyHopping!=NULL) && (pusch_Config->resourceAllocation != NR_PUSCH_Config__resourceAllocation_resourceAllocationType0)) { + if ((pusch_Config!=NULL) && (pusch_Config->frequencyHopping!=NULL) && (pusch_Config->resourceAllocation != NR_PUSCH_Config__resourceAllocation_resourceAllocationType0)){ pusch_config_pdu->frequency_hopping = dci->frequency_hopping_flag.val; } @@ -714,21 +762,17 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, pusch_config_pdu->pusch_data.rv_index = dci->rv; /* HARQ_PROCESS_NUMBER */ pusch_config_pdu->pusch_data.harq_process_id = dci->harq_pid; - /* TPC_PUSCH */ // according to TS 38.213 Table Table 7.1.1-1 if (dci->tpc == 0) { pusch_config_pdu->absolute_delta_PUSCH = -4; } - if (dci->tpc == 1) { pusch_config_pdu->absolute_delta_PUSCH = -1; } - if (dci->tpc == 2) { pusch_config_pdu->absolute_delta_PUSCH = 1; } - if (dci->tpc == 3) { pusch_config_pdu->absolute_delta_PUSCH = 4; } @@ -743,7 +787,6 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, mappingtype, add_pos, dmrslength, pusch_config_pdu->start_symbol_index, mac->scc ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position); - if ((mac->ULbwp[0] && pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled)) pusch_config_pdu->num_dmrs_cdm_grps_no_data = 1; else if (*dci_format == NR_UL_DCI_FORMAT_0_0 || (mac->ULbwp[0] && pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled)) @@ -757,15 +800,16 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead) N_PRB_oh = *mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead; + else N_PRB_oh = 0; /* PTRS */ if (mac->ULbwp[0] && - mac->ULbwp[0]->bwp_Dedicated && - mac->ULbwp[0]->bwp_Dedicated->pusch_Config && - mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup && - mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB && - mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS) { + mac->ULbwp[0]->bwp_Dedicated && + mac->ULbwp[0]->bwp_Dedicated->pusch_Config && + mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup && + mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB && + mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS) { if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled) { nfapi_nr_ue_ptrs_ports_t ptrs_ports_list; pusch_config_pdu->pusch_ptrs.ptrs_ports_list = &ptrs_ports_list; @@ -774,23 +818,23 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, &pusch_config_pdu->pusch_ptrs.ptrs_freq_density,&pusch_config_pdu->pusch_ptrs.ptrs_time_density, &pusch_config_pdu->pusch_ptrs.ptrs_ports_list->ptrs_re_offset,&pusch_config_pdu->pusch_ptrs.num_ptrs_ports, &pusch_config_pdu->pusch_ptrs.ul_ptrs_power, pusch_config_pdu->nr_of_symbols); - if(valid_ptrs_setup==true) { pusch_config_pdu->pdu_bit_map |= PUSCH_PDU_BITMAP_PUSCH_PTRS; } - LOG_D(NR_MAC, "UL PTRS values: PTRS time den: %d, PTRS freq den: %d\n", pusch_config_pdu->pusch_ptrs.ptrs_time_density, pusch_config_pdu->pusch_ptrs.ptrs_freq_density); } } + } LOG_D(NR_MAC, "In %s: received UL grant (rb_start %d, rb_size %d, start_symbol_index %d, nr_of_symbols %d) for RNTI type %s \n", - __FUNCTION__, - pusch_config_pdu->rb_start, - pusch_config_pdu->rb_size, - pusch_config_pdu->start_symbol_index, - pusch_config_pdu->nr_of_symbols, - rnti_types[rnti_type]); + __FUNCTION__, + pusch_config_pdu->rb_start, + pusch_config_pdu->rb_size, + pusch_config_pdu->start_symbol_index, + pusch_config_pdu->nr_of_symbols, + rnti_types[rnti_type]); + pusch_config_pdu->ul_dmrs_symb_pos = l_prime_mask; pusch_config_pdu->target_code_rate = nr_get_code_rate_ul(pusch_config_pdu->mcs_index, pusch_config_pdu->mcs_table); pusch_config_pdu->qam_mod_order = nr_get_Qm_ul(pusch_config_pdu->mcs_index, pusch_config_pdu->mcs_table); @@ -801,35 +845,42 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, } get_num_re_dmrs(pusch_config_pdu, &nb_dmrs_re_per_rb, &number_dmrs_symbols); + // Compute TBS pusch_config_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_config_pdu->qam_mod_order, - pusch_config_pdu->target_code_rate, - pusch_config_pdu->rb_size, - pusch_config_pdu->nr_of_symbols, - nb_dmrs_re_per_rb*number_dmrs_symbols, - N_PRB_oh, - 0, // TBR to verify tb scaling - pusch_config_pdu->nrOfLayers)/8; + pusch_config_pdu->target_code_rate, + pusch_config_pdu->rb_size, + pusch_config_pdu->nr_of_symbols, + nb_dmrs_re_per_rb*number_dmrs_symbols, + N_PRB_oh, + 0, // TBR to verify tb scaling + pusch_config_pdu->nrOfLayers)/8; + return 0; + } // Performs : // 1. TODO: Call RRC for link status return to PHY // 2. TODO: Perform SR/BSR procedures for scheduling feedback // 3. TODO: Perform PHR procedures -NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_indication_t *ul_info) { - if (dl_info) { +NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_indication_t *ul_info){ + + if (dl_info){ + module_id_t mod_id = dl_info->module_id; uint32_t gNB_index = dl_info->gNB_index; int cc_id = dl_info->cc_id; frame_t rx_frame = dl_info->frame; slot_t rx_slot = dl_info->slot; NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request; + nr_scheduled_response_t scheduled_response; nr_dcireq_t dcireq; - if(mac->cg != NULL) { // we have a cg + if(mac->cg != NULL){ // we have a cg dcireq.module_id = mod_id; dcireq.gNB_index = gNB_index; dcireq.cc_id = cc_id; @@ -837,31 +888,30 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in dcireq.slot = rx_slot; dcireq.dl_config_req.number_pdus = 0; nr_ue_dcireq(&dcireq); //to be replaced with function pointer later - fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id); + fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id); if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) mac->if_module->scheduled_response(&scheduled_response); - } else { + } + else { // this is for Msg2/Msg4 if (mac->ra.ra_state >= WAIT_RAR) { fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15; rel15->num_dci_options = mac->ra.ra_state == WAIT_RAR ? 1 : 2; rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0; - if (mac->ra.ra_state == WAIT_CONTENTION_RESOLUTION) rel15->dci_format_options[1] = NR_UL_DCI_FORMAT_0_0; // msg3 retransmission - - config_dci_pdu(mac, rel15, dl_config, mac->ra.ra_state == WAIT_RAR ? NR_RNTI_RA : NR_RNTI_TC, -1); + config_dci_pdu(mac, rel15, dl_config, mac->ra.ra_state == WAIT_RAR ? NR_RNTI_RA : NR_RNTI_TC , -1); fill_dci_search_candidates(mac->ra.ss, rel15); dl_config->number_pdus = 1; LOG_D(MAC,"mac->cg %p: Calling fill_scheduled_response rnti %x, type0_pdcch, num_pdus %d\n",mac->cg,rel15->rnti,dl_config->number_pdus); fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id); - if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) mac->if_module->scheduled_response(&scheduled_response); } } } else if (ul_info) { + int cc_id = ul_info->cc_id; frame_t rx_frame = ul_info->frame_rx; slot_t rx_slot = ul_info->slot_rx; @@ -869,46 +919,51 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in slot_t slot_tx = ul_info->slot_tx; module_id_t mod_id = ul_info->module_id; uint32_t gNB_index = ul_info->gNB_index; + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); RA_config_t *ra = &mac->ra; + fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx); // Schedule ULSCH only if the current frame and slot match those in ul_config_req // AND if a UL grant (UL DCI or Msg3) has been received (as indicated by num_pdus) - if (ul_config && (ul_info->slot_tx == ul_config->slot && ul_info->frame_tx == ul_config->sfn) && ul_config->number_pdus > 0) { + if (ul_config && (ul_info->slot_tx == ul_config->slot && ul_info->frame_tx == ul_config->sfn) && ul_config->number_pdus > 0){ + LOG_D(NR_MAC, "In %s:[%d.%d]: number of UL PDUs: %d with UL transmission in [%d.%d]\n", __FUNCTION__, frame_tx, slot_tx, ul_config->number_pdus, ul_config->sfn, ul_config->slot); + uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES]; nr_scheduled_response_t scheduled_response; fapi_nr_tx_request_t tx_req; for (int j = 0; j < ul_config->number_pdus; j++) { + fapi_nr_ul_config_request_pdu_t *ulcfg_pdu = &ul_config->ul_config_list[j]; if (ulcfg_pdu->pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH) { + uint16_t TBS_bytes = ulcfg_pdu->pusch_config_pdu.pusch_data.tb_size; LOG_D(NR_MAC,"harq_id %d, NDI %d NDI_DCI %d, TBS_bytes %d\n", ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id, mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id], ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator, TBS_bytes); - - if (ra->ra_state == WAIT_RAR && !ra->cfra) { + if (ra->ra_state == WAIT_RAR && !ra->cfra){ memcpy(ulsch_input_buffer, mac->ulsch_pdu.payload, TBS_bytes); LOG_D(NR_MAC,"[RAPROC] Msg3 to be transmitted:\n"); - for (int k = 0; k < TBS_bytes; k++) { LOG_D(NR_MAC,"(%i): 0x%x\n",k,mac->ulsch_pdu.payload[k]); } - LOG_D(NR_MAC,"Flipping NDI for harq_id %d (Msg3)\n",ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator); mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator; mac->first_ul_tx[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = 0; } else { + if ((mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] != ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator || - mac->first_ul_tx[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id]==1) && + mac->first_ul_tx[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id]==1) && ((get_softmodem_params()->phy_test == 1) || - (ra->ra_state == RA_SUCCEEDED) || - (ra->ra_state == WAIT_RAR && ra->cfra))) { + (ra->ra_state == RA_SUCCEEDED) || + (ra->ra_state == WAIT_RAR && ra->cfra))){ + // Getting IP traffic to be transmitted nr_ue_get_sdu(mod_id, frame_tx, slot_tx, gNB_index, ulsch_input_buffer, TBS_bytes); } @@ -916,6 +971,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in LOG_D(NR_MAC,"Flipping NDI for harq_id %d\n",ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator); mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator; mac->first_ul_tx[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = 0; + } // Config UL TX PDU @@ -926,13 +982,12 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in tx_req.tx_request_body[0].pdu_index = j; tx_req.tx_request_body[0].pdu = ulsch_input_buffer; - if (ra->ra_state == WAIT_CONTENTION_RESOLUTION && !ra->cfra) { + if (ra->ra_state == WAIT_CONTENTION_RESOLUTION && !ra->cfra){ LOG_I(NR_MAC,"[RAPROC] RA-Msg3 retransmitted\n"); // 38.321 restart the ra-ContentionResolutionTimer at each HARQ retransmission in the first symbol after the end of the Msg3 transmission nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->gNB_index); } - - if (ra->ra_state == WAIT_RAR && !ra->cfra) { + if (ra->ra_state == WAIT_RAR && !ra->cfra){ LOG_I(NR_MAC,"[RAPROC] RA-Msg3 transmitted\n"); nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->gNB_index); } @@ -940,20 +995,19 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in } fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, mod_id, cc_id, rx_frame, rx_slot, ul_info->thread_id); - - if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) { + if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){ mac->if_module->scheduled_response(&scheduled_response); } } } if (dl_info) { - return (CONNECTION_OK); + return (CONNECTION_OK); } - module_id_t mod_id = ul_info->module_id; frame_t txFrameP = ul_info->frame_tx; slot_t txSlotP = ul_info->slot_tx; + // Handle the SR/BSR procedures per subframe NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); uint8_t gNB_indexP=0; @@ -987,13 +1041,13 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in "[UE %d][BSR] Regular BSR Triggered Frame %d slot %d SR for PUSCH is pending\n", mod_id, txFrameP, txSlotP); } - return UE_CONNECTION_OK; + } boolean_t nr_update_bsr(module_id_t module_idP, frame_t frameP, - slot_t slotP, uint8_t gNB_index) { + slot_t slotP, uint8_t gNB_index) { mac_rlc_status_resp_t rlc_status; boolean_t bsr_regular_triggered = FALSE; uint8_t lcid; @@ -1002,11 +1056,11 @@ nr_update_bsr(module_id_t module_idP, frame_t frameP, uint32_t lcgid_buffer_remain[NR_MAX_NUM_LCGID] = {0,0,0,0,0,0,0,0}; int32_t lcid_bytes_in_buffer[NR_MAX_NUM_LCID]; /* Array for ordering LCID with data per decreasing priority order */ - uint8_t lcid_reordered_array[NR_MAX_NUM_LCID]= { - NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID, - NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID, - NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID, - NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID, + uint8_t lcid_reordered_array[NR_MAX_NUM_LCID]= + {NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID, + NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID, + NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID, + NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID, }; uint8_t pos_next = 0; //uint8_t highest_priority = 16; @@ -1014,7 +1068,6 @@ nr_update_bsr(module_id_t module_idP, frame_t frameP, // Reset All BSR Infos lcid_bytes_in_buffer[0] = 0; NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); - for (lcid=DCCH; lcid < NR_MAX_NUM_LCID; lcid++) { // Reset transmission status lcid_bytes_in_buffer[lcid] = 0; @@ -1042,6 +1095,7 @@ nr_update_bsr(module_id_t module_idP, frame_t frameP, lcid, 0, 0 ); + lcid_bytes_in_buffer[lcid] = rlc_status.bytes_in_buffer; if (rlc_status.bytes_in_buffer > 0) { @@ -1087,6 +1141,7 @@ nr_update_bsr(module_id_t module_idP, frame_t frameP, for (array_index = 0; array_index < num_lcid_with_data; array_index++) { lcid = lcid_reordered_array[array_index]; + /* UL data, for a logical channel which belongs to a LCG, becomes available for transmission in the RLC entity either the data belongs to a logical channel with higher priority than the priorities of the logical channels which belong to any LCG and for which data is already available for transmission @@ -1284,7 +1339,7 @@ int nr_get_sf_retxBSRTimer(uint8_t sf_offset) { // PUSCH scheduler: // - Calculate the slot in which ULSCH should be scheduled. This is current slot + K2, // - where K2 is the offset between the slot in which UL DCI is received and the slot -// - in which ULSCH should be scheduled. K2 is configured in RRC configuration. +// - in which ULSCH should be scheduled. K2 is configured in RRC configuration. // PUSCH Msg3 scheduler: // - scheduled by RAR UL grant according to 8.3 of TS 38.213 // Note: Msg3 tx in the uplink symbols of mixed slot @@ -1294,16 +1349,18 @@ int nr_ue_pusch_scheduler(NR_UE_MAC_INST_t *mac, int current_slot, frame_t *frame_tx, int *slot_tx, - uint8_t tda_id) { + uint8_t tda_id){ + int delta = 0; NR_BWP_Uplink_t *ubwp = mac->ULbwp[0]; // Get the numerology to calculate the Tx frame and slot int mu = ubwp ? - ubwp->bwp_Common->genericParameters.subcarrierSpacing : - mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing; + ubwp->bwp_Common->genericParameters.subcarrierSpacing : + mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing; + NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = ubwp ? - ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList: - mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; + ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList: + mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; // k2 as per 3GPP TS 38.214 version 15.9.0 Release 15 ch 6.1.2.1.1 // PUSCH time domain resource allocation is higher layer configured from uschTimeDomainAllocationList in either pusch-ConfigCommon int k2; @@ -1315,15 +1372,12 @@ int nr_ue_pusch_scheduler(NR_UE_MAC_INST_t *mac, case 0: delta = 2; break; - case 1: delta = 3; break; - case 2: delta = 4; break; - case 3: delta = 6; break; @@ -1332,17 +1386,18 @@ int nr_ue_pusch_scheduler(NR_UE_MAC_INST_t *mac, AssertFatal((k2+delta) >= DURATION_RX_TO_TX, "Slot offset (%d) for Msg3 cannot be less than DURATION_RX_TO_TX (%d)\n", k2+delta,DURATION_RX_TO_TX); - *slot_tx = (current_slot + k2 + delta) % nr_slots_per_frame[mu]; - if (current_slot + k2 + delta > nr_slots_per_frame[mu]) { + *slot_tx = (current_slot + k2 + delta) % nr_slots_per_frame[mu]; + if (current_slot + k2 + delta > nr_slots_per_frame[mu]){ *frame_tx = (current_frame + 1) % 1024; } else { *frame_tx = current_frame; } + } else { + // Get slot offset K2 which will be used to calculate TX slot k2 = get_k2(mac, tda_id); - if (k2 < 0) { // This can happen when a false DCI is received return -1; } @@ -1350,14 +1405,18 @@ int nr_ue_pusch_scheduler(NR_UE_MAC_INST_t *mac, // Calculate TX slot and frame *slot_tx = (current_slot + k2) % nr_slots_per_frame[mu]; *frame_tx = ((current_slot + k2) > nr_slots_per_frame[mu]) ? (current_frame + 1) % 1024 : current_frame; + } LOG_D(NR_MAC, "In %s: currently at [%d.%d] UL transmission in [%d.%d] (k2 %d delta %d)\n", __FUNCTION__, current_frame, current_slot, *frame_tx, *slot_tx, k2, delta); + return 0; + } // Build the list of all the valid RACH occasions in the maximum association pattern period according to the PRACH config static void build_ro_list(NR_UE_MAC_INST_t *mac) { + int x,y; // PRACH Configuration Index table variables used to compute the valid frame numbers int y2; // PRACH Configuration Index table additional variable used to compute the valid frame numbers uint8_t slot_shift_for_map; @@ -1372,16 +1431,20 @@ static void build_ro_list(NR_UE_MAC_INST_t *mac) { uint16_t format = 0xffff; uint8_t format2 = 0xff; int nb_fdm; + uint8_t config_index, mu; int msg1_FDM; + uint8_t prach_conf_period_idx; uint8_t nb_of_frames_per_prach_conf_period; uint8_t prach_conf_period_frame_idx; int64_t *prach_config_info_p; + NR_RACH_ConfigCommon_t *setup = (mac->scc) ? - mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup: - mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup; + mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup: + mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup; NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric; + config_index = rach_ConfigGeneric->prach_ConfigurationIndex; if (setup->msg1_SubcarrierSpacing) { @@ -1394,14 +1457,13 @@ static void build_ro_list(NR_UE_MAC_INST_t *mac) { msg1_FDM = rach_ConfigGeneric->msg1_FDM; - switch (msg1_FDM) { + switch (msg1_FDM){ case 0: case 1: case 2: case 3: nb_fdm = 1 << msg1_FDM; break; - default: AssertFatal(1 == 0, "Unknown msg1_FDM from rach_ConfigGeneric %d\n", msg1_FDM); } @@ -1409,46 +1471,51 @@ static void build_ro_list(NR_UE_MAC_INST_t *mac) { // Create the PRACH occasions map // ============================== // WIP: For now assume no rejected PRACH occasions because of conflict with SSB or TDD_UL_DL_ConfigurationCommon schedule + int unpaired = mac->phy_config.config_req.cell_config.frame_duplex_type; + prach_config_info_p = get_prach_config_info(mac->frequency_range, config_index, unpaired); + // Identify the proper PRACH Configuration Index table according to the operating frequency LOG_D(NR_MAC,"mu = %u, PRACH config index = %u, unpaired = %u\n", mu, config_index, unpaired); if (mac->frequency_range == FR2) { //FR2 + x = prach_config_info_p[2]; y = prach_config_info_p[3]; y2 = prach_config_info_p[4]; + s_map = prach_config_info_p[5]; + prach_conf_start_symbol = prach_config_info_p[6]; N_t_slot = prach_config_info_p[8]; N_dur = prach_config_info_p[9]; - if (prach_config_info_p[1] != -1) format2 = (uint8_t) prach_config_info_p[1]; - format = ((uint8_t) prach_config_info_p[0]) | (format2<<8); - slot_shift_for_map = mu-2; + slot_shift_for_map = mu-2; if ( (mu == 3) && (prach_config_info_p[7] == 1) ) even_slot_invalid = true; else even_slot_invalid = false; - } else { // FR1 + } + else { // FR1 x = prach_config_info_p[2]; y = prach_config_info_p[3]; y2 = y; + s_map = prach_config_info_p[4]; + prach_conf_start_symbol = prach_config_info_p[5]; N_t_slot = prach_config_info_p[7]; N_dur = prach_config_info_p[8]; LOG_D(NR_MAC,"N_t_slot %d, N_dur %d\n",N_t_slot,N_dur); - if (prach_config_info_p[1] != -1) format2 = (uint8_t) prach_config_info_p[1]; - format = ((uint8_t) prach_config_info_p[0]) | (format2<<8); - slot_shift_for_map = mu; + slot_shift_for_map = mu; if ( (mu == 1) && (prach_config_info_p[6] <= 1) ) // no prach in even slots @ 30kHz for 1 prach per subframe even_slot_invalid = true; @@ -1458,6 +1525,7 @@ static void build_ro_list(NR_UE_MAC_INST_t *mac) { prach_assoc_pattern.nb_of_prach_conf_period_in_max_period = MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD / x; nb_of_frames_per_prach_conf_period = x; + LOG_D(NR_MAC,"nb_of_prach_conf_period_in_max_period %d\n", prach_assoc_pattern.nb_of_prach_conf_period_in_max_period); // Fill in the PRACH occasions table for every slot in every frame in every PRACH configuration periods in the maximum association pattern period @@ -1469,33 +1537,36 @@ static void build_ro_list(NR_UE_MAC_INST_t *mac) { prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].nb_of_prach_occasion = 0; prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].nb_of_frame = nb_of_frames_per_prach_conf_period; prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].nb_of_slot = nr_slots_per_frame[mu]; + LOG_D(NR_MAC,"PRACH Conf Period Idx %d\n", prach_conf_period_idx); // For every frames in a PRACH configuration period // ------------------------------------------------ for (prach_conf_period_frame_idx=0; prach_conf_period_frame_idx<nb_of_frames_per_prach_conf_period; prach_conf_period_frame_idx++) { frame = (prach_conf_period_idx * nb_of_frames_per_prach_conf_period) + prach_conf_period_frame_idx; - LOG_D(NR_MAC,"PRACH Conf Period Frame Idx %d - Frame %d\n", prach_conf_period_frame_idx, frame); + LOG_D(NR_MAC,"PRACH Conf Period Frame Idx %d - Frame %d\n", prach_conf_period_frame_idx, frame); // Is it a valid frame for this PRACH configuration index? (n_sfn mod x = y) if ( (frame%x)==y || (frame%x)==y2 ) { + // For every slot in a frame // ------------------------- for (slot=0; slot<nr_slots_per_frame[mu]; slot++) { // Is it a valid slot? map_shift = slot >> slot_shift_for_map; // in PRACH configuration index table slots are numbered wrt 60kHz - if ( (s_map>>map_shift)&0x01 ) { // Valid slot // Additionally, for 30kHz/120kHz, we must check for the n_RA_Slot param also if ( even_slot_invalid && (slot%2 == 0) ) - continue; // no prach in even slots @ 30kHz/120kHz for 1 prach per 60khz slot/subframe + continue; // no prach in even slots @ 30kHz/120kHz for 1 prach per 60khz slot/subframe // We're good: valid frame and valid slot // Compute all the PRACH occasions in the slot + uint8_t n_prach_occ_in_time; uint8_t n_prach_occ_in_freq; + prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].prach_occasion_slot_map[prach_conf_period_frame_idx][slot].nb_of_prach_occasion_in_time = N_t_slot; prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].prach_occasion_slot_map[prach_conf_period_frame_idx][slot].nb_of_prach_occasion_in_freq = nb_fdm; @@ -1504,18 +1575,19 @@ static void build_ro_list(NR_UE_MAC_INST_t *mac) { LOG_D(NR_MAC,"PRACH Occ in time %d\n", n_prach_occ_in_time); for (n_prach_occ_in_freq=0; n_prach_occ_in_freq<nb_fdm; n_prach_occ_in_freq++) { - prach_occasion_info_t *prach_occasion_p = - &prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].prach_occasion_slot_map[prach_conf_period_frame_idx][slot].prach_occasion[n_prach_occ_in_time][n_prach_occ_in_freq]; + prach_occasion_info_t *prach_occasion_p = &prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].prach_occasion_slot_map[prach_conf_period_frame_idx][slot].prach_occasion[n_prach_occ_in_time][n_prach_occ_in_freq]; + prach_occasion_p->start_symbol = start_symbol; prach_occasion_p->fdm = n_prach_occ_in_freq; prach_occasion_p->frame = frame; prach_occasion_p->slot = slot; prach_occasion_p->format = format; prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].nb_of_prach_occasion++; + LOG_D(NR_MAC,"Adding a PRACH occasion: frame %u, slot-symbol %d-%d, occ_in_time-occ_in-freq %d-%d, nb ROs in conf period %d, for this slot: RO# in time %d, RO# in freq %d\n", - frame, slot, start_symbol, n_prach_occ_in_time, n_prach_occ_in_freq, prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].nb_of_prach_occasion, - prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].prach_occasion_slot_map[prach_conf_period_frame_idx][slot].nb_of_prach_occasion_in_time, - prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].prach_occasion_slot_map[prach_conf_period_frame_idx][slot].nb_of_prach_occasion_in_freq); + frame, slot, start_symbol, n_prach_occ_in_time, n_prach_occ_in_freq, prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].nb_of_prach_occasion, + prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].prach_occasion_slot_map[prach_conf_period_frame_idx][slot].nb_of_prach_occasion_in_time, + prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].prach_occasion_slot_map[prach_conf_period_frame_idx][slot].nb_of_prach_occasion_in_freq); } // For every freq in the slot } // For every time occasions in the slot } // Valid slot? @@ -1527,6 +1599,7 @@ static void build_ro_list(NR_UE_MAC_INST_t *mac) { // Build the list of all the valid/transmitted SSBs according to the config static void build_ssb_list(NR_UE_MAC_INST_t *mac) { + // Create the list of transmitted SSBs // =================================== BIT_STRING_t *ssb_bitmap; @@ -1535,10 +1608,10 @@ static void build_ssb_list(NR_UE_MAC_INST_t *mac) { if (mac->scc) { NR_ServingCellConfigCommon_t *scc = mac->scc; - switch (scc->ssb_PositionsInBurst->present) { case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_shortBitmap: ssb_bitmap = &scc->ssb_PositionsInBurst->choice.shortBitmap; + ssb_positionsInBurst = BIT_STRING_to_uint8(ssb_bitmap); LOG_D(NR_MAC,"SSB config: SSB_positions_in_burst 0x%lx\n", ssb_positionsInBurst); @@ -1549,14 +1622,12 @@ static void build_ssb_list(NR_UE_MAC_INST_t *mac) { ssb_list.tx_ssb[ssb_idx].transmitted = true; LOG_D(NR_MAC,"SSB idx %d transmitted\n", ssb_idx); } - ssb_idx++; } - break; - case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap: ssb_bitmap = &scc->ssb_PositionsInBurst->choice.mediumBitmap; + ssb_positionsInBurst = BIT_STRING_to_uint8(ssb_bitmap); LOG_D(NR_MAC,"SSB config: SSB_positions_in_burst 0x%lx\n", ssb_positionsInBurst); @@ -1567,14 +1638,12 @@ static void build_ssb_list(NR_UE_MAC_INST_t *mac) { ssb_list.tx_ssb[ssb_idx].transmitted = true; LOG_D(NR_MAC,"SSB idx %d transmitted\n", ssb_idx); } - ssb_idx++; } - break; - case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_longBitmap: ssb_bitmap = &scc->ssb_PositionsInBurst->choice.longBitmap; + ssb_positionsInBurst = BIT_STRING_to_uint64(ssb_bitmap); LOG_D(NR_MAC,"SSB config: SSB_positions_in_burst 0x%lx\n", ssb_positionsInBurst); @@ -1585,20 +1654,20 @@ static void build_ssb_list(NR_UE_MAC_INST_t *mac) { ssb_list.tx_ssb[ssb_idx].transmitted = true; LOG_D(NR_MAC,"SSB idx %d transmitted\n", ssb_idx); } - ssb_idx++; } - break; - default: AssertFatal(false,"ssb_PositionsInBurst not present\n"); break; } } else { // This is configuration from SIB1 + AssertFatal(mac->scc_SIB->ssb_PositionsInBurst.groupPresence == NULL, "Handle case for >8 SSBs\n"); ssb_bitmap = &mac->scc_SIB->ssb_PositionsInBurst.inOneGroup; + ssb_positionsInBurst = BIT_STRING_to_uint8(ssb_bitmap); + LOG_D(NR_MAC,"SSB config: SSB_positions_in_burst 0x%lx\n", ssb_positionsInBurst); for (uint8_t bit_nb=7; bit_nb<=7; bit_nb--) { @@ -1608,7 +1677,6 @@ static void build_ssb_list(NR_UE_MAC_INST_t *mac) { ssb_list.tx_ssb[ssb_idx].transmitted = true; LOG_D(NR_MAC,"SSB idx %d transmitted\n", ssb_idx); } - ssb_idx++; } } @@ -1616,13 +1684,15 @@ static void build_ssb_list(NR_UE_MAC_INST_t *mac) { // Map the transmitted SSBs to the ROs and create the association pattern according to the config static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac) { + // Map SSBs to PRACH occasions // =========================== // WIP: Assumption: No PRACH occasion is rejected because of a conflict with SSBs or TDD_UL_DL_ConfigurationCommon schedule NR_RACH_ConfigCommon_t *setup = (mac->scc) ? - mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup: - mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup; + mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup: + mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup; NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR ssb_perRACH_config = setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present; + boolean_t multiple_ssb_per_ro; // true if more than one or exactly one SSB per RACH occasion, false if more than one RO per SSB uint8_t ssb_rach_ratio; // Nb of SSBs per RACH or RACHs per SSB uint16_t required_nb_of_prach_occasion; // Nb of RACH occasions required to map all the SSBs @@ -1630,63 +1700,55 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac) { // Determine the SSB to RACH mapping ratio // ======================================= - switch (ssb_perRACH_config) { + switch (ssb_perRACH_config){ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneEighth: multiple_ssb_per_ro = false; ssb_rach_ratio = 8; break; - case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneFourth: multiple_ssb_per_ro = false; ssb_rach_ratio = 4; break; - case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneHalf: multiple_ssb_per_ro = false; ssb_rach_ratio = 2; break; - case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_one: multiple_ssb_per_ro = true; ssb_rach_ratio = 1; break; - case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_two: multiple_ssb_per_ro = true; ssb_rach_ratio = 2; break; - case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_four: multiple_ssb_per_ro = true; ssb_rach_ratio = 4; break; - case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_eight: multiple_ssb_per_ro = true; ssb_rach_ratio = 8; break; - case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_sixteen: multiple_ssb_per_ro = true; ssb_rach_ratio = 16; break; - default: AssertFatal(1 == 0, "Unsupported ssb_perRACH_config %d\n", ssb_perRACH_config); break; } - LOG_D(NR_MAC,"SSB rach ratio %d, Multiple SSB per RO %d\n", ssb_rach_ratio, multiple_ssb_per_ro); + // Evaluate the number of PRACH configuration periods required to map all the SSBs and set the association period // ============================================================================================================== // WIP: Assumption for now is that all the PRACH configuration periods within a maximum association pattern period have the same number of PRACH occasions // (No PRACH occasions are conflicting with SSBs nor TDD_UL_DL_ConfigurationCommon schedule) // There is only one possible association period which can contain up to 16 PRACH configuration periods LOG_D(NR_MAC,"Evaluate the number of PRACH configuration periods required to map all the SSBs and set the association period\n"); - if (true == multiple_ssb_per_ro) { required_nb_of_prach_occasion = ((ssb_list.nb_tx_ssb-1) + ssb_rach_ratio) / ssb_rach_ratio; - } else { + } + else { required_nb_of_prach_occasion = ssb_list.nb_tx_ssb * ssb_rach_ratio; } @@ -1698,40 +1760,47 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac) { if (required_nb_of_prach_conf_period == 1) { prach_assoc_pattern.prach_association_period_list[0].nb_of_prach_conf_period = 1; - } else if (required_nb_of_prach_conf_period == 2) { + } + else if (required_nb_of_prach_conf_period == 2) { prach_assoc_pattern.prach_association_period_list[0].nb_of_prach_conf_period = 2; - } else if (required_nb_of_prach_conf_period <= 4) { + } + else if (required_nb_of_prach_conf_period <= 4) { prach_assoc_pattern.prach_association_period_list[0].nb_of_prach_conf_period = 4; - } else if (required_nb_of_prach_conf_period <= 8) { + } + else if (required_nb_of_prach_conf_period <= 8) { prach_assoc_pattern.prach_association_period_list[0].nb_of_prach_conf_period = 8; - } else if (required_nb_of_prach_conf_period <= 16) { + } + else if (required_nb_of_prach_conf_period <= 16) { prach_assoc_pattern.prach_association_period_list[0].nb_of_prach_conf_period = 16; - } else { + } + else { AssertFatal(1 == 0, "Invalid number of PRACH config periods within an association period %d\n", required_nb_of_prach_conf_period); } prach_assoc_pattern.nb_of_assoc_period = 1; // WIP: only one possible association period - prach_assoc_pattern.prach_association_period_list[0].nb_of_frame = prach_assoc_pattern.prach_association_period_list[0].nb_of_prach_conf_period * - prach_assoc_pattern.prach_conf_period_list[0].nb_of_frame; + prach_assoc_pattern.prach_association_period_list[0].nb_of_frame = prach_assoc_pattern.prach_association_period_list[0].nb_of_prach_conf_period * prach_assoc_pattern.prach_conf_period_list[0].nb_of_frame; prach_assoc_pattern.nb_of_frame = prach_assoc_pattern.prach_association_period_list[0].nb_of_frame; + LOG_D(NR_MAC,"Assoc period %d, Nb of frames in assoc period %d\n", prach_assoc_pattern.prach_association_period_list[0].nb_of_prach_conf_period, prach_assoc_pattern.prach_association_period_list[0].nb_of_frame); + // Proceed to the SSB to RO mapping // ================================ uint8_t association_period_idx; // Association period index within the association pattern uint8_t ssb_idx = 0; uint8_t prach_configuration_period_idx; // PRACH Configuration period index within the association pattern prach_conf_period_t *prach_conf_period_p; + // Map all the association periods within the association pattern period LOG_D(NR_MAC,"Proceed to the SSB to RO mapping\n"); - for (association_period_idx=0; association_period_idx<prach_assoc_pattern.nb_of_assoc_period; association_period_idx++) { uint8_t n_prach_conf=0; // PRACH Configuration period index within the association period uint8_t frame=0; uint8_t slot=0; uint8_t ro_in_time=0; uint8_t ro_in_freq=0; + // Set the starting PRACH Configuration period index in the association_pattern map for this particular association period prach_configuration_period_idx = 0; // WIP: only one possible association period so the starting PRACH configuration period is automatically 0 @@ -1742,6 +1811,7 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac) { // Multiple SSBs per RO // -------------------- // -------------------- + // WIP: For the moment, only map each SSB idx once per association period if configuration is multiple SSBs per RO // this is true if no PRACH occasions are conflicting with SSBs nor TDD_UL_DL_ConfigurationCommon schedule ssb_idx = 0; @@ -1770,6 +1840,7 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac) { ssb_list.tx_ssb[ssb_idx].mapped_ro[ssb_list.tx_ssb[ssb_idx].nb_mapped_ro] = ro_p; ssb_list.tx_ssb[ssb_idx].nb_mapped_ro++; AssertFatal(MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN > ssb_list.tx_ssb[ssb_idx].nb_mapped_ro,"Too many mapped ROs (%d) to a single SSB\n", ssb_list.tx_ssb[ssb_idx].nb_mapped_ro); + LOG_D(NR_MAC,"Mapped ssb_idx %u to RO slot-symbol %u-%u, %u-%u-%u/%u\n", ssb_idx, ro_p->slot, ro_p->start_symbol, slot, ro_in_time, ro_in_freq, prach_conf_period_p->prach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_freq); @@ -1804,26 +1875,32 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac) { } // for n_prach_conf // WIP: note that there is no re-mapping of the SSBs within the association period since there is no invalid ROs in the PRACH config periods that would create this situation + } // if multiple_ssbs_per_ro + else { // -------------------- // -------------------- // Multiple ROs per SSB // -------------------- // -------------------- + n_prach_conf = 0; // Go through the list of transmitted SSBs for (ssb_idx=0; ssb_idx<MAX_NB_SSB; ssb_idx++) { uint8_t nb_mapped_ro_in_association_period=0; // Reset the nb of mapped ROs for the new SSB index - LOG_D(NR_MAC,"Checking ssb_idx %d => %d\n", - ssb_idx,ssb_list.tx_ssb[ssb_idx].transmitted); + + LOG_D(NR_MAC,"Checking ssb_idx %d => %d\n", + ssb_idx,ssb_list.tx_ssb[ssb_idx].transmitted); // Map only the transmitted ssb_idx if (true == ssb_list.tx_ssb[ssb_idx].transmitted) { + // Map all the required ROs to this SSB // Go through the list of PRACH config periods within this association period for (; n_prach_conf<prach_assoc_pattern.prach_association_period_list[association_period_idx].nb_of_prach_conf_period; n_prach_conf++, prach_configuration_period_idx++) { + // Build the association period with its association PRACH Configuration indexes prach_conf_period_p = &prach_assoc_pattern.prach_conf_period_list[prach_configuration_period_idx]; prach_assoc_pattern.prach_association_period_list[association_period_idx].prach_conf_period_list[n_prach_conf] = prach_conf_period_p; @@ -1833,6 +1910,7 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac) { for (; ro_in_time<prach_conf_period_p->prach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_time; ro_in_time++) { for (; ro_in_freq<prach_conf_period_p->prach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_freq; ro_in_freq++) { prach_occasion_info_t *ro_p = &prach_conf_period_p->prach_occasion_slot_map[frame][slot].prach_occasion[ro_in_time][ro_in_freq]; + ro_p->mapped_ssb_idx[0] = ssb_idx; ro_p->nb_mapped_ssb = 1; ssb_list.tx_ssb[ssb_idx].mapped_ro[ssb_list.tx_ssb[ssb_idx].nb_mapped_ro] = ro_p; @@ -1840,6 +1918,7 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac) { AssertFatal(MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN > ssb_list.tx_ssb[ssb_idx].nb_mapped_ro,"Too many mapped ROs (%d) to a single SSB\n", ssb_list.tx_ssb[ssb_idx].nb_mapped_ro); nb_mapped_ro_in_association_period++; + LOG_D(NR_MAC,"Mapped ssb_idx %u to RO slot-symbol %u-%u, %u-%u-%u/%u\n", ssb_idx, ro_p->slot, ro_p->start_symbol, slot, ro_in_time, ro_in_freq, prach_conf_period_p->prach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_freq); @@ -1858,40 +1937,49 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac) { // Exit the loop if this SSB has been mapped to all the required ROs if (nb_mapped_ro_in_association_period == ssb_rach_ratio) { break; - } else ro_in_freq = 0; // else go to the next time symbol in that slot and reset the freq index + } + else ro_in_freq = 0; // else go to the next time symbol in that slot and reset the freq index } // for ro_in_time // Exit the loop if this SSB has been mapped to all the required ROs if (nb_mapped_ro_in_association_period == ssb_rach_ratio) { break; - } else ro_in_time = 0; // else go to the next slot in that PRACH config period and reset the symbol index + } + else ro_in_time = 0; // else go to the next slot in that PRACH config period and reset the symbol index } // for slot // Exit the loop if this SSB has been mapped to all the required ROs if (nb_mapped_ro_in_association_period == ssb_rach_ratio) { break; - } else slot = 0; // else go to the next frame in that PRACH config period and reset the slot index + } + else slot = 0; // else go to the next frame in that PRACH config period and reset the slot index } // for frame // Exit the loop if this SSB has been mapped to all the required ROs if (nb_mapped_ro_in_association_period == ssb_rach_ratio) { break; - } else frame = 0; // else go to the next PRACH config period in that association period and reset the frame index + } + else frame = 0; // else go to the next PRACH config period in that association period and reset the frame index } // for n_prach_conf + } // if ssb_idx is transmitted } // for ssb_idx } // else if multiple_ssbs_per_ro + } // for association_period_index } // Returns a RACH occasion if any matches the SSB idx, the frame and the slot static int get_nr_prach_info_from_ssb_index(uint8_t ssb_idx, - int frame, - int slot, - prach_occasion_info_t **prach_occasion_info_pp) { + int frame, + int slot, + prach_occasion_info_t **prach_occasion_info_pp) { + ssb_info_t *ssb_info_p; prach_occasion_slot_t *prach_occasion_slot_p = NULL; + *prach_occasion_info_pp = NULL; + // Search for a matching RO slot in the SSB_to_RO map // A valid RO slot will match: // - ssb_idx mapped to one of the ROs in that RO slot @@ -1899,13 +1987,12 @@ static int get_nr_prach_info_from_ssb_index(uint8_t ssb_idx, // - frame offset ssb_info_p = &ssb_list.tx_ssb[ssb_idx]; LOG_D(NR_MAC,"checking for prach : ssb_info_p->nb_mapped_ro %d\n",ssb_info_p->nb_mapped_ro); - for (uint8_t n_mapped_ro=0; n_mapped_ro<ssb_info_p->nb_mapped_ro; n_mapped_ro++) { LOG_D(NR_MAC,"%d.%d: mapped_ro[%d]->frame.slot %d.%d, prach_assoc_pattern.nb_of_frame %d\n", frame,slot,n_mapped_ro,ssb_info_p->mapped_ro[n_mapped_ro]->frame,ssb_info_p->mapped_ro[n_mapped_ro]->slot,prach_assoc_pattern.nb_of_frame); - if ((slot == ssb_info_p->mapped_ro[n_mapped_ro]->slot) && (ssb_info_p->mapped_ro[n_mapped_ro]->frame == (frame % prach_assoc_pattern.nb_of_frame))) { + uint8_t prach_config_period_nb = ssb_info_p->mapped_ro[n_mapped_ro]->frame / prach_assoc_pattern.prach_conf_period_list[0].nb_of_frame; uint8_t frame_nb_in_prach_config_period = ssb_info_p->mapped_ro[n_mapped_ro]->frame % prach_assoc_pattern.prach_conf_period_list[0].nb_of_frame; prach_occasion_slot_p = &prach_assoc_pattern.prach_conf_period_list[prach_config_period_nb].prach_occasion_slot_map[frame_nb_in_prach_config_period][slot]; @@ -1913,8 +2000,10 @@ static int get_nr_prach_info_from_ssb_index(uint8_t ssb_idx, } // If there is a matching RO slot in the SSB_to_RO map - if (NULL != prach_occasion_slot_p) { + if (NULL != prach_occasion_slot_p) + { // A random RO mapped to the SSB index should be selected in the slot + // First count the number of times the SSB index is found in that RO uint8_t nb_mapped_ssb = 0; @@ -1932,10 +2021,11 @@ static int get_nr_prach_info_from_ssb_index(uint8_t ssb_idx, // Choose a random SSB nb uint8_t random_ssb_nb = 0; + random_ssb_nb = ((taus()) % nb_mapped_ssb); + // Select the RO according to the chosen random SSB nb nb_mapped_ssb=0; - for (int ro_in_time=0; ro_in_time < prach_occasion_slot_p->nb_of_prach_occasion_in_time; ro_in_time++) { for (int ro_in_freq=0; ro_in_freq < prach_occasion_slot_p->nb_of_prach_occasion_in_freq; ro_in_freq++) { prach_occasion_info_t *prach_occasion_info_p = &prach_occasion_slot_p->prach_occasion[ro_in_time][ro_in_freq]; @@ -1945,7 +2035,8 @@ static int get_nr_prach_info_from_ssb_index(uint8_t ssb_idx, if (nb_mapped_ssb == random_ssb_nb) { *prach_occasion_info_pp = prach_occasion_info_p; return 1; - } else { + } + else { nb_mapped_ssb++; } } @@ -1959,15 +2050,19 @@ static int get_nr_prach_info_from_ssb_index(uint8_t ssb_idx, // Build the SSB to RO mapping upon RRC configuration update void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac) { + // Clear all the lists and maps memset(&prach_assoc_pattern, 0, sizeof(prach_association_pattern_t)); memset(&ssb_list, 0, sizeof(ssb_list_info_t)); + // Build the list of all the valid RACH occasions in the maximum association pattern period according to the PRACH config LOG_D(NR_MAC,"Build RO list\n"); build_ro_list(mac); + // Build the list of all the valid/transmitted SSBs according to the config LOG_D(NR_MAC,"Build SSB list\n"); build_ssb_list(mac); + // Map the transmitted SSBs to the ROs and create the association pattern according to the config LOG_D(NR_MAC,"Map SSB to RO\n"); map_ssb_to_ro(mac); @@ -1976,11 +2071,13 @@ void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac) { void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, int thread_id) { + NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); int O_SR = 0; int O_ACK = 0; int O_CSI = 0; int N_UCI = 0; + PUCCH_sched_t *pucch = calloc(1,sizeof(*pucch)); pucch->resource_indicator = -1; pucch->initial_pucch_id = -1; @@ -2001,6 +2098,7 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, in // ACKNACK O_ACK = get_downlink_ack(mac, frameP, slotP, pucch); + NR_BWP_Id_t bwp_id = mac->UL_BWP_Id; NR_PUCCH_Config_t *pucch_Config = NULL; @@ -2010,16 +2108,18 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, in mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config && mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup) { pucch_Config = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup; - } else if (bwp_id==0 && - mac->cg && - mac->cg->spCellConfig && - mac->cg->spCellConfig->spCellConfigDedicated && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) { - pucch_Config = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup; } + else if (bwp_id==0 && + mac->cg && + mac->cg->spCellConfig && + mac->cg->spCellConfig->spCellConfigDedicated && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) { + pucch_Config = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup; + } + // if multiplexing of HARQ and CSI is not possible, transmit only HARQ bits if ((O_ACK != 0) && (O_CSI != 0) && @@ -2038,6 +2138,7 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, in return; if (N_UCI > 0) { + pucch->resource_set_id = find_pucch_resource_set(mac, N_UCI); select_pucch_resource(mac, pucch); fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP); @@ -2051,10 +2152,10 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, in fill_ul_config(ul_config, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PUCCH); nr_scheduled_response_t scheduled_response; fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id); - if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) mac->if_module->scheduled_response(&scheduled_response); } + } // This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211, tables 6.3.3.2.x @@ -2062,59 +2163,73 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, in // - todo: // - Partial configuration is actually already stored in (fapi_nr_prach_config_t) &mac->phy_config.config_req->prach_config void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, int thread_id) { + uint16_t format, format0, format1, ncs; int is_nr_prach_slot; prach_occasion_info_t *prach_occasion_info_p; + NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); RA_config_t *ra = &mac->ra; + //fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP); fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request[0]; fapi_nr_ul_config_prach_pdu *prach_config_pdu; fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; fapi_nr_prach_config_t *prach_config = &cfg->prach_config; nr_scheduled_response_t scheduled_response; + NR_ServingCellConfigCommon_t *scc = mac->scc; NR_ServingCellConfigCommonSIB_t *scc_SIB = mac->scc_SIB; NR_RACH_ConfigCommon_t *setup; - if (scc!=NULL) setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; else setup = scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup; - NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric; + ra->RA_offset = 2; // to compensate the rx frame offset at the gNB ra->generate_nr_prach = GENERATE_IDLE; // Reset flag for PRACH generation NR_TDD_UL_DL_ConfigCommon_t *tdd_config = scc==NULL ? scc_SIB->tdd_UL_DL_ConfigurationCommon : scc->tdd_UL_DL_ConfigurationCommon; if (is_nr_UL_slot(tdd_config, slotP, mac->frame_type)) { + // WIP Need to get the proper selected ssb_idx // Initial beam selection functionality is not available yet uint8_t selected_gnb_ssb_idx = mac->mib_ssb; + // Get any valid PRACH occasion in the current slot for the selected SSB index is_nr_prach_slot = get_nr_prach_info_from_ssb_index(selected_gnb_ssb_idx, - (int)frameP, - (int)slotP, - &prach_occasion_info_p); + (int)frameP, + (int)slotP, + &prach_occasion_info_p); if (is_nr_prach_slot && ra->ra_state == RA_UE_IDLE) { AssertFatal(NULL != prach_occasion_info_p,"PRACH Occasion Info not returned in a valid NR Prach Slot\n"); + ra->generate_nr_prach = GENERATE_PREAMBLE; + format = prach_occasion_info_p->format; format0 = format & 0xff; // single PRACH format format1 = (format >> 8) & 0xff; // dual PRACH format + prach_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu; memset(prach_config_pdu, 0, sizeof(fapi_nr_ul_config_prach_pdu)); + fill_ul_config(ul_config, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PRACH); + LOG_D(PHY, "In %s: (%p) %d UL PDUs:\n", __FUNCTION__, ul_config, ul_config->number_pdus); + ncs = get_NCS(rach_ConfigGeneric->zeroCorrelationZoneConfig, format0, setup->restrictedSetConfig); + prach_config_pdu->phys_cell_id = mac->physCellId; prach_config_pdu->num_prach_ocas = 1; prach_config_pdu->prach_slot = prach_occasion_info_p->slot; prach_config_pdu->prach_start_symbol = prach_occasion_info_p->start_symbol; prach_config_pdu->num_ra = prach_occasion_info_p->fdm; + prach_config_pdu->num_cs = ncs; prach_config_pdu->root_seq_id = prach_config->num_prach_fd_occasions_list[prach_occasion_info_p->fdm].prach_root_sequence_index; prach_config_pdu->restricted_set = prach_config->restricted_set_config; prach_config_pdu->freq_msg1 = prach_config->num_prach_fd_occasions_list[prach_occasion_info_p->fdm].k1; + LOG_D(NR_MAC,"Selected RO Frame %u, Slot %u, Symbol %u, Fdm %u\n", frameP, prach_config_pdu->prach_slot, prach_config_pdu->prach_start_symbol, prach_config_pdu->num_ra); // Search which SSB is mapped in the RO (among all the SSBs mapped to this RO) @@ -2122,7 +2237,6 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s if (prach_occasion_info_p->mapped_ssb_idx[prach_config_pdu->ssb_nb_in_ro] == selected_gnb_ssb_idx) break; } - AssertFatal(prach_config_pdu->ssb_nb_in_ro<prach_occasion_info_p->nb_mapped_ssb, "%u not found in the mapped SSBs to the PRACH occasion", selected_gnb_ssb_idx); if (format1 != 0xff) { @@ -2130,71 +2244,55 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s case 0xa1: prach_config_pdu->prach_format = 11; break; - case 0xa2: prach_config_pdu->prach_format = 12; break; - case 0xa3: prach_config_pdu->prach_format = 13; break; - - default: - AssertFatal(1 == 0, "Only formats A1/B1 A2/B2 A3/B3 are valid for dual format"); + default: + AssertFatal(1 == 0, "Only formats A1/B1 A2/B2 A3/B3 are valid for dual format"); } } else { switch(format0) { // single PRACH format case 0: prach_config_pdu->prach_format = 0; break; - case 1: prach_config_pdu->prach_format = 1; break; - case 2: prach_config_pdu->prach_format = 2; break; - case 3: prach_config_pdu->prach_format = 3; break; - case 0xa1: prach_config_pdu->prach_format = 4; break; - case 0xa2: prach_config_pdu->prach_format = 5; break; - case 0xa3: prach_config_pdu->prach_format = 6; break; - case 0xb1: prach_config_pdu->prach_format = 7; break; - case 0xb4: prach_config_pdu->prach_format = 8; break; - case 0xc0: prach_config_pdu->prach_format = 9; break; - case 0xc2: prach_config_pdu->prach_format = 10; break; - default: AssertFatal(1 == 0, "Invalid PRACH format"); } } // if format1 - fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id); - if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) mac->if_module->scheduled_response(&scheduled_response); } // is_nr_prach_slot @@ -2210,13 +2308,16 @@ void nr_ue_sib1_scheduler(module_id_t module_idP, uint32_t ssb_index, uint16_t ssb_start_subcarrier, frequency_range_t frequency_range) { + NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); nr_scheduled_response_t scheduled_response; int frame_s,slot_s,ret; fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request; fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15; + uint8_t scs_ssb = get_softmodem_params()->numerology; uint16_t ssb_offset_point_a = (ssb_start_subcarrier - ssb_subcarrier_offset)/12; + get_type0_PDCCH_CSS_config_parameters(&mac->type0_PDCCH_CSS_config, frame, mac->mib, @@ -2230,13 +2331,12 @@ void nr_ue_sib1_scheduler(module_id_t module_idP, ssb_offset_point_a); if(mac->search_space_zero == NULL) mac->search_space_zero=calloc(1,sizeof(*mac->search_space_zero)); - if(mac->coreset0 == NULL) mac->coreset0 = calloc(1,sizeof(*mac->coreset0)); for (int i=0; i<3; i++) { // loop over possible aggregation levels + fill_coresetZero(mac->coreset0, &mac->type0_PDCCH_CSS_config); ret = fill_searchSpaceZero(mac->search_space_zero, &mac->type0_PDCCH_CSS_config,4<<i); - if (ret) { rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15; rel15->num_dci_options = 1; @@ -2244,28 +2344,27 @@ void nr_ue_sib1_scheduler(module_id_t module_idP, config_dci_pdu(mac, rel15, dl_config, NR_RNTI_SI, -1); fill_dci_search_candidates(mac->search_space_zero, rel15); - if(mac->type0_PDCCH_CSS_config.type0_pdcch_ss_mux_pattern == 1) { + if(mac->type0_PDCCH_CSS_config.type0_pdcch_ss_mux_pattern == 1){ // same frame as ssb if ((mac->type0_PDCCH_CSS_config.frame & 0x1) == mac->type0_PDCCH_CSS_config.sfn_c) frame_s = 0; else frame_s = 1; - slot_s = mac->type0_PDCCH_CSS_config.n_0; - } else { + } + else{ frame_s = 0; // same frame as ssb slot_s = mac->type0_PDCCH_CSS_config.n_c; } - LOG_D(MAC,"Calling fill_scheduled_response, type0_pdcch, num_pdus %d\n",dl_config->number_pdus); fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, module_idP, cc_id, frame_s, slot_s, 0); // TODO fix thread_id, for now assumed 0 } } - if (dl_config->number_pdus) { if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) mac->if_module->scheduled_response(&scheduled_response); - } else + } + else AssertFatal(1==0,"Unable to find aggregation level for type0 CSS\n"); } @@ -2289,6 +2388,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, uint8_t gNB_index, uint8_t *ulsch_buffer, uint16_t buflen) { + int16_t buflen_remain = 0; uint8_t bsr_len = 0, bsr_ce_len = 0, bsr_header_len = 0; //uint8_t phr_header_len = 0, phr_ce_len = 0, phr_len = 0; @@ -2313,8 +2413,10 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, //int highest_priority = 16; int num_lcg_id_with_data = 0; const uint8_t sh_size = sizeof(NR_MAC_SUBHEADER_LONG); + // Pointer used to build the MAC PDU by placing the RLC SDUs in the ULSCH buffer uint8_t *pdu = ulsch_buffer; + // Preparing the MAC CEs sub-PDUs and get the total size bsr_header_len = 0; //phr_header_len = 1; //sizeof(SCH_SUBHEADER_FIXED); @@ -2372,13 +2474,16 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, bsr_len = bsr_ce_len + bsr_header_len; int tot_mac_ce_len = bsr_len + phr_len; uint8_t total_mac_pdu_header_len = tot_mac_ce_len; + LOG_D(NR_MAC, "In %s: [UE %d] [%d.%d] process UL transport block at with size TBS = %d bytes \n", __FUNCTION__, module_idP, frameP, subframe, buflen); // Check for DCCH first // TO DO: Multiplex in the order defined by the logical channel prioritization for (lcid = UL_SCH_LCID_SRB1; lcid < MAX_LCID; lcid++) { + buflen_remain = buflen - (total_mac_pdu_header_len + sdu_length_total + sh_size); + LOG_D(NR_MAC, "In %s: [UE %d] [%d.%d] UL-DXCH -> ULSCH, RLC with LCID 0x%02x (TBS %d bytes, sdu_length_total %d bytes, MAC header len %d bytes, buflen_remain %d bytes)\n", __FUNCTION__, module_idP, @@ -2390,10 +2495,13 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, tot_mac_ce_len, buflen_remain); - while (buflen_remain > 0) { + while (buflen_remain > 0){ + // Pointer used to build the MAC sub-PDU headers in the ULSCH buffer for each SDU NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) pdu; + pdu += sh_size; + sdu_length = mac_rlc_data_req(module_idP, mac->crnti, gNB_index, @@ -2405,6 +2513,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, (char *)pdu, 0, 0); + AssertFatal(buflen_remain >= sdu_length, "In %s: LCID = 0x%02x RLC has segmented %d bytes but MAC has max %d remaining bytes\n", __FUNCTION__, lcid, @@ -2412,26 +2521,32 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, buflen_remain); if (sdu_length > 0) { + LOG_D(NR_MAC, "In %s: Generating UL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID 0x%02x (buflen (TBS) %d bytes)\n", __FUNCTION__, - num_sdus + 1, - sdu_length, - lcid, - buflen); + num_sdus + 1, + sdu_length, + lcid, + buflen); + header->R = 0; header->F = 1; header->LCID = lcid; header->L1 = ((unsigned short) sdu_length >> 8) & 0x7f; header->L2 = (unsigned short) sdu_length & 0xff; -#ifdef ENABLE_MAC_PAYLOAD_DEBUG + + #ifdef ENABLE_MAC_PAYLOAD_DEBUG LOG_I(NR_MAC, "In %s: dumping MAC sub-header with length %d: \n", __FUNCTION__, sh_size); log_dump(NR_MAC, header, sh_size, LOG_DUMP_CHAR, "\n"); LOG_I(NR_MAC, "In %s: dumping MAC SDU with length %d \n", __FUNCTION__, sdu_length); log_dump(NR_MAC, pdu, sdu_length, LOG_DUMP_CHAR, "\n"); -#endif + #endif + pdu += sdu_length; sdu_length_total += sdu_length; total_mac_pdu_header_len += sh_size; + num_sdus++; + } else { pdu -= sh_size; LOG_D(NR_MAC, "In %s: no data to transmit for RB with LCID 0x%02x\n", __FUNCTION__, lcid); @@ -2439,6 +2554,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, } buflen_remain = buflen - (total_mac_pdu_header_len + sdu_length_total + sh_size); + //Update Buffer remain and BSR bytes after transmission mac->scheduling_info.LCID_buffer_remain[lcid] -= sdu_length; mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]] -= sdu_length; @@ -2446,7 +2562,6 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, "[UE %d] Update BSR [%d.%d] num_lcg_id_with_data %d. BSR_bytes for LCG%d=%d\n", module_idP, frameP, subframe, num_lcg_id_with_data, mac->scheduling_info.LCGID[lcid], mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]]); - if (mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]] < 0) mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]] = 0; @@ -2466,18 +2581,17 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, lcg_id_bsr_trunc = 0; for (lcg_id = 0; lcg_id < NR_MAX_NUM_LCGID; lcg_id++) { - if (bsr_ce_len == sizeof(NR_BSR_SHORT)) { + if (bsr_ce_len == sizeof(NR_BSR_SHORT)) { mac->scheduling_info.BSR[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_SHORT_BSR_TABLE, NR_SHORT_BSR_TABLE_SIZE, - mac->scheduling_info. - BSR_bytes[lcg_id]); - } else { + mac->scheduling_info. + BSR_bytes[lcg_id]); + } else { mac->scheduling_info.BSR[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_LONG_BSR_TABLE, NR_LONG_BSR_TABLE_SIZE, - mac->scheduling_info. - BSR_bytes[lcg_id]); - } - + mac->scheduling_info. + BSR_bytes[lcg_id]); + } if (mac->scheduling_info.BSR_bytes[lcg_id]) { num_lcg_id_with_data++; lcg_id_bsr_trunc = lcg_id; @@ -2514,8 +2628,8 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, // REPORT SHORT TRUNCATED BSR //Get LCGID of highest priority LCID with data for (lcid = DCCH; lcid < NR_MAX_NUM_LCID; lcid++) { - // if (mac-> - // logicalChannelConfig[lcid] != NULL) { +// if (mac-> +// logicalChannelConfig[lcid] != NULL) { if (1) { // todo lcg_id = mac->scheduling_info. @@ -2525,14 +2639,14 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, && (mac-> scheduling_info.BSR_bytes[lcg_id]) && - // (mac->logicalChannelConfig - // [lcid]->ul_SpecificParameters->priority <= - // highest_priority)) { +// (mac->logicalChannelConfig +// [lcid]->ul_SpecificParameters->priority <= +// highest_priority)) { (1)) { //todo - // highest_priority = - // mac-> - // logicalChannelConfig[lcid]-> - // ul_SpecificParameters->priority; +// highest_priority = +// mac-> +// logicalChannelConfig[lcid]-> +// ul_SpecificParameters->priority; lcg_id_bsr_trunc = lcg_id; } } @@ -2622,26 +2736,32 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, } if (tot_mac_ce_len > 0) { + LOG_D(NR_MAC, "In %s copying %d bytes of MAC CEs to the UL PDU \n", __FUNCTION__, tot_mac_ce_len); nr_write_ce_ulsch_pdu(pdu, mac, 0, NULL, bsr_t, bsr_s, bsr_l); pdu += (unsigned char) tot_mac_ce_len; -#ifdef ENABLE_MAC_PAYLOAD_DEBUG + + #ifdef ENABLE_MAC_PAYLOAD_DEBUG LOG_I(NR_MAC, "In %s: dumping MAC CE with length tot_mac_ce_len %d: \n", __FUNCTION__, tot_mac_ce_len); log_dump(NR_MAC, mac_header_control_elements, tot_mac_ce_len, LOG_DUMP_CHAR, "\n"); -#endif + #endif + } buflen_remain = buflen - (total_mac_pdu_header_len + sdu_length_total); // Compute final offset for padding and fill remainder of ULSCH with 0 if (buflen_remain > 0) { - LOG_D(NR_MAC, "In %s filling remainder %d bytes to the UL PDU \n", __FUNCTION__, buflen_remain); + + LOG_D(NR_MAC, "In %s filling remainder %d bytes to the UL PDU \n", __FUNCTION__, buflen_remain); ((NR_MAC_SUBHEADER_FIXED *) pdu)->R = 0; ((NR_MAC_SUBHEADER_FIXED *) pdu)->LCID = UL_SCH_LCID_PADDING; -#ifdef ENABLE_MAC_PAYLOAD_DEBUG + + #ifdef ENABLE_MAC_PAYLOAD_DEBUG LOG_I(NR_MAC, "In %s: padding MAC sub-header with length %ld bytes \n", __FUNCTION__, sizeof(NR_MAC_SUBHEADER_FIXED)); log_dump(NR_MAC, pdu, sizeof(NR_MAC_SUBHEADER_FIXED), LOG_DUMP_CHAR, "\n"); -#endif + #endif + pdu++; buflen_remain--; @@ -2653,16 +2773,18 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, memset(pdu, 0, buflen_remain); } -#ifdef ENABLE_MAC_PAYLOAD_DEBUG + #ifdef ENABLE_MAC_PAYLOAD_DEBUG LOG_I(NR_MAC, "In %s: MAC padding sub-PDU with length %d bytes \n", __FUNCTION__, buflen_remain); log_dump(NR_MAC, pdu, buflen_remain, LOG_DUMP_CHAR, "\n"); -#endif + #endif + } -#ifdef ENABLE_MAC_PAYLOAD_DEBUG + #ifdef ENABLE_MAC_PAYLOAD_DEBUG LOG_I(NR_MAC, "In %s: dumping MAC PDU with length %d: \n", __FUNCTION__, buflen); log_dump(NR_MAC, ulsch_buffer, buflen, LOG_DUMP_CHAR, "\n"); -#endif + #endif + LOG_D(NR_MAC, "[UE %d][SR] Gave SDU to PHY, clearing any scheduling request\n", module_idP); @@ -2677,7 +2799,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, // Reset ReTx BSR Timer mac->scheduling_info.retxBSR_SF = nr_get_sf_retxBSRTimer(mac-> - scheduling_info.retxBSR_Timer); + scheduling_info.retxBSR_Timer); LOG_D(NR_MAC, "[UE %d] MAC ReTx BSR Timer Reset =%d\n", module_idP, mac->scheduling_info.retxBSR_SF); @@ -2687,7 +2809,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, periodicBSR_Timer != NR_BSR_Config__periodicBSR_Timer_infinity)) { mac->scheduling_info.periodicBSR_SF = nr_get_sf_periodicBSRTimer(mac->scheduling_info. - periodicBSR_Timer); + periodicBSR_Timer); LOG_D(NR_MAC, "[UE %d] MAC Periodic BSR Timer Reset =%d\n", module_idP, mac->scheduling_info.periodicBSR_SF); @@ -2698,4 +2820,5 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, } return num_sdus > 0 ? 1 : 0; + } -- 2.26.2