Merge remote-tracking branch 'origin/some_fixes' into integration_2026_w16 (!4030)

Miscellaneous code improvements

- A fix in a yaml config file as reported by @Abdo-Gaber
- proper positioning of static functions in a couple of gNB scheduler
  files
- some effort to split NR from LTE code in compilation
- harmonization of macros for unused variables
This commit is contained in:
Robert Schmidt
2026-04-16 12:43:06 +02:00
31 changed files with 265 additions and 271 deletions
+120 -123
View File
@@ -7,7 +7,6 @@
*/
#include "common/platform_types.h"
#include "uper_decoder.h"
/* MAC */
#include "nr_mac_gNB.h"
@@ -24,8 +23,6 @@
#include <executables/softmodem-common.h>
static void nr_fill_rar(NR_UE_info_t *UE, uint8_t *dlsch_buffer, nfapi_nr_pusch_pdu_t *pusch_pdu);
static const float ssb_per_rach_occasion[8] = {0.125, 0.25, 0.5, 1, 2, 4, 8};
static int16_t ssb_index_from_prach(module_id_t module_idP,
@@ -1027,6 +1024,126 @@ static bool get_feasible_msg3_tda(const NR_ServingCellConfigCommon_t *scc,
return false;
}
/////////////////////////////////////
// Random Access Response PDU //
// TS 38.213 ch 8.2 //
// TS 38.321 ch 6.2.3 //
/////////////////////////////////////
//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// bit-wise
//| E | T | R A P I D |//
//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |//
//| R | T A |//
//| T A | UL grant |//
//| UL grant |//
//| UL grant |//
//| UL grant |//
//| T C - R N T I |//
//| T C - R N T I |//
/////////////////////////////////////
// UL grant (27 bits) //
/////////////////////////////////////
//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// bit-wise
//|-------------------|FHF|F_alloc|//
//| Freq allocation |//
//| F_alloc |Time allocation|//
//| MCS | TPC |CSI|//
/////////////////////////////////////
// WIP
// todo:
// - handle MAC RAR BI subheader
// - sending only 1 RAR subPDU
// - UL Grant: hardcoded CSI, TPC, time alloc
// - padding
static void nr_fill_rar(NR_UE_info_t *UE, uint8_t *dlsch_buffer, nfapi_nr_pusch_pdu_t *pusch_pdu)
{
NR_RA_t *ra = UE->ra;
LOG_D(NR_MAC,
"[gNB] Generate RAR MAC PDU frame %d slot %d preamble index %u TA command %d \n",
ra->Msg2_frame,
ra->Msg2_slot,
ra->preamble_index,
ra->timing_offset);
NR_RA_HEADER_BI *rarbi = (NR_RA_HEADER_BI *) dlsch_buffer;
NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) (dlsch_buffer + 1);
NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 2);
unsigned char csi_req = 0;
/// E/T/R/R/BI subheader ///
// E = 1, MAC PDU includes another MAC sub-PDU (RAPID)
// T = 0, Back-off indicator subheader
// R = 2, Reserved
// BI = 0, 5ms
rarbi->E = 1;
rarbi->T = 0;
rarbi->R = 0;
rarbi->BI = 0;
/// 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;
/// RAR MAC payload ///
rar->R = 0;
// TA command
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
// TC-RNTI
rar->TCRNTI_1 = (uint8_t) (UE->rnti >> 8); // 8 MSBs of rnti
rar->TCRNTI_2 = (uint8_t) (UE->rnti & 0xff); // 8 LSBs of rnti
// UL grant
if (pusch_pdu->frequency_hopping)
AssertFatal(1==0,"PUSCH with frequency hopping currently not supported");
int bwp_size = pusch_pdu->bwp_size;
int prb_alloc = PRBalloc_to_locationandbandwidth0(ra->msg3_nb_rb, ra->msg3_first_rb, bwp_size);
int valid_bits = 14;
int f_alloc = prb_alloc & ((1 << valid_bits) - 1);
uint32_t ul_grant = csi_req | (ra->msg3_TPC << 1) | (pusch_pdu->mcs_index << 4) | (ra->Msg3_tda_id << 8) | (f_alloc << 12) | (pusch_pdu->frequency_hopping << 26);
rar->UL_GRANT_1 = (uint8_t) (ul_grant >> 24) & 0x07;
rar->UL_GRANT_2 = (uint8_t) (ul_grant >> 16) & 0xff;
rar->UL_GRANT_3 = (uint8_t) (ul_grant >> 8) & 0xff;
rar->UL_GRANT_4 = (uint8_t) ul_grant & 0xff;
#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);
#endif
LOG_D(NR_MAC,
"In %s: Transmitted RAR with t_alloc %d f_alloc %d ta_command %d mcs %d freq_hopping %d tpc_command %d csi_req %d t_crnti "
"%x \n",
__FUNCTION__,
rar->UL_GRANT_3 & 0x0f,
(rar->UL_GRANT_3 >> 4) | (rar->UL_GRANT_2 << 4) | ((rar->UL_GRANT_1 & 0x03) << 12),
rar->TA2 + (rar->TA1 << 5),
rar->UL_GRANT_4 >> 4,
rar->UL_GRANT_1 >> 2,
ra->msg3_TPC,
csi_req,
rar->TCRNTI_2 + (rar->TCRNTI_1 << 8));
// resetting msg3 TPC to 0dB for possible retransmissions
ra->msg3_TPC = 1;
}
static bool nr_get_Msg3alloc(gNB_MAC_INST *mac, int CC_id, int current_slot, frame_t current_frame, NR_UE_info_t *UE)
{
NR_RA_t *ra = UE->ra;
@@ -1964,126 +2081,6 @@ bool nr_check_Msg4_MsgB_Ack(module_id_t module_id, frame_t frame, slot_t slot, N
return false;
}
/////////////////////////////////////
// Random Access Response PDU //
// TS 38.213 ch 8.2 //
// TS 38.321 ch 6.2.3 //
/////////////////////////////////////
//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// bit-wise
//| E | T | R A P I D |//
//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |//
//| R | T A |//
//| T A | UL grant |//
//| UL grant |//
//| UL grant |//
//| UL grant |//
//| T C - R N T I |//
//| T C - R N T I |//
/////////////////////////////////////
// UL grant (27 bits) //
/////////////////////////////////////
//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// bit-wise
//|-------------------|FHF|F_alloc|//
//| Freq allocation |//
//| F_alloc |Time allocation|//
//| MCS | TPC |CSI|//
/////////////////////////////////////
// WIP
// todo:
// - handle MAC RAR BI subheader
// - sending only 1 RAR subPDU
// - UL Grant: hardcoded CSI, TPC, time alloc
// - padding
static void nr_fill_rar(NR_UE_info_t *UE, uint8_t *dlsch_buffer, nfapi_nr_pusch_pdu_t *pusch_pdu)
{
NR_RA_t *ra = UE->ra;
LOG_D(NR_MAC,
"[gNB] Generate RAR MAC PDU frame %d slot %d preamble index %u TA command %d \n",
ra->Msg2_frame,
ra->Msg2_slot,
ra->preamble_index,
ra->timing_offset);
NR_RA_HEADER_BI *rarbi = (NR_RA_HEADER_BI *) dlsch_buffer;
NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) (dlsch_buffer + 1);
NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 2);
unsigned char csi_req = 0;
/// E/T/R/R/BI subheader ///
// E = 1, MAC PDU includes another MAC sub-PDU (RAPID)
// T = 0, Back-off indicator subheader
// R = 2, Reserved
// BI = 0, 5ms
rarbi->E = 1;
rarbi->T = 0;
rarbi->R = 0;
rarbi->BI = 0;
/// 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;
/// RAR MAC payload ///
rar->R = 0;
// TA command
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
// TC-RNTI
rar->TCRNTI_1 = (uint8_t) (UE->rnti >> 8); // 8 MSBs of rnti
rar->TCRNTI_2 = (uint8_t) (UE->rnti & 0xff); // 8 LSBs of rnti
// UL grant
if (pusch_pdu->frequency_hopping)
AssertFatal(1==0,"PUSCH with frequency hopping currently not supported");
int bwp_size = pusch_pdu->bwp_size;
int prb_alloc = PRBalloc_to_locationandbandwidth0(ra->msg3_nb_rb, ra->msg3_first_rb, bwp_size);
int valid_bits = 14;
int f_alloc = prb_alloc & ((1 << valid_bits) - 1);
uint32_t ul_grant = csi_req | (ra->msg3_TPC << 1) | (pusch_pdu->mcs_index << 4) | (ra->Msg3_tda_id << 8) | (f_alloc << 12) | (pusch_pdu->frequency_hopping << 26);
rar->UL_GRANT_1 = (uint8_t) (ul_grant >> 24) & 0x07;
rar->UL_GRANT_2 = (uint8_t) (ul_grant >> 16) & 0xff;
rar->UL_GRANT_3 = (uint8_t) (ul_grant >> 8) & 0xff;
rar->UL_GRANT_4 = (uint8_t) ul_grant & 0xff;
#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);
#endif
LOG_D(NR_MAC,
"In %s: Transmitted RAR with t_alloc %d f_alloc %d ta_command %d mcs %d freq_hopping %d tpc_command %d csi_req %d t_crnti "
"%x \n",
__FUNCTION__,
rar->UL_GRANT_3 & 0x0f,
(rar->UL_GRANT_3 >> 4) | (rar->UL_GRANT_2 << 4) | ((rar->UL_GRANT_1 & 0x03) << 12),
rar->TA2 + (rar->TA1 << 5),
rar->UL_GRANT_4 >> 4,
rar->UL_GRANT_1 >> 2,
ra->msg3_TPC,
csi_req,
rar->TCRNTI_2 + (rar->TCRNTI_1 << 8));
// resetting msg3 TPC to 0dB for possible retransmissions
ra->msg3_TPC = 1;
}
/** @brief remove the UE with RNTI rnti from list of UEs doing RA.
*
* The corresponding function to add is add_new_UE_RA(). */
@@ -16,16 +16,12 @@
#include "UTIL/OPT/opt.h"
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
#include "F1AP_CauseRadioNetwork.h"
#include "intertask_interface.h"
#include "openair2/F1AP/f1ap_ids.h"
#include "F1AP_CauseRadioNetwork.h"
#include "T.h"
#include "uper_encoder.h"
#include "uper_decoder.h"
#include "SIMULATION/TOOLS/sim.h" // for taus
@@ -96,11 +92,6 @@ static const uint16_t cqi_table3[16][2] = {{0, 0},
{6, 6660},
{6, 7720}};
static void determine_aggregation_level_search_order(int agg_level_search_order[NUM_PDCCH_AGG_LEVELS],
float pdcch_cl_adjust);
static int nr_mac_interrupt_ue_transmission(gNB_MAC_INST *mac, NR_UE_info_t *UE, int slots, int slots_per_frame);
int get_ssbidx_from_beam(gNB_MAC_INST *mac, int beam_idx)
{
for (int i = 0; i < MAX_NUM_OF_SSB; i++)
@@ -570,6 +561,21 @@ int find_pdcch_candidate(const gNB_MAC_INST *mac,
return -1;
}
/// @brief Orders PDCCH aggregation levels so that we first check desired aggregation level according to
/// pdcch_cl_adjust
/// @param agg_level_search_order in/out 5-element array of aggregation levels from 0 to 4
/// @param pdcch_cl_adjust value from 0 to 1 indication channel impariments (0 - good channel, 1 - bad channel)
static void determine_aggregation_level_search_order(int agg_level_search_order[NUM_PDCCH_AGG_LEVELS], float pdcch_cl_adjust)
{
int desired_agg_level_index = round(4 * pdcch_cl_adjust);
int agg_level_search_index = 0;
for (int i = desired_agg_level_index; i < NUM_PDCCH_AGG_LEVELS; i++) {
agg_level_search_order[agg_level_search_index++] = i;
}
for (int i = desired_agg_level_index - 1; i >= 0; i--) {
agg_level_search_order[agg_level_search_index++] = i;
}
}
int get_cce_index(const gNB_MAC_INST *nrmac,
const int CC_id,
@@ -3448,6 +3454,25 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, slot_t slot, nfapi_nr_dl_tt
}
}
static void nr_mac_interrupt_ue_transmission(gNB_MAC_INST *mac, NR_UE_info_t *UE, int slots, int slots_per_frame)
{
DevAssert(mac != NULL);
DevAssert(UE != NULL);
NR_SCHED_ENSURE_LOCKED(&mac->sched_lock);
nr_timer_setup(&UE->UE_sched_ctrl.transm_interrupt, slots, 1);
nr_timer_start(&UE->UE_sched_ctrl.transm_interrupt);
// it might happen that timing advance command should be sent during the UE inactivity time.
// To prevent this, delay next TA command just after the UE inactivity time.
const int inactive_frames = slots / slots_per_frame + 1;
if ((UE->UE_sched_ctrl.ta_frame - mac->frame + MAX_FRAME_NUMBER) % MAX_FRAME_NUMBER < inactive_frames)
UE->UE_sched_ctrl.ta_frame = (mac->frame + inactive_frames) % MAX_FRAME_NUMBER;
LOG_D(NR_MAC, "UE %04x: Interrupt UE transmission (%d slots)\n", UE->rnti, slots);
}
void nr_measgap_scheduling(gNB_MAC_INST *nr_mac, frame_t frame, sub_frame_t slot)
{
NR_SCHED_ENSURE_LOCKED(&nr_mac->sched_lock);
@@ -3517,25 +3542,6 @@ int nr_mac_get_reconfig_delay_slots(NR_SubcarrierSpacing_t scs)
return (delay_ms << scs) + sl_ahead;
}
static int nr_mac_interrupt_ue_transmission(gNB_MAC_INST *mac, NR_UE_info_t *UE, int slots, int slots_per_frame)
{
DevAssert(mac != NULL);
DevAssert(UE != NULL);
NR_SCHED_ENSURE_LOCKED(&mac->sched_lock);
nr_timer_setup(&UE->UE_sched_ctrl.transm_interrupt, slots, 1);
nr_timer_start(&UE->UE_sched_ctrl.transm_interrupt);
// it might happen that timing advance command should be sent during the UE inactivity time.
// To prevent this, delay next TA command just after the UE inactivity time.
const int inactive_frames = slots / slots_per_frame + 1;
if ((UE->UE_sched_ctrl.ta_frame - mac->frame + MAX_FRAME_NUMBER) % MAX_FRAME_NUMBER < inactive_frames)
UE->UE_sched_ctrl.ta_frame = (mac->frame + inactive_frames) % MAX_FRAME_NUMBER;
LOG_D(NR_MAC, "UE %04x: Interrupt UE transmission (%d slots)\n", UE->rnti, slots);
return 0;
}
static void nr_mac_ue_transmission_timeout(gNB_MAC_INST *mac, NR_UE_info_t *UE, int slots)
{
DevAssert(mac != NULL);
@@ -4120,22 +4126,6 @@ bool nr_mac_get_new_rnti(NR_UEs_t *UEs, rnti_t *rnti)
return loop < 100; // nothing found: loop count 100
}
/// @brief Orders PDCCH aggregation levels so that we first check desired aggregation level according to
/// pdcch_cl_adjust
/// @param agg_level_search_order in/out 5-element array of aggregation levels from 0 to 4
/// @param pdcch_cl_adjust value from 0 to 1 indication channel impariments (0 - good channel, 1 - bad channel)
static void determine_aggregation_level_search_order(int agg_level_search_order[NUM_PDCCH_AGG_LEVELS], float pdcch_cl_adjust)
{
int desired_agg_level_index = round(4 * pdcch_cl_adjust);
int agg_level_search_index = 0;
for (int i = desired_agg_level_index; i < NUM_PDCCH_AGG_LEVELS; i++) {
agg_level_search_order[agg_level_search_index++] = i;
}
for (int i = desired_agg_level_index - 1; i >= 0; i--) {
agg_level_search_order[agg_level_search_index++] = i;
}
}
/// @brief Update PDCCH closed loop adjust for UE depending on detection of feedback.
/// @param sched_ctrl UE scheduling control info
/// @param feedback_not_detected Whether feedback (PUSCH or HARQ) was detected