From 6d09f0542b456c96eb330bf7cd670d61a6c5f5fe Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Tue, 21 May 2024 21:08:34 +0200 Subject: [PATCH 01/16] Fix a bug in DELTA_TF calculation for PUCCH format 1. --- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index f4812e639c..8b9b325a92 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -1688,7 +1688,7 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, break; case 1: N_ref_PUCCH = 14; - DELTA_TF = 10 * log10(N_ref_PUCCH/N_symb_PUCCH); + DELTA_TF = 10 * log10(N_ref_PUCCH/N_symb_PUCCH * O_uci); delta_F_PUCCH_config = power_config->deltaF_PUCCH_f1; break; case 2: From a1902a03f8429590bda560d9a99776f15d719014 Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Thu, 23 May 2024 09:16:04 +0200 Subject: [PATCH 02/16] Accumulate delta PUCCH for each PUCCH occasion. --- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 1 - openair2/LAYER2/NR_MAC_UE/mac_proto.h | 1 + openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 3 +-- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 27 +++++++++++++++++--- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 1 + 5 files changed, 26 insertions(+), 7 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 2cda190f23..b77bf953e8 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -394,7 +394,6 @@ typedef struct { int n_harq; int n_CCE; int N_CCE; - int delta_pucch; int initial_pucch_id; } PUCCH_sched_t; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 1eac68350c..7b31d999ce 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -228,6 +228,7 @@ int get_deltatf(uint16_t nb_of_prbs, int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, int slot, + frame_t frame, uint16_t rnti, PUCCH_sched_t *pucch, fapi_nr_ul_config_pucch_pdu *pucch_pdu); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 4d74e4985a..5831bd2b11 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -930,7 +930,6 @@ void prepare_msg4_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack) mac->nr_ue_emul_l1.num_harqs = 1; PUCCH_sched_t pucch = {.n_CCE = current_harq->n_CCE, .N_CCE = current_harq->N_CCE, - .delta_pucch = current_harq->delta_pucch, .ack_payload = ack_nack, .n_harq = 1}; current_harq->active = false; @@ -943,7 +942,7 @@ void prepare_msg4_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack) fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, sched_frame, sched_slot, FAPI_NR_UL_CONFIG_TYPE_PUCCH); if (!pdu) return; - int ret = nr_ue_configure_pucch(mac, sched_slot, mac->ra.t_crnti, &pucch, &pdu->pucch_config_pdu); + int ret = nr_ue_configure_pucch(mac, sched_slot, sched_frame, mac->ra.t_crnti, &pucch, &pdu->pucch_config_pdu); if (ret != 0) remove_ul_config_last_item(pdu); release_ul_config(pdu, false); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 8b9b325a92..dddd20123c 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -104,6 +104,7 @@ random-access procedure @returns timing advance or 0xffff if preamble doesn't match */ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info, int pdu_id); +int get_sum_delta_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame); int get_pucch0_mcs(const int O_ACK, const int O_SR, const int ack_payload, const int sr_payload) { @@ -1381,6 +1382,7 @@ void set_harq_status(NR_UE_MAC_INST_t *mac, int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, int slot, + frame_t frame, uint16_t rnti, PUCCH_sched_t *pucch, fapi_nr_ul_config_pucch_pdu *pucch_pdu) @@ -1579,10 +1581,12 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, return -1; } + int sum_delta_pucch = get_sum_delta_pucch(mac, slot, frame); + pucch_pdu->pucch_tx_power = get_pucch_tx_power_ue(mac, scs, pucch_Config, - pucch->delta_pucch, + sum_delta_pucch, pucch_pdu->format_type, pucch_pdu->prb_size, pucch_pdu->freq_hop_flag, @@ -1629,7 +1633,7 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, int scs, NR_PUCCH_Config_t *pucch_Config, - int delta_pucch, + int sum_delta_pucch, uint8_t format_type, uint16_t nb_of_prbs, uint8_t freq_hop_flag, @@ -1666,7 +1670,7 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, G_b_f_c = 0; } else { - G_b_f_c = delta_pucch; + G_b_f_c = sum_delta_pucch; LOG_E(MAC,"PUCCH Transmit power control command not yet implemented for NR\n"); return (PUCCH_POWER_DEFAULT); } @@ -2362,7 +2366,6 @@ bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sche res_ind = temp_ind; pucch->n_CCE = current_harq->n_CCE; pucch->N_CCE = current_harq->N_CCE; - pucch->delta_pucch = current_harq->delta_pucch; LOG_D(NR_MAC,"%4d.%2d Sent %d ack on harq pid %d\n", frame, slot, current_harq->ack, dl_harq_pid); } } @@ -4065,3 +4068,19 @@ int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac, short ssb_rsrp_dBm) return pathloss; } + +// This is not entirely correct. In certain k2/k1/k0 settings we might postpone accumulating delta_PUCCH until next HARQ feedback +// slot. The correct way to do this would be to calculate the K_PUCCH (delta_PUCCH summation window end) for each PUCCH occasion and +// compare PUCCH transmission symbol with the reception symbol of the DCI containing delta_PUCCH to determine if the delta_PUCCH +// should be added at each occasion. +int get_sum_delta_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame) +{ + int delta_tpc_sum = 0; + for (int i = 0; i < NR_MAX_HARQ_PROCESSES; i++) { + if (mac->dl_harq_info[i].active && mac->dl_harq_info[i].ul_slot == slot && mac->dl_harq_info[i].ul_frame == frame) { + delta_tpc_sum += mac->dl_harq_info[i].delta_pucch; + mac->dl_harq_info[i].delta_pucch = 0; + } + } + return delta_tpc_sum; +} diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 54065ad757..2a2f2638ac 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -2064,6 +2064,7 @@ void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slotP, voi mac->nr_ue_emul_l1.active_uci_sfn_slot = NFAPI_SFNSLOT2HEX(frameP, slotP); int ret = nr_ue_configure_pucch(mac, slotP, + frameP, mac->crnti, // FIXME not sure this is valid for all pucch instances &pucch[j], &pdu->pucch_config_pdu); From 760e0aaae4a5dd7676a7893bcae3eb06041de97e Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Thu, 23 May 2024 09:20:34 +0200 Subject: [PATCH 03/16] PUCCH power control state. --- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 4 +- openair2/LAYER2/NR_MAC_UE/mac_proto.h | 12 +- openair2/LAYER2/NR_MAC_UE/main_ue_nr.c | 2 + .../LAYER2/NR_MAC_UE/nr_ue_power_procedures.c | 202 ++++++++++++++++++ openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 177 +-------------- 5 files changed, 213 insertions(+), 184 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index b77bf953e8..423036ee2e 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -577,7 +577,9 @@ typedef struct NR_UE_MAC_INST_s { //SIDELINK MAC PARAMETERS sl_nr_ue_mac_params_t *SL_MAC_PARAMS; - + // PUCCH closed loop power control state + int G_b_f_c; + bool pucch_power_control_initialized; } NR_UE_MAC_INST_t; /*@}*/ diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 7b31d999ce..af2db59a86 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -217,14 +217,8 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, uint8_t add_dmrs_flag, uint8_t N_symb_PUCCH, int subframe_number, - int O_uci); - -int get_deltatf(uint16_t nb_of_prbs, - uint8_t N_symb_PUCCH, - uint8_t freq_hop_flag, - uint8_t add_dmrs_flag, - int N_sc_ctrl_RB, - int O_UCI); + int O_uci, + uint16_t start_prb); int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, int slot, @@ -235,6 +229,8 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, int nr_get_Pcmax(NR_UE_MAC_INST_t *mac, int Qm, bool powerBoostPi2BPSK, int scs, int N_RB_UL, bool is_transform_precoding, int n_prbs, int start_prb); +int get_sum_delta_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame); + /* Random Access */ /* \brief This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211 tables 6.3.3.2.x diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index cc602ed240..3941488682 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -82,6 +82,8 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac) for (int i = 0; i < NR_MAX_SR_ID; i++) memset(&mac->scheduling_info.sr_info[i], 0, sizeof(mac->scheduling_info.sr_info[i])); + + mac->pucch_power_control_initialized = false; } void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c index 1c3f1b7b0b..3e9669775d 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c @@ -31,6 +31,40 @@ #include "LAYER2/NR_MAC_UE/mac_proto.h" +#define DEFAULT_P0_NOMINAL_PUCCH_0_DBM 0 +#define DEFAULT_DELTA_F_PUCCH_0_DB 0 + +// TODO: This should be part of mac instance +/* TS 38.213 9.2.5.2 UE procedure for multiplexing HARQ-ACK/SR and CSI in a PUCCH */ +/* this is a counter of number of pucch format 4 per subframe */ +static int nb_pucch_format_4_in_subframes[LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] = {0}; + +/* TS 38.211 Table 6.4.1.3.3.2-1: DM-RS positions for PUCCH format 3 and 4 */ +static const int nb_symbols_excluding_dmrs[11][2][2] += { +/* No additional DMRS Additional DMRS */ +/* PUCCH length No hopping hopping No hopping hopping */ +/* index 0 1 0 1 */ +/* 4 */ {{ 3 , 2 } , { 3 , 2 }}, +/* 5 */ {{ 3 , 3 } , { 3 , 3 }}, +/* 6 */ {{ 4 , 4 } , { 4 , 4 }}, +/* 7 */ {{ 5 , 5 } , { 5 , 5 }}, +/* 8 */ {{ 6 , 6 } , { 6 , 6 }}, +/* 9 */ {{ 7 , 7 } , { 7 , 7 }}, +/* 10 */ {{ 8 , 8 } , { 6 , 6 }}, +/* 11 */ {{ 9 , 9 } , { 7 , 7 }}, +/* 12 */ {{ 10 , 10 } , { 8 , 8 }}, +/* 13 */ {{ 11 , 11 } , { 9 , 9 }}, +/* 14 */ {{ 12 , 12 } , { 10 , 10 }}, +}; + +static int get_deltatf(uint16_t nb_of_prbs, + uint8_t N_symb_PUCCH, + uint8_t freq_hop_flag, + uint8_t add_dmrs_flag, + int N_sc_ctrl_RB, + int O_UCI); + // Implementation of 6.2.4 Configured ransmitted power // 3GPP TS 38.101-1 version 16.5.0 Release 16 // - @@ -156,3 +190,171 @@ int nr_get_Pcmax(NR_UE_MAC_INST_t *mac, int Qm, bool powerBoostPi2BPSK, int scs, } } +// This is not entirely correct. In certain k2/k1/k0 settings we might postpone accumulating delta_PUCCH until next HARQ feedback +// slot. The correct way to do this would be to calculate the K_PUCCH (delta_PUCCH summation window end) for each PUCCH occasion and +// compare PUCCH transmission symbol with the reception symbol of the DCI containing delta_PUCCH to determine if the delta_PUCCH +// should be added at each occasion. +int get_sum_delta_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame) +{ + int delta_tpc_sum = 0; + for (int i = 0; i < NR_MAX_HARQ_PROCESSES; i++) { + if (mac->dl_harq_info[i].active && mac->dl_harq_info[i].ul_slot == slot && mac->dl_harq_info[i].ul_frame == frame) { + delta_tpc_sum += mac->dl_harq_info[i].delta_pucch; + mac->dl_harq_info[i].delta_pucch = 0; + } + } + return delta_tpc_sum; +} + +// PUCCH Power control according to 38.213 section 7.2.1 +int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, + int scs, + NR_PUCCH_Config_t *pucch_Config, + int sum_delta_pucch, + uint8_t format_type, + uint16_t nb_of_prbs, + uint8_t freq_hop_flag, + uint8_t add_dmrs_flag, + uint8_t N_symb_PUCCH, + int subframe_number, + int O_uci, + uint16_t start_prb) +{ + NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; + AssertFatal(current_UL_BWP && current_UL_BWP->pucch_ConfigCommon, + "Missing configuration: need UL_BWP and pucch_ConfigCommon to calculate PUCCH tx power\n"); + int PUCCH_POWER_DEFAULT = 0; + // p0_nominal is optional + int16_t P_O_NOMINAL_PUCCH = DEFAULT_P0_NOMINAL_PUCCH_0_DBM; + if (current_UL_BWP->pucch_ConfigCommon->p0_nominal != NULL) { + P_O_NOMINAL_PUCCH = *current_UL_BWP->pucch_ConfigCommon->p0_nominal; + } + + struct NR_PUCCH_PowerControl *power_config = pucch_Config ? pucch_Config->pucch_PowerControl : NULL; + + if (!power_config) + return (PUCCH_POWER_DEFAULT); + + int16_t P_O_UE_PUCCH = 0; + + if (pucch_Config->spatialRelationInfoToAddModList != NULL) { /* FFS TODO NR */ + LOG_D(MAC,"PUCCH Spatial relation infos are not yet implemented\n"); + return (PUCCH_POWER_DEFAULT); + } + + int G_b_f_c = 0; + if (power_config->p0_Set != NULL) { + P_O_UE_PUCCH = power_config->p0_Set->list.array[0]->p0_PUCCH_Value; /* get from index 0 if no spatial relation set */ + } + + int P_O_PUCCH = P_O_NOMINAL_PUCCH + P_O_UE_PUCCH; + + int16_t delta_F_PUCCH = DEFAULT_DELTA_F_PUCCH_0_DB; + long *delta_F_PUCCH_config = NULL; + int DELTA_TF; + uint16_t N_ref_PUCCH; + int N_sc_ctrl_RB = 0; + + /* computing of pucch transmission power adjustment */ + switch (format_type) { + case 0: + N_ref_PUCCH = 2; + DELTA_TF = 10 * log10(N_ref_PUCCH/N_symb_PUCCH); + delta_F_PUCCH_config = power_config->deltaF_PUCCH_f0; + break; + case 1: + N_ref_PUCCH = 14; + DELTA_TF = 10 * log10(N_ref_PUCCH/N_symb_PUCCH * O_uci); + delta_F_PUCCH_config = power_config->deltaF_PUCCH_f1; + break; + case 2: + N_sc_ctrl_RB = 10; + DELTA_TF = get_deltatf(nb_of_prbs, N_symb_PUCCH, freq_hop_flag, add_dmrs_flag, N_sc_ctrl_RB, O_uci); + delta_F_PUCCH_config = power_config->deltaF_PUCCH_f2; + break; + case 3: + N_sc_ctrl_RB = 14; + DELTA_TF = get_deltatf(nb_of_prbs, N_symb_PUCCH, freq_hop_flag, add_dmrs_flag, N_sc_ctrl_RB, O_uci); + delta_F_PUCCH_config = power_config->deltaF_PUCCH_f3; + break; + case 4: + N_sc_ctrl_RB = 14/(nb_pucch_format_4_in_subframes[subframe_number]); + DELTA_TF = get_deltatf(nb_of_prbs, N_symb_PUCCH, freq_hop_flag, add_dmrs_flag, N_sc_ctrl_RB, O_uci); + delta_F_PUCCH_config = power_config->deltaF_PUCCH_f4; + break; + default: + { + LOG_E(MAC,"PUCCH unknown pucch format %d\n", format_type); + return (0); + } + } + if (delta_F_PUCCH_config != NULL) { + delta_F_PUCCH = *delta_F_PUCCH_config; + } + + // PUCCH shall be as specified for QPSK modulated DFT-s-OFDM of equivalent RB allocation (38.101-1) + // TODO: P_CMAX for format 2 + int P_CMAX = nr_get_Pcmax(mac, 2, false, mac->current_UL_BWP->scs, mac->current_UL_BWP->BWPSize, true, 1, start_prb); + int P_CMIN = -40; // TODO: minimum TX power, possibly 38.101-1 6.3.1 + int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm); + + if (power_config->twoPUCCH_PC_AdjustmentStates && *power_config->twoPUCCH_PC_AdjustmentStates > 1) { + LOG_E(MAC,"PUCCH power control adjustment states with 2 states not yet implemented\n"); + return (PUCCH_POWER_DEFAULT); + } + int M_pucch_component = (10 * log10((double)(pow(2,scs) * nb_of_prbs))); + + int16_t pucch_power_without_g_pucch = P_O_PUCCH + M_pucch_component + pathloss + delta_F_PUCCH + DELTA_TF; + + if (power_config->p0_Set == NULL) { + if (mac->pucch_power_control_initialized == false) { + // Initialize power control state + // Assuming only sending on PCell + NR_PRACH_RESOURCES_t* prach_resources = &mac->ra.prach_resources; + float DELTA_P_rampup_requested = (prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP; + float DELTA_P_rampup = P_CMAX - (P_O_PUCCH + pathloss + delta_F_PUCCH + DELTA_TF + sum_delta_pucch); + DELTA_P_rampup = max(min(0, DELTA_P_rampup), DELTA_P_rampup_requested); + mac->G_b_f_c = DELTA_P_rampup + sum_delta_pucch; + mac->pucch_power_control_initialized = true; + } + else { + // PUCCH closed loop power control state + G_b_f_c = mac->G_b_f_c; + if (!((pucch_power_without_g_pucch + G_b_f_c >= P_CMAX && sum_delta_pucch > 0) || + (pucch_power_without_g_pucch + G_b_f_c <= P_CMIN && sum_delta_pucch < 0))) { + G_b_f_c += sum_delta_pucch; + } + mac->G_b_f_c = G_b_f_c; + } + } + + + int pucch_power = min(P_CMAX, pucch_power_without_g_pucch + G_b_f_c); + + LOG_D(MAC, "PUCCH ( Tx power : %d dBm ) ( 10Log(...) : %d ) ( from Path Loss : %d ) ( delta_F_PUCCH : %d ) ( DELTA_TF : %d ) ( G_b_f_c : %d ) \n", + pucch_power, M_pucch_component, pathloss, delta_F_PUCCH, DELTA_TF, G_b_f_c); + + return pucch_power; +} + +static int get_deltatf(uint16_t nb_of_prbs, + uint8_t N_symb_PUCCH, + uint8_t freq_hop_flag, + uint8_t add_dmrs_flag, + int N_sc_ctrl_RB, + int O_UCI) +{ + int DELTA_TF; + int O_CRC = compute_pucch_crc_size(O_UCI); + int N_symb = N_symb_PUCCH < 4 ? N_symb_PUCCH : nb_symbols_excluding_dmrs[N_symb_PUCCH - 4][add_dmrs_flag][freq_hop_flag]; + float N_RE = nb_of_prbs * N_sc_ctrl_RB * N_symb; + float K1 = 6; + if (O_UCI + O_CRC < 12) + DELTA_TF = 10 * log10((double)(((K1 * (O_UCI)) / N_RE))); + else { + float K2 = 2.4; + float BPRE = (O_UCI + O_CRC) / N_RE; + DELTA_TF = 10 * log10((double)(pow(2, (K2 * BPRE)) - 1)); + } + return DELTA_TF; +} diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index dddd20123c..f996c5f7cf 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -58,18 +58,11 @@ #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" -#define DEFAULT_P0_NOMINAL_PUCCH_0_DBM 0 -#define DEFAULT_DELTA_F_PUCCH_0_DB 0 - // #define DEBUG_MIB // #define ENABLE_MAC_PAYLOAD_DEBUG 1 // #define DEBUG_RAR extern uint32_t N_RB_DL; -/* TS 38.213 9.2.5.2 UE procedure for multiplexing HARQ-ACK/SR and CSI in a PUCCH */ -/* this is a counter of number of pucch format 4 per subframe */ -static int nb_pucch_format_4_in_subframes[LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] = { 0 } ; - /* TS 36.213 Table 9.2.3-3: Mapping of values for one HARQ-ACK bit to sequences */ static const int sequence_cyclic_shift_1_harq_ack_bit[2] /* HARQ-ACK Value 0 1 */ @@ -104,7 +97,6 @@ random-access procedure @returns timing advance or 0xffff if preamble doesn't match */ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info, int pdu_id); -int get_sum_delta_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame); int get_pucch0_mcs(const int O_ACK, const int O_SR, const int ack_payload, const int sr_payload) { @@ -127,25 +119,6 @@ int get_pucch0_mcs(const int O_ACK, const int O_SR, const int ack_payload, const return mcs; } -/* TS 38.211 Table 6.4.1.3.3.2-1: DM-RS positions for PUCCH format 3 and 4 */ -static const int nb_symbols_excluding_dmrs[11][2][2] -= { -/* No additional DMRS Additional DMRS */ -/* PUCCH length No hopping hopping No hopping hopping */ -/* index 0 1 0 1 */ -/* 4 */ {{ 3 , 2 } , { 3 , 2 }}, -/* 5 */ {{ 3 , 3 } , { 3 , 3 }}, -/* 6 */ {{ 4 , 4 } , { 4 , 4 }}, -/* 7 */ {{ 5 , 5 } , { 5 , 5 }}, -/* 8 */ {{ 6 , 6 } , { 6 , 6 }}, -/* 9 */ {{ 7 , 7 } , { 7 , 7 }}, -/* 10 */ {{ 8 , 8 } , { 6 , 6 }}, -/* 11 */ {{ 9 , 9 } , { 7 , 7 }}, -/* 12 */ {{ 10 , 10 } , { 8 , 8 }}, -/* 13 */ {{ 11 , 11 } , { 9 , 9 }}, -/* 14 */ {{ 12 , 12 } , { 10 , 10 }}, -}; - /* TS 36.213 Table 9.2.1-1: PUCCH resource sets before dedicated PUCCH resource configuration */ const initial_pucch_resource_t initial_pucch_resource[16] = { /* format first symbol Number of symbols PRB offset nb index for set of initial CS */ @@ -1395,8 +1368,6 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, const int scs = current_UL_BWP->scs; int subframe_number = slot / (nr_slots_per_frame[scs]/10); - nb_pucch_format_4_in_subframes[subframe_number] = 0; - pucch_pdu->rnti = rnti; LOG_D(NR_MAC, "initial_pucch_id %d, pucch_resource %p\n", pucch->initial_pucch_id, pucch->pucch_resource); @@ -1593,7 +1564,8 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, pucch_pdu->add_dmrs_flag, pucch_pdu->nr_of_symbols, subframe_number, - n_uci); + n_uci, + pucch_pdu->prb_start); } else { LOG_E(NR_MAC, "problem with pucch configuration\n"); return -1; @@ -1629,135 +1601,6 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, return 0; } -// PUCCH Power control according to 38.213 section 7.2.1 -int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, - int scs, - NR_PUCCH_Config_t *pucch_Config, - int sum_delta_pucch, - uint8_t format_type, - uint16_t nb_of_prbs, - uint8_t freq_hop_flag, - uint8_t add_dmrs_flag, - uint8_t N_symb_PUCCH, - int subframe_number, - int O_uci) -{ - NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; - AssertFatal(current_UL_BWP && current_UL_BWP->pucch_ConfigCommon, - "Missing configuration: need UL_BWP and pucch_ConfigCommon to calculate PUCCH tx power\n"); - int PUCCH_POWER_DEFAULT = 0; - // p0_nominal is optional - int16_t P_O_NOMINAL_PUCCH = DEFAULT_P0_NOMINAL_PUCCH_0_DBM; - if (current_UL_BWP->pucch_ConfigCommon->p0_nominal != NULL) { - P_O_NOMINAL_PUCCH = *current_UL_BWP->pucch_ConfigCommon->p0_nominal; - } - - struct NR_PUCCH_PowerControl *power_config = pucch_Config ? pucch_Config->pucch_PowerControl : NULL; - - if (!power_config) - return (PUCCH_POWER_DEFAULT); - - int16_t P_O_UE_PUCCH; - int16_t G_b_f_c = 0; - - if (pucch_Config->spatialRelationInfoToAddModList != NULL) { /* FFS TODO NR */ - LOG_D(MAC,"PUCCH Spatial relation infos are not yet implemented\n"); - return (PUCCH_POWER_DEFAULT); - } - - if (power_config->p0_Set != NULL) { - P_O_UE_PUCCH = power_config->p0_Set->list.array[0]->p0_PUCCH_Value; /* get from index 0 if no spatial relation set */ - G_b_f_c = 0; - } - else { - G_b_f_c = sum_delta_pucch; - LOG_E(MAC,"PUCCH Transmit power control command not yet implemented for NR\n"); - return (PUCCH_POWER_DEFAULT); - } - - int P_O_PUCCH = P_O_NOMINAL_PUCCH + P_O_UE_PUCCH; - - int16_t delta_F_PUCCH = DEFAULT_DELTA_F_PUCCH_0_DB; - long *delta_F_PUCCH_config = NULL; - int DELTA_TF; - uint16_t N_ref_PUCCH; - int N_sc_ctrl_RB = 0; - - /* computing of pucch transmission power adjustment */ - switch (format_type) { - case 0: - N_ref_PUCCH = 2; - DELTA_TF = 10 * log10(N_ref_PUCCH/N_symb_PUCCH); - delta_F_PUCCH_config = power_config->deltaF_PUCCH_f0; - break; - case 1: - N_ref_PUCCH = 14; - DELTA_TF = 10 * log10(N_ref_PUCCH/N_symb_PUCCH * O_uci); - delta_F_PUCCH_config = power_config->deltaF_PUCCH_f1; - break; - case 2: - N_sc_ctrl_RB = 10; - DELTA_TF = get_deltatf(nb_of_prbs, N_symb_PUCCH, freq_hop_flag, add_dmrs_flag, N_sc_ctrl_RB, O_uci); - delta_F_PUCCH_config = power_config->deltaF_PUCCH_f2; - break; - case 3: - N_sc_ctrl_RB = 14; - DELTA_TF = get_deltatf(nb_of_prbs, N_symb_PUCCH, freq_hop_flag, add_dmrs_flag, N_sc_ctrl_RB, O_uci); - delta_F_PUCCH_config = power_config->deltaF_PUCCH_f3; - break; - case 4: - N_sc_ctrl_RB = 14/(nb_pucch_format_4_in_subframes[subframe_number]); - DELTA_TF = get_deltatf(nb_of_prbs, N_symb_PUCCH, freq_hop_flag, add_dmrs_flag, N_sc_ctrl_RB, O_uci); - delta_F_PUCCH_config = power_config->deltaF_PUCCH_f4; - break; - default: - { - LOG_E(MAC,"PUCCH unknown pucch format %d\n", format_type); - return (0); - } - } - if (delta_F_PUCCH_config != NULL) { - delta_F_PUCCH = *delta_F_PUCCH_config; - } - - if (power_config->twoPUCCH_PC_AdjustmentStates && *power_config->twoPUCCH_PC_AdjustmentStates > 1) { - LOG_E(MAC,"PUCCH power control adjustment states with 2 states not yet implemented\n"); - return (PUCCH_POWER_DEFAULT); - } - - int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm); - int M_pucch_component = (10 * log10((double)(pow(2,scs) * nb_of_prbs))); - - int16_t pucch_power = P_O_PUCCH + M_pucch_component + pathloss + delta_F_PUCCH + DELTA_TF + G_b_f_c; - - LOG_D(MAC, "PUCCH ( Tx power : %d dBm ) ( 10Log(...) : %d ) ( from Path Loss : %d ) ( delta_F_PUCCH : %d ) ( DELTA_TF : %d ) ( G_b_f_c : %d ) \n", - pucch_power, M_pucch_component, pathloss, delta_F_PUCCH, DELTA_TF, G_b_f_c); - - return (pucch_power); -} - -int get_deltatf(uint16_t nb_of_prbs, - uint8_t N_symb_PUCCH, - uint8_t freq_hop_flag, - uint8_t add_dmrs_flag, - int N_sc_ctrl_RB, - int O_UCI) -{ - int DELTA_TF; - int O_CRC = compute_pucch_crc_size(O_UCI); - int N_symb = N_symb_PUCCH < 4 ? N_symb_PUCCH : nb_symbols_excluding_dmrs[N_symb_PUCCH - 4][add_dmrs_flag][freq_hop_flag]; - float N_RE = nb_of_prbs * N_sc_ctrl_RB * N_symb; - float K1 = 6; - if (O_UCI + O_CRC < 12) - DELTA_TF = 10 * log10((double)(((K1 * (O_UCI)) / N_RE))); - else { - float K2 = 2.4; - float BPRE = (O_UCI + O_CRC) / N_RE; - DELTA_TF = 10 * log10((double)(pow(2,(K2*BPRE)) - 1)); - } - return DELTA_TF; -} - static int find_pucch_resource_set(NR_PUCCH_Config_t *pucch_Config, int size) { // Procedure described in 38.213 Section 9.2.1 @@ -4068,19 +3911,3 @@ int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac, short ssb_rsrp_dBm) return pathloss; } - -// This is not entirely correct. In certain k2/k1/k0 settings we might postpone accumulating delta_PUCCH until next HARQ feedback -// slot. The correct way to do this would be to calculate the K_PUCCH (delta_PUCCH summation window end) for each PUCCH occasion and -// compare PUCCH transmission symbol with the reception symbol of the DCI containing delta_PUCCH to determine if the delta_PUCCH -// should be added at each occasion. -int get_sum_delta_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame) -{ - int delta_tpc_sum = 0; - for (int i = 0; i < NR_MAX_HARQ_PROCESSES; i++) { - if (mac->dl_harq_info[i].active && mac->dl_harq_info[i].ul_slot == slot && mac->dl_harq_info[i].ul_frame == frame) { - delta_tpc_sum += mac->dl_harq_info[i].delta_pucch; - mac->dl_harq_info[i].delta_pucch = 0; - } - } - return delta_tpc_sum; -} From f23c91cc5aec063a26647cf62320aade45cb8242 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Tue, 4 Jun 2024 18:41:27 +0200 Subject: [PATCH 04/16] remove rb_mask_ul from permanent storage for stack local usage --- .../PHY/NR_ESTIMATION/nr_measurements_gNB.c | 11 ++++------ openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h | 2 +- openair1/PHY/defs_gNB.h | 3 --- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 22 +++++++++---------- openair1/SCHED_NR/sched_nr.h | 1 - openair1/SIMULATION/NR_PHY/pucchsim.c | 5 +++-- 6 files changed, 19 insertions(+), 25 deletions(-) diff --git a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c index ded4ece652..47938f3b78 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c +++ b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c @@ -114,10 +114,8 @@ void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB) { } - - -void gNB_I0_measurements(PHY_VARS_gNB *gNB,int slot, int first_symb,int num_symb) { - +void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_symb, uint32_t rb_mask_ul[14][9]) +{ NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; NR_gNB_COMMON *common_vars = &gNB->common_vars; PHY_MEASUREMENTS_gNB *measurements = &gNB->measurements; @@ -140,8 +138,8 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB,int slot, int first_symb,int num_symb for (int s=first_symb;s<(first_symb+num_symb);s++) { int offset0 = ((slot&3)*frame_parms->symbols_per_slot + s) * frame_parms->ofdm_symbol_size; for (rb=0; rbN_RB_UL; rb++) { - if ((gNB->rb_mask_ul[s][rb >> 5] & (1U << (rb & 31))) == 0 && // check that rb was not used in this subframe - !(I0_SKIP_DC && rb == frame_parms->N_RB_UL>>1)) { // skip middle PRB because of artificial noise possibly created by FFT + if ((rb_mask_ul[s][rb >> 5] & (1U << (rb & 31))) == 0 && // check that rb was not used in this subframe + !(I0_SKIP_DC && rb == frame_parms->N_RB_UL >> 1)) { // skip middle PRB because of artificial noise possibly created by FFT int offset = offset0 + (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size; nb_symb[rb]++; for (int aarx=0; aarxnb_antennas_rx; aarx++) { @@ -192,7 +190,6 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB,int slot, int first_symb,int num_symb } } - // Scope: This function computes the UL SNR from the UL channel estimates // // Todo: diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h index cb1745b027..e1e905c3fa 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h @@ -54,7 +54,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB); -void gNB_I0_measurements(PHY_VARS_gNB *gNB,int slot,int first_symb,int num_symb); +void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_symb, uint32_t rb_mask_ul[14][9]); void nr_gnb_measurements(PHY_VARS_gNB *gNB, NR_gNB_ULSCH_t *ulsch, diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 20413098bd..579cb24e60 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -622,9 +622,6 @@ typedef struct PHY_VARS_gNB_s { /// PUSCH DMRS uint32_t ****nr_gold_pusch_dmrs; - // Mask of occupied RBs, per symbol and PRB - uint32_t rb_mask_ul[14][9]; - /// PRS sequence uint32_t ****nr_gold_prs; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index d6eaafde79..8b9134f4a0 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -541,20 +541,20 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, } // Function to fill UL RB mask to be used for N0 measurements -void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { - +static void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, uint32_t rb_mask_ul[14][9]) +{ int rb = 0; int rb2 = 0; int prbpos = 0; for (int symbol = 0; symbol < 14; symbol++) { for (int m = 0; m < 9; m++) { - gNB->rb_mask_ul[symbol][m] = 0; + rb_mask_ul[symbol][m] = 0; for (int i = 0; i < 32; i++) { prbpos = (m * 32) + i; if (prbpos>gNB->frame_parms.N_RB_UL) break; - gNB->rb_mask_ul[symbol][m] |= (gNB->ulprbbl[prbpos] > 0 ? 1U : 0) << i; + rb_mask_ul[symbol][m] |= (gNB->ulprbbl[prbpos] > 0 ? 1U : 0) << i; } } } @@ -574,7 +574,7 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { rb2 = rb + pucch_pdu->bwp_start + ((symbol < pucch_pdu->start_symbol_index+(pucch_pdu->nr_of_symbols>>1)) || (pucch_pdu->freq_hop_flag == 0) ? pucch_pdu->prb_start : pucch_pdu->second_hop_prb); - gNB->rb_mask_ul[symbol][rb2>>5] |= (((uint32_t)1)<<(rb2&31)); + rb_mask_ul[symbol][rb2>>5] |= (((uint32_t)1)<<(rb2&31)); } } } @@ -599,7 +599,7 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { LOG_D(PHY, "symbol %d Filling rb_mask_ul rb_size %d\n", symbol, ulsch_harq->ulsch_pdu.rb_size); for (rb = 0; rb < ulsch_harq->ulsch_pdu.rb_size; rb++) { rb2 = rb + ulsch_harq->ulsch_pdu.rb_start + ulsch_harq->ulsch_pdu.bwp_start; - gNB->rb_mask_ul[symbol][rb2 >> 5] |= 1U << (rb2 & 31); + rb_mask_ul[symbol][rb2 >> 5] |= 1U << (rb2 & 31); } } } @@ -613,14 +613,13 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { nfapi_nr_srs_pdu_t *srs_pdu = &srs->srs_pdu; for(int symbol = 0; symbol<(1<num_symbols); symbol++) { for(rb = srs_pdu->bwp_start; rb < (srs_pdu->bwp_start+srs_pdu->bwp_size); rb++) { - gNB->rb_mask_ul[gNB->frame_parms.symbols_per_slot - srs_pdu->time_start_position - 1 + symbol][rb >> 5] |= 1U + rb_mask_ul[gNB->frame_parms.symbols_per_slot - srs_pdu->time_start_position - 1 + symbol][rb >> 5] |= 1U << (rb & 31); } } } } } - } int fill_srs_reported_symbol_list(nfapi_nr_srs_reported_symbol_t *prgs, @@ -718,8 +717,9 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,1); LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d\n",frame_rx,slot_rx); - - fill_ul_rb_mask(gNB, frame_rx, slot_rx); + // Mask of occupied RBs, per symbol and PRB + uint32_t rb_mask_ul[14][9]; + fill_ul_rb_mask(gNB, frame_rx, slot_rx, rb_mask_ul); int first_symb=0,num_symb=0; if (gNB->frame_parms.frame_type == TDD) @@ -731,7 +731,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) } else num_symb = NR_NUMBER_OF_SYMBOLS_PER_SLOT; - gNB_I0_measurements(gNB,slot_rx,first_symb,num_symb); + gNB_I0_measurements(gNB, slot_rx, first_symb, num_symb, rb_mask_ul); const int soffset = (slot_rx & 3) * gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size; int offset = 10 * gNB->frame_parms.ofdm_symbol_size + gNB->frame_parms.first_carrier_offset; diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h index eb9a790e45..4e1c7e2509 100644 --- a/openair1/SCHED_NR/sched_nr.h +++ b/openair1/SCHED_NR/sched_nr.h @@ -32,7 +32,6 @@ #include "PHY/NR_TRANSPORT/nr_dci.h" #include "phy_frame_config_nr.h" -void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx); void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME_PARMS *fp); void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, int frame_tx, int slot_tx, int do_meas); int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx); diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index f9c25a48c8..1609c36511 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -629,16 +629,17 @@ int main(int argc, char **argv) 12); // set UL mask for pucch allocation + uint32_t rb_mask_ul[14][9] = {0}; for (int s=0;ssymbols_per_slot;s++){ if (s>=startingSymbolIndex && s<(startingSymbolIndex+nrofSymbols)) for (int rb=0; rbrb_mask_ul[s][rb2>>5] |= (1<<(rb2&31)); + rb_mask_ul[s][rb2 >> 5] |= (1 << (rb2 & 31)); } } // noise measurement (all PRBs) - gNB_I0_measurements(gNB, nr_slot_tx, 0, gNB->frame_parms.symbols_per_slot); + gNB_I0_measurements(gNB, nr_slot_tx, 0, gNB->frame_parms.symbols_per_slot, rb_mask_ul); if (n_trials==1) printf("noise rxlev %d (%d dB), rxlev pucch %d dB sigma2 %f dB, SNR %f, TX %f, I0 (pucch) %d, I0 (avg) %d\n",rxlev,dB_fixed(rxlev),dB_fixed(rxlev_pucch),sigma2_dB,SNR,10*log10((double)txlev*UE->frame_parms.ofdm_symbol_size/12),gNB->measurements.n0_subband_power_tot_dB[startingPRB],gNB->measurements.n0_subband_power_avg_dB); if(format==0){ From 7aec889cf62e9c07ebd95036e80e8abe968ec2be Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Fri, 31 May 2024 16:18:20 +0200 Subject: [PATCH 05/16] Remove some global variables --- .../nr_dlsch_llr_computation.c | 2 -- openair1/SCHED_NR_UE/pucch_uci_ue_nr.c | 19 ------------------- openair1/SCHED_NR_UE/pucch_uci_ue_nr.h | 2 -- .../NR_UE_PHY/unit_tests/src/pucch_uci_test.c | 2 -- openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 3 --- openair2/PHY_INTERFACE/phy_interface_vars.h | 9 --------- openair3/NAS/NR_UE/nr_nas_msg_sim.c | 12 +++++------- openair3/NAS/NR_UE/nr_nas_msg_sim.h | 2 ++ 8 files changed, 7 insertions(+), 44 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c index 0f13fea3ca..82b3410bc1 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c @@ -38,8 +38,6 @@ //#define DEBUG_LLR_SIC -int16_t nr_zeros[8] __attribute__((aligned(16))) = {0, 0, 0, 0, 0, 0, 0, 0}; - //============================================================================================== // SINGLE-STREAM //============================================================================================== diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c index fddb484727..ef83d8013b 100644 --- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c +++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c @@ -186,22 +186,3 @@ void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, n pucch_vars->active[i] = false; } } - -int dummy_csi_status = 0; -uint32_t dummy_csi_payload = 0; - - -/* FFS TODO_NR code that should be removed */ - -void set_csi_nr(int csi_status, uint32_t csi_payload) -{ - dummy_csi_status = csi_status; - - if (dummy_csi_status == 0) { - dummy_csi_payload = 0; - } - else { - dummy_csi_payload = csi_payload; - } -} - diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h index e4063fbd78..6c3cc3abd6 100644 --- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h +++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h @@ -52,6 +52,4 @@ void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data, c16_t **txdataF); -void set_csi_nr(int csi_status, uint32_t csi_payload); - #endif /* PUCCH_UCI_UE_NR_H */ diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c index c19680c6d0..0c9968ce55 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c @@ -1074,8 +1074,6 @@ int test_csi_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc) ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid = NR_MAX_DLSCH_HARQ_PROCESSES; - set_csi_nr( 4, 0x0E ); - printf("\n => Test : PUCCH format from dedicated config with CSI alone \n"); if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 58adc41a65..17b1b02408 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -60,9 +60,6 @@ static int nr_pdcp_current_time_last_subframe; hash_table_t *pdcp_coll_p; static uint64_t pdcp_optmask; -uint8_t first_dcch = 0; -uint8_t proto_agent_flag = 0; - static ngran_node_t node_type; nr_pdcp_entity_t *nr_pdcp_get_rb(nr_pdcp_ue_t *ue, int rb_id, bool srb_flag) diff --git a/openair2/PHY_INTERFACE/phy_interface_vars.h b/openair2/PHY_INTERFACE/phy_interface_vars.h index 5f205d3024..db33f52091 100644 --- a/openair2/PHY_INTERFACE/phy_interface_vars.h +++ b/openair2/PHY_INTERFACE/phy_interface_vars.h @@ -31,14 +31,5 @@ #endif -unsigned int mac_debug; - -//MAC_xface *mac_xface; - -//MACPHY_PARAMS MACPHY_params; - -unsigned int mac_registered; - - #endif diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index f9d551ef3d..e0712c3691 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -53,8 +53,6 @@ #include "openair3/SECU/nas_stream_eia2.h" #include "openair3/UTILS/conversions.h" -uint8_t *registration_request_buf; -uint32_t registration_request_len; extern char *baseNetAddress; extern uint16_t NB_UE_INST; static nr_ue_nas_t nr_ue_nas = {0}; @@ -474,10 +472,10 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas) // encode the message initialNasMsg->data = malloc16_clear(size * sizeof(Byte_t)); - registration_request_buf = initialNasMsg->data; + nas->registration_request_buf = initialNasMsg->data; initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size); - registration_request_len = initialNasMsg->length; + nas->registration_request_len = initialNasMsg->length; } @@ -591,9 +589,9 @@ static void generateSecurityModeComplete(nr_ue_nas_t *nas, as_nas_info_t *initia size += fill_imeisv(&mm_msg->fgs_security_mode_complete.fgsmobileidentity, nas->uicc); - mm_msg->fgs_security_mode_complete.fgsnasmessagecontainer.nasmessagecontainercontents.value = registration_request_buf; - mm_msg->fgs_security_mode_complete.fgsnasmessagecontainer.nasmessagecontainercontents.length = registration_request_len; - size += (registration_request_len + 2); + mm_msg->fgs_security_mode_complete.fgsnasmessagecontainer.nasmessagecontainercontents.value = nas->registration_request_buf; + mm_msg->fgs_security_mode_complete.fgsnasmessagecontainer.nasmessagecontainercontents.length = nas->registration_request_len; + size += (nas->registration_request_len + 2); // encode the message initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t)); diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.h b/openair3/NAS/NR_UE/nr_nas_msg_sim.h index 0d2d8f5cc9..9a260dfc8f 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.h +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.h @@ -102,6 +102,8 @@ typedef struct { stream_security_container_t *security_container; Guti5GSMobileIdentity_t *guti; bool termination_procedure; + uint8_t *registration_request_buf; + uint32_t registration_request_len; } nr_ue_nas_t; typedef enum fgs_protocol_discriminator_e { From 6d5a0ab454d5c37821bb8ab618af1b92e149e4e3 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 22 May 2024 15:18:04 -0400 Subject: [PATCH 06/16] synch the USRP time accross devices using the host clock --- radio/USRP/usrp_lib.cpp | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/radio/USRP/usrp_lib.cpp b/radio/USRP/usrp_lib.cpp index ad0404f13d..c5aba63cdc 100644 --- a/radio/USRP/usrp_lib.cpp +++ b/radio/USRP/usrp_lib.cpp @@ -1012,6 +1012,28 @@ int trx_usrp_reset_stats(openair0_device *device) { return(0); } +/*! \brief synch the USRP time accross devices using the host clock (ideally syched with PTP, but also NTP works) and assuming all + * devices are synched by octoclock */ +static void usrp_sync_pps(usrp_state_t *s) +{ + // First, wait for PPS. + uhd::time_spec_t time_last_pps = s->usrp->get_time_last_pps(); + + while (time_last_pps == s->usrp->get_time_last_pps()) { + boost::this_thread::sleep(boost::posix_time::milliseconds(1)); + } + + // get host time + struct timespec tp; + if (clock_gettime(CLOCK_TAI, &tp) != 0) + LOG_W(PHY, "error getting system time\n"); + double tai_sec = (double)tp.tv_sec; + + // set USRP time to host time at next pps + s->usrp->set_time_next_pps(uhd::time_spec_t(tai_sec)); + LOG_I(HW, "USRP clock set to %f sec\n", tai_sec); +} + extern "C" { int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { LOG_I(HW, "openair0_cfg[0].sdr_addrs == '%s'\n", openair0_cfg[0].sdr_addrs); @@ -1188,8 +1210,12 @@ extern "C" { exit(EXIT_FAILURE); } } else { - s->usrp->set_time_next_pps(uhd::time_spec_t(0.0)); - + if (s->usrp->get_time_source(0) == "external") { + usrp_sync_pps(s); + } else { + s->usrp->set_time_next_pps(uhd::time_spec_t(0.0)); + } + if (s->usrp->get_clock_source(0) == "external") { if (check_ref_locked(s,0)) { LOG_I(HW,"USRP locked to external reference!\n"); From 1dfb30b8570a9ce535ead18311b72169372cb514 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 5 Jun 2024 15:11:59 +0200 Subject: [PATCH 07/16] USRP: add a T trace to record the RX IQ data on antenna 0 --- common/utils/T/T_messages.txt | 5 +++++ radio/USRP/usrp_lib.cpp | 2 ++ 2 files changed, 7 insertions(+) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index de221a0d73..1ca8c90e89 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -4,6 +4,11 @@ ID = ENB_MASTER_TICK GROUP = ALL:GENERAL:ENB FORMAT = int,eNB_ID : int,frame : int,subframe +ID = USRP_RX_ANT0 + DESC = RX IQ data as received by USRP driver on antenna 0 + GROUP = ALL:HEAVY + FORMAT = int,timestap : buffer,data + #PHY logs ID = ENB_PHY_UL_TICK DESC = eNodeB uplink tick - one tick per ms at start of uplink processing diff --git a/radio/USRP/usrp_lib.cpp b/radio/USRP/usrp_lib.cpp index ad0404f13d..608c6e1f4b 100644 --- a/radio/USRP/usrp_lib.cpp +++ b/radio/USRP/usrp_lib.cpp @@ -768,6 +768,8 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate); *ptimestamp = s->rx_timestamp; + T(T_USRP_RX_ANT0, T_INT(s->rx_timestamp), T_BUFFER(buff[0], samples_received*4)); + recplay_state_t *recPlay=device->recplay_state; if (device->openair0_cfg->recplay_mode == RECPLAY_RECORDMODE) { // record mode From ae60dede8e9cc60793cac4414715fc37acc61498 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 5 Jun 2024 15:15:35 +0200 Subject: [PATCH 08/16] build_oai: fix bad options' names --- cmake_targets/build_oai | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index beb1b51039..5c189166b3 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -414,19 +414,19 @@ function main() { grep -sq "Ubuntu 18.04" /etc/os-release && echo_error "Bug in OS with this option, see CMakeLists.txt" CMAKE_CMD="$CMAKE_CMD -DSANITIZE_ADDRESS=True" shift;; - --sanitize-undefined | -fundefined=address) + --sanitize-undefined | -fsanitize=undefined) CMAKE_CMD="$CMAKE_CMD -DSANITIZE_UNDEFINED=True" shift;; --sanitize-memory | -fsanitize=memory) CMAKE_CMD="$CMAKE_CMD -DSANITIZE_MEMORY=ON -DSANITIZE_ADDRESS=OFF -DSANITIZE_UNDEFINED=OFF" shift;; + --sanitize-thread | -fsanitize=thread) + CMAKE_CMD="$CMAKE_CMD -DSANITIZE_THREAD=True" + shift;; --trace-asn1c-enc-dec) CMAKE_CMD="$CMAKE_CMD -DTRACE_ASN1C_ENC_DEC=ON" echo_info "Enabling asn1c internal traces via OAI logging system" shift 1;; - --sanitize-thread | -fthread=address) - CMAKE_CMD="$CMAKE_CMD -DSANITIZE_THREAD=True" - shift;; -h | --help) print_help exit 1;; From 830b8a208a30525ccb44e8eb6648c8ea2a4df8da Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 13 Oct 2023 16:34:36 +0200 Subject: [PATCH 09/16] handling reception of CSI command for aperiodic CSI reporting --- .../nfapi/public_inc/fapi_nr_ue_interface.h | 20 +-- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 5 + openair2/LAYER2/NR_MAC_COMMON/nr_mac.h | 1 + openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 5 +- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h | 2 +- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 13 ++ openair2/LAYER2/NR_MAC_UE/mac_proto.h | 37 ++-- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 169 +++++++++++------- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 76 +++++++- 9 files changed, 232 insertions(+), 96 deletions(-) diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index 8ff7030af5..68e41c160f 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -37,18 +37,6 @@ typedef signed char int8_t; */ - -typedef struct { - uint8_t uci_format; - uint8_t uci_channel; - uint8_t harq_ack_bits; - uint32_t harq_ack; - uint8_t csi_bits; - uint32_t csi; - uint8_t sr_bits; - uint32_t sr; -} fapi_nr_uci_pdu_rel15_t; - typedef enum { RLM_no_monitoring = 0, RLM_out_of_sync = 1, @@ -257,10 +245,16 @@ typedef struct typedef struct { + // payloads with fixed array size + // no place to free the dinamically allocated + // vector without L1 implementation uint16_t harq_ack_bit_length; + uint64_t harq_payload; uint16_t csi_part1_bit_length; + uint64_t csi_part1_payload; uint16_t csi_part2_bit_length; - uint8_t alpha_scaling; + uint64_t csi_part2_payload; + uint8_t alpha_scaling; // 0 = 0.5, 1 = 0.65, 2 = 0.8, 3 = 1 uint8_t beta_offset_harq_ack; uint8_t beta_offset_csi1; uint8_t beta_offset_csi2; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 225a20aa36..7f34c25b45 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -123,6 +123,11 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, const nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &ulsch_ue->pusch_pdu; uint32_t tb_size = pusch_pdu->pusch_data.tb_size; + AssertFatal(pusch_pdu->pusch_uci.harq_ack_bit_length == 0 && + pusch_pdu->pusch_uci.csi_part1_bit_length == 0 && + pusch_pdu->pusch_uci.csi_part2_bit_length == 0, + "UCI on PUSCH not supported\n"); + int start_symbol = pusch_pdu->start_symbol_index; uint16_t ul_dmrs_symb_pos = pusch_pdu->ul_dmrs_symb_pos; uint8_t number_of_symbols = pusch_pdu->nr_of_symbols; diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index c6d1b72422..6202303d65 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -561,6 +561,7 @@ typedef struct NR_UE_UL_BWP { NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList_Common; NR_ConfiguredGrantConfig_t *configuredGrantConfig; NR_PUSCH_Config_t *pusch_Config; + NR_UCI_OnPUSCH_t *uci_onPusch; NR_PUCCH_Config_t *pucch_Config; NR_PUCCH_ConfigCommon_t *pucch_ConfigCommon; NR_SRS_Config_t *srs_Config; diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index d254906a33..df79cbcabd 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -5018,7 +5018,8 @@ void compute_cqi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, } //!TODO : same function can be written to handle csi_resources -void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report_t *csi_report_template) { +void compute_csi_bitlen(const NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report_t *csi_report_template) +{ uint8_t csi_report_id = 0; uint8_t nb_resources = 0; NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type; @@ -5039,7 +5040,7 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report_t *cs int csi_resourceidx = 0; while (found_resource == 0 && csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count) { csi_resourceconfig = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]; - if ( csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId) + if (csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId) found_resource = 1; csi_resourceidx++; } diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index d055d76676..dc9285bc3f 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -307,7 +307,7 @@ void compute_cqi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, uint8_t ri_restriction, nr_csi_report_t *csi_report); -void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report_t *csi_report_template); +void compute_csi_bitlen(const NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report_t *csi_report_template); uint16_t nr_get_csi_bitlen(nr_csi_report_t *csi_report_template, uint8_t csi_report_id); diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 2cda190f23..bcf477d52b 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -482,6 +482,19 @@ typedef struct { A_SEQUENCE_OF(NR_SearchSpace_t) list_SS; } NR_BWP_PDCCH_t; +typedef struct csi_payload { + uint32_t part1_payload; + uint32_t part2_payload; + int p1_bits; + int p2_bits; +} csi_payload_t; + +typedef enum { + WIDEBAND_ON_PUCCH, + SUBBAND_ON_PUCCH, + ON_PUSCH +} CSI_mapping_t; + /*!\brief Top level UE MAC structure */ typedef struct NR_UE_MAC_INST_s { module_id_t ue_id; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 1eac68350c..b401bcb20a 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -111,6 +111,8 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac, void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info); void nr_ue_dl_scheduler(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info); +csi_payload_t nr_ue_aperiodic_csi_reporting(NR_UE_MAC_INST_t *mac, dci_field_t csi_request, int tda, long *K2); + /*! \fn int8_t nr_ue_get_SR(NR_UE_MAC_INST_t *mac, frame_t frame, slot_t slot, NR_SchedulingRequestId_t sr_id); \brief This function schedules a positive or negative SR for schedulingRequestID sr_id depending on the presence of any active SR and the prohibit timer. @@ -132,28 +134,26 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, int nr_get_csi_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sched_t *pucch); -uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, - PUCCH_sched_t *pucch, - struct NR_CSI_ReportConfig *csi_reportconfig, - NR_CSI_ResourceConfigId_t csi_ResourceConfigId, - NR_CSI_MeasConfig_t *csi_MeasConfig); +csi_payload_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, + struct NR_CSI_ReportConfig *csi_reportconfig, + NR_CSI_ResourceConfigId_t csi_ResourceConfigId, + NR_CSI_MeasConfig_t *csi_MeasConfig); -uint8_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac, - PUCCH_sched_t *pucch, +csi_payload_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac, + struct NR_CSI_ReportConfig *csi_reportconfig, + NR_CSI_ResourceConfigId_t csi_ResourceConfigId, + NR_CSI_MeasConfig_t *csi_MeasConfig, + CSI_mapping_t mapping_type); + +csi_payload_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac, struct NR_CSI_ReportConfig *csi_reportconfig, NR_CSI_ResourceConfigId_t csi_ResourceConfigId, - NR_CSI_MeasConfig_t *csi_MeasConfig); + const NR_CSI_MeasConfig_t *csi_MeasConfig); -uint8_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac, - PUCCH_sched_t *pucch, - struct NR_CSI_ReportConfig *csi_reportconfig, - NR_CSI_ResourceConfigId_t csi_ResourceConfigId, - NR_CSI_MeasConfig_t *csi_MeasConfig); - -uint8_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac, - PUCCH_sched_t *pucch, - int csi_report_id, - NR_CSI_MeasConfig_t *csi_MeasConfig); +csi_payload_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac, + int csi_report_id, + CSI_mapping_t mapping_type, + NR_CSI_MeasConfig_t *csi_MeasConfig); uint8_t get_rsrp_index(int rsrp); uint8_t get_rsrp_diff_index(int best_rsrp,int current_rsrp); @@ -367,6 +367,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, NR_tda_info_t *tda_info, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, dci_pdu_rel15_t *dci, + csi_payload_t *csi_report, RAR_grant_t *rar_grant, uint16_t rnti, int ss_type, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index f4812e639c..1c3ee94cec 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -443,7 +443,15 @@ static int nr_ue_process_dci_ul_00(NR_UE_MAC_INST_t *mac, if (!pdu) return -1; - int ret = nr_config_pusch_pdu(mac, &tda_info, &pdu->pusch_config_pdu, dci, NULL, dci_ind->rnti, dci_ind->ss_type, NR_UL_DCI_FORMAT_0_0); + int ret = nr_config_pusch_pdu(mac, + &tda_info, + &pdu->pusch_config_pdu, + dci, + NULL, + NULL, + dci_ind->rnti, + dci_ind->ss_type, + NR_UL_DCI_FORMAT_0_0); if (ret != 0) remove_ul_config_last_item(pdu); release_ul_config(pdu, false); @@ -489,6 +497,12 @@ static int nr_ue_process_dci_ul_01(NR_UE_MAC_INST_t *mac, // - SECOND_DAI // - SRS_RESOURCE_IND + /* CSI_REQUEST */ + long csi_K2 = -1; + csi_payload_t csi_report = {0}; + if (dci->csi_request.nbits > 0 && dci->csi_request.val > 0) + csi_report = nr_ue_aperiodic_csi_reporting(mac, dci->csi_request, dci->time_domain_assignment.val, &csi_K2); + /* SRS_REQUEST */ AssertFatal(dci->srs_request.nbits == 2, "If SUL is supported in the cell, there is an additional bit in SRS request field\n"); if (dci->srs_request.val > 0) @@ -504,6 +518,13 @@ static int nr_ue_process_dci_ul_01(NR_UE_MAC_INST_t *mac, dci_ind->ss_type, get_rnti_type(mac, dci_ind->rnti), dci->time_domain_assignment.val); + + if (dci->ulsch_indicator == 0) { + // in case of CSI on PUSCH and no ULSCH we need to use reportSlotOffset in trigger state + AssertFatal(csi_K2 > 0, "Invalid CSI K2 value %ld\n", csi_K2); + tda_info.k2 = csi_K2; + } + if (tda_info.nrOfSymbols == 0) return -1; @@ -515,7 +536,15 @@ static int nr_ue_process_dci_ul_01(NR_UE_MAC_INST_t *mac, fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH); if (!pdu) return -1; - int ret = nr_config_pusch_pdu(mac, &tda_info, &pdu->pusch_config_pdu, dci, NULL, dci_ind->rnti, dci_ind->ss_type, NR_UL_DCI_FORMAT_0_1); + int ret = nr_config_pusch_pdu(mac, + &tda_info, + &pdu->pusch_config_pdu, + dci, + &csi_report, + NULL, + dci_ind->rnti, + dci_ind->ss_type, + NR_UL_DCI_FORMAT_0_1); if (ret != 0) remove_ul_config_last_item(pdu); release_ul_config(pdu, false); @@ -2584,14 +2613,12 @@ int nr_get_csi_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCC NR_CSI_MeasConfig_t *csi_measconfig = mac->sc_info.csi_MeasConfig; int csi_priority = INT_MAX; - for (int csi_report_id = 0; csi_report_id < csi_measconfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){ + for (int csi_report_id = 0; csi_report_id < csi_measconfig->csi_ReportConfigToAddModList->list.count; csi_report_id++) { NR_CSI_ReportConfig_t *csirep = csi_measconfig->csi_ReportConfigToAddModList->list.array[csi_report_id]; - if(csirep->reportConfigType.present == NR_CSI_ReportConfig__reportConfigType_PR_periodic){ - + if(csirep->reportConfigType.present == NR_CSI_ReportConfig__reportConfigType_PR_periodic) { int period, offset; csi_period_offset(csirep, NULL, &period, &offset); - const int n_slots_frame = nr_slots_per_frame[current_UL_BWP->scs]; if (((n_slots_frame*frame + slot - offset)%period) == 0 && pucch_Config) { int csi_res_id = -1; @@ -2619,47 +2646,50 @@ int nr_get_csi_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCC // we discard previous report csi_priority = temp_priority; num_csi = 1; - pucch->n_csi = nr_get_csi_payload(mac, pucch, csi_report_id, csi_measconfig); + csi_payload_t csi = nr_get_csi_payload(mac, csi_report_id, WIDEBAND_ON_PUCCH, csi_measconfig); + pucch->n_csi = csi.p1_bits; + pucch->csi_part1_payload = csi.part1_payload; pucch->pucch_resource = csi_pucch; } else continue; } else { num_csi = 1; csi_priority = temp_priority; - pucch->n_csi = nr_get_csi_payload(mac, pucch, csi_report_id, csi_measconfig); + csi_payload_t csi = nr_get_csi_payload(mac, csi_report_id, WIDEBAND_ON_PUCCH, csi_measconfig); + pucch->n_csi = csi.p1_bits; + pucch->csi_part1_payload = csi.part1_payload; pucch->pucch_resource = csi_pucch; } } } else - AssertFatal(1==0,"Only periodic CSI reporting is currently implemented\n"); + AssertFatal(csirep->reportConfigType.present == NR_CSI_ReportConfig__reportConfigType_PR_aperiodic, + "Not supported CSI report type\n"); } } return num_csi; } -uint8_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac, - PUCCH_sched_t *pucch, - int csi_report_id, - NR_CSI_MeasConfig_t *csi_MeasConfig) { - - int n_csi_bits = 0; - - AssertFatal(csi_MeasConfig->csi_ReportConfigToAddModList->list.count>0,"No CSI Report configuration available\n"); - +csi_payload_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac, + int csi_report_id, + CSI_mapping_t mapping_type, + NR_CSI_MeasConfig_t *csi_MeasConfig) +{ + AssertFatal(csi_MeasConfig->csi_ReportConfigToAddModList->list.count > 0,"No CSI Report configuration available\n"); + csi_payload_t csi = {0}; struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]; NR_CSI_ResourceConfigId_t csi_ResourceConfigId = csi_reportconfig->resourcesForChannelMeasurement; switch(csi_reportconfig->reportQuantity.present) { case NR_CSI_ReportConfig__reportQuantity_PR_none: break; case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP: - n_csi_bits = get_ssb_rsrp_payload(mac,pucch,csi_reportconfig,csi_ResourceConfigId,csi_MeasConfig); + csi = get_ssb_rsrp_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig); break; case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI: - n_csi_bits = get_csirs_RI_PMI_CQI_payload(mac,pucch,csi_reportconfig,csi_ResourceConfigId,csi_MeasConfig); + csi = get_csirs_RI_PMI_CQI_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig, mapping_type); break; case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP: - n_csi_bits = get_csirs_RSRP_payload(mac,pucch,csi_reportconfig,csi_ResourceConfigId,csi_MeasConfig); + csi = get_csirs_RSRP_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig); break; case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1: case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1_CQI: @@ -2670,16 +2700,15 @@ uint8_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac, default: AssertFatal(1==0,"Invalid CSI report quantity type %d\n",csi_reportconfig->reportQuantity.present); } - return (n_csi_bits); + return csi; } -uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, - PUCCH_sched_t *pucch, - struct NR_CSI_ReportConfig *csi_reportconfig, - NR_CSI_ResourceConfigId_t csi_ResourceConfigId, - NR_CSI_MeasConfig_t *csi_MeasConfig) { - +csi_payload_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, + struct NR_CSI_ReportConfig *csi_reportconfig, + NR_CSI_ResourceConfigId_t csi_ResourceConfigId, + NR_CSI_MeasConfig_t *csi_MeasConfig) +{ int nb_ssb = 0; // nb of ssb in the resource int nb_meas = 0; // nb of ssb to report measurements on int bits = 0; @@ -2750,18 +2779,22 @@ uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, break; // resorce found } } - pucch->csi_part1_payload = temp_payload; - return bits; + AssertFatal(bits <= 32, "Not supporting CSI report with more than 32 bits\n"); + csi_payload_t csi = {.part1_payload = temp_payload, .p1_bits = bits, csi.p2_bits = 0}; + return csi; } -uint8_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac, - PUCCH_sched_t *pucch, - struct NR_CSI_ReportConfig *csi_reportconfig, - NR_CSI_ResourceConfigId_t csi_ResourceConfigId, - NR_CSI_MeasConfig_t *csi_MeasConfig) { - - int n_bits = 0; - uint64_t temp_payload = 0; +csi_payload_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac, + struct NR_CSI_ReportConfig *csi_reportconfig, + NR_CSI_ResourceConfigId_t csi_ResourceConfigId, + NR_CSI_MeasConfig_t *csi_MeasConfig, + CSI_mapping_t mapping_type) +{ + int p1_bits = 0; + int p2_bits = 0; + uint64_t temp_payload_1 = 0; + uint64_t temp_payload_2 = 0; + AssertFatal(mapping_type != SUBBAND_ON_PUCCH, "CSI mapping for subband PMI and CQI not implemented\n"); for (int csi_resourceidx = 0; csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_resourceidx++) { @@ -2774,14 +2807,12 @@ uint8_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac, nr_csi_report_t *csi_report = &mac->csi_report_template[csi_idx]; compute_csi_bitlen(csi_MeasConfig, mac->csi_report_template); - n_bits = nr_get_csi_bitlen(mac->csi_report_template, csi_idx); int cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen; int ri_bitlen = csi_report->csi_meas_bitlen.ri_bitlen; int pmi_x1_bitlen = csi_report->csi_meas_bitlen.pmi_x1_bitlen[mac->csirs_measurements.rank_indicator]; int pmi_x2_bitlen = csi_report->csi_meas_bitlen.pmi_x2_bitlen[mac->csirs_measurements.rank_indicator]; int cqi_bitlen = csi_report->csi_meas_bitlen.cqi_bitlen[mac->csirs_measurements.rank_indicator]; - int padding_bitlen = n_bits - (cri_bitlen + ri_bitlen + pmi_x1_bitlen + pmi_x2_bitlen + cqi_bitlen); if (get_softmodem_params()->emulate_l1) { static const uint8_t mcs_to_cqi[] = {0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, @@ -2794,38 +2825,53 @@ uint8_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac, mac->csirs_measurements.cqi = mcs_to_cqi[mcs]; } + int padding_bitlen = 0; // TODO: Improvements will be needed to cri_bitlen>0 and pmi_x1_bitlen>0 - temp_payload = (mac->csirs_measurements.rank_indicator<<(cri_bitlen+cqi_bitlen+pmi_x2_bitlen+padding_bitlen+pmi_x1_bitlen)) | - (mac->csirs_measurements.i1<<(cri_bitlen+cqi_bitlen+pmi_x2_bitlen)) | - (mac->csirs_measurements.i2<<(cri_bitlen+cqi_bitlen)) | - (mac->csirs_measurements.cqi<csi_measurements.cri*/ << (cqi_bitlen + ri_bitlen)) | + (mac->csirs_measurements.rank_indicator << cqi_bitlen) | + (mac->csirs_measurements.cqi); + temp_payload_2 = (mac->csirs_measurements.i1 << pmi_x2_bitlen) | + mac->csirs_measurements.i2; + } + else { + p1_bits = nr_get_csi_bitlen(mac->csi_report_template, csi_idx); + padding_bitlen = p1_bits - (cri_bitlen + ri_bitlen + pmi_x1_bitlen + pmi_x2_bitlen + cqi_bitlen); + temp_payload_1 = (0/*mac->csi_measurements.cri*/ << (cqi_bitlen + pmi_x2_bitlen + pmi_x1_bitlen + padding_bitlen + ri_bitlen)) | + (mac->csirs_measurements.rank_indicator << (cqi_bitlen + pmi_x2_bitlen + pmi_x1_bitlen + padding_bitlen)) | + (mac->csirs_measurements.i1 << (cqi_bitlen + pmi_x2_bitlen)) | + (mac->csirs_measurements.i2 << (cqi_bitlen)) | + (mac->csirs_measurements.cqi); + } + temp_payload_1 = reverse_bits(temp_payload_1, p1_bits); + temp_payload_2 = reverse_bits(temp_payload_2, p2_bits); LOG_D(NR_MAC, "cri_bitlen = %d\n", cri_bitlen); LOG_D(NR_MAC, "ri_bitlen = %d\n", ri_bitlen); LOG_D(NR_MAC, "pmi_x1_bitlen = %d\n", pmi_x1_bitlen); LOG_D(NR_MAC, "pmi_x2_bitlen = %d\n", pmi_x2_bitlen); LOG_D(NR_MAC, "cqi_bitlen = %d\n", cqi_bitlen); - LOG_D(NR_MAC, "csi_part1_payload = 0x%lx\n", temp_payload); - LOG_D(NR_MAC, "n_bits = %d\n", n_bits); - + LOG_D(NR_MAC, "csi_part1_payload = 0x%lx\n", temp_payload_1); + LOG_D(NR_MAC, "csi_part2_payload = 0x%lx\n", temp_payload_2); + LOG_D(NR_MAC, "part1_bits = %d\n", p1_bits); + LOG_D(NR_MAC, "part2_bits = %d\n", p2_bits); break; } } } } - pucch->csi_part1_payload = temp_payload; - return n_bits; + AssertFatal(p1_bits <= 32 && p2_bits <= 32, "Not supporting CSI report with more than 32 bits\n"); + csi_payload_t csi = {.part1_payload = temp_payload_1, .part2_payload = temp_payload_2, .p1_bits = p1_bits, csi.p2_bits = p2_bits}; + return csi; } -uint8_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac, - PUCCH_sched_t *pucch, - struct NR_CSI_ReportConfig *csi_reportconfig, - NR_CSI_ResourceConfigId_t csi_ResourceConfigId, - NR_CSI_MeasConfig_t *csi_MeasConfig) { - +csi_payload_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac, + struct NR_CSI_ReportConfig *csi_reportconfig, + NR_CSI_ResourceConfigId_t csi_ResourceConfigId, + const NR_CSI_MeasConfig_t *csi_MeasConfig) +{ int n_bits = 0; uint64_t temp_payload = 0; @@ -2875,9 +2921,9 @@ uint8_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac, } } } - - pucch->csi_part1_payload = temp_payload; - return n_bits; + AssertFatal(n_bits <= 32, "Not supporting CSI report with more than 32 bits\n"); + csi_payload_t csi = {.part1_payload = temp_payload, .p1_bits = n_bits, csi.p2_bits = 0}; + return csi; } // returns index from RSRP @@ -4027,6 +4073,7 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d &tda_info, &pdu->pusch_config_pdu, NULL, + NULL, &rar_grant, rnti, NR_SearchSpace__searchSpaceType_PR_common, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 54065ad757..5b89fe2918 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -515,6 +515,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, NR_tda_info_t *tda_info, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, dci_pdu_rel15_t *dci, + csi_payload_t *csi_report, RAR_grant_t *rar_grant, uint16_t rnti, int ss_type, @@ -631,6 +632,38 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, pusch_config_pdu->tbslbrm = 0; } else if (dci) { + + if (dci->csi_request.nbits > 0 && dci->csi_request.val > 0) { + AssertFatal(csi_report, "CSI report needs to be present in case of CSI request\n"); + pusch_config_pdu->pusch_uci.csi_part1_bit_length = csi_report->p1_bits; + pusch_config_pdu->pusch_uci.csi_part1_payload = csi_report->part1_payload; + pusch_config_pdu->pusch_uci.csi_part2_bit_length = csi_report->p2_bits; + pusch_config_pdu->pusch_uci.csi_part2_payload = csi_report->part2_payload; + AssertFatal(pusch_Config && pusch_Config->uci_OnPUSCH, + "UCI on PUSCH need to be configured\n"); + pusch_config_pdu->pusch_uci.alpha_scaling = pusch_Config->uci_OnPUSCH->choice.setup->scaling; + AssertFatal(pusch_Config->uci_OnPUSCH->choice.setup->betaOffsets && + pusch_Config->uci_OnPUSCH->choice.setup->betaOffsets->present == NR_UCI_OnPUSCH__betaOffsets_PR_semiStatic, + "Only semistatic beta offset is supported\n"); + NR_BetaOffsets_t *beta_offsets = pusch_Config->uci_OnPUSCH->choice.setup->betaOffsets->choice.semiStatic; + pusch_config_pdu->pusch_uci.beta_offset_harq_ack = pusch_config_pdu->pusch_uci.harq_ack_bit_length > 2 ? + (pusch_config_pdu->pusch_uci.harq_ack_bit_length < 12 ? *beta_offsets->betaOffsetACK_Index2 : + *beta_offsets->betaOffsetACK_Index3) : + *beta_offsets->betaOffsetACK_Index1; + pusch_config_pdu->pusch_uci.beta_offset_csi1 = pusch_config_pdu->pusch_uci.csi_part1_bit_length < 12 ? + *beta_offsets->betaOffsetCSI_Part1_Index1 : + *beta_offsets->betaOffsetCSI_Part1_Index2; + pusch_config_pdu->pusch_uci.beta_offset_csi2 = pusch_config_pdu->pusch_uci.csi_part2_bit_length < 12 ? + *beta_offsets->betaOffsetCSI_Part2_Index1 : + *beta_offsets->betaOffsetCSI_Part2_Index2; + } + else { + pusch_config_pdu->pusch_uci.csi_part1_bit_length = 0; + pusch_config_pdu->pusch_uci.csi_part2_bit_length = 0; + } + + pusch_config_pdu->pusch_uci.harq_ack_bit_length = 0; + pusch_config_pdu->bwp_start = current_UL_BWP->BWPStart; pusch_config_pdu->bwp_size = current_UL_BWP->BWPSize; @@ -891,6 +924,47 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, return 0; } +csi_payload_t nr_ue_aperiodic_csi_reporting(NR_UE_MAC_INST_t *mac, dci_field_t csi_request, int tda, long *k2) +{ + NR_CSI_AperiodicTriggerStateList_t *aperiodicTriggerStateList = mac->sc_info.aperiodicTriggerStateList; + AssertFatal(aperiodicTriggerStateList, "Received CSI request via DCI but aperiodicTriggerStateList is not present\n"); + int n_states = aperiodicTriggerStateList->list.count; + int n_ts = csi_request.nbits; + csi_payload_t csi = {0}; + AssertFatal(n_states <= ((1 << n_ts) - 1), "Case of subselection indication of trigger states not supported yet\n"); + int num_trig = 0; + for (int i = 0; i < n_ts; i++) { + // A non-zero codepoint of the CSI request field in the DCI is mapped to a CSI triggering state + // according to the order of the associated positions of the up to (2^n_ts -1) trigger states + // in CSI-AperiodicTriggerStateList with codepoint 1 mapped to the triggering state in the first position + if (csi_request.val & (1 << i)) { + AssertFatal(num_trig == 0, "Multiplexing more than 1 CSI report is not supported\n"); + NR_CSI_AperiodicTriggerState_t *trigger_state = aperiodicTriggerStateList->list.array[i]; + AssertFatal(trigger_state->associatedReportConfigInfoList.list.count == 1, + "Cannot handle more than 1 report configuration per state\n"); + NR_CSI_AssociatedReportConfigInfo_t *reportconfig = trigger_state->associatedReportConfigInfoList.list.array[0]; + NR_CSI_ReportConfigId_t id = reportconfig->reportConfigId; + NR_CSI_MeasConfig_t *csi_measconfig = mac->sc_info.csi_MeasConfig; + int found = -1; + for (int c = 0; c < csi_measconfig->csi_ReportConfigToAddModList->list.count; c++) { + NR_CSI_ReportConfig_t *report_config = csi_measconfig->csi_ReportConfigToAddModList->list.array[c]; + if (report_config->reportConfigId == id) { + struct NR_CSI_ReportConfig__reportConfigType__aperiodic__reportSlotOffsetList *offset_list = &report_config->reportConfigType.choice.aperiodic->reportSlotOffsetList; + AssertFatal(tda < offset_list->list.count, "TDA index from DCI %d exceeds slot offset list %d\n", tda, offset_list->list.count); + if (k2 == NULL || *k2 < *offset_list->list.array[tda]) + k2 = offset_list->list.array[tda]; + found = c; + break; + } + } + AssertFatal(found >= 0, "Couldn't find csi-ReportConfig with ID %ld\n", id); + num_trig++; + csi = nr_get_csi_payload(mac, found, ON_PUSCH, csi_measconfig); + } + } + return csi; +} + int configure_srs_pdu(NR_UE_MAC_INST_t *mac, NR_SRS_Resource_t *srs_resource, fapi_nr_ul_config_srs_pdu *srs_config_pdu, @@ -2185,7 +2259,7 @@ uint8_t set_csirs_measurement_bitmap(NR_CSI_MeasConfig_t *csi_measconfig, NR_CSI if (csi_res_id > NR_maxNrofCSI_ResourceConfigurations) return meas_bitmap; // CSI-RS for tracking for(int i = 0; i < csi_measconfig->csi_ReportConfigToAddModList->list.count; i++) { - struct NR_CSI_ReportConfig *report_config = csi_measconfig->csi_ReportConfigToAddModList->list.array[i]; + NR_CSI_ReportConfig_t *report_config = csi_measconfig->csi_ReportConfigToAddModList->list.array[i]; if(report_config->resourcesForChannelMeasurement != csi_res_id) continue; // bit 0 RSRP bit 1 RI bit 2 LI bit 3 PMI bit 4 CQI bit 5 i1 From 33b19935fff50b77e4c515aa52721afdb8fed673 Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 25 Oct 2023 17:37:26 +0200 Subject: [PATCH 10/16] uci on pusch at MAC UE --- .../nfapi/public_inc/fapi_nr_ue_interface.h | 1 + openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 2 +- openair2/LAYER2/NR_MAC_UE/mac_proto.h | 2 +- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 107 +++++++++++++++--- 4 files changed, 97 insertions(+), 15 deletions(-) diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index 68e41c160f..d9d63a9704 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -349,6 +349,7 @@ typedef struct uint8_t nr_of_symbols; uint32_t tbslbrm; uint8_t ldpcBaseGraph; + uint8_t ulsch_indicator; //Optional Data only included if indicated in pduBitmap nfapi_nr_ue_pusch_data_t pusch_data; nfapi_nr_ue_pusch_uci_t pusch_uci; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 7f34c25b45..482c49be25 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -126,7 +126,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, AssertFatal(pusch_pdu->pusch_uci.harq_ack_bit_length == 0 && pusch_pdu->pusch_uci.csi_part1_bit_length == 0 && pusch_pdu->pusch_uci.csi_part2_bit_length == 0, - "UCI on PUSCH not supported\n"); + "UCI on PUSCH not supported at PHY\n"); int start_symbol = pusch_pdu->start_symbol_index; uint16_t ul_dmrs_symb_pos = pusch_pdu->ul_dmrs_symb_pos; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index b401bcb20a..307c7faa14 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -243,7 +243,7 @@ and fills the PRACH PDU per each FD occasion. @param slotP Slot index @returns void */ -void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slotP, void *phy_data); +void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slotP); void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot); void nr_schedule_csi_for_im(NR_UE_MAC_INST_t *mac, int frame, int slot); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 5b89fe2918..84434d640a 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -632,7 +632,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, pusch_config_pdu->tbslbrm = 0; } else if (dci) { - + pusch_config_pdu->ulsch_indicator = dci->ulsch_indicator; if (dci->csi_request.nbits > 0 && dci->csi_request.val > 0) { AssertFatal(csi_report, "CSI report needs to be present in case of CSI request\n"); pusch_config_pdu->pusch_uci.csi_part1_bit_length = csi_report->p1_bits; @@ -1421,6 +1421,10 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) ulcfg_pdu++; } release_ul_config(ulcfg_pdu, false); + + if(mac->state >= UE_PERFORMING_RA && mac->state < UE_DETACHING) + nr_ue_pucch_scheduler(mac, frame_tx, slot_tx); + if (mac->if_module != NULL && mac->if_module->scheduled_response != NULL) { LOG_D(NR_MAC, "3# scheduled_response transmitted,%d, %d\n", frame_tx, slot_tx); nr_scheduled_response_t scheduled_response = {.ul_config = mac->ul_config_request + slot_tx, @@ -1459,9 +1463,6 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) nr_timer_start(&sched_info->Bj_timer); } } - - if(mac->state >= UE_PERFORMING_RA && mac->state < UE_DETACHING) - nr_ue_pucch_scheduler(mac, frame_tx, slot_tx, ul_info->phy_data); } static uint8_t nr_locate_BsrIndexByBufferSize(const uint32_t *table, int size, int value) @@ -2082,7 +2083,89 @@ void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac) LOG_D(NR_MAC,"Map SSB to RO done\n"); } -void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slotP, void *phy_data) +static bool schedule_uci_on_pusch(NR_UE_MAC_INST_t *mac, frame_t frame_tx, int slot_tx, const PUCCH_sched_t *pucch) +{ + fapi_nr_ul_config_request_pdu_t *ulcfg_pdu = lockGet_ul_iterator(mac, frame_tx, slot_tx); + if (!ulcfg_pdu) + return NULL; + + nfapi_nr_ue_pusch_pdu_t *pusch_pdu = NULL; + while (ulcfg_pdu->pdu_type != FAPI_NR_END) { + if (ulcfg_pdu->pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH) { + int start_pusch = ulcfg_pdu->pusch_config_pdu.start_symbol_index; + int nsymb_pusch = ulcfg_pdu->pusch_config_pdu.nr_of_symbols; + int end_pusch = start_pusch + nsymb_pusch; + NR_PUCCH_Resource_t *pucchres = pucch->pucch_resource; + int nr_of_symbols = 0; + int start_symbol_index = 0; + switch(pucchres->format.present) { + case NR_PUCCH_Resource__format_PR_format0 : + nr_of_symbols = pucchres->format.choice.format0->nrofSymbols; + start_symbol_index = pucchres->format.choice.format0->startingSymbolIndex; + break; + case NR_PUCCH_Resource__format_PR_format1 : + nr_of_symbols = pucchres->format.choice.format1->nrofSymbols; + start_symbol_index = pucchres->format.choice.format1->startingSymbolIndex; + break; + case NR_PUCCH_Resource__format_PR_format2 : + nr_of_symbols = pucchres->format.choice.format2->nrofSymbols; + start_symbol_index = pucchres->format.choice.format2->startingSymbolIndex; + break; + case NR_PUCCH_Resource__format_PR_format3 : + nr_of_symbols = pucchres->format.choice.format3->nrofSymbols; + start_symbol_index = pucchres->format.choice.format3->startingSymbolIndex; + break; + case NR_PUCCH_Resource__format_PR_format4 : + nr_of_symbols = pucchres->format.choice.format4->nrofSymbols; + start_symbol_index = pucchres->format.choice.format4->startingSymbolIndex; + break; + default : + AssertFatal(false, "Undefined PUCCH format \n"); + } + int final_symbol = nr_of_symbols + start_symbol_index; + // PUCCH overlapping in time with PUSCH + if (start_symbol_index < end_pusch && final_symbol > start_pusch) { + pusch_pdu = &ulcfg_pdu->pusch_config_pdu; + break; + } + } + ulcfg_pdu++; + } + + if (!pusch_pdu) { + release_ul_config(ulcfg_pdu, false); + return false; + } + + // If a UE would transmit on a serving cell a PUSCH without UL-SCH that overlaps with a PUCCH transmission + // on a serving cell that includes positive SR information, the UE does not transmit the PUSCH. + if (pusch_pdu && pusch_pdu->ulsch_indicator == 0 && pucch->sr_payload == 1) { + release_ul_config(ulcfg_pdu, false); + return false; + } + + // - UE multiplexes only HARQ-ACK information, if any, from the UCI in the PUSCH transmission + // and does not transmit the PUCCH if the UE multiplexes aperiodic or semi-persistent CSI reports in the PUSCH + + // - UE multiplexes only HARQ-ACK information and CSI reports, if any, from the UCI in the PUSCH transmission + // and does not transmit the PUCCH if the UE does not multiplex aperiodic or semi-persistent CSI reports in the PUSCH + bool mux_done = false; + if (pucch->n_harq > 0) { + pusch_pdu->pusch_uci.harq_ack_bit_length = pucch->n_harq; + pusch_pdu->pusch_uci.harq_payload = pucch->ack_payload; + mux_done = true; + } + if (pusch_pdu->pusch_uci.csi_part1_bit_length == 0 && pusch_pdu->pusch_uci.csi_part2_bit_length == 0) { + // To support this we would need to shift some bits into CSI part2 -> need to change the logic + AssertFatal(pucch->n_csi == 0, "Multiplexing periodic CSI on PUSCH not supported\n"); + } + + release_ul_config(ulcfg_pdu, false); + // only use PUSCH if any mux is done otherwise send PUCCH + return mux_done; +} + +void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slotP) { PUCCH_sched_t pucch[3] = {0}; // TODO the size might change in the future in case of multiple SR or multiple CSI in a slot @@ -2118,6 +2201,7 @@ void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slotP, voi if (num_res > 1) multiplex_pucch_resource(mac, pucch, num_res); + for (int j = 0; j < num_res; j++) { if (pucch[j].n_harq + pucch[j].n_sr + pucch[j].n_csi != 0) { LOG_D(NR_MAC, @@ -2130,6 +2214,11 @@ void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slotP, voi mac->nr_ue_emul_l1.num_srs = pucch[j].n_sr; mac->nr_ue_emul_l1.num_harqs = pucch[j].n_harq; mac->nr_ue_emul_l1.num_csi_reports = pucch[j].n_csi; + + // checking if we need to schedule pucch[j] on PUSCH + if (schedule_uci_on_pusch(mac, frameP, slotP, &pucch[j])) + continue; + fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PUCCH); if (!pdu) { LOG_E(NR_MAC, "Error in pucch allocation\n"); @@ -2145,14 +2234,6 @@ void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slotP, voi remove_ul_config_last_item(pdu); release_ul_config(pdu, false); } - if (mac->if_module != NULL && mac->if_module->scheduled_response != NULL) { - nr_scheduled_response_t scheduled_response = {.ul_config = mac->ul_config_request + slotP, - .mac = mac, - .module_id = mac->ue_id, - .CC_id = 0 /*TBR fix*/, - .phy_data = phy_data}; - mac->if_module->scheduled_response(&scheduled_response); - } } } From c985a794c7767a2f6850b7a55edc10ba154716b7 Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 5 Feb 2024 09:55:39 +0100 Subject: [PATCH 11/16] fix UE uci on PUSCH config --- openair2/LAYER2/NR_MAC_UE/config_ue.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 77f53a32a5..d63a8ff46a 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -952,13 +952,15 @@ static void setup_puschconfig(NR_PUSCH_Config_t *source, NR_PUSCH_Config_t *targ if (source->uci_OnPUSCH->present == NR_SetupRelease_UCI_OnPUSCH_PR_release) asn1cFreeStruc(asn_DEF_NR_UCI_OnPUSCH, target->uci_OnPUSCH); if (source->uci_OnPUSCH->present == NR_SetupRelease_UCI_OnPUSCH_PR_setup) { - if (target->uci_OnPUSCH) { - target->uci_OnPUSCH->choice.setup->scaling = source->uci_OnPUSCH->choice.setup->scaling; - if (source->uci_OnPUSCH->choice.setup->betaOffsets) - UPDATE_IE(target->uci_OnPUSCH->choice.setup->betaOffsets, - source->uci_OnPUSCH->choice.setup->betaOffsets, - struct NR_UCI_OnPUSCH__betaOffsets); + if (!target->uci_OnPUSCH) { + target->uci_OnPUSCH = calloc(1, sizeof(*target->uci_OnPUSCH)); + target->uci_OnPUSCH->choice.setup = calloc(1, sizeof(*target->uci_OnPUSCH->choice.setup)); } + target->uci_OnPUSCH->choice.setup->scaling = source->uci_OnPUSCH->choice.setup->scaling; + if (source->uci_OnPUSCH->choice.setup->betaOffsets) + UPDATE_IE(target->uci_OnPUSCH->choice.setup->betaOffsets, + source->uci_OnPUSCH->choice.setup->betaOffsets, + struct NR_UCI_OnPUSCH__betaOffsets); } } } From 12e1045d2a003230cc7339dd1c7268a4f2271dcb Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 5 Feb 2024 10:44:43 +0100 Subject: [PATCH 12/16] fix for MAC template with CSI report config --- openair2/LAYER2/NR_MAC_COMMON/nr_mac.h | 1 + openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 16 ++++++------ openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h | 2 +- openair2/LAYER2/NR_MAC_UE/config_ue.c | 9 ++++--- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 26 +++++++++++++------ .../LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 2 +- 6 files changed, 35 insertions(+), 21 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index 6202303d65..c8d8232382 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -501,6 +501,7 @@ typedef struct{ } CSI_Meas_bitlen_t; typedef struct nr_csi_report { + NR_CSI_ReportConfigId_t reportConfigId; NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type; long periodicity; uint16_t offset; diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index df79cbcabd..cdd55fc2d7 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -5028,7 +5028,7 @@ void compute_csi_bitlen(const NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report // for each CSI measurement report configuration (list of CSI-ReportConfig) LOG_D(NR_MAC,"Searching %d csi_reports\n",csi_MeasConfig->csi_ReportConfigToAddModList->list.count); - for (csi_report_id=0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){ + for (csi_report_id = 0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++) { struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]; // MAC structure for CSI measurement reports (per UE and per report) nr_csi_report_t *csi_report = &csi_report_template[csi_report_id]; @@ -5051,6 +5051,7 @@ void compute_csi_bitlen(const NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report reportQuantity_type = csi_reportconfig->reportQuantity.present; csi_report->reportQuantity_type = reportQuantity_type; + csi_report->reportConfigId = csi_reportconfig->reportConfigId; // setting the CSI or SSB index list if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == csi_report->reportQuantity_type) { @@ -5115,21 +5116,21 @@ void compute_csi_bitlen(const NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report } } -uint16_t nr_get_csi_bitlen(nr_csi_report_t *csi_report_template, uint8_t csi_report_id) { - +uint16_t nr_get_csi_bitlen(nr_csi_report_t *csi_report) +{ uint16_t csi_bitlen = 0; uint16_t max_bitlen = 0; L1_RSRP_bitlen_t *CSI_report_bitlen = NULL; CSI_Meas_bitlen_t *csi_meas_bitlen = NULL; - if (csi_report_template[csi_report_id].reportQuantity_type == NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP || - csi_report_template[csi_report_id].reportQuantity_type == NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP) { - CSI_report_bitlen = &(csi_report_template[csi_report_id].CSI_report_bitlen); // This might need to be moodif for Aperiodic CSI-RS measurements + if (csi_report->reportQuantity_type == NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP || + csi_report->reportQuantity_type == NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP) { + CSI_report_bitlen = &(csi_report->CSI_report_bitlen); // This might need to be moodif for Aperiodic CSI-RS measurements csi_bitlen += ((CSI_report_bitlen->cri_ssbri_bitlen * CSI_report_bitlen->nb_ssbri_cri) + CSI_report_bitlen->rsrp_bitlen +(CSI_report_bitlen->diff_rsrp_bitlen * (CSI_report_bitlen->nb_ssbri_cri -1 ))); } else { - csi_meas_bitlen = &(csi_report_template[csi_report_id].csi_meas_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements + csi_meas_bitlen = &(csi_report->csi_meas_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements uint16_t temp_bitlen; for (int i = 0; i < 8; i++) { temp_bitlen = (csi_meas_bitlen->cri_bitlen+ @@ -5143,7 +5144,6 @@ uint16_t nr_get_csi_bitlen(nr_csi_report_t *csi_report_template, uint8_t csi_rep } csi_bitlen += max_bitlen; } - return csi_bitlen; } diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index dc9285bc3f..617aa64be2 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -309,7 +309,7 @@ void compute_cqi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, void compute_csi_bitlen(const NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report_t *csi_report_template); -uint16_t nr_get_csi_bitlen(nr_csi_report_t *csi_report_template, uint8_t csi_report_id); +uint16_t nr_get_csi_bitlen(nr_csi_report_t *csi_report); uint16_t compute_PDU_length(uint32_t num_TLV, uint16_t total_length); diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index d63a8ff46a..7fd87081ee 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -1964,10 +1964,13 @@ static void configure_csiconfig(NR_UE_ServingCell_Info_t *sc_info, struct NR_Set } } -static void configure_servingcell_info(NR_UE_ServingCell_Info_t *sc_info, NR_ServingCellConfig_t *scd) +static void configure_servingcell_info(NR_UE_MAC_INST_t *mac, NR_ServingCellConfig_t *scd) { - if (scd->csi_MeasConfig) + NR_UE_ServingCell_Info_t *sc_info = &mac->sc_info; + if (scd->csi_MeasConfig) { configure_csiconfig(sc_info, scd->csi_MeasConfig); + compute_csi_bitlen(sc_info->csi_MeasConfig, mac->csi_report_template); + } if (scd->supplementaryUplink) UPDATE_IE(sc_info->supplementaryUplink, scd->supplementaryUplink, NR_UplinkConfig_t); @@ -2228,7 +2231,7 @@ void nr_rrc_mac_config_req_cg(module_id_t module_id, handle_reconfiguration_with_sync(mac, cc_idP, spCellConfig->reconfigurationWithSync); } if (scd) { - configure_servingcell_info(&mac->sc_info, scd); + configure_servingcell_info(mac, scd); configure_BWPs(mac, scd); } } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 1c3ee94cec..94cfc384b0 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2805,9 +2805,14 @@ csi_payload_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac, if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_ResourceSetId == *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0])) { - nr_csi_report_t *csi_report = &mac->csi_report_template[csi_idx]; - compute_csi_bitlen(csi_MeasConfig, mac->csi_report_template); - + nr_csi_report_t *csi_report = NULL; + for (int i = 0; i < MAX_CSI_REPORTCONFIG; i++) { + if (mac->csi_report_template[i].reportConfigId == csi_reportconfig->reportConfigId) { + csi_report = &mac->csi_report_template[i]; + break; + } + } + AssertFatal(csi_report, "Couldn't find CSI report with ID %ld\n", csi_reportconfig->reportConfigId); int cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen; int ri_bitlen = csi_report->csi_meas_bitlen.ri_bitlen; int pmi_x1_bitlen = csi_report->csi_meas_bitlen.pmi_x1_bitlen[mac->csirs_measurements.rank_indicator]; @@ -2837,7 +2842,7 @@ csi_payload_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac, mac->csirs_measurements.i2; } else { - p1_bits = nr_get_csi_bitlen(mac->csi_report_template, csi_idx); + p1_bits = nr_get_csi_bitlen(csi_report); padding_bitlen = p1_bits - (cri_bitlen + ri_bitlen + pmi_x1_bitlen + pmi_x2_bitlen + cqi_bitlen); temp_payload_1 = (0/*mac->csi_measurements.cri*/ << (cqi_bitlen + pmi_x2_bitlen + pmi_x1_bitlen + padding_bitlen + ri_bitlen)) | (mac->csirs_measurements.rank_indicator << (cqi_bitlen + pmi_x2_bitlen + pmi_x1_bitlen + padding_bitlen)) | @@ -2884,10 +2889,15 @@ csi_payload_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac, if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_ResourceSetId == *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0])) { - nr_csi_report_t *csi_report = &mac->csi_report_template[csi_idx]; - compute_csi_bitlen(csi_MeasConfig, mac->csi_report_template); - n_bits = nr_get_csi_bitlen(mac->csi_report_template, csi_idx); - + nr_csi_report_t *csi_report = NULL; + for (int i = 0; i < MAX_CSI_REPORTCONFIG; i++) { + if (mac->csi_report_template[i].reportConfigId == csi_reportconfig->reportConfigId) { + csi_report = &mac->csi_report_template[i]; + break; + } + } + AssertFatal(csi_report, "Couldn't find CSI report with ID %ld\n", csi_reportconfig->reportConfigId); + n_bits = nr_get_csi_bitlen(csi_report); int cri_ssbri_bitlen = csi_report->CSI_report_bitlen.cri_ssbri_bitlen; int rsrp_bitlen = csi_report->CSI_report_bitlen.rsrp_bitlen; int diff_rsrp_bitlen = csi_report->CSI_report_bitlen.diff_rsrp_bitlen; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index b2a6827d04..20f6810f71 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -273,7 +273,7 @@ void nr_csi_meas_reporting(int Mod_idP, curr_pucch->frame = sched_frame; curr_pucch->ul_slot = sched_slot; curr_pucch->resource_indicator = res_index; - curr_pucch->csi_bits += nr_get_csi_bitlen(UE->csi_report_template, csi_report_id); + curr_pucch->csi_bits += nr_get_csi_bitlen(&UE->csi_report_template[csi_report_id]); curr_pucch->active = true; int bwp_start = ul_bwp->BWPStart; From f5f9983173c2f80e8839064ffe9bd34975e9ee09 Mon Sep 17 00:00:00 2001 From: francescomani Date: Tue, 13 Feb 2024 14:32:27 +0100 Subject: [PATCH 13/16] fix in setup and release of aperiodicTriggerStateList --- openair2/LAYER2/NR_MAC_UE/config_ue.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 7fd87081ee..dbf255524c 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -1836,22 +1836,25 @@ static void configure_csiconfig(NR_UE_ServingCell_Info_t *sc_info, struct NR_Set switch (csi_MeasConfig_sr->present) { case NR_SetupRelease_CSI_MeasConfig_PR_NOTHING: break; - case NR_SetupRelease_CSI_MeasConfig_PR_release : + case NR_SetupRelease_CSI_MeasConfig_PR_release: asn1cFreeStruc(asn_DEF_NR_CSI_MeasConfig, sc_info->csi_MeasConfig); + asn1cFreeStruc(asn_DEF_NR_CSI_AperiodicTriggerStateList, sc_info->aperiodicTriggerStateList); break; - case NR_SetupRelease_CSI_MeasConfig_PR_setup: + case NR_SetupRelease_CSI_MeasConfig_PR_setup: { + NR_CSI_MeasConfig_t *csi_MeasConfig = csi_MeasConfig_sr->choice.setup; + // separately handling aperiodicTriggerStateList + // because it is set directly into sc_info structure + if (csi_MeasConfig->aperiodicTriggerStateList) + HANDLE_SETUPRELEASE_DIRECT(sc_info->aperiodicTriggerStateList, + csi_MeasConfig->aperiodicTriggerStateList, + NR_CSI_AperiodicTriggerStateList_t, + asn_DEF_NR_CSI_AperiodicTriggerStateList); if (!sc_info->csi_MeasConfig) { // setup - UPDATE_IE(sc_info->csi_MeasConfig, csi_MeasConfig_sr->choice.setup, NR_CSI_MeasConfig_t); + UPDATE_IE(sc_info->csi_MeasConfig, csi_MeasConfig, NR_CSI_MeasConfig_t); } else { // modification NR_CSI_MeasConfig_t *target = sc_info->csi_MeasConfig; - NR_CSI_MeasConfig_t *csi_MeasConfig = csi_MeasConfig_sr->choice.setup; if (csi_MeasConfig->reportTriggerSize) UPDATE_IE(target->reportTriggerSize, csi_MeasConfig->reportTriggerSize, long); - if (csi_MeasConfig->aperiodicTriggerStateList) - HANDLE_SETUPRELEASE_DIRECT(sc_info->aperiodicTriggerStateList, - csi_MeasConfig->aperiodicTriggerStateList, - NR_CSI_AperiodicTriggerStateList_t, - asn_DEF_NR_CSI_AperiodicTriggerStateList); if (csi_MeasConfig->semiPersistentOnPUSCH_TriggerStateList) HANDLE_SETUPRELEASE_IE(target->semiPersistentOnPUSCH_TriggerStateList, csi_MeasConfig->semiPersistentOnPUSCH_TriggerStateList, @@ -1959,6 +1962,7 @@ static void configure_csiconfig(NR_UE_ServingCell_Info_t *sc_info, struct NR_Set } } break; + } default: AssertFatal(false, "Invalid case\n"); } From 165afbd5b5d6eee6db1dde465e6c3f3e6259917b Mon Sep 17 00:00:00 2001 From: francescomani Date: Tue, 27 Feb 2024 16:45:41 +0100 Subject: [PATCH 14/16] improve handling of CSI-MeasConfig setup --- openair2/LAYER2/NR_MAC_UE/config_ue.c | 227 +++++++++++++------------- 1 file changed, 115 insertions(+), 112 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index dbf255524c..73f0a3e624 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -1831,6 +1831,117 @@ static void configure_csiim_resource(NR_CSI_IM_Resource_t *target, NR_CSI_IM_Res UPDATE_IE(target->periodicityAndOffset, source->periodicityAndOffset, NR_CSI_ResourcePeriodicityAndOffset_t); } +static void modify_csi_measconfig(NR_CSI_MeasConfig_t *source, NR_CSI_MeasConfig_t *target) +{ + if (source->reportTriggerSize) + UPDATE_IE(target->reportTriggerSize, source->reportTriggerSize, long); + if (source->semiPersistentOnPUSCH_TriggerStateList) + HANDLE_SETUPRELEASE_IE(target->semiPersistentOnPUSCH_TriggerStateList, + source->semiPersistentOnPUSCH_TriggerStateList, + NR_CSI_SemiPersistentOnPUSCH_TriggerStateList_t, + asn_DEF_NR_SetupRelease_CSI_SemiPersistentOnPUSCH_TriggerStateList); + // NZP-CSI-RS-Resources + if (source->nzp_CSI_RS_ResourceToReleaseList) { + RELEASE_IE_FROMLIST(source->nzp_CSI_RS_ResourceToReleaseList, + target->nzp_CSI_RS_ResourceToAddModList, + nzp_CSI_RS_ResourceId); + } + if (source->nzp_CSI_RS_ResourceToAddModList) { + if (!target->nzp_CSI_RS_ResourceToAddModList) + target->nzp_CSI_RS_ResourceToAddModList = calloc(1, sizeof(*target->nzp_CSI_RS_ResourceToAddModList)); + ADDMOD_IE_FROMLIST_WFUNCTION(source->nzp_CSI_RS_ResourceToAddModList, + target->nzp_CSI_RS_ResourceToAddModList, + nzp_CSI_RS_ResourceId, + NR_NZP_CSI_RS_Resource_t, + configure_csirs_resource); + } + // NZP-CSI-RS-ResourceSets + if (source->nzp_CSI_RS_ResourceSetToReleaseList) { + RELEASE_IE_FROMLIST(source->nzp_CSI_RS_ResourceSetToReleaseList, + target->nzp_CSI_RS_ResourceSetToAddModList, + nzp_CSI_ResourceSetId); + } + if (source->nzp_CSI_RS_ResourceSetToAddModList) { + if (!target->nzp_CSI_RS_ResourceSetToAddModList) + target->nzp_CSI_RS_ResourceSetToAddModList = calloc(1, sizeof(*target->nzp_CSI_RS_ResourceSetToAddModList)); + ADDMOD_IE_FROMLIST(source->nzp_CSI_RS_ResourceSetToAddModList, + target->nzp_CSI_RS_ResourceSetToAddModList, + nzp_CSI_ResourceSetId, + NR_NZP_CSI_RS_ResourceSet_t); + } + // CSI-IM-Resource + if (source->csi_IM_ResourceToReleaseList) { + RELEASE_IE_FROMLIST(source->csi_IM_ResourceToReleaseList, + target->csi_IM_ResourceToAddModList, + csi_IM_ResourceId); + } + if (source->csi_IM_ResourceToAddModList) { + if (!target->csi_IM_ResourceToAddModList) + target->csi_IM_ResourceToAddModList = calloc(1, sizeof(*target->csi_IM_ResourceToAddModList)); + ADDMOD_IE_FROMLIST_WFUNCTION(source->csi_IM_ResourceToAddModList, + target->csi_IM_ResourceToAddModList, + csi_IM_ResourceId, + NR_CSI_IM_Resource_t, + configure_csiim_resource); + } + // CSI-IM-ResourceSets + if (source->csi_IM_ResourceSetToReleaseList) { + RELEASE_IE_FROMLIST(source->csi_IM_ResourceSetToReleaseList, + target->csi_IM_ResourceSetToAddModList, + csi_IM_ResourceSetId); + } + if (source->csi_IM_ResourceSetToAddModList) { + if (!target->csi_IM_ResourceSetToAddModList) + target->csi_IM_ResourceSetToAddModList = calloc(1, sizeof(*target->csi_IM_ResourceSetToAddModList)); + ADDMOD_IE_FROMLIST(source->csi_IM_ResourceSetToAddModList, + target->csi_IM_ResourceSetToAddModList, + csi_IM_ResourceSetId, + NR_CSI_IM_ResourceSet_t); + } + // CSI-SSB-ResourceSets + if (source->csi_SSB_ResourceSetToReleaseList) { + RELEASE_IE_FROMLIST(source->csi_SSB_ResourceSetToReleaseList, + target->csi_SSB_ResourceSetToAddModList, + csi_SSB_ResourceSetId); + } + if (source->csi_SSB_ResourceSetToAddModList) { + if (!target->csi_SSB_ResourceSetToAddModList) + target->csi_SSB_ResourceSetToAddModList = calloc(1, sizeof(*target->csi_SSB_ResourceSetToAddModList)); + ADDMOD_IE_FROMLIST(source->csi_SSB_ResourceSetToAddModList, + target->csi_SSB_ResourceSetToAddModList, + csi_SSB_ResourceSetId, + NR_CSI_SSB_ResourceSet_t); + } + // CSI-ResourceConfigs + if (source->csi_ResourceConfigToReleaseList) { + RELEASE_IE_FROMLIST(source->csi_ResourceConfigToReleaseList, + target->csi_ResourceConfigToAddModList, + csi_ResourceConfigId); + } + if (source->csi_ResourceConfigToAddModList) { + if (!target->csi_ResourceConfigToAddModList) + target->csi_ResourceConfigToAddModList = calloc(1, sizeof(*target->csi_ResourceConfigToAddModList)); + ADDMOD_IE_FROMLIST(source->csi_ResourceConfigToAddModList, + target->csi_ResourceConfigToAddModList, + csi_ResourceConfigId, + NR_CSI_ResourceConfig_t); + } + // CSI-ReportConfigs + if (source->csi_ReportConfigToReleaseList) { + RELEASE_IE_FROMLIST(source->csi_ReportConfigToReleaseList, + target->csi_ReportConfigToAddModList, + reportConfigId); + } + if (source->csi_ReportConfigToAddModList) { + if (!target->csi_ReportConfigToAddModList) + target->csi_ReportConfigToAddModList = calloc(1, sizeof(*target->csi_ReportConfigToAddModList)); + ADDMOD_IE_FROMLIST(source->csi_ReportConfigToAddModList, + target->csi_ReportConfigToAddModList, + reportConfigId, + NR_CSI_ReportConfig_t); + } +} + static void configure_csiconfig(NR_UE_ServingCell_Info_t *sc_info, struct NR_SetupRelease_CSI_MeasConfig *csi_MeasConfig_sr) { switch (csi_MeasConfig_sr->present) { @@ -1841,125 +1952,17 @@ static void configure_csiconfig(NR_UE_ServingCell_Info_t *sc_info, struct NR_Set asn1cFreeStruc(asn_DEF_NR_CSI_AperiodicTriggerStateList, sc_info->aperiodicTriggerStateList); break; case NR_SetupRelease_CSI_MeasConfig_PR_setup: { - NR_CSI_MeasConfig_t *csi_MeasConfig = csi_MeasConfig_sr->choice.setup; // separately handling aperiodicTriggerStateList // because it is set directly into sc_info structure - if (csi_MeasConfig->aperiodicTriggerStateList) + if (csi_MeasConfig_sr->choice.setup->aperiodicTriggerStateList) HANDLE_SETUPRELEASE_DIRECT(sc_info->aperiodicTriggerStateList, - csi_MeasConfig->aperiodicTriggerStateList, + csi_MeasConfig_sr->choice.setup->aperiodicTriggerStateList, NR_CSI_AperiodicTriggerStateList_t, asn_DEF_NR_CSI_AperiodicTriggerStateList); if (!sc_info->csi_MeasConfig) { // setup - UPDATE_IE(sc_info->csi_MeasConfig, csi_MeasConfig, NR_CSI_MeasConfig_t); + UPDATE_IE(sc_info->csi_MeasConfig, csi_MeasConfig_sr->choice.setup, NR_CSI_MeasConfig_t); } else { // modification - NR_CSI_MeasConfig_t *target = sc_info->csi_MeasConfig; - if (csi_MeasConfig->reportTriggerSize) - UPDATE_IE(target->reportTriggerSize, csi_MeasConfig->reportTriggerSize, long); - if (csi_MeasConfig->semiPersistentOnPUSCH_TriggerStateList) - HANDLE_SETUPRELEASE_IE(target->semiPersistentOnPUSCH_TriggerStateList, - csi_MeasConfig->semiPersistentOnPUSCH_TriggerStateList, - NR_CSI_SemiPersistentOnPUSCH_TriggerStateList_t, - asn_DEF_NR_SetupRelease_CSI_SemiPersistentOnPUSCH_TriggerStateList); - // NZP-CSI-RS-Resources - if (csi_MeasConfig->nzp_CSI_RS_ResourceToReleaseList) { - RELEASE_IE_FROMLIST(csi_MeasConfig->nzp_CSI_RS_ResourceToReleaseList, - target->nzp_CSI_RS_ResourceToAddModList, - nzp_CSI_RS_ResourceId); - } - if (csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList) { - if (!target->nzp_CSI_RS_ResourceToAddModList) - target->nzp_CSI_RS_ResourceToAddModList = calloc(1, sizeof(*target->nzp_CSI_RS_ResourceToAddModList)); - ADDMOD_IE_FROMLIST_WFUNCTION(csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList, - target->nzp_CSI_RS_ResourceToAddModList, - nzp_CSI_RS_ResourceId, - NR_NZP_CSI_RS_Resource_t, - configure_csirs_resource); - } - // NZP-CSI-RS-ResourceSets - if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToReleaseList) { - RELEASE_IE_FROMLIST(csi_MeasConfig->nzp_CSI_RS_ResourceSetToReleaseList, - target->nzp_CSI_RS_ResourceSetToAddModList, - nzp_CSI_ResourceSetId); - } - if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList) { - if (!target->nzp_CSI_RS_ResourceSetToAddModList) - target->nzp_CSI_RS_ResourceSetToAddModList = calloc(1, sizeof(*target->nzp_CSI_RS_ResourceSetToAddModList)); - ADDMOD_IE_FROMLIST(csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList, - target->nzp_CSI_RS_ResourceSetToAddModList, - nzp_CSI_ResourceSetId, - NR_NZP_CSI_RS_ResourceSet_t); - } - // CSI-IM-Resource - if (csi_MeasConfig->csi_IM_ResourceToReleaseList) { - RELEASE_IE_FROMLIST(csi_MeasConfig->csi_IM_ResourceToReleaseList, - target->csi_IM_ResourceToAddModList, - csi_IM_ResourceId); - } - if (csi_MeasConfig->csi_IM_ResourceToAddModList) { - if (!target->csi_IM_ResourceToAddModList) - target->csi_IM_ResourceToAddModList = calloc(1, sizeof(*target->csi_IM_ResourceToAddModList)); - ADDMOD_IE_FROMLIST_WFUNCTION(csi_MeasConfig->csi_IM_ResourceToAddModList, - target->csi_IM_ResourceToAddModList, - csi_IM_ResourceId, - NR_CSI_IM_Resource_t, - configure_csiim_resource); - } - // CSI-IM-ResourceSets - if (csi_MeasConfig->csi_IM_ResourceSetToReleaseList) { - RELEASE_IE_FROMLIST(csi_MeasConfig->csi_IM_ResourceSetToReleaseList, - target->csi_IM_ResourceSetToAddModList, - csi_IM_ResourceSetId); - } - if (csi_MeasConfig->csi_IM_ResourceSetToAddModList) { - if (!target->csi_IM_ResourceSetToAddModList) - target->csi_IM_ResourceSetToAddModList = calloc(1, sizeof(*target->csi_IM_ResourceSetToAddModList)); - ADDMOD_IE_FROMLIST(csi_MeasConfig->csi_IM_ResourceSetToAddModList, - target->csi_IM_ResourceSetToAddModList, - csi_IM_ResourceSetId, - NR_CSI_IM_ResourceSet_t); - } - // CSI-SSB-ResourceSets - if (csi_MeasConfig->csi_SSB_ResourceSetToReleaseList) { - RELEASE_IE_FROMLIST(csi_MeasConfig->csi_SSB_ResourceSetToReleaseList, - target->csi_SSB_ResourceSetToAddModList, - csi_SSB_ResourceSetId); - } - if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList) { - if (!target->csi_SSB_ResourceSetToAddModList) - target->csi_SSB_ResourceSetToAddModList = calloc(1, sizeof(*target->csi_SSB_ResourceSetToAddModList)); - ADDMOD_IE_FROMLIST(csi_MeasConfig->csi_SSB_ResourceSetToAddModList, - target->csi_SSB_ResourceSetToAddModList, - csi_SSB_ResourceSetId, - NR_CSI_SSB_ResourceSet_t); - } - // CSI-ResourceConfigs - if (csi_MeasConfig->csi_ResourceConfigToReleaseList) { - RELEASE_IE_FROMLIST(csi_MeasConfig->csi_ResourceConfigToReleaseList, - target->csi_ResourceConfigToAddModList, - csi_ResourceConfigId); - } - if (csi_MeasConfig->csi_ResourceConfigToAddModList) { - if (!target->csi_ResourceConfigToAddModList) - target->csi_ResourceConfigToAddModList = calloc(1, sizeof(*target->csi_ResourceConfigToAddModList)); - ADDMOD_IE_FROMLIST(csi_MeasConfig->csi_ResourceConfigToAddModList, - target->csi_ResourceConfigToAddModList, - csi_ResourceConfigId, - NR_CSI_ResourceConfig_t); - } - // CSI-ReportConfigs - if (csi_MeasConfig->csi_ReportConfigToReleaseList) { - RELEASE_IE_FROMLIST(csi_MeasConfig->csi_ReportConfigToReleaseList, - target->csi_ReportConfigToAddModList, - reportConfigId); - } - if (csi_MeasConfig->csi_ReportConfigToAddModList) { - if (!target->csi_ReportConfigToAddModList) - target->csi_ReportConfigToAddModList = calloc(1, sizeof(*target->csi_ReportConfigToAddModList)); - ADDMOD_IE_FROMLIST(csi_MeasConfig->csi_ReportConfigToAddModList, - target->csi_ReportConfigToAddModList, - reportConfigId, - NR_CSI_ReportConfig_t); - } + modify_csi_measconfig(csi_MeasConfig_sr->choice.setup, sc_info->csi_MeasConfig); } break; } From f94941b5e666d3cc19d28013e6a527d2e47733d7 Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 29 Feb 2024 16:31:58 +0100 Subject: [PATCH 15/16] fix for UCI on PUSCH fapi PDU configuration in case of only HARQ bits --- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 31 ++++++++++++++------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 84434d640a..314f374517 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -639,23 +639,21 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, pusch_config_pdu->pusch_uci.csi_part1_payload = csi_report->part1_payload; pusch_config_pdu->pusch_uci.csi_part2_bit_length = csi_report->p2_bits; pusch_config_pdu->pusch_uci.csi_part2_payload = csi_report->part2_payload; - AssertFatal(pusch_Config && pusch_Config->uci_OnPUSCH, - "UCI on PUSCH need to be configured\n"); - pusch_config_pdu->pusch_uci.alpha_scaling = pusch_Config->uci_OnPUSCH->choice.setup->scaling; - AssertFatal(pusch_Config->uci_OnPUSCH->choice.setup->betaOffsets && - pusch_Config->uci_OnPUSCH->choice.setup->betaOffsets->present == NR_UCI_OnPUSCH__betaOffsets_PR_semiStatic, + AssertFatal(pusch_Config && pusch_Config->uci_OnPUSCH, "UCI on PUSCH need to be configured\n"); + NR_UCI_OnPUSCH_t *onPusch = pusch_Config->uci_OnPUSCH->choice.setup; + AssertFatal(onPusch && + onPusch->betaOffsets && + onPusch->betaOffsets->present == NR_UCI_OnPUSCH__betaOffsets_PR_semiStatic, "Only semistatic beta offset is supported\n"); - NR_BetaOffsets_t *beta_offsets = pusch_Config->uci_OnPUSCH->choice.setup->betaOffsets->choice.semiStatic; - pusch_config_pdu->pusch_uci.beta_offset_harq_ack = pusch_config_pdu->pusch_uci.harq_ack_bit_length > 2 ? - (pusch_config_pdu->pusch_uci.harq_ack_bit_length < 12 ? *beta_offsets->betaOffsetACK_Index2 : - *beta_offsets->betaOffsetACK_Index3) : - *beta_offsets->betaOffsetACK_Index1; + NR_BetaOffsets_t *beta_offsets = onPusch->betaOffsets->choice.semiStatic; + pusch_config_pdu->pusch_uci.beta_offset_csi1 = pusch_config_pdu->pusch_uci.csi_part1_bit_length < 12 ? *beta_offsets->betaOffsetCSI_Part1_Index1 : *beta_offsets->betaOffsetCSI_Part1_Index2; pusch_config_pdu->pusch_uci.beta_offset_csi2 = pusch_config_pdu->pusch_uci.csi_part2_bit_length < 12 ? *beta_offsets->betaOffsetCSI_Part2_Index1 : *beta_offsets->betaOffsetCSI_Part2_Index2; + pusch_config_pdu->pusch_uci.alpha_scaling = onPusch->scaling; } else { pusch_config_pdu->pusch_uci.csi_part1_bit_length = 0; @@ -2153,6 +2151,19 @@ static bool schedule_uci_on_pusch(NR_UE_MAC_INST_t *mac, frame_t frame_tx, int s if (pucch->n_harq > 0) { pusch_pdu->pusch_uci.harq_ack_bit_length = pucch->n_harq; pusch_pdu->pusch_uci.harq_payload = pucch->ack_payload; + NR_PUSCH_Config_t *pusch_Config = mac->current_UL_BWP->pusch_Config; + AssertFatal(pusch_Config && pusch_Config->uci_OnPUSCH, "UCI on PUSCH need to be configured\n"); + NR_UCI_OnPUSCH_t *onPusch = pusch_Config->uci_OnPUSCH->choice.setup; + AssertFatal(onPusch && + onPusch->betaOffsets && + onPusch->betaOffsets->present == NR_UCI_OnPUSCH__betaOffsets_PR_semiStatic, + "Only semistatic beta offset is supported\n"); + NR_BetaOffsets_t *beta_offsets = onPusch->betaOffsets->choice.semiStatic; + pusch_pdu->pusch_uci.beta_offset_harq_ack = pucch->n_harq > 2 ? + (pucch->n_harq < 12 ? *beta_offsets->betaOffsetACK_Index2 : + *beta_offsets->betaOffsetACK_Index3) : + *beta_offsets->betaOffsetACK_Index1; + pusch_pdu->pusch_uci.alpha_scaling = onPusch->scaling; mux_done = true; } if (pusch_pdu->pusch_uci.csi_part1_bit_length == 0 && pusch_pdu->pusch_uci.csi_part2_bit_length == 0) { From 582e8302c6f1098a60573e57c16f178e6b55ebfd Mon Sep 17 00:00:00 2001 From: Anurag Asokan Date: Wed, 21 Feb 2024 15:30:00 +0100 Subject: [PATCH 16/16] LTTng logger (CTF) This commit introduces LTTng logging mechanism which is an open source tracing tool. URL: https://lttng.org/ --- CMakeLists.txt | 9 ++ cmake_targets/build_oai | 11 +++ cmake_targets/tools/build_helper | 91 +++++++++++++++++ common/utils/LOG/DOC/log.md | 1 + common/utils/LOG/DOC/lttng_logs.md | 153 +++++++++++++++++++++++++++++ common/utils/LOG/log.c | 19 ++++ common/utils/LOG/log.h | 55 ++++++++++- common/utils/LOG/lttng-log.h | 44 +++++++++ common/utils/LOG/lttng-tp.c | 34 +++++++ common/utils/LOG/lttng-tp.h | 54 ++++++++++ 10 files changed, 468 insertions(+), 3 deletions(-) create mode 100644 common/utils/LOG/DOC/lttng_logs.md create mode 100644 common/utils/LOG/lttng-log.h create mode 100644 common/utils/LOG/lttng-tp.c create mode 100644 common/utils/LOG/lttng-tp.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 136b2ebd62..03cbc144c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -284,6 +284,7 @@ add_boolean_option(DEBUG_ASN1 False "Enable ASN1 debug logs" OFF) # see common/utils/config.h add_boolean_option(TRACE_ASN1C_ENC_DEC OFF "Enable ASN1 encoder/decoder debug traces via OAI logging system" ON) add_boolean_option(T_TRACER True "Activate the T tracer, a debugging/monitoring framework" ON) +add_boolean_option(ENABLE_LTTNG False "Activate the LTTNG tracer, a debugging/monitoring framework" ON) add_boolean_option(UE_AUTOTEST_TRACE False "Activate UE autotest specific logs" ON) add_boolean_option(UE_DEBUG_TRACE False "Activate UE debug trace" ON) add_boolean_option(UE_TIMING_TRACE False "Activate UE timing trace" ON) @@ -659,6 +660,14 @@ add_library(UTIL ${OPENAIR_DIR}/common/utils/time_meas.c ${OPENAIR_DIR}/common/utils/time_stat.c ) +if (ENABLE_LTTNG) + find_package(LTTngUST 2.3.8 EXACT REQUIRED) + target_sources(UTIL PRIVATE common/utils/LOG/lttng-tp.c) + target_link_libraries(UTIL PUBLIC lttng-ust) +else() + message(STATUS "LTTNG support disabled") +endif() + pkg_check_modules(cap libcap) if (cap_FOUND) # see system.c for more info diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index beb1b51039..4c71ce4c94 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -124,6 +124,8 @@ Options: --disable-cpu-affinity Disables CPU Affinity between UHD/TX/RX Threads (Valid only when deadline scheduler is disabled). By defaulT, CPU Affinity is enabled when not using deadline scheduler. It is enabled only with >2 CPUs. For eNB, CPU_0-> Device library (UHD), CPU_1->TX Threads, CPU_2...CPU_MAX->Rx Threads. For UE, CPU_0->Device Library(UHD), CPU_1..CPU_MAX -> All the UE threads --enable-cpu-affinity +--enable-LTTNG + Enable LTTNG log. While lttng is enabled, T-Tracer will be disabled --disable-T-Tracer Disables the T tracer. --disable-hardware-dependency @@ -353,6 +355,11 @@ function main() { BUILD_DOXYGEN=1 echo_info "Will build doxygen support" shift;; + --enable-LTTNG) + CMAKE_CMD="$CMAKE_CMD -DENABLE_LTTNG=ON -DT_TRACER=OFF" + echo_info "Enable LTTNG tracer" + USE_LTTNG=1 + shift 1;; --disable-T-Tracer) CMAKE_CMD="$CMAKE_CMD -DT_TRACER=False" echo_info "Disabling the T tracer" @@ -454,6 +461,10 @@ function main() { if [ "$INSTALL_EXTERNAL" = "1" ] ; then echo_info "Installing packages" check_install_oai_software + if [ "$USE_LTTNG" = "1" ] ; then + echo_info "installing LTTng" + install_lttng $1 + fi if [ "$HW" == "OAI_USRP" ] ; then echo_info "installing packages for USRP support" check_install_usrp_uhd_driver diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 9c567792f1..041621ffe4 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -704,6 +704,97 @@ install_simde_from_source(){ $SUDO \cp -rv ../simde /usr/include } +install_lttng() { + if [[ "$OS_DISTRO" != "ubuntu" ]]; then + echo_info "LTTng is supported only for ubuntu at the moment." + echo_info $distribution + return + fi + + set +e + $SUDO apt-add-repository ppa:lttng/stable-2.13 -y && apt-get update + $SUDO apt-get install -y lttng-tools lttng-modules-dkms liblttng-ust-dev + if [[ $? > 0 ]]; then + echo "Failed to install LTTng using apt. Installing from source" + install_lttng_deps + install_lttng_from_source + fi + set -e +} + +install_lttng_deps() { + echo "installing dependencies of LTTng" + $SUDO apt-get install uuid-dev libxml2-dev -y +} + +install_lttng_from_source() { + echo "installing LTTng from source" + install_popt_1_18_from_source + install_userspace_rcu + install_lttng_ust_2_13_from_source + install_lttng_tools_2_13_from_source +} + +install_popt_1_18_from_source() { + $SUDO $INSTALLER -y install wget + echo_info "\nInstalling popt_1_18." + cd $(mktemp -d) && + wget http://ftp.rpm.org/popt/releases/popt-1.x/popt-1.18.tar.gz + tar -xf popt-1.18.tar.gz && cd popt-1.18 + ./configure && make -j16 && $SUDO make install +} + +install_userspace_rcu() { + echo_info "\nInstalling U-RCU from source." + cd /tmp + $SUDO rm -rf /tmp/urcu + git clone https://github.com/urcu/userspace-rcu.git /tmp/urcu + cd /tmp/urcu + git checkout stable-0.12 + ./bootstrap && ./configure && make + $SUDO make install + $SUDO ldconfig +} + + +install_lttng_modules_2_13_from_source() { + $SUDO $INSTALLER -y install wget + echo_info "\nInstalling LTTng Modules." + cd $(mktemp -d) && + wget https://lttng.org/files/lttng-modules/lttng-modules-latest-2.13.tar.bz2 && + tar -xf lttng-modules-latest-2.13.tar.bz2 && + cd lttng-modules-2.13.* && + make && + $SUDO make modules_install && + $SUDO depmod -a +} + +install_lttng_ust_2_13_from_source() { + $SUDO $INSTALLER -y install wget + echo_info "\nInstalling LTTng UST." + cd $(mktemp -d) && + wget https://lttng.org/files/lttng-ust/lttng-ust-latest-2.13.tar.bz2 && + tar -xf lttng-ust-latest-2.13.tar.bz2 && + cd lttng-ust-2.13.* && + ./configure --disable-numa && + make && + $SUDO make install && + $SUDO ldconfig +} + +install_lttng_tools_2_13_from_source() { + $SUDO $INSTALLER -y install wget + echo_info "\nInstalling LTTng Tools." + cd $(mktemp -d) && + wget https://lttng.org/files/lttng-tools/lttng-tools-latest-2.13.tar.bz2 && + tar -xf lttng-tools-latest-2.13.tar.bz2 && + cd lttng-tools-2.13.* && + ./configure && + make && + $SUDO make install && + $SUDO ldconfig +} + ################################################# # 2. compile ################################################ diff --git a/common/utils/LOG/DOC/log.md b/common/utils/LOG/DOC/log.md index 4d97e3845d..4209c537f3 100644 --- a/common/utils/LOG/DOC/log.md +++ b/common/utils/LOG/DOC/log.md @@ -15,5 +15,6 @@ By default, this facility is included at build-time and activated at run-time. T * [runtime usage](rtusage.md) * [developer usage](devusage.md) * [module architecture](arch.md) +* [lttng usage](lttng_logs.md) [oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) diff --git a/common/utils/LOG/DOC/lttng_logs.md b/common/utils/LOG/DOC/lttng_logs.md new file mode 100644 index 0000000000..4b4eda43f5 --- /dev/null +++ b/common/utils/LOG/DOC/lttng_logs.md @@ -0,0 +1,153 @@ +# OAI gNB LTTng Tracing Setup Guide + +## Overview + +This guide will walk you through setting up tracing for an OpenAirInterface (OAI) gNB (gNodeB) using LTTng (Linux Trace Toolkit Next Generation) and Babeltrace. +### What is LTTng and Why Use It? + +LTTng, or Linux Trace Toolkit Next Generation, is a powerful logging framework designed for Linux systems. It provides low-overhead tracing capabilities, allowing developers to monitor and analyze system behavior in real-time without significant performance impact. LTTng offers several advantages: + +- **Low Overhead**: LTTng introduces minimal overhead to the system, making it suitable for use in production environments without affecting system performance. + +- **Customizable**: LTTng allows users to define custom tracepoints in their applications, providing fine-grained control over what events to trace and collect. + +- **Scalability**: It can scale to large distributed systems, making it suitable for tracing complex software stacks across multiple nodes. + +## Prerequisites + +- Ubuntu system + +Note: only LTTng 2.3.8 is supported. + +## Building OAI gNB + +1. **Clean and Build OAI gNB with LTTng:** + + 1.1 Install Dependencies + + ```bash + ./build_oai --ninja -I --clean --enable-LTTNG + + ``` + 1.2 Build gNB and nrUE + ``` + ./build_oai --ninja --gNB --nrUE -w SIMU --enable-LTTNG + ``` +## Setting up LTTng + +1. **Start LTTng Session and Relay:** + + ```bash + sudo lttng-sessiond -d + sudo lttng-relayd -d + ``` + +2. **Create Live LTTng Session:** + + ```bash + sudo lttng create my-session --live --set-url=net://127.0.0.1 + ``` + +3. **Enable gNB Trace Events:** + + ```bash + sudo lttng enable-event --userspace OAI:gNB + ``` + +4. **Start LTTng Tracing:** + + ```bash + sudo lttng start + ``` + +## Running the gNB + +1. **Run gNB:** + + ```bash + ./$binary_path -O $configuration_file PARALLEL_SINGLE_THREAD --rfsimulator.serveraddr server --rfsim --sa -E + ``` + +## Verifying Tracepoints + +1. **List Active Tracepoints:** + + ```bash + sudo lttng list -u + ``` + + *Possible Output:* + + ``` + UST events: + ------------- + + PID: 1154722 - Name: /home/firecell/Desktop/FirecellRepos/firecellrd-oai5g-ran/cmake_targets/ran_build/build/nr-softmodem + OAI:gNB (loglevel: TRACE_DEBUG_FUNCTION (12)) (type: tracepoint) + ``` + +## Analyzing Traces + +1. **Install Babeltrace:** + + ```bash + sudo apt-get install babeltrace + ``` + + +2. **Capture Trace Logs Live:** + + - To learn the full path of the trace session: + + ```bash + babeltrace --input-format=lttng-live net://localhost + ``` + + - Trace logs using the full path: + + ```bash + babeltrace --input-format=lttng-live net://localhost/host/firecell-XPS-15-9530/my-session + ``` + + *Possible Output:* + + ``` + [19:35:32.181608002] (+2.664882127) firecell-XPS-15-9530 OAI:gNB: { cpu_id = 10 }, { MODNAME = "OAI-NR_MAC info", EVENTID = -1, SFN = -1, SLOT = -1, FUNCTION = "gNB_dlsch_ulsch_scheduler", LINE = 246, MSG = "Frame.Slot 0.0\n" } + ``` +3. **Capture Trace Logs Offline:** + + - Create an offline trace session with a specified output directory: + + ```bash + sudo lttng create offline_session --output=/home/trace_offline/ + ``` + + - Enable gNB trace events: + + ```bash + sudo lttng enable-event --userspace OAI:gNB + ``` + + - Start capturing trace logs: + + ```bash + sudo lttng start + ``` + + - Stop the trace capture: + + ```bash + sudo lttng stop + ``` + + - Destroy the trace session: + + ```bash + sudo lttng destroy + ``` + + - Use Babeltrace to analyze the captured trace logs: + + ```bash + sudo babeltrace /home/trace_offline/ + ``` diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index a37ec44751..17ffe91c1d 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -603,6 +603,25 @@ void logRecord_mt(const char *file, log_output_memory(c, file,func,line,comp,level,format,args); va_end(args); } +#if ENABLE_LTTNG +void logRecord_lttng(const char *file, const char *func, int line, int comp, int level, const char *format, ...) +{ + log_component_t *c = &g_log->log_component[comp]; + char header[48]; + char buf[MAX_LOG_TOTAL]; + va_list args; + va_start(args, format); + vsnprintf(buf, sizeof(buf) - 1, format, args); + va_end(args); + + if (map_int_to_str(log_level_names, level) != NULL) + snprintf(header, sizeof(header), "OAI-%s %s", c->name, map_int_to_str(log_level_names, level)); + else + snprintf(header, sizeof(header), "OAI-%s", c->name); + + LOG_FC(header, func, line, buf); +} +#endif void vlogRecord_mt(const char *file, const char *func, diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index 249dab5580..6ebc5a4827 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -52,6 +52,9 @@ #endif #include #include +#if ENABLE_LTTNG +#include "lttng-log.h" +#endif /*----------------------------------------------------------------------------*/ #include #ifdef NDEBUG @@ -234,6 +237,10 @@ void logTerm (void); int isLogInitDone (void); void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...) __attribute__ ((format (printf, 6, 7))); void vlogRecord_mt(const char *file, const char *func, int line, int comp, int level, const char *format, va_list args ); +#if ENABLE_LTTNG +void logRecord_lttng(const char *file, const char *func, int line, int comp, int level, const char *format, ...) + __attribute__((format(printf, 6, 7))); +#endif void log_dump(int component, void *buffer, int buffsize,int datatype, const char *format, ... ); int set_log(int component, int level); void set_glog(int level); @@ -425,9 +432,50 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int /* define variable only used in LOG macro's */ #define LOG_VAR(A, B) A B - -#else /* no T_TRACER */ - +#else /* T_TRACER */ +#if ENABLE_LTTNG +#define LOG_E(c, x...) \ + do { \ + if (g_log->log_component[c].level >= OAILOG_ERR) { \ + logRecord_lttng(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_ERR, x); \ + } \ + } while (0) +#define LOG_W(c, x...) \ + do { \ + if (g_log->log_component[c].level >= OAILOG_WARNING) { \ + logRecord_lttng(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_WARNING, x); \ + } \ + } while (0) +#define LOG_A(c, x...) \ + do { \ + if (g_log->log_component[c].level >= OAILOG_ANALYSIS) { \ + logRecord_lttng(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_ANALYSIS, x); \ + } \ + } while (0) +#define LOG_I(c, x...) \ + do { \ + if (g_log->log_component[c].level >= OAILOG_INFO) { \ + logRecord_lttng(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_INFO, x); \ + } \ + } while (0) +#define LOG_D(c, x...) \ + do { \ + if (g_log->log_component[c].level >= OAILOG_DEBUG) { \ + logRecord_lttng(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_DEBUG, x); \ + } \ + } while (0) +#define LOG_T(c, x...) \ + do { \ + if (g_log->log_component[c].level >= OAILOG_TRACE) { \ + logRecord_lttng(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_TRACE, x); \ + } \ + } while (0) +#define LOG_DDUMP(c, b, s, f, x...) \ + do { \ + if (g_log->log_component[c].level >= OAILOG_DEBUG) \ + log_dump(c, b, s, f, x); \ + } while (0) +#else #define LOG_E(c, x...) \ do { \ if (g_log->log_component[c].level >= OAILOG_ERR) \ @@ -469,6 +517,7 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int if (g_log->log_component[c].level >= OAILOG_TRACE) \ logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_TRACE, x); \ } while (0) +#endif #define VLOG(c, l, f, args) \ do { \ diff --git a/common/utils/LOG/lttng-log.h b/common/utils/LOG/lttng-log.h new file mode 100644 index 0000000000..cf5b83fa19 --- /dev/null +++ b/common/utils/LOG/lttng-log.h @@ -0,0 +1,44 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file lttng-log.h +* \brief LTTng Log interface +* \author Anurag Asokan +* \date 2024 +* \version 0.5 +* @ingroup util + +*/ + +#ifndef __LTTNG_LOG_H__ +#define __LTTNG_LOG_H__ +#if ENABLE_LTTNG +#include "lttng-tp.h" + +#define LOG_FC(component, func, line, log) \ + do { \ + tracepoint(OAI, gNB, component, -1, -1, -1, func, line, log); \ + } while (0) +#else +#define LOG_FC(component, func, line, log) +#endif + +#endif /** __LTTNG_LOG_H__ */ diff --git a/common/utils/LOG/lttng-tp.c b/common/utils/LOG/lttng-tp.c new file mode 100644 index 0000000000..2d372958f8 --- /dev/null +++ b/common/utils/LOG/lttng-tp.c @@ -0,0 +1,34 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file lttng-tp.c +* \brief Lttng trace implementaion +* \author Anurag Asokan +* \date 2024 +* \version 0.5 +* @ingroup util + +*/ +//This file is used to define the tracepoints for the lttng tracing.In order to to do linkage with the lttng-tp.h file, we need to define the tracepoints here. +#define TRACEPOINT_CREATE_PROBES +#define TRACEPOINT_DEFINE + +#include "lttng-tp.h" diff --git a/common/utils/LOG/lttng-tp.h b/common/utils/LOG/lttng-tp.h new file mode 100644 index 0000000000..7938ce9070 --- /dev/null +++ b/common/utils/LOG/lttng-tp.h @@ -0,0 +1,54 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file lttng-tp.h +* \brief Lttng tracer implementaion +* \author Anurag Asokan +* \date 2024 +* \version 0.5 +* @ingroup util + +*/ + +#ifndef _LTTNG_TP_H +#define _LTTNG_TP_H + +#undef TRACEPOINT_PROVIDER +#define TRACEPOINT_PROVIDER OAI + +#undef TRACEPOINT_INCLUDE +#define TRACEPOINT_INCLUDE "./common/utils/LOG/lttng-tp.h" + +#include +#include + +TRACEPOINT_EVENT( + OAI, + gNB, + TP_ARGS(const char*, log_modName, int, event_id, int, sfn, int, slot, const char*, funcName, int, lineNo, const char*, msg), + TP_FIELDS(ctf_string(MODNAME, log_modName) ctf_integer(int32_t, EVENTID, event_id) ctf_integer(int32_t, SFN, sfn) + ctf_integer(int32_t, SLOT, slot) ctf_string(FUNCTION, funcName) ctf_integer(int32_t, LINE, lineNo) + ctf_string(MSG, msg))) +TRACEPOINT_LOGLEVEL(OAI, gNB, TRACE_DEBUG_FUNCTION) + +#endif /* _LTTNG_TP_H */ + +#include