diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index aba27b4dae6f65ab9fff4675e318345b8f1d2078..6f7c0126704ca2328376204ca09faf5bbe84acde 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -1321,7 +1321,7 @@ void ulsch_common_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_ #endif -UE_MODE_t get_nrUE_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t gNB_id){ // TBR generate enum for NR +UE_MODE_t get_nrUE_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t gNB_id){ return(PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[gNB_id]); } @@ -3152,19 +3152,47 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB } } +// WIP TBR fix: +// - time domain indication hardcoded to 0 for k2 offset +// - extend TS 38.213 ch 8.3 Msg3 PUSCH +// - b buffer +// - ulsch power offset +// - UE_mode == PUSCH case (should be handled by TA updates) +// - harq +// - optimize: mu_pusch, j and table_6_1_2_1_1_2_time_dom_res_alloc_A are already defined in nr_ue_procedures void nr_process_rar(nr_downlink_indication_t *dl_info) { module_id_t module_id = dl_info->module_id; - int cc_id = dl_info->cc_id, frame_rx = dl_info->proc->frame_rx, nr_tti_rx = dl_info->proc->nr_tti_rx, ta_command, harq_pid = 0; + int cc_id = dl_info->cc_id, frame_rx = dl_info->proc->frame_rx, nr_tti_rx = dl_info->proc->nr_tti_rx, ta_command, k2, delta; uint8_t gNB_index = dl_info->gNB_index, *rar; fapi_nr_dci_indication_t *dci_ind = dl_info->dci_ind; PHY_VARS_NR_UE *ue = PHY_vars_UE_g[module_id][cc_id]; NR_UE_DLSCH_t *dlsch0 = ue->dlsch_ra[gNB_index]; UE_MODE_t UE_mode = ue->UE_mode[gNB_index]; NR_PRACH_RESOURCES_t *prach_resources = ue->prach_resources[gNB_index]; + uint16_t slots_per_frame = ue->frame_parms.slots_per_frame; - uint8_t next1_thread_id = ue->current_thread_id[nr_tti_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[nr_tti_rx]+1); // TBR double check - uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1); // TBR double check + 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 + {j, 0,14}, // row index 1 + {j, 0,12}, // row index 2 + {j, 0,10}, // row index 3 + {j, 2,10}, // row index 4 + {j, 4,10}, // row index 5 + {j, 4,8}, // row index 6 + {j, 4,6}, // row index 7 + {j+1,0,14}, // row index 8 + {j+1,0,12}, // row index 9 + {j+1,0,10}, // row index 10 + {j+2,0,14}, // row index 11 + {j+2,0,12}, // row index 12 + {j+2,0,10}, // row index 13 + {j, 8,6}, // row index 14 + {j+3,0,14}, // row index 15 + {j+3,0,10} // row index 16 + }; LOG_D(PHY,"[UE %d][RAPROC] Frame %d subframe %d Received RAR mode %d\n", module_id, frame_rx, nr_tti_rx, UE_mode); @@ -3173,66 +3201,75 @@ void nr_process_rar(nr_downlink_indication_t *dl_info) { LOG_D(PHY,"[UE %d][RAPROC] Frame %d subframe %d Invoking MAC for RAR (current preamble %d)\n", module_id, frame_rx, nr_tti_rx, prach_resources->ra_PreambleIndex); - // TBR double check - // fix crnti - // ta_command = nr_ue_process_rar(ue->Mod_id, - // cc_id, - // frame_rx, - // prach_resources->ra_RNTI, - // dlsch0->harq_processes[0]->b, - // &ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][gNB_index]->crnti, - // prach_resources->ra_PreambleIndex, - // dlsch0->harq_processes[0]->b); // alter the 'b' buffer so it contains only the selected RAR header and RAR payload - - // ue->pdcch_vars[next1_thread_id][gNB_index]->crnti = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][gNB_index]->crnti; - // ue->pdcch_vars[next2_thread_id][gNB_index]->crnti = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][gNB_index]->crnti; - - // TBR double check + ta_command = nr_ue_process_rar(ue->Mod_id, + cc_id, + frame_rx, + dlsch0->harq_processes[0]->b, + &ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][gNB_index]->pdcch_config[0].rnti, + prach_resources->ra_PreambleIndex, + dlsch0->harq_processes[0]->b); // alter the 'b' buffer so it contains only the selected RAR header and RAR payload + if (ta_command != 0xffff) { - // LOG_D(PHY,"[UE %d][RAPROC] Frame %d subframe %d Got rnti %x and timing advance %d from RAR\n", - // ue->Mod_id, - // frame_rx, - // nr_tti_rx, - // ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][gNB_index]->crnti, - // ta_command); - - // fix TBR : C-RNTI is still a TC-RNTI - // ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][gNB_index]->crnti_is_temporary = 1; + LOG_D(PHY,"[UE %d][RAPROC] Frame %d subframe %d Got Temporary C-RNTI %x and timing advance %d from RAR\n", + ue->Mod_id, + frame_rx, + nr_tti_rx, + ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][gNB_index]->pdcch_config[0].rnti, + ta_command); + nr_process_timing_advance_rar(ue, dl_info->proc, ta_command); if (UE_mode != debug_prach) { ue->ulsch_Msg3_active[gNB_index] = 1; - // nr_get_Msg3_alloc(&ue->frame_parms, - // nr_tti_rx, - // frame_rx, - // &ue->ulsch_Msg3_frame[gNB_index], - // &ue->ulsch_Msg3_subframe[gNB_index]); // TBR + // TS 38.213 ch 8.3 Msg3 PUSCH + // PUSCH time domain resource allocation A for normal CP + // TS 38.214 ch 6.1.2.1.1 + k2 = table_6_1_2_1_1_2_time_dom_res_alloc_A[0][0]; + switch (mu_pusch) { + case 0: + delta = 2; + break; + case 1: + delta = 3; + break; + case 2: + delta = 4; + break; + case 3: + delta = 6; + break; + } + + ue->ulsch_Msg3_subframe[gNB_index] = (nr_tti_rx + k2 + delta) % slots_per_frame; + if (nr_tti_rx + k2 + delta > slots_per_frame){ + ue->ulsch_Msg3_frame[gNB_index] = (frame_rx + 1) % 1024; + } else { + ue->ulsch_Msg3_frame[gNB_index] = frame_rx; + } + LOG_D(PHY,"[UE %d][RAPROC] Got Msg3_alloc Frame %d subframe %d: Msg3_frame %d, Msg3_subframe %d\n", ue->Mod_id, frame_rx, nr_tti_rx, ue->ulsch_Msg3_frame[gNB_index], ue->ulsch_Msg3_subframe[gNB_index]); - // todo TBR // harq_pid = subframe2harq_pid(&ue->frame_parms, // ue->ulsch_Msg3_frame[gNB_index], // ue->ulsch_Msg3_subframe[gNB_index]); // ue->ulsch[gNB_index]->harq_processes[harq_pid]->round = 0; - // ue->UE_mode[gNB_index] = RA_RESPONSE; // ue->Msg3_timer[gNB_index] = 10; // ue->ulsch[gNB_index].power_offset = 6; // ue->ulsch_no_allocation_counter[gNB_index] = 0; + ue->UE_mode[gNB_index] = RA_RESPONSE; } - } else { // PRACH preamble doesn't match RAR - LOG_W(PHY,"[UE %d][RAPROC] Received RAR preamble (%d) doesn't match !!!\n", - ue->Mod_id, - prach_resources->ra_PreambleIndex); + } else { + LOG_W(PHY,"[UE %d][RAPROC] Received RAR preamble (%d) doesn't match !!!\n", ue->Mod_id, prach_resources->ra_PreambleIndex); } - } // mode != PUSCH + } } else { - rar = dlsch0->harq_processes[0]->b+1; - ta_command = ((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4)); - nr_process_timing_advance_rar(ue, dl_info->proc, ta_command); + // rar = dlsch0->harq_processes[0]->b+1; + // ta_command = ((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4)); + // nr_process_timing_advance_rar(ue, dl_info->proc, ta_command); } } @@ -4468,7 +4505,6 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t uint16_t preamble_tx = 50, pathloss; NR_PRACH_RESOURCES_t prach_resources; uint8_t mod_id = ue->Mod_id; - NR_UE_MAC_INST_t *nr_UE_mac_inst = get_mac_inst(mod_id); UE_MODE_t UE_mode = get_nrUE_mode(mod_id, ue->CC_id, gNB_id); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN); diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index 2cb1dac75dfa3971d231f22b7e727e01349add26..82418f360ec251254c2ff773d19c5a72f8a1b0b9 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -147,14 +147,21 @@ typedef struct { // uint8_t payload[RAR_PAYLOAD_SIZE_MAX]; // } __attribute__ ((__packed__)) RAR_PDU; -/*!\brief MAC header of Random Access Response for Random access preamble identifier (RAPID) */ +//* RAR MAC subheader // TS 38.321 ch. 6.1.5, 6.2.2 *// +// - E: The Extension field is a flag indicating if the MAC subPDU including this MAC subheader is the last MAC subPDU or not in the MAC PDU +// - T: The Type field is a flag indicating whether the MAC subheader contains a Random Access Preamble ID or a Backoff Indicator (0, BI) (1, RAPID) +// - R: Reserved bit, set to "0" +// - BI: The Backoff Indicator field identifies the overload condition in the cell. +// - RAPID: The Random Access Preamble IDentifier field identifies the transmitted Random Access Preamble + +/*!\brief RAR MAC subheader with RAPID */ typedef struct { uint8_t RAPID:6; uint8_t T:1; uint8_t E:1; } __attribute__ ((__packed__)) NR_RA_HEADER_RAPID; -/*!\brief MAC header of Random Access Response for backoff indicator (BI)*/ +/*!\brief RAR MAC subheader with Backoff Indicator */ typedef struct { uint8_t BI:4; uint8_t R:2; @@ -162,6 +169,19 @@ typedef struct { uint8_t E:1; } __attribute__ ((__packed__)) NR_RA_HEADER_BI; +// TS 38.321 ch. 6.2.3 +typedef struct { + uint8_t R:1; // octet 1 [7] + uint8_t TA1:7; // octet 1 [7:0] + uint8_t TA2:5; // octet 2 [7:2] + uint8_t UL_GRANT_1:3; // octet 2 [2:0] + uint8_t UL_GRANT_2:8; // octet 3 [7:0] + uint8_t UL_GRANT_3:8; // octet 4 [7:0] + uint8_t UL_GRANT_4:8; // octet 5 [7:0] + uint8_t TCRNTI_1:8; // octet 6 [7:0] + uint8_t TCRNTI_2:8; // octet 7 [7:0] +} __attribute__ ((__packed__)) NR_MAC_RAR; + // 38.321 ch6.2.1, 38.331 #define DL_SCH_LCID_CCCH 0x00 #define DL_SCH_LCID_DCCH 0x01 diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index b3c5e078e7b43b177907d4103573fb613cfec9dc..5e223c5cd2a2f8c90f69fde046b322d0987643a4 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -145,6 +145,8 @@ typedef struct { /// Preamble Power Ramping Counter uint8_t RA_PREAMBLE_POWER_RAMPING_COUNTER; /// Random-access backoff counter + int16_t RA_backoff_indicator; + /// Random-access backoff counter int16_t RA_backoff_cnt; /// Random-access variable for window calculation (frame of last change in window counter) uint32_t RA_tx_frame; @@ -165,6 +167,8 @@ typedef struct { int8_t deltaPreamble_Msg3; /// Flag to monitor if matching RAPID was received in RAR uint8_t RA_RAPID_found; + /// Flag to monitor if BI was received in RAR + uint8_t RA_BI_found; /// UE_Mode variable should be used in the case of Phy_stub operation since we won't have access to PHY_VARS_UE /// where the UE_mode originally is for the full stack operation mode. The transitions between the states of the UE_Mode /// will be triggered within phy_stub_ue.c in this case diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index ab3b22794da3c7738d3149c99a9addb4eda26d14..f78b09f5af138c322ef4ab15bb228fc1ae16922f 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -206,13 +206,12 @@ random-access procedure @param selected_rar_buffer the output buffer for storing the selected RAR header and RAR payload @returns timing advance or 0xffff if preamble doesn't match */ -uint16_t nr_ue_process_rar(const module_id_t mod_id, - const int CC_id, - const frame_t frameP, - const rnti_t ra_rnti, - uint8_t * const dlsch_buffer, - rnti_t * const t_crnti, - const uint8_t preamble_index, +uint16_t nr_ue_process_rar(module_id_t mod_id, + int CC_id, + frame_t frameP, + uint8_t * dlsch_buffer, + rnti_t * t_crnti, + uint8_t preamble_index, uint8_t * selected_rar_buffer); void nr_process_rar(nr_downlink_indication_t *dl_info); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index b4708a6c8100c1c890fff1175d32a167159ecfab..4f50115927974c6ae48591f3d8a231e815fc59ed 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -31,7 +31,6 @@ */ #include "mac.h" -// TBR missing NR_nr_UE_mac_inst in mac.h /* #include "common/utils/LOG/vcd_signal_dumper.h" @@ -69,6 +68,7 @@ extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9]; //extern uint8_t nfapi_mode; +// WIP // This routine implements Section 5.1.2 (UE Random Access Resource Selection) // and Section 5.1.3 (Random Access Preamble Transmission) from 3GPP TS 38.321 void nr_get_prach_resources(module_id_t mod_id, @@ -78,15 +78,15 @@ void nr_get_prach_resources(module_id_t mod_id, uint8_t first_Msg3, NR_RACH_ConfigDedicated_t * rach_ConfigDedicated){ - NR_UE_MAC_INST_t *nr_UE_mac_inst = get_mac_inst(mod_id); - NR_PRACH_RESOURCES_t *prach_resources = &nr_UE_mac_inst->RA_prach_resources; - NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = nr_UE_mac_inst->nr_rach_ConfigCommon; - // NR_BeamFailureRecoveryConfig_t *beam_failure_recovery_config = &nr_UE_mac_inst->RA_BeamFailureRecoveryConfig; // todo + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + NR_PRACH_RESOURCES_t *prach_resources = &mac->RA_prach_resources; + NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->nr_rach_ConfigCommon; + // NR_BeamFailureRecoveryConfig_t *beam_failure_recovery_config = &mac->RA_BeamFailureRecoveryConfig; // todo int messagePowerOffsetGroupB, messageSizeGroupA, PLThreshold, sizeOfRA_PreamblesGroupA, numberOfRA_Preambles, frequencyStart, i, deltaPreamble_Msg3; uint8_t noGroupB = 0, s_id, f_id, ul_carrier_id, msg1_FDM, prach_ConfigIndex, SFN_nbr, Msg3_size; - // NR_RSRP_Range_t rsrp_ThresholdSSB; // TBR todo + // NR_RSRP_Range_t rsrp_ThresholdSSB; // todo /////////////////////////////////////////////////////////// //////////* UE Random Access Resource Selection *////////// @@ -103,7 +103,7 @@ void nr_get_prach_resources(module_id_t mod_id, // -- SSB selection, set prach_resources->ra_PreambleIndex // if (rach_ConfigDedicated) { // This is for network controlled Mobility - // // TBR operation for contention-free RA resources when: + // // operation for contention-free RA resources when: // // - available SSB with SS-RSRP above rsrp-ThresholdSSB: SSB selection // // - availalbe CSI-RS with CSI-RSRP above rsrp-ThresholdCSI-RS: CSI-RS selection // prach_resources->ra_PreambleIndex = rach_ConfigDedicated->ra_PreambleIndex; @@ -111,11 +111,13 @@ void nr_get_prach_resources(module_id_t mod_id, // } //////////* Contention-based RA preamble selection *////////// + // todo + // - selection of SSB with SS-RSRP above rsrp-ThresholdSSB else select any SSB + // - todo determine next available PRACH occasion - // todo: selection of SSB with SS-RSRP above rsrp-ThresholdSSB else select any SSB - // rsrp_ThresholdSSB = *nr_rach_ConfigCommon->rsrp_ThresholdSSB; // TBR + // rsrp_ThresholdSSB = *nr_rach_ConfigCommon->rsrp_ThresholdSSB; - Msg3_size = nr_UE_mac_inst->RA_Msg3_size; + Msg3_size = mac->RA_Msg3_size; numberOfRA_Preambles = nr_rach_ConfigCommon->totalNumberOfRA_Preambles; if (!nr_rach_ConfigCommon->groupBconfigured) { @@ -194,8 +196,8 @@ void nr_get_prach_resources(module_id_t mod_id, } // todo Msg3-DeltaPreamble should be provided from higher layers, otherwise is 0 - nr_UE_mac_inst->deltaPreamble_Msg3 = 0; - deltaPreamble_Msg3 = nr_UE_mac_inst->deltaPreamble_Msg3; + mac->deltaPreamble_Msg3 = 0; + deltaPreamble_Msg3 = mac->deltaPreamble_Msg3; } PLThreshold = prach_resources->RA_PCMAX - nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB; @@ -205,31 +207,27 @@ void nr_get_prach_resources(module_id_t mod_id, if (noGroupB == 1) { // use Group A preamble prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles; - nr_UE_mac_inst->RA_usedGroupA = 1; + mac->RA_usedGroupA = 1; } else if ((Msg3_size < messageSizeGroupA) && (get_PL(mod_id, 0, gNB_id) > PLThreshold)) { // Group B is configured and RA preamble Group A is used // - todo TBR update get_PL to NR get_nr_PL (needs PHY_VARS_NR_UE) // - todo add condition on CCCH_sdu_size for initiation by CCCH prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA; - nr_UE_mac_inst->RA_usedGroupA = 1; + mac->RA_usedGroupA = 1; } else { // Group B preamble is configured and used // the first sizeOfRA_PreamblesGroupA RA preambles belong to RA Preambles Group A // the remaining belong to RA Preambles Group B prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA); - nr_UE_mac_inst->RA_usedGroupA = 0; + mac->RA_usedGroupA = 0; } } else { // Msg3 is being retransmitted - if (nr_UE_mac_inst->RA_usedGroupA == 1) { - if (nr_rach_ConfigCommon->groupBconfigured){ - prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA; - } else { - prach_resources->ra_PreambleIndex = (taus()) & 0x3f; // TBR check this - } - } else { - prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA); - } + if (mac->RA_usedGroupA == 1) { + prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA; + } else { + prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA); } + } // todo determine next available PRACH occasion // - if RA initiated for SI request and ra_AssociationPeriodIndex and si-RequestPeriod are configured @@ -239,11 +237,12 @@ void nr_get_prach_resources(module_id_t mod_id, ///////////////////////////////////////////////////////////////////////////// //////////* Random Access Preamble Transmission (5.1.3 TS 38.321) *////////// ///////////////////////////////////////////////////////////////////////////// + // todo: + // - condition on notification of suspending power ramping counter from lower layer (5.1.3 TS 38.321) + // - check if SSB or CSI-RS have not changed since the selection in the last RA Preamble tranmission - // todo condition on notification of suspending power ramping counter from lower layer (5.1.3 TS 38.321) // TBR - // todo check if SSB or CSI-RS have not changed since the selection in the last RA Preamble tranmission - if (nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER > 1) - nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER++; + if (mac->RA_PREAMBLE_TRANSMISSION_COUNTER > 1) + mac->RA_PREAMBLE_TRANSMISSION_COUNTER++; prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(mod_id, CC_id); @@ -278,7 +277,7 @@ void nr_get_prach_resources(module_id_t mod_id, // - s_id is starting symbol of the PRACH occasion [0...14] // - t_id is the first slot of the PRACH occasion in a system frame [0...80] - ul_carrier_id = 0; // todo SUL + ul_carrier_id = 0; // NUL f_id = nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart; SFN_nbr = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][4]; s_id = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][5]; @@ -295,15 +294,13 @@ void nr_get_prach_resources(module_id_t mod_id, LOG_D(MAC, "Computed ra_RNTI is %d", prach_resources->ra_RNTI); } +// todo: RA_attempt_number not used TBR void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){ - - NR_UE_MAC_INST_t *nr_UE_mac_inst = get_mac_inst(mod_id); - AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); - + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + mac->ra_state == WAIT_RAR; // Start contention resolution timer - nr_UE_mac_inst->RA_attempt_number++; // todo this is not used - + mac->RA_attempt_number++; } void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){ @@ -313,8 +310,8 @@ void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint LOG_D(MAC,"[UE %d][RAPROC] Frame %d : Msg3_tx: Setting contention resolution timer\n", mod_id, frameP); // start contention resolution timer - nr_UE_mac_inst->RA_contention_resolution_cnt = 0; - nr_UE_mac_inst->RA_contention_resolution_timer_active = 1; + mac->RA_contention_resolution_cnt = 0; + mac->RA_contention_resolution_timer_active = 1; #endif } @@ -326,6 +323,7 @@ void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint /// Only one RA procedure is ongoing at any point in time in a MAC entity /// the RA procedure on a SCell shall only be initiated by PDCCH order +// WIP NR_PRACH_RESOURCES_t *nr_ue_get_rach(module_id_t mod_id, int CC_id, UE_MODE_t UE_mode, @@ -333,31 +331,31 @@ NR_PRACH_RESOURCES_t *nr_ue_get_rach(module_id_t mod_id, uint8_t gNB_id, int nr_tti_tx){ - NR_UE_MAC_INST_t *nr_UE_mac_inst = get_mac_inst(mod_id); - uint8_t lcid = CCCH, dcch_header_len = 0, mac_sdus[MAX_NR_ULSCH_PAYLOAD_BYTES], * payload; + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + uint8_t lcid = CCCH, dcch_header_len = 0, mac_sdus[MAX_NR_ULSCH_PAYLOAD_BYTES], * payload, ra_ResponseWindow; uint16_t size_sdu = 0; unsigned short post_padding; NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = (struct NR_RACH_ConfigCommon_t *) NULL; - NR_PRACH_RESOURCES_t *prach_resources = &nr_UE_mac_inst->RA_prach_resources; + NR_PRACH_RESOURCES_t *prach_resources = &mac->RA_prach_resources; int32_t frame_diff = 0; uint8_t sdu_lcids[NB_RB_MAX] = {0}; // TBR uint16_t sdu_lengths[NB_RB_MAX] = {0}; // TBR - int TBS_bytes = 848, header_length_total, num_sdus, offset; // TBR + int TBS_bytes = 848, header_length_total, num_sdus, offset, preambleTransMax; // TBR AssertFatal(CC_id == 0,"Transmission on secondary CCs is not supported yet\n"); if (UE_mode == PRACH) { - LOG_D(MAC, "nr_ue_get_rach, RA_active value: %d", nr_UE_mac_inst->RA_active); + LOG_D(MAC, "nr_ue_get_rach, RA_active value: %d", mac->RA_active); - AssertFatal(nr_UE_mac_inst->nr_rach_ConfigCommon != NULL, "[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id); + AssertFatal(mac->nr_rach_ConfigCommon != NULL, "[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id); - if (nr_UE_mac_inst->nr_rach_ConfigCommon) { // TBR check the condition - nr_rach_ConfigCommon = nr_UE_mac_inst->nr_rach_ConfigCommon; + if (mac->nr_rach_ConfigCommon) { // TBR check the condition + nr_rach_ConfigCommon = mac->nr_rach_ConfigCommon; } else return NULL; - if (nr_UE_mac_inst->RA_active == 0) { + if (mac->RA_active == 0) { /* RA not active - checking if RRC is ready to initiate the RA procedure */ LOG_I(MAC, "RA not active. Starting RA preamble initialization.\n"); @@ -371,7 +369,7 @@ NR_PRACH_RESOURCES_t *nr_ue_get_rach(module_id_t mod_id, } */ - nr_UE_mac_inst->RA_RAPID_found = 0; + mac->RA_RAPID_found = 0; /* Set RA_PREAMBLE_POWER_RAMPING_STEP */ switch (nr_rach_ConfigCommon->rach_ConfigGeneric.powerRampingStep){ // in dB @@ -401,7 +399,7 @@ NR_PRACH_RESOURCES_t *nr_ue_get_rach(module_id_t mod_id, if (!IS_SOFTMODEM_NOS1){ // todo mac_rrc_nr_data_req_ue - payload = &nr_UE_mac_inst->CCCH_pdu.payload; + payload = &mac->CCCH_pdu.payload; size_sdu = (uint16_t) mac_rrc_nr_data_req_ue(mod_id, CC_id, frame, @@ -414,7 +412,7 @@ NR_PRACH_RESOURCES_t *nr_ue_get_rach(module_id_t mod_id, } else { // fill ulsch_buffer with random data - payload = (uint8_t *)nr_UE_mac_inst->ulsch_pdu.payload[0]; + payload = (uint8_t *)mac->ulsch_pdu.payload[0]; for (int i = 0; i < TBS_bytes; i++){ mac_sdus[i] = (unsigned char) (lrand48()&0xff); } @@ -427,11 +425,10 @@ NR_PRACH_RESOURCES_t *nr_ue_get_rach(module_id_t mod_id, num_sdus +=1; } - // TBR which frame and slot ? - nr_UE_mac_inst->RA_tx_frame = frame; - nr_UE_mac_inst->RA_tx_subframe = nr_tti_tx; - nr_UE_mac_inst->RA_backoff_frame = frame; - nr_UE_mac_inst->RA_backoff_subframe = nr_tti_tx; + mac->RA_tx_frame = frame; + mac->RA_tx_subframe = nr_tti_tx; + mac->RA_backoff_frame = frame; + mac->RA_backoff_subframe = nr_tti_tx; if (size_sdu > 0) { // TBR size_sdu + MAC_Header_len + mac_ce_len /* TBR initialisation by RRC @@ -439,20 +436,42 @@ NR_PRACH_RESOURCES_t *nr_ue_get_rach(module_id_t mod_id, LOG_I(MAC, "[UE %d] Frame %d: Initialisation Random Access Procedure\n", mod_id, frame); - nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER = 1; - nr_UE_mac_inst->RA_PREAMBLE_POWER_RAMPING_COUNTER = 1; - nr_UE_mac_inst->RA_Msg3_size = size_sdu + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); // TBR size_sdu + MAC_Header_len + mac_ce_len - nr_UE_mac_inst->RA_prachMaskIndex = 0; + mac->RA_PREAMBLE_TRANSMISSION_COUNTER = 1; + mac->RA_PREAMBLE_POWER_RAMPING_COUNTER = 1; + mac->RA_Msg3_size = size_sdu + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); // TBR size_sdu + MAC_Header_len + mac_ce_len + mac->RA_prachMaskIndex = 0; // TBR todo: add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator) - nr_UE_mac_inst->RA_backoff_cnt = 0; - nr_UE_mac_inst->RA_active = 1; + mac->RA_backoff_cnt = 0; + mac->RA_active = 1; prach_resources->Msg3 = payload; - // TBR todo double check window count - // nr_UE_mac_inst->RA_window_cnt = 2 + nr_rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize; - // if (nr_UE_mac_inst->RA_window_cnt == 9) { - // nr_UE_mac_inst->RA_window_cnt = 10; // Note: 9 subframe window doesn't exist, after 8 is 10! - // } + ra_ResponseWindow = nr_rach_ConfigCommon->rach_ConfigGeneric.ra_ResponseWindow; + switch (ra_ResponseWindow) { + case 0: + mac->RA_window_cnt = 1; + break; + case 1: + mac->RA_window_cnt = 2; + break; + case 2: + mac->RA_window_cnt = 4; + break; + case 3: + mac->RA_window_cnt = 8; + break; + case 4: + mac->RA_window_cnt = 10; + break; + case 5: + mac->RA_window_cnt = 20; + break; + case 6: + mac->RA_window_cnt = 40; + break; + case 7: + mac->RA_window_cnt = 80; + break; + } // Fill in preamble and PRACH resources nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 1, NULL); @@ -487,50 +506,29 @@ NR_PRACH_RESOURCES_t *nr_ue_get_rach(module_id_t mod_id, // todo: // - handle beam failure recovery request // - handle DL assignment on PDCCH for RA-RNTI + // - handle backoff and raResponseWindow params LOG_D(MAC, "[MAC][UE %d][RAPROC] frame %d, subframe %d: RA Active, window cnt %d (RA_tx_frame %d, RA_tx_subframe %d)\n", - mod_id, frame, nr_tti_tx, nr_UE_mac_inst->RA_window_cnt, nr_UE_mac_inst->RA_tx_frame, nr_UE_mac_inst->RA_tx_subframe); + mod_id, frame, nr_tti_tx, mac->RA_window_cnt, mac->RA_tx_frame, mac->RA_tx_subframe); - if (nr_UE_mac_inst->rnti_type = NR_RNTI_RA){ // add condition on BI - // TBR todo + if (mac->RA_BI_found){ + prach_resources->RA_PREAMBLE_BACKOFF = prach_resources->RA_SCALING_FACTOR_BI * mac->RA_backoff_indicator; } else { prach_resources->RA_PREAMBLE_BACKOFF = 0; } - // compute backoff parameters - if (nr_UE_mac_inst->RA_backoff_cnt > 0){ - frame_diff = (sframe_t) frame - nr_UE_mac_inst->RA_backoff_frame; - if (frame_diff < 0) frame_diff = -frame_diff; - nr_UE_mac_inst->RA_backoff_cnt -= ((10 * frame_diff) + (nr_tti_tx - nr_UE_mac_inst->RA_backoff_subframe)); - nr_UE_mac_inst->RA_backoff_frame = frame; - nr_UE_mac_inst->RA_backoff_subframe = nr_tti_tx; - } - // - TBR check - - // - TBR check - // compute RA window parameters - if (nr_UE_mac_inst->RA_window_cnt > 0){ - frame_diff = (frame_t) frame - nr_UE_mac_inst->RA_tx_frame; - if (frame_diff < 0) frame_diff = -frame_diff; - nr_UE_mac_inst->RA_window_cnt -= ((10 * frame_diff) + (nr_tti_tx - nr_UE_mac_inst->RA_tx_subframe)); - LOG_D(MAC, "[MAC][UE %d][RAPROC] Frame %d, subframe %d: RA Active, adjusted window cnt %d\n", mod_id, frame, nr_tti_tx, nr_UE_mac_inst->RA_window_cnt); - } - // - TBR check - - //if ((nr_UE_mac_inst->RA_window_cnt <= 0) && (nr_UE_mac_inst->RA_backoff_cnt <= 0)){ - if ((nr_UE_mac_inst->RA_window_cnt <= 0) && (nr_UE_mac_inst->RA_RAPID_found == 0)){ // TODO TBR double check the condition - - LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: subframe %d: RAR reception not successful, (RA window count %d) \n", mod_id, frame, nr_tti_tx, nr_UE_mac_inst->RA_window_cnt); - - nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER++; - // - TBR check RA_tx_frame RA_tx_subframe - nr_UE_mac_inst->RA_tx_frame = frame; - nr_UE_mac_inst->RA_tx_subframe = nr_tti_tx; - prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER += (prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP << 1); // 2dB increments in ASN.1 definition - // - TBR check ra_PREAMBLE_RECEIVED_TARGET_POWER increment + if (mac->RA_window_cnt > 0 && mac->RA_RAPID_found == 1) { + mac->ra_state == WAIT_CONTENTION_RESOLUTION; + } else { + LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: subframe %d: RAR reception not successful, (RA window count %d) \n", + mod_id, + frame, + nr_tti_tx, + mac->RA_window_cnt); - int preambleTransMax = -1; + mac->RA_PREAMBLE_TRANSMISSION_COUNTER++; + preambleTransMax = -1; switch (nr_rach_ConfigCommon->rach_ConfigGeneric.preambleTransMax) { case NR_RACH_ConfigGeneric__preambleTransMax_n3: preambleTransMax = 3; @@ -567,30 +565,39 @@ NR_PRACH_RESOURCES_t *nr_ue_get_rach(module_id_t mod_id, break; } - if (nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER == preambleTransMax + 1){ - + if (mac->RA_PREAMBLE_TRANSMISSION_COUNTER == preambleTransMax + 1){ LOG_D(MAC, "[UE %d] Frame %d: Maximum number of RACH attempts (%d)\n", mod_id, frame, preambleTransMax); - - // TBR select random backoff according to a uniform distribution between 0 and PREAMBLE_BACKOFF - // (rand() % prach_resources->RA_PREAMBLE_BACKOFF - - // TODO TBR send message to RRC - nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER = 1; - prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(mod_id, CC_id); // TBR check if this is necessary + mac->RA_backoff_cnt = rand() % (prach_resources->RA_PREAMBLE_BACKOFF + 1); + mac->RA_PREAMBLE_TRANSMISSION_COUNTER = 1; + prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP << 1; // 2 dB increment + prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(mod_id, CC_id); } - // TBR ra_SupervisionInfo.ra_ResponseWindowSize is missing - // nr_UE_mac_inst->RA_window_cnt = 2 + nr_rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize; - nr_UE_mac_inst->RA_backoff_cnt = 0; + // compute backoff parameters + // if (mac->RA_backoff_cnt > 0){ + // frame_diff = (sframe_t) frame - mac->RA_backoff_frame; + // if (frame_diff < 0) frame_diff = -frame_diff; + // mac->RA_backoff_frame = frame; + // mac->RA_backoff_subframe = nr_tti_tx; + // } + // compute RA window parameters + // if (mac->RA_window_cnt > 0){ + // frame_diff = (frame_t) frame - mac->RA_tx_frame; + // if (frame_diff < 0) frame_diff = -frame_diff; + // mac->RA_window_cnt -= ((10 * frame_diff) + (nr_tti_tx - mac->RA_tx_subframe)); + // LOG_D(MAC, "[MAC][UE %d][RAPROC] Frame %d, subframe %d: RA Active, adjusted window cnt %d\n", mod_id, frame, nr_tti_tx, mac->RA_window_cnt); + // } + mac->RA_tx_frame = frame; + mac->RA_tx_subframe = nr_tti_tx; // Fill in preamble and PRACH resources nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 0, NULL); - return (&nr_UE_mac_inst->RA_prach_resources); + return (&mac->RA_prach_resources); } } } else if (UE_mode == PUSCH) { - LOG_D(MAC, "[UE %d] FATAL: Should not have checked for RACH in PUSCH yet ...", mod_id); - AssertFatal(1 == 0, ""); + LOG_D(MAC, "[UE %d] FATAL: Should not have checked for RACH in PUSCH yet ...", mod_id); + AssertFatal(1 == 0, ""); } return NULL; } \ No newline at end of file diff --git a/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c b/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c index 2f81e781630e02357120d7350d8257cae7426a8d..a9f304fe2beacb6c635742ba2330ee71dfec27e4 100644 --- a/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c +++ b/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c @@ -47,103 +47,91 @@ #define DEBUG_RAR -uint16_t nr_ue_process_rar(const module_id_t mod_id, - const int CC_id, - const frame_t frameP, - const rnti_t ra_rnti, - uint8_t * const dlsch_buffer, - rnti_t * const t_crnti, - const uint8_t preamble_index, +// table 7.2-1 TS 38.321 +uint8_t table_7_2_1[16] = { + {5}, // row index 0 + {10}, // row index 1 + {20}, // row index 2 + {30}, // row index 3 + {40}, // row index 4 + {60}, // row index 5 + {80}, // row index 6 + {120}, // row index 7 + {160}, // row index 8 + {240}, // row index 9 + {320}, // row index 10 + {480}, // row index 11 + {960}, // row index 12 + {1920}, // row index 13 +}; + +// WIP todo: +// - UL grant +uint16_t nr_ue_process_rar(module_id_t mod_id, + int CC_id, + frame_t frameP, + uint8_t * dlsch_buffer, + rnti_t * t_crnti, + uint8_t preamble_index, uint8_t * selected_rar_buffer){ - NR_UE_MAC_INST_t *nrUE_mac_inst = get_mac_inst(mod_id); - NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer; - uint16_t ret = 0; - // NR_RAR_PDU *rar = (RAR_PDU *)(dlsch_buffer+1); - uint8_t *rar = (uint8_t *) (dlsch_buffer + 1); - // get the last RAR payload for working with CMW500 - uint8_t n_rarpy = 0; // number of RAR payloads - uint8_t n_rarh = 0; // number of MAC RAR subheaders - uint8_t best_rx_rapid = -1; // the closest RAPID receive from all RARs + NR_UE_MAC_INST_t *ue_mac = get_mac_inst(mod_id); + 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 n_subPDUs = 0; // number of RAR payloads + uint8_t n_subheaders = 0; // number of MAC RAR subheaders + uint8_t best_rx_rapid = -1; // the closest RAPID receive from all RARs + uint16_t ta_command = 0; AssertFatal(CC_id == 0, "RAR reception on secondary CCs is not supported yet\n"); while (1) { - n_rarh++; + n_subheaders++; if (rarh->T == 1) { - n_rarpy++; - LOG_D(MAC, "RAPID %d\n", rarh->RAPID); + n_subPDUs++; + LOG_D(MAC, "[UE %d][RAPROC] Got RAPID RAR subPDU %d\n", mod_id, rarh->RAPID); + } else { + n_subPDUs++; + ue_mac->RA_backoff_indicator = table_7_2_1[((NR_RA_HEADER_BI *)rarh)->BI]; + ue_mac->RA_BI_found = 1; + LOG_D(MAC, "[UE %d][RAPROC] Got BI RAR subPDU %d\n", mod_id, ue_mac->RA_backoff_indicator); } - if (rarh->RAPID == preamble_index) { - LOG_D(PHY, "Found RAR with the intended RAPID %d\n", - rarh->RAPID); - rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6); - nrUE_mac_inst->RA_RAPID_found = 1; - break; - } - - if (abs((int) rarh->RAPID - (int) preamble_index) < - abs((int) best_rx_rapid - (int) preamble_index)) { - best_rx_rapid = rarh->RAPID; - rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6); + LOG_D(PHY, "[UE %d][RAPROC] Found RAR with the intended RAPID %d\n", rarh->RAPID); + rar = (NR_MAC_RAR *) (dlsch_buffer + n_subheaders + (n_subPDUs - 1) * sizeof(NR_MAC_RAR)); + ue_mac->RA_RAPID_found = 1; + break; } - + // if (abs((int) rarh->RAPID - (int) preamble_index) < abs((int) best_rx_rapid - (int) preamble_index)) { + // best_rx_rapid = rarh->RAPID; + // rar = (NR_MAC_RAR *) (dlsch_buffer + n_subheaders + (n_subPDUs - 1) * sizeof(NR_MAC_RAR)); + // } if (rarh->E == 0) { - LOG_I(PHY, "No RAR found with the intended RAPID. The closest RAPID in all RARs is %d\n", best_rx_rapid); - break; + LOG_I(PHY, "No RAR found with the intended RAPID. The closest RAPID in all RARs is %d\n", best_rx_rapid); + break; } else { - rarh++; + rarh += sizeof(NR_MAC_RAR) + 1; } }; - LOG_D(MAC, "number of RAR subheader %d; number of RAR pyloads %d\n", - n_rarh, n_rarpy); - - LOG_I(MAC, - "[UE %d][RAPROC] Frame %d Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n", - mod_id, frameP, *(uint8_t *) rarh, rar[0], rar[1], rar[2], - rar[3], rar[4], rar[5], rarh->RAPID, preamble_index); -#ifdef DEBUG_RAR - LOG_D(MAC, "[UE %d][RAPROC] rarh->E %d\n", mod_id, rarh->E); - LOG_D(MAC, "[UE %d][RAPROC] rarh->T %d\n", mod_id, rarh->T); - LOG_D(MAC, "[UE %d][RAPROC] rarh->RAPID %d\n", mod_id, - rarh->RAPID); - - // LOG_I(MAC,"[UE %d][RAPROC] rar->R %d\n",mod_id,rar->R); - LOG_D(MAC, "[UE %d][RAPROC] rar->Timing_Advance_Command %d\n", - mod_id, (((uint16_t) (rar[0] & 0x7f)) << 4) + (rar[1] >> 4)); - // LOG_I(MAC,"[UE %d][RAPROC] rar->hopping_flag %d\n",mod_id,rar->hopping_flag); - // LOG_I(MAC,"[UE %d][RAPROC] rar->rb_alloc %d\n",mod_id,rar->rb_alloc); - // LOG_I(MAC,"[UE %d][RAPROC] rar->mcs %d\n",mod_id,rar->mcs); - // LOG_I(MAC,"[UE %d][RAPROC] rar->TPC %d\n",mod_id,rar->TPC); - // LOG_I(MAC,"[UE %d][RAPROC] rar->UL_delay %d\n",mod_id,rar->UL_delay); - // LOG_I(MAC,"[UE %d][RAPROC] rar->cqi_req %d\n",mod_id,rar->cqi_req); - LOG_D(MAC, "[UE %d][RAPROC] rar->t_crnti %x\n", mod_id, - (uint16_t) rar[5] + (rar[4] << 8)); -#endif - - if (opt_enabled) { - LOG_D(OPT, - "[UE %d][RAPROC] CC_id %d RAR Frame %d trace pdu for ra-RNTI %x\n", - mod_id, CC_id, frameP, ra_rnti); - /*trace_pdu(DIRECTION_DOWNLINK, (uint8_t *) dlsch_buffer, n_rarh + n_rarpy * 6, - mod_id, WS_RA_RNTI, ra_rnti, nrUE_mac_inst->rxFrame, - nrUE_mac_inst->rxSubframe, 0, 0);*/ // TODO TBR fix rxframe and subframe - } - if (preamble_index == rarh->RAPID) { // TBR double check this - *t_crnti = (uint16_t) rar[5] + (rar[4] << 8); //rar->t_crnti; - nrUE_mac_inst->crnti = *t_crnti; //rar->t_crnti; - //return(rar->Timing_Advance_Command); - ret = ((((uint16_t) (rar[0] & 0x7f)) << 4) + (rar[1] >> 4)); + LOG_D(MAC, "number of RAR subheader %d; number of RAR pyloads %d\n", n_subheaders, n_subPDUs); + + LOG_I(MAC, "[UE %d][RAPROC] Frame %d Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n", + mod_id, frameP, *(uint8_t *) rarh, rar[0], rar[1], rar[2], rar[3], rar[4], rar[5], rarh->RAPID, preamble_index); + + if (ue_mac->RA_RAPID_found) { + *t_crnti = rar->TCRNTI_2 + (rar->TCRNTI_1 << 8); + ue_mac->t_crnti = *t_crnti; + ue_mac->rnti_type == NR_RNTI_TC; + ta_command = rar->TA2 + (rar->TA1 << 5); } else { - nrUE_mac_inst->crnti = 0; - ret = (0xffff); + ue_mac->t_crnti = 0; + ta_command = (0xffff); } // move the selected RAR to the front of the RA_PDSCH buffer - memcpy(selected_rar_buffer + 0, (uint8_t *) rarh, 1); - memcpy(selected_rar_buffer + 1, (uint8_t *) rar, 6); + memcpy((void *) (selected_rar_buffer + 0), (void *) rarh, 1); + memcpy((void *) (selected_rar_buffer + 1), (void *) rar, sizeof(NR_MAC_RAR)); - return ret; + return ta_command; } \ No newline at end of file diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 0573462ebdf5b2dfd42e2f69ab16d2893a9e6aab..3258628b7f92f595d8a6da6cd6ebc15ec1801689 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -382,7 +382,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, // Phytest scheduling if (phy_test && slot_txP==1){ nr_schedule_uss_dlsch_phytest(module_idP, frame_txP, slot_txP,NULL); - // This schedules Random-Access for NR starting in subframeP nr_schedule_RA(module_idP, frame_txP, slot_txP); // resetting ta flag gNB->ta_len = 0; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 1645ba85745c068bf9e5ea98aa6e53a83d4e3317..074eda8ea8083aeb9aed4950aba797430a005dd2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -78,7 +78,7 @@ void nr_initiate_ra_proc(module_id_t module_idP, ra->preamble_subframe = slotP; // if(cc->tdd_Config!=NULL){ - // switch(cc->tdd_Config->subframeAssignment){ // TBR missing tdd_Config + // switch(cc->tdd_Config->subframeAssignment){ // default: printf("%s:%d: TODO\n", __FILE__, __LINE__); abort(); // case 1 : // offset = 6; @@ -95,11 +95,11 @@ void nr_initiate_ra_proc(module_id_t module_idP, nr_add_subframe(&msg2_frame, &msg2_slot, offset); ra->Msg2_frame = msg2_frame; - ra->Msg2_subframe = msg2_slot; + ra->Msg2_slot = msg2_slot; - LOG_D(MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d offset:%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_subframe, frameP, slotP, offset); + LOG_D(MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d offset:%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP, offset); - ra->Msg2_subframe = (slotP + offset) % 10; // TBR this is done twice ? + ra->Msg2_slot = (slotP + offset) % 10; // TBR this is done twice ? do { ra->rnti = taus(); // todo 5.1.3 TS 38.321 @@ -121,7 +121,7 @@ void nr_initiate_ra_proc(module_id_t module_idP, CC_id, frameP, ra->Msg2_frame, - ra->Msg2_subframe, + ra->Msg2_slot, ra->state); return; @@ -137,157 +137,228 @@ void nr_initiate_ra_proc(module_id_t module_idP, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); } +// WIP void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ + //uint8_t i = 0; + int CC_id = 0; gNB_MAC_INST *mac = RC.mac[module_idP]; - NR_COMMON_channels_t *cc = mac->common_channels; - NR_RA_t *ra; - uint8_t i, CC_id = 0; + NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; + NR_RA_t *ra = &cc->ra[0]; start_meas(&mac->schedule_ra); - for (i = 0; i < NR_NB_RA_PROC_MAX; i++) { - ra = (NR_RA_t *) & cc[CC_id].ra[i]; - LOG_D(MAC,"RA[state:%d]\n",ra->state); - switch (ra->state){ - case Msg2: - nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra); - break; - case Msg4: - //generate_Msg4(module_idP, CC_id, frameP, slotP, ra); // TBR - break; - case WAIT_Msg4_ACK: - check_Msg4_retransmission(module_idP, CC_id, frameP, slotP, ra); - break; - } + //for (i = 0; i < NR_NB_RA_PROC_MAX; i++) { + LOG_D(MAC,"RA[state:%d]\n",ra->state); + switch (ra->state){ + case Msg2: + //nr_generate_Msg2(module_idP, CC_id, frameP, slotP); + break; + case Msg4: + //generate_Msg4(module_idP, CC_id, frameP, slotP, ra); + break; + case WAIT_Msg4_ACK: + check_Msg4_retransmission(module_idP, CC_id, frameP, slotP, ra); + break; } + //} stop_meas(&mac->schedule_ra); } -void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, - sub_frame_t slotP, NR_RA_t * ra){ +// WIP +void nr_generate_Msg2(module_id_t module_idP, + int CC_id, + frame_t frameP, + sub_frame_t slotP){ + + int first_rb, UE_id = 0, dci_formats[2], rnti_types[2], CCEIndex, dlBWP_carrier_bandwidth, mcsIndex = 9; + int startSymbolAndLength = 0, StartSymbolIndex = -1, NrOfSymbols = 14, StartSymbolIndex_tmp, NrOfSymbols_tmp, x_Overhead, time_domain_assignment = 2; + int bwp_id = 1, coreset_id = 0, aggregation = 4, search_space = 0, N_RB_UL = 106; + gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; + NR_COMMON_channels_t *cc = &nr_mac->common_channels[0]; + NR_RA_t *ra = &cc->ra[0]; + NR_UE_list_t *UE_list = &nr_mac->UE_list; + + uint16_t rnti = ra->rnti, RA_rnti = ra->RA_rnti, numDlDci; + long locationAndBandwidth; + // uint8_t *vrb_map = cc[CC_id].vrb_map, CC_id; + + if ((ra->Msg2_frame == frameP) && (ra->Msg2_slot == slotP)) { + + // todo + // Allocate 4 PRBS starting in RB 0 + // first_rb = 0; + // vrb_map[first_rb] = 1; + // vrb_map[first_rb + 1] = 1; + // vrb_map[first_rb + 2] = 1; + // vrb_map[first_rb + 3] = 1; + + nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body; + nfapi_nr_dl_tti_request_pdu_t *dl_config_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; + nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs]; + + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; + memset((void*)dl_tti_pdcch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); + dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; + dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); + + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs+1]; + memset((void *)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); + dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE; + dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu)); + + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; + nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu; + numDlDci = pdcch_pdu_rel15->numDlDci; + + // Checking if the DCI allocation is feasible in current subframe + if (dl_req->nPDUs == NFAPI_NR_MAX_DL_TTI_PDUS) { + LOG_I(MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, RA_rnti); + return; + } else { + LOG_D(MAC, "[RAPROC] Subframe %d: Checking CCE feasibility format : (%x,%d) \n", slotP, RA_rnti, aggregation); + CCEIndex = allocate_nr_CCEs(nr_mac, bwp_id, coreset_id, aggregation, search_space, UE_id, 0); + AssertFatal(CCEIndex > 0,"CCEIndex is negative\n"); + } - int first_rb, N_RB_DL; - gNB_MAC_INST *mac = RC.nrmac[module_idP]; - NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; - uint8_t *vrb_map = cc[CC_id].vrb_map; - -// /* TBR - MIGRATE TO THE NEW NFAPI */ -// nfapi_nr_dl_tti_request_body_t *dl_req = &mac->DL_req[CC_id].dl_config_request_body; -// nfapi_nr_dl_tti_request_pdu_t *dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; -// nfapi_tx_request_pdu_t *TX_req; -// -// /* TBR: BW should be retrieved from -// // NR_ServingCellConfigCommonSIB_t -> NR_BWP_DownlinkCommon_t -> NR_BWP_t -// N_RB_DL = to_prb(cc[CC_id].mib->message.dl_Bandwidth); -// // Temporary hardcoded -// */ -// N_RB_DL = 106; -// -// if ((ra->Msg2_frame == frameP) && (ra->Msg2_subframe == slotP)) { -// -// LOG_D(MAC,"[gNB %d] CC_id %d Frame %d, slotP %d: -// Generating RAR DCI, state %d\n", -// module_idP, CC_id, frameP, slotP, ra->state); -// -// // Allocate 4 PRBS starting in RB 0 -// // commented out because preprocessor is missing -// /*first_rb = 0; -// vrb_map[first_rb] = 1; -// vrb_map[first_rb + 1] = 1; -// vrb_map[first_rb + 2] = 1; -// vrb_map[first_rb + 3] = 1;*/ -// -// memset((void *) dl_config_pdu, 0, sizeof(nfapi_nr_dl_config_request_pdu_t)); -// -// dl_config_pdu->pdu_type = NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE; -// dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); -// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; -// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; -// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; -// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = ra->RA_rnti; -// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // RA-RNTI : see Table 4-10 from SCF082 - nFAPI specifications -// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power -// -// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; -// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC -// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1; -// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 0; -// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; -// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0; -// -// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); -// -// // This checks if the above DCI allocation is feasible in current subframe -// if (!nr_CCE_allocation_infeasible(module_idP, CC_id, 0, slotP, -// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, ra->RA_rnti)) { -// -// LOG_D(MAC, "Frame %d: Subframe %d : Adding common DCI for RA_RNTI %x\n", frameP, slotP, ra->RA_rnti); -// dl_req->number_dci++; -// dl_req->number_pdu++; -// -// dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; -// memset((void *) dl_config_pdu, 0, sizeof(nfapi_nr_dl_config_request_pdu_t)); -// dl_config_pdu->pdu_type = NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE; -// dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_nr_dl_config_dlsch_pdu)); -// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_NR_DL_CONFIG_REQUEST_DLSCH_PDU_REL15_TAG; -// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = mac->pdu_index[CC_id]; -// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->RA_rnti; -// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D -// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized -// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); -// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK -// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; -// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block -// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; -// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; -// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; -// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; -// // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; -// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; -// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB -// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; -// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; -// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored -// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; -// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; -// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; -// // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; -// dl_req->number_pdu++; -// mac->DL_req[CC_id].sfn_sf = frameP<<4 | slotP; -// -// // Program UL processing for Msg3 -// nr_get_Msg3alloc(&cc[CC_id], slotP, frameP,&ra->Msg3_frame, &ra->Msg3_subframe); -// -// LOG_D(MAC, "Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n", -// frameP, slotP, ra->Msg3_frame, -// ra->Msg3_subframe); -// -// nr_fill_rar(module_idP, CC_id, ra, frameP, cc[CC_id].RAR_pdu.payload, N_RB_DL, 7); -// nr_add_msg3(module_idP, CC_id, ra, frameP, slotP); -// ra->state = WAITMSG3; -// LOG_D(MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG3\n", module_idP, frameP, slotP); -// -// // DL request -// mac->TX_req[CC_id].sfn_sf = (frameP << 4) + slotP; -// TX_req = &mac->TX_req[CC_id].tx_request_body.tx_pdu_list[mac->TX_req[CC_id].tx_request_body.number_of_pdus]; -// TX_req->pdu_length = 7; // This should be changed if we have more than 1 preamble -// TX_req->pdu_index = mac->pdu_index[CC_id]++; -// TX_req->num_segments = 1; -// TX_req->segments[0].segment_length = 7; -// TX_req->segments[0].segment_data = cc[CC_id].RAR_pdu.payload; -// mac->TX_req[CC_id].tx_request_body.number_of_pdus++; -// -// /*if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){ -// set_dl_ue_select_msg2(CC_id, 4, -1, ra->rnti); -// }*/ -// } // PDCCH CCE allocation is feasible -// } // Msg2 frame/subframe condition + LOG_D(MAC,"[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RAR DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state); + + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + locationAndBandwidth = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth; + dlBWP_carrier_bandwidth = NRRIV2BW(locationAndBandwidth,275); + NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id]; + AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, + "downlinkBWP_ToAddModList has %d BWP!\n", secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); + NR_BWP_Downlink_t *bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id - 1]; + + LOG_D(MAC, "[RAPROC] Scheduling common search space DCI type 1 dlBWP BW.firstRB %d.%d\n", dlBWP_carrier_bandwidth, + NRRIV2PRBOFFSET(locationAndBandwidth, 275)); + + pdsch_pdu_rel15->pduBitmap = 0; + pdsch_pdu_rel15->rnti = rnti; + pdsch_pdu_rel15->pduIndex = 0; + pdsch_pdu_rel15->BWPSize = NRRIV2BW(locationAndBandwidth,275); + pdsch_pdu_rel15->BWPStart = NRRIV2PRBOFFSET(locationAndBandwidth,275); + pdsch_pdu_rel15->SubcarrierSpacing = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing; + pdsch_pdu_rel15->CyclicPrefix = 0; + pdsch_pdu_rel15->NrOfCodewords = 1; + pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcsIndex,0); + pdsch_pdu_rel15->qamModOrder[0] = 2; + pdsch_pdu_rel15->mcsIndex[0] = mcsIndex; + pdsch_pdu_rel15->mcsTable[0] = 0; + pdsch_pdu_rel15->rvIndex[0] = 0; + pdsch_pdu_rel15->dataScramblingId = *scc->physCellId; + pdsch_pdu_rel15->nrOfLayers = 1; + pdsch_pdu_rel15->transmissionScheme = 0; + pdsch_pdu_rel15->refPoint = 0; + pdsch_pdu_rel15->dmrsConfigType = 0; + pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; + pdsch_pdu_rel15->SCID = 0; + pdsch_pdu_rel15->numDmrsCdmGrpsNoData = 1; + pdsch_pdu_rel15->dmrsPorts = 1; + pdsch_pdu_rel15->resourceAlloc = 1; + pdsch_pdu_rel15->rbStart = 0; + pdsch_pdu_rel15->rbSize = 6; + pdsch_pdu_rel15->VRBtoPRBMapping = 1; + + for (int i=0; i<scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count; i++) { + startSymbolAndLength = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength; + SLIV2SL(startSymbolAndLength, &StartSymbolIndex_tmp, &NrOfSymbols_tmp); + if (NrOfSymbols_tmp < NrOfSymbols) { + NrOfSymbols = NrOfSymbols_tmp; + StartSymbolIndex = StartSymbolIndex_tmp; + } + } + + AssertFatal(StartSymbolIndex >= 0, "StartSymbolIndex is negative\n"); + pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex; + pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols; + pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(NULL, scc->dmrs_TypeA_Position, NrOfSymbols); + + dci_pdu_rel15_t dci_pdu_rel15[MAX_DCI_CORESET]; + dci_pdu_rel15[0].frequency_domain_assignment = PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize, + pdsch_pdu_rel15->rbStart, + NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, 275)); + dci_pdu_rel15[0].time_domain_assignment = time_domain_assignment; + dci_pdu_rel15[0].vrb_to_prb_mapping = 1; + dci_pdu_rel15[0].mcs = pdsch_pdu_rel15->mcsIndex[0]; + dci_pdu_rel15[0].tb_scaling = 1; + dci_pdu_rel15[0].frequency_hopping_flag = 0; + dci_pdu_rel15[0].ra_preamble_index = ra->preamble_index; + dci_pdu_rel15[0].format_indicator = 1; + dci_pdu_rel15[0].ndi = 1; + dci_pdu_rel15[0].rv = 0; + dci_pdu_rel15[0].harq_pid = 0; + dci_pdu_rel15[0].dai = 2; + dci_pdu_rel15[0].tpc = 2; + dci_pdu_rel15[0].pucch_resource_indicator = 7; + dci_pdu_rel15[0].pdsch_to_harq_feedback_timing_indicator = 7; + + LOG_D(MAC, "[RAPROC] DCI type 1 payload: freq_alloc %d (%d,%d,%d), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n", + dci_pdu_rel15[0].frequency_domain_assignment, + pdsch_pdu_rel15->rbStart, + pdsch_pdu_rel15->rbSize, + NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275), + dci_pdu_rel15[0].time_domain_assignment, + dci_pdu_rel15[0].vrb_to_prb_mapping, + dci_pdu_rel15[0].mcs, + dci_pdu_rel15[0].tb_scaling, + dci_pdu_rel15[0].ndi, + dci_pdu_rel15[0].rv); + + nr_configure_pdcch(pdcch_pdu_rel15, 0, scc, bwp); + + LOG_D(MAC, "Frame %d: Subframe %d : Adding common DL DCI for RA_RNTI %x CCEIndex %d\n", frameP, slotP, RA_rnti, CCEIndex); + dci_pdu->RNTI[numDlDci] = RA_rnti; + dci_pdu->AggregationLevel[numDlDci] = aggregation; + dci_pdu->powerControlOffsetSS[numDlDci] = 0; + dci_pdu->CceIndex[numDlDci] = CCEIndex; + dci_pdu->beta_PDCCH_1_0[numDlDci] = 0; + dci_pdu->powerControlOffsetSS[numDlDci] = 1; + + dci_formats[0] = NR_DL_DCI_FORMAT_1_0; + rnti_types[0] = NR_RNTI_RA; + + LOG_D(MAC, "[RAPROC] DCI params: rnti %d, rnti_type %d, dci_format %d coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n", + pdcch_pdu_rel15->dci_pdu.RNTI[0], + rnti_types[0], + dci_formats[0], + (unsigned long long)pdcch_pdu_rel15->FreqDomainResource, + pdcch_pdu_rel15->StartSymbolIndex, + pdcch_pdu_rel15->DurationSymbols); + + dci_pdu->PayloadSizeBits[0] = nr_dci_size(dci_formats[0], rnti_types[0], pdcch_pdu_rel15->BWPSize); + fill_dci_pdu_rel15(pdcch_pdu_rel15, &dci_pdu_rel15[0], dci_formats, rnti_types); + pdcch_pdu_rel15->numDlDci++; + dl_req->nPDUs++; + + // Program UL processing for Msg3 + // nr_get_Msg3alloc(&cc[CC_id], slotP, frameP,&ra->Msg3_frame, &ra->Msg3_slot); + LOG_D(MAC, "Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot); + nr_fill_rar(ra, cc[CC_id].RAR_pdu.payload, N_RB_UL); + nr_add_msg3(module_idP, CC_id, frameP, slotP); + ra->state = WAIT_Msg3; + LOG_D(MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state); + + x_Overhead = 0; + nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead); + + // DL TX request + tx_req->PDU_length = pdsch_pdu_rel15->TBSize[0]; + tx_req->PDU_index = nr_mac->pdu_index[CC_id]++; + tx_req->num_TLV = 1; + tx_req->TLVs[0].length = 8; + nr_mac->TX_req[CC_id].SFN = frameP; + nr_mac->TX_req[CC_id].Number_of_PDUs++; + nr_mac->TX_req[CC_id].Slot = slotP; + memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&cc[CC_id].RAR_pdu.payload[0], tx_req->TLVs[0].length); + } } void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP){ unsigned char i; - NR_RA_t *ra = (NR_RA_t *) &RC.mac[module_idP]->common_channels[CC_id].ra[0]; + NR_RA_t *ra = &RC.mac[module_idP]->common_channels[CC_id].ra[0]; LOG_D(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Clear Random access information rnti %x\n", module_idP, CC_id, frameP, ra->rnti); ra->state = IDLE; ra->timing_offset = 0; @@ -296,201 +367,160 @@ void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP){ ra->msg3_round = 0; } -unsigned short nr_fill_rar(const module_id_t mod_id, - const int CC_id, - NR_RA_t * ra, - const frame_t frameP, - uint8_t * const dlsch_buffer, - const uint16_t N_RB_UL, - const uint8_t input_buffer_length){ - - RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer; - uint8_t *rar = (uint8_t *) (dlsch_buffer + 1); - - /* E/T/RAPID subheader - - E = 0, one only RAR, first and last - - T = 1, E/T/RAPID subheader */ +// todo: +// - handle MAC RAR BI subheader +// - sending only 1 RAR subPDU +// - UL Grant +// - padding +void nr_fill_rar(NR_RA_t * ra, + uint8_t * dlsch_buffer, + uint16_t N_RB_UL){ + + LOG_D(MAC, "[gNB] Generate RAR MAC PDU frame %d slot %d ", ra->Msg2_frame, ra-> Msg2_slot); + NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer; + NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1); + + // E/T/RAPID subheader + // E = 0, one only RAR, first and last + // T = 1, RAPID rarh->E = 0; rarh->T = 1; - rarh->RAPID = ra->preamble_index; // TBR Respond to Preamble 0 only for the moment - /* TBR handle MAC RAR BI subheader*/ - - /* TC-RNTI */ - // TBR double check - rar[5] = (uint8_t) (ra->rnti >> 8); - rar[6] = (uint8_t) (ra->rnti & 0xff); - // TBR double check - - /* Timing Advance Command */ - // TBR double check - //ra->timing_offset = 0; - //printf("ra->timing_offset %d\n", ra->timing_offset); // TBR remove - - ra->timing_offset /= 16; //T_A = N_TA/16, where N_TA should be on a 30.72Msps - rar[0] = (uint8_t) (ra->timing_offset >> (2 + 4)); // 7 MSBs of timing advance + divide by 4 - rar[1] = (uint8_t) (ra->timing_offset << (4 - 2)) & 0xf0; // 4 LSBs of timing advance + divide by 4 - // TBR double check - - // TBR double check - COMMON_channels_t *cc = &RC.mac[mod_id]->common_channels[CC_id]; - if(N_RB_UL == 25){ - ra->msg3_first_rb = 1; - }else{ - // if (cc->tdd_Config && N_RB_UL == 100) { // TBR missing tdd_Config - // ra->msg3_first_rb = 3; - // } else { - // ra->msg3_first_rb = 2; - // } - } - ra->msg3_nb_rb = 1; - // TBR double check - - /* UL Grant */ - // TBR fix this - uint16_t rballoc = nr_mac_compute_RIV(N_RB_UL, ra->msg3_first_rb, ra->msg3_nb_rb); // first PRB only for UL Grant - rar[1] |= (rballoc >> 7) & 7; // Hopping = 0 (bit 3), 3 MSBs of rballoc - rar[2] = ((uint8_t) (rballoc & 0xff)) << 1; // 7 LSBs of rballoc - ra->msg3_mcs = 10; - ra->msg3_TPC = 3; - ra->msg3_ULdelay = 0; - ra->msg3_cqireq = 0; - ra->msg3_round = 0; - rar[2] |= ((ra->msg3_mcs & 0x8) >> 3); // mcs 10 - rar[3] = (((ra->msg3_mcs & 0x7) << 5)) | ((ra->msg3_TPC & 7) << 2) | ((ra->msg3_ULdelay & 1) << 1) | (ra->msg3_cqireq & 1); - // TBR double check - - return ra->rnti; + rarh->RAPID = ra->preamble_index; + + // RAR MAC payload + rar->R = 0; + rar->TA1 = (uint8_t) (ra->timing_offset >> 5); // 7 MSBs of timing advance + rar->TA2 = (uint8_t) (ra->timing_offset & 0x1f); // 5 LSBs of timing advance + rar->TCRNTI_1 = (uint8_t) (ra->rnti >> 8); // 8 MSBs of rnti + rar->TCRNTI_2 = (uint8_t) (ra->rnti & 0xff); // 8 LSBs of rnti + + // uint16_t rballoc = nr_mac_compute_RIV(N_RB_UL, ra->msg3_first_rb, ra->msg3_nb_rb); // first PRB only for UL Grant + // uint32_t buffer = 0; + // rar->UL_GRANT_1 = (uint8_t) (buffer >> 24) & 0x7; + // rar->UL_GRANT_2 = (uint8_t) (buffer >> 16) & 0xFF; + // rar->UL_GRANT_3 = (uint8_t) (buffer >> 8) & 0xFF; + // rar->UL_GRANT_4 = (uint8_t) buffer & 0xff; } -void nr_add_msg3(module_id_t module_idP, int CC_id, NR_RA_t *ra, frame_t frameP, sub_frame_t subframeP){ - - #if 0 - eNB_MAC_INST *mac = RC.mac[module_idP]; - COMMON_channels_t *cc = &mac->common_channels[CC_id]; - uint8_t j; - nfapi_ul_config_request_t *ul_req; - nfapi_ul_config_request_body_t *ul_req_body; - nfapi_ul_config_request_pdu_t *ul_config_pdu; - nfapi_hi_dci0_request_t *hi_dci0_req; - nfapi_hi_dci0_request_body_t *hi_dci0_req_body; - nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu; - uint8_t sf_ahead_dl; - uint8_t rvseq[4] = {0, 2, 3, 1}; - ul_req = &mac->UL_req_tmp[CC_id][ra->Msg3_subframe]; - ul_req_body = &ul_req->ul_config_request_body; - AssertFatal(ra->state != IDLE, "RA is not active for RA %X\n", - ra->rnti); -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - - if (ra->rach_resource_type > 0) { - LOG_D (MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d CE level %d is active, Msg3 in (%d,%d)\n", - module_idP, frameP, subframeP, CC_id, ra->rach_resource_type - 1, ra->Msg3_frame, ra->Msg3_subframe); - LOG_D (MAC, "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d)\n", - frameP, subframeP, ra->Msg3_frame, ra->Msg3_subframe, ra->msg3_nb_rb, ra->msg3_round); - ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; - memset ((void *) ul_config_pdu, 0, sizeof (nfapi_ul_config_request_pdu_t)); - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; - ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_ul_config_ulsch_pdu)); - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = mac->ul_handle++; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = ra->rnti; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = narrowband_to_first_rb (cc, ra->msg34_narrowband) + ra->msg3_first_rb; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = ra->msg3_nb_rb; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 2; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = rvseq[ra->msg3_round]; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = 1; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = get_TBS_UL (ra->msg3_mcs, ra->msg3_nb_rb); - // Re13 fields - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type = ra->rach_resource_type > 2 ? 2 : 1; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions = 1; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number = 1; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = (ra->Msg3_frame * 10) + ra->Msg3_subframe; - ul_req_body->number_of_pdus++; - } // if (ra->rach_resource_type>0) { - else -#endif - { - LOG_D(MAC, - "[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", - module_idP, frameP, subframeP, CC_id, ra->Msg3_frame, - ra->Msg3_subframe); - LOG_D(MAC, - "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n", - frameP, subframeP, ra->Msg3_frame, ra->Msg3_subframe, - ra->msg3_nb_rb, ra->msg3_first_rb, ra->msg3_round, ra->rnti); - ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; - memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; - ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu)); - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = mac->ul_handle++; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = ra->rnti; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = ra->msg3_first_rb; - AssertFatal(ra->msg3_nb_rb > 0, "nb_rb = 0\n"); - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = ra->msg3_nb_rb; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 2; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = rvseq[ra->msg3_round]; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = subframe2harqpid(cc, ra->Msg3_frame, ra->Msg3_subframe); - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = 1; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = get_TBS_UL(10, ra->msg3_nb_rb); - ul_req_body->number_of_pdus++; - ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - ul_req->sfn_sf = ra->Msg3_frame<<4|ra->Msg3_subframe; - ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; - - // save UL scheduling information for preprocessor - for (j = 0; j < ra->msg3_nb_rb; j++) - cc->vrb_map_UL[ra->msg3_first_rb + j] = 1; - - LOG_D(MAC, "MSG3: UL_CONFIG SFN/SF:%d number_of_pdus:%d ra->msg3_round:%d\n", NFAPI_SFNSF2DEC(ul_req->sfn_sf), ul_req_body->number_of_pdus, ra->msg3_round); - - if (ra->msg3_round != 0) { // program HI too - sf_ahead_dl = ul_subframe2_k_phich(cc, subframeP); - hi_dci0_req = &mac->HI_DCI0_req[CC_id][(subframeP+sf_ahead_dl)%10]; - hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body; - hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; - memset((void *) hi_dci0_pdu, 0, - sizeof(nfapi_hi_dci0_request_pdu_t)); - hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; - hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu); - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG; - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = ra->msg3_first_rb; - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0; - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 0; - hi_dci0_req_body->number_of_hi++; - hi_dci0_req_body->sfnsf = sfnsf_add_subframe(ra->Msg3_frame, ra->Msg3_subframe, 0); - hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; - hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP, subframeP, sf_ahead_dl); - hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; - - if (NFAPI_MODE != NFAPI_MONOLITHIC) { - oai_nfapi_hi_dci0_req(hi_dci0_req); - hi_dci0_req_body->number_of_hi=0; - } - - LOG_D(MAC, "MSG3: HI_DCI0 SFN/SF:%d number_of_dci:%d number_of_hi:%d\n", NFAPI_SFNSF2DEC(hi_dci0_req->sfn_sf), hi_dci0_req_body->number_of_dci, hi_dci0_req_body->number_of_hi); - - // save UL scheduling information for preprocessor - for (j = 0; j < ra->msg3_nb_rb; j++) - cc->vrb_map_UL[ra->msg3_first_rb + j] = 1; - - LOG_D(MAC, - "[eNB %d][PUSCH-RA %x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) RA (mcs %d, first rb %d, nb_rb %d,round %d)\n", - module_idP, ra->rnti, CC_id, frameP, subframeP, 10, 1, 1, - ra->msg3_round - 1); - } // if (ra->msg3_round != 0) { // program HI too - } // non-BL/CE UE case - #endif +// WIP +void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP){ + + gNB_MAC_INST *mac = RC.nrmac[module_idP]; + NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + NR_RA_t *ra = &cc->ra[0]; + NR_UE_list_t *UE_list = &mac->UE_list; + + nfapi_nr_ul_tti_request_t *ul_req = &mac->UL_tti_req[0]; + nfapi_nr_ul_dci_request_t *UL_dci_req = &mac->UL_dci_req[0]; + nfapi_nr_pusch_pdu_t *pusch_pdu = &ul_req->pdus_list[0].pusch_pdu; + nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu = &UL_dci_req->ul_dci_pdu_list[UL_dci_req->numPdus]; + + int UE_id = 0, CCEIndex, dci_formats[2], rnti_types[2], bwp_id = 1, coreset_id = 0, aggregation = 4, search_space = 1; + + AssertFatal(ra->state != IDLE, "RA is not active for RA %X\n", ra->rnti); + + // if(N_RB_UL == 25) { + // ra->msg3_first_rb = 1; + // } else { + // if (cc->tdd_Config && N_RB_UL == 100) { + // ra->msg3_first_rb = 3; + // } else { + // ra->msg3_first_rb = 2; + // } + // } + // ra->msg3_nb_rb = 1; + // /* UL Grant */ + // ra->msg3_mcs = 10; + // ra->msg3_TPC = 3; + // ra->msg3_ULdelay = 0; + // ra->msg3_cqireq = 0; + // ra->msg3_round = 0; + + LOG_D(MAC, "[gNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot); + + ul_req->SFN = ra->Msg3_frame << 4 | ra->Msg3_slot; // TBR + ul_req->Slot = slotP; + ul_req->n_pdus = 1; + ul_req->pdus_list[0].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE; + ul_req->pdus_list[0].pdu_size = sizeof(nfapi_nr_pusch_pdu_t); + memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t)); + + memset((void*)ul_dci_request_pdu,0,sizeof(nfapi_nr_ul_dci_request_pdus_t)); + ul_dci_request_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; + ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); + + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15; + + AssertFatal(UE_list->active[UE_id] >=0,"Cannot find UE_id %d is not active\n", UE_id); + + NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id]; + AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, + "downlinkBWP_ToAddModList has %d BWP!\n", secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); + NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1]; + NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]; + LOG_D(MAC, "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n", + frameP, + slotP, + ra->Msg3_frame, + ra->Msg3_slot, + ra->msg3_nb_rb, + ra->msg3_first_rb, + ra->msg3_round, + ra->rnti); + + pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; + pusch_pdu->rnti = ra->rnti; + pusch_pdu->handle = 0; + pusch_pdu->bwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275); + pusch_pdu->bwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275); + pusch_pdu->subcarrier_spacing = ubwp->bwp_Common->genericParameters.subcarrierSpacing; + pusch_pdu->cyclic_prefix = 0; + pusch_pdu->mcs_index = 9; + pusch_pdu->mcs_table = 0; + pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table); + pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table); + pusch_pdu->transform_precoding = 0; + pusch_pdu->data_scrambling_id = 0; + pusch_pdu->nrOfLayers = 1; + pusch_pdu->ul_dmrs_symb_pos = 1; + pusch_pdu->dmrs_config_type = 0; + pusch_pdu->ul_dmrs_scrambling_id = 0; //If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id. // TBR + pusch_pdu->scid = 0; //DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]. Should match what is sent in DCI 0_1, otherwise set to 0. + pusch_pdu->resource_alloc = 1; //type 1 + //pusch_pdu->rb_bitmap;// for ressource alloc type 0 + pusch_pdu->rb_start = ra->msg3_first_rb; + pusch_pdu->rb_size = ra->msg3_nb_rb; + pusch_pdu->vrb_to_prb_mapping = 0; + pusch_pdu->frequency_hopping = 0; + //pusch_pdu->tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE] + pusch_pdu->uplink_frequency_shift_7p5khz = 0; + //Resource Allocation in time domain + pusch_pdu->start_symbol_index = 2; + pusch_pdu->nr_of_symbols = 12; + //Optional Data only included if indicated in pduBitmap + pusch_pdu->pusch_data.rv_index = 0; + pusch_pdu->pusch_data.harq_process_id = 0; + pusch_pdu->pusch_data.new_data_indicator = 0; + pusch_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->mcs_index, + pusch_pdu->target_code_rate, + pusch_pdu->rb_size, + pusch_pdu->nr_of_symbols, + 6, //nb_re_dmrs - not sure where this is coming from - its not in the FAPI + 0, //nb_rb_oh + pusch_pdu->nrOfLayers = 1); + pusch_pdu->pusch_data.num_cb = 0; + + CCEIndex = allocate_nr_CCEs(mac, bwp_id, coreset_id, aggregation, search_space, UE_id, 0); + AssertFatal(CCEIndex >= 0, "CCEIndex is negative\n"); + pdcch_pdu_rel15->dci_pdu.CceIndex[pdcch_pdu_rel15->numDlDci] = CCEIndex; + LOG_D(PHY, "CCEIndex %d\n", pdcch_pdu_rel15->dci_pdu.CceIndex[pdcch_pdu_rel15->numDlDci]); + + LOG_D(MAC,"Configuring ULDCI/PDCCH in %d.%d\n", frameP,slotP); + nr_configure_pdcch(pdcch_pdu_rel15, 1, scc, bwp); + + dci_pdu_rel15_t dci_pdu_rel15[MAX_DCI_CORESET]; + config_uldci(ubwp, pusch_pdu, pdcch_pdu_rel15, &dci_pdu_rel15[0], dci_formats, rnti_types); + pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[0] = nr_dci_size(dci_formats[0], rnti_types[0], pdcch_pdu_rel15->BWPSize); + fill_dci_pdu_rel15(pdcch_pdu_rel15, &dci_pdu_rel15[0], dci_formats, rnti_types); } \ No newline at end of file diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index f02032b1e7c9c69df86a02bc514cd5a9c99375b3..55ef77dc299143a7fb4e1b65bdc05a813c9bd759 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -1365,62 +1365,6 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){ } */ -/* -boolean_t nr_CCE_allocation_infeasible(int module_idP, int CC_id, int format_flag, int slot, int aggregation, int rnti){ - - gNB_MAC_INST *mac = RC.nrmac[module_idP]; - nfapi_nr_dl_tti_request_body_t *dl_req = &mac->DL_req[CC_id].dl_config_request_body; - nfapi_nr_dl_tti_request_pdu_t *dl_config_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; - - nfapi_hi_dci0_request_body_t *HI_DCI0_req = &RC.mac[module_idP]->HI_DCI0_req[CC_id][slot].hi_dci0_request_body; - nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci + HI_DCI0_req->number_of_hi]; - - int ret; - boolean_t res = FALSE; - - if (format_flag != 2) { // DL DCI - if (dl_req->number_pdu == MAX_NUM_DL_PDU) { - LOG_W(MAC, - "Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", - slot, rnti); - } else { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = (format_flag == 0) ? 2 : 1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = aggregation; - dl_req->number_pdu++; - - LOG_D(MAC, "Subframe %d: Checking CCE feasibility format %d : (%x,%d) (%x,%d,%d)\n", - slot, format_flag, rnti, aggregation, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type); - - // ret = nr_allocate_CCEs(module_idP, CC_id, 0, slot, 0); // TBR - - if (ret == -1) res = TRUE; - - dl_req->number_pdu--; - } - } else { // ue-specific UL DCI - if (HI_DCI0_req->number_of_dci + HI_DCI0_req->number_of_hi == MAX_NUM_HI_DCI0_PDU) { - LOG_W(MAC, "Subframe %d: FAPI UL structure is full, skip scheduling UE %d\n", slot, rnti); - } else { - hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; - HI_DCI0_req->number_of_dci++; - // ret = nr_allocate_CCEs(module_idP, CC_id, 0, slot, 0); // TBR - if (ret == -1) res = TRUE; - HI_DCI0_req->number_of_dci--; - } - } - - return res; -}*/ /* // TBR fix this void nr_get_Msg3alloc(NR_COMMON_channels_t *cc, @@ -1531,11 +1475,11 @@ void nr_get_Msg3alloc(NR_COMMON_channels_t *cc, } // else TDD }*/ -uint16_t nr_mac_compute_RIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs){ // TBR this is outdated - uint16_t RIV; - - if (Lcrbs <= (1 + (N_RB_DL >> 1))) RIV = (N_RB_DL * (Lcrbs - 1)) + RBstart; - else RIV = (N_RB_DL * (N_RB_DL + 1 - Lcrbs)) + (N_RB_DL - 1 - RBstart); - - return RIV; -} \ No newline at end of file +// uint16_t nr_mac_compute_RIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs){ // TBR +// uint16_t RIV; +// +// if (Lcrbs <= (1 + (N_RB_DL >> 1))) RIV = (N_RB_DL * (Lcrbs - 1)) + RBstart; +// else RIV = (N_RB_DL * (N_RB_DL + 1 - Lcrbs)) + (N_RB_DL - 1 - RBstart); +// +// return RIV; +// } \ No newline at end of file diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index c2ca2dc1fe914c6b847c1ce520c9ba4224ca3a5d..16b9924c8306f0f7aca6a3a9b83a205121d82fc9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -98,13 +98,6 @@ void nr_initiate_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, sub_ void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP); -boolean_t nr_CCE_allocation_infeasible(int module_idP, - int CC_idP, - int common_flag, - int slot, - int aggregation, - int rnti); - int nr_allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, sub_frame_t slotP, int test_only); void nr_get_Msg3alloc(NR_COMMON_channels_t *cc, @@ -113,19 +106,14 @@ void nr_get_Msg3alloc(NR_COMMON_channels_t *cc, frame_t *frame, sub_frame_t *subframe); -/* \brief Function in gNB to fill RAR pdu when requested by PHY. This provides a single RAR SDU for the moment and returns the t-CRNTI. -@param Mod_id Instance ID of gNB -@param dlsch_buffer Pointer to DLSCH input buffer +/* \brief Function in gNB to fill RAR pdu when requested by PHY. +@param ra Instance of RA resources of gNB +@param dlsch_buffer Pointer to RAR input buffer @param N_RB_UL Number of UL resource blocks -@returns t_CRNTI */ -unsigned short nr_fill_rar(const module_id_t module_idP, - const int CC_id, - NR_RA_t *ra, - const frame_t frameP, - uint8_t * const dlsch_buffer, - const uint16_t N_RB_UL, - const uint8_t input_buffer_length); +void nr_fill_rar(NR_RA_t * ra, + uint8_t * dlsch_buffer, + uint16_t N_RB_UL); uint16_t nr_mac_compute_RIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 71d8aa7b150a765906229cc6208e41d5712afbdf..03aa639baef689ff0e383f1be0f846d857a134ef 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -90,15 +90,15 @@ typedef struct { /// Subframe where preamble was received uint8_t preamble_subframe; /// Subframe where Msg2 is to be sent - uint8_t Msg2_subframe; + uint8_t Msg2_slot; /// Frame where Msg2 is to be sent frame_t Msg2_frame; /// Subframe where Msg3 is to be sent - sub_frame_t Msg3_subframe; + sub_frame_t Msg3_slot; /// Frame where Msg3 is to be sent frame_t Msg3_frame; /// Subframe where Msg4 is to be sent - sub_frame_t Msg4_subframe; + sub_frame_t Msg4_slot; /// Frame where Msg4 is to be sent frame_t Msg4_frame; /// harq_pid used for Msg4 transmission