From 16f028dba56b88148ffaf0e84e35d097a2b4eedf Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Mon, 21 Oct 2024 10:54:55 +0200 Subject: [PATCH 1/2] Dynamic PDCCH aggregation level The aggregation level search order for PDCCH candidates is modified: - the search starts from desired_agg_level_index, which is a value from 0 to 4 proportial to pdcch_cl_adjust. - pdcch_cl_adjust is a value between 0 and 1 that indicates PDCCH channel quality by averaging HARQ DTX rate. A value of 0 means perfect channel, a value o 1 means impaired channel. --- doc/MAC/mac-usage.md | 22 +++++++++ openair1/PHY/NR_TRANSPORT/nr_dci.c | 5 +- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 8 ++-- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 6 ++- .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 6 ++- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 47 ++++++++++++++++--- .../LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 1 + .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 9 ++-- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 4 +- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 13 +++++ 10 files changed, 102 insertions(+), 19 deletions(-) diff --git a/doc/MAC/mac-usage.md b/doc/MAC/mac-usage.md index f96f94d522..8141e50df3 100644 --- a/doc/MAC/mac-usage.md +++ b/doc/MAC/mac-usage.md @@ -38,6 +38,28 @@ The actual scheduler implementation can be found in functions `pf_dl()` and [`gNB_scheduler_ulsch.c`](../../openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c) (for UL), respectively. +## PDDCH aggregation level + +PDCCH aggregation level is selected using closed loop controller, where DL HARQ +feedback is the controller feedback signal. It is used to increment `pdcch_cl_adjust` +variable if no feedback is detected and decrement the variable when feedback is detected. +`pdcch_cl_adjust` is later mapped PDCCH aggregation level range. + +The value of `pdcch_cl_adjust` is clamped to range <0,1>, the increment value is 0.05 while +the decrement value is 0.01. + +### Examples: +#### Example 1: +Say we have 90% PDCCH success rate at aggregation level 1, `pdcch_cl_adjust` will stay at 0 +for most of the time. 2 consecutive PDCCH failures will not result in increasing the aggregation +level (because (0.05 + 0.05) * 4 = 0.4 which is closer to 0 than to 1). If PDCCH fails 3 times +in a row the aggregation level will change to 2 and hopefully back to 1 once more PDDCH successes +happen. + +### Example 2 +Say we have 0% PDCCH success rate (radio link failure scenario) but `pdcch_cl_adjust` is 0 indicating +perfect PDCCH channel. it would take ~18 PDCCH failures to reach maximum aggregation level. + # Periodic output and interpretation The scheduler periodically outputs statistics that can help you judge the radio diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index 9bda1b96c4..49f07063d2 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -99,7 +99,7 @@ static void nr_generate_dci(PHY_VARS_gNB *gNB, if (dci_pdu->RNTI != 0xFFFF) LOG_D(NR_PHY_DCI, "DL_DCI : rb_offset %d, nb_rb %d, DMRS length per symbol %d\t DCI encoded length %d (precoder_granularity %d, " - "reg_mapping %d), Scrambling_Id %d, ScramblingRNTI %x, PayloadSizeBits %d\n", + "reg_mapping %d), Scrambling_Id %d, ScramblingRNTI %x, PayloadSizeBits %d AggregationLevel %d\n", rb_offset, n_rb, dmrs_length, @@ -108,7 +108,8 @@ static void nr_generate_dci(PHY_VARS_gNB *gNB, pdcch_pdu_rel15->CceRegMappingType, dci_pdu->ScramblingId, dci_pdu->ScramblingRNTI, - dci_pdu->PayloadSizeBits); + dci_pdu->PayloadSizeBits, + dci_pdu->AggregationLevel); dmrs_length += rb_offset*6; // To accommodate more DMRS symbols in case of rb offset /// DMRS QPSK modulation diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 3f3cbbad12..2d61a7332e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -874,7 +874,8 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, ss, coreset, &ra->sched_pdcch, - true); + true, + 0); if (CCEIndex < 0) { LOG_E(NR_MAC, "UE %04x cannot find free CCE!\n", ra->rnti); return; @@ -1484,7 +1485,7 @@ static void nr_generate_Msg2(module_id_t module_idP, } uint8_t aggregation_level; - int CCEIndex = get_cce_index(nr_mac, CC_id, slotP, 0, &aggregation_level, beam.idx, ss, coreset, &ra->sched_pdcch, true); + int CCEIndex = get_cce_index(nr_mac, CC_id, slotP, 0, &aggregation_level, beam.idx, ss, coreset, &ra->sched_pdcch, true, 0); if (CCEIndex < 0) { LOG_W(NR_MAC, "UE %04x: %d.%d cannot find free CCE for Msg2!\n", ra->rnti, frameP, slotP); @@ -2006,7 +2007,8 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP, ss, coreset, &ra->sched_pdcch, - true); + true, + 0); if (CCEIndex < 0) { LOG_E(NR_MAC, "Cannot find free CCE for RA RNTI 0x%04x!\n", ra->rnti); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 8b6639a3e7..5660f2b6b5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -553,7 +553,8 @@ static bool allocate_dl_retransmission(module_id_t module_id, sched_ctrl->search_space, sched_ctrl->coreset, &sched_ctrl->sched_pdcch, - false); + false, + sched_ctrl->pdcch_cl_adjust); if (CCEIndex<0) { LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find free CCE for DL DCI retransmission\n", UE->rnti, frame, slot); return false; @@ -817,7 +818,8 @@ static void pf_dl(module_id_t module_id, sched_ctrl->search_space, sched_ctrl->coreset, &sched_ctrl->sched_pdcch, - false); + false, + sched_ctrl->pdcch_cl_adjust); if (CCEIndex < 0) { LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find free CCE for DL DCI\n", rnti, frame, slot); reset_beam_status(&mac->beam_info, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 989aa1be9a..4aee39b45e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -148,7 +148,8 @@ void nr_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_t s sched_ctrl->search_space, sched_ctrl->coreset, &sched_ctrl->sched_pdcch, - false); + false, + 0); AssertFatal(CCEIndex >= 0, "Could not find CCE for UE %04x\n", UE->rnti); NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; @@ -312,7 +313,8 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ sched_ctrl->search_space, sched_ctrl->coreset, &sched_ctrl->sched_pdcch, - false); + false, + 0); if (CCEIndex < 0) { LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PUSCH\n", __func__); return false; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index d6f63d46d1..2db589d0ee 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -119,6 +119,9 @@ static const uint16_t cqi_table3[16][2] = {{0, 0}, {6, 6660}, {6, 7720}}; +static void determine_aggregation_level_search_order(int agg_level_search_order[NUM_PDCCH_AGG_LEVELS], + float pdcch_cl_adjust); + uint8_t get_dl_nrOfLayers(const NR_UE_sched_ctrl_t *sched_ctrl, const nr_dci_format_t dci_format) { @@ -550,15 +553,18 @@ int get_cce_index(const gNB_MAC_INST *nrmac, const NR_SearchSpace_t *ss, const NR_ControlResourceSet_t *coreset, NR_sched_pdcch_t *sched_pdcch, - bool is_common) + bool is_common, + float pdcch_cl_adjust) { - const uint32_t Y = is_common ? 0 : get_Y(ss, slot, rnti); uint8_t nr_of_candidates; - for (int i = 0; i < 5; i++) { - // for now taking the lowest value among the available aggregation levels - find_aggregation_candidates(aggregation_level, &nr_of_candidates, ss, 1 << i); - if(nr_of_candidates > 0) + + int agg_level_search_order[NUM_PDCCH_AGG_LEVELS]; + determine_aggregation_level_search_order(agg_level_search_order, pdcch_cl_adjust); + + for (int i = 0; i < NUM_PDCCH_AGG_LEVELS; i++) { + find_aggregation_candidates(aggregation_level, &nr_of_candidates, ss, 1 << agg_level_search_order[i]); + if (nr_of_candidates > 0) break; } int CCEIndex = find_pdcch_candidate(nrmac, CC_id, *aggregation_level, nr_of_candidates, beam_idx, sched_pdcch, coreset, Y); @@ -2516,6 +2522,7 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf sched_ctrl->ta_update = 31; sched_ctrl->sched_srs.frame = -1; sched_ctrl->sched_srs.slot = -1; + sched_ctrl->pdcch_cl_adjust = 0; // initialize LCID structure seq_arr_init(&sched_ctrl->lc_config, sizeof(nr_lc_config_t)); @@ -3524,3 +3531,31 @@ bool nr_mac_get_new_rnti(NR_UEs_t *UEs, const NR_RA_t *ra_base, int ra_count, rn } while (loop < 100 && (exist_connected_ue || exist_in_pending_ra_ue)); return loop < 100; // nothing found: loop count 100 } + +/// @brief Orders PDCCH aggregation levels so that we first check desired aggregation level according to +/// pdcch_cl_adjust +/// @param agg_level_search_order in/out 5-element array of aggregation levels from 0 to 4 +/// @param pdcch_cl_adjust value from 0 to 1 indication channel impariments (0 - good channel, 1 - bad channel) +static void determine_aggregation_level_search_order(int agg_level_search_order[NUM_PDCCH_AGG_LEVELS], float pdcch_cl_adjust) +{ + int desired_agg_level_index = round(4 * pdcch_cl_adjust); + int agg_level_search_index = 0; + for (int i = desired_agg_level_index; i < NUM_PDCCH_AGG_LEVELS; i++) { + agg_level_search_order[agg_level_search_index++] = i; + } + for (int i = desired_agg_level_index - 1; i >= 0; i--) { + agg_level_search_order[agg_level_search_index++] = i; + } +} + +/// @brief Update PDCCH closed loop adjust for UE depending on detection of feedback. +/// @param sched_ctrl UE scheduling control info +/// @param feedback_not_detected Whether feedback (PUSCH or HARQ) was detected +void nr_mac_update_pdcch_closed_loop_adjust(NR_UE_sched_ctrl_t *sched_ctrl, bool feedback_not_detected) +{ + if (feedback_not_detected) { + sched_ctrl->pdcch_cl_adjust = min(1, sched_ctrl->pdcch_cl_adjust + 0.05); + } else { + sched_ctrl->pdcch_cl_adjust = max(0, sched_ctrl->pdcch_cl_adjust - 0.01); + } +} diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 853a4a5ff8..cdf4861cff 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -787,6 +787,7 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, const int8_t pid = sched_ctrl->feedback_dl_harq.head; remove_front_nr_list(&sched_ctrl->feedback_dl_harq); LOG_D(NR_MAC,"%4d.%2d bit %d pid %d ack/nack %d\n",frame, slot, harq_bit,pid,harq_value); + nr_mac_update_pdcch_closed_loop_adjust(sched_ctrl, harq_confidence != 0); handle_dl_harq(UE, pid, harq_value == 0 && harq_confidence == 0, nrmac->dl_bler.harq_round_max); if (!UE->Msg4_MsgB_ACKed && harq_value == 0 && harq_confidence == 0) UE->Msg4_MsgB_ACKed = true; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 3aacade706..a8efe1a98d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -1742,7 +1742,8 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, sched_ctrl->search_space, sched_ctrl->coreset, &sched_ctrl->sched_pdcch, - false); + false, + sched_ctrl->pdcch_cl_adjust); if (CCEIndex<0) { LOG_D(NR_MAC, "[UE %04x][%4d.%2d] no free CCE for retransmission UL DCI UE\n", UE->rnti, frame, slot); return false; @@ -1926,7 +1927,8 @@ static void pf_ul(module_id_t module_id, sched_ctrl->search_space, sched_ctrl->coreset, &sched_ctrl->sched_pdcch, - false); + false, + sched_ctrl->pdcch_cl_adjust); if (CCEIndex < 0) { LOG_D(NR_MAC, "[UE %04x][%4d.%2d] no free CCE for UL DCI (BSR 0)\n", UE->rnti, frame, slot); reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, n, beam.new_beam); @@ -2073,7 +2075,8 @@ static void pf_ul(module_id_t module_id, sched_ctrl->search_space, sched_ctrl->coreset, &sched_ctrl->sched_pdcch, - false); + false, + sched_ctrl->pdcch_cl_adjust); if (CCEIndex < 0) { reset_beam_status(&nrmac->beam_info, frame, slot, iterator->UE->UE_beam_index, n_dl, dci_beam.new_beam); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index ee66bcaf90..57f8a9dba5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -433,7 +433,8 @@ int get_cce_index(const gNB_MAC_INST *nrmac, const NR_SearchSpace_t *ss, const NR_ControlResourceSet_t *coreset, NR_sched_pdcch_t *sched_pdcch, - bool is_common); + bool is_common, + float pdcch_cl_adjust); bool nr_find_nb_rb(uint16_t Qm, uint16_t R, @@ -493,5 +494,6 @@ bool nr_mac_add_lcid(NR_UE_sched_ctrl_t *sched_ctrl, const nr_lc_config_t *c); bool nr_mac_remove_lcid(NR_UE_sched_ctrl_t *sched_ctrl, long lcid); bool nr_mac_get_new_rnti(NR_UEs_t *UEs, const NR_RA_t *ra_base, int ra_count, rnti_t *rnti); +void nr_mac_update_pdcch_closed_loop_adjust(NR_UE_sched_ctrl_t *sched_ctrl, bool feedback_not_detected); #endif /*__LAYER2_NR_MAC_PROTO_H__*/ diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index c8604c431f..5abaa6f4c9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -125,6 +125,15 @@ typedef enum { nrRA_WAIT_Msg4_MsgB_ACK, } RA_gNB_state_t; +typedef enum { + PDCCH_AGG_LEVEL1 = 0, + PDCCH_AGG_LEVEL2, + PDCCH_AGG_LEVEL4, + PDCCH_AGG_LEVEL8, + PDCCH_AGG_LEVEL16, + NUM_PDCCH_AGG_LEVELS +} Pdcch_Aggregation_Level_t; + static const char *const nrra_text[] = {"IDLE", "Msg2", "WAIT_MsgA_PUSCH", "WAIT_Msg3", "Msg3_retransmission", "Msg3_dcch_dtch", "Msg4", "MsgB", "WAIT_Msg4_ACK"}; @@ -675,6 +684,10 @@ typedef struct { /// per-LC configuration seq_arr_t lc_config; + + // pdcch closed loop adjust for PDCCH aggregation level, range <0, 1> + // 0 - good channel, 1 - bad channel + float pdcch_cl_adjust; } NR_UE_sched_ctrl_t; typedef struct { From 095b7919299d7da69a56c5a71078b2177526d12e Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Wed, 15 Jan 2025 11:09:31 +0100 Subject: [PATCH 2/2] Add PDCCH UESS aggregation level configuration option Added uess_agg_levels configuration option which changes the number of PDCCH candidates per aggregation level. --- common/platform_types.h | 9 ++ common/utils/nr/nr_common.c | 12 ++ common/utils/nr/nr_common.h | 1 + doc/MAC/mac-usage.md | 9 +- openair1/SIMULATION/NR_PHY/dlsim.c | 3 +- openair2/GNB_APP/gnb_config.c | 48 +++++++- openair2/GNB_APP/gnb_paramdef.h | 6 + openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 10 +- openair2/RRC/NR/nr_rrc_config.c | 105 +++++++++++++----- openair2/RRC/NR/nr_rrc_config.h | 5 +- .../gnb.sa.band78.fr1.106PRB.usrpb210.conf | 1 + .../gnb.sa.band78.fr1.106PRB.usrpb210.yaml | 1 + 12 files changed, 168 insertions(+), 42 deletions(-) diff --git a/common/platform_types.h b/common/platform_types.h index 1001a454a9..b44efb6c7e 100644 --- a/common/platform_types.h +++ b/common/platform_types.h @@ -150,6 +150,15 @@ typedef enum ip_traffic_type_e { TRAFFIC_PC5S_SESSION_INIT = 10 } ip_traffic_type_t; +typedef enum { + PDCCH_AGG_LEVEL1 = 0, + PDCCH_AGG_LEVEL2, + PDCCH_AGG_LEVEL4, + PDCCH_AGG_LEVEL8, + PDCCH_AGG_LEVEL16, + NUM_PDCCH_AGG_LEVELS +} Pdcch_Aggregation_Level_t; + typedef struct net_ip_address_s { unsigned ipv4: 1; unsigned ipv6: 1; diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 5bacbe9f38..1a2820f236 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -551,6 +551,18 @@ void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset) { *n_rb = 6*count; } +// According to 38.211 7.3.2.2 +int get_coreset_num_cces(uint8_t *FreqDomainResource, int duration) +{ + int num_rbs; + int rb_offset; + get_coreset_rballoc(FreqDomainResource, &num_rbs, &rb_offset); + int total_resource_element_groups = num_rbs * duration; + int reg_per_cce = 6; + int total_cces = total_resource_element_groups / reg_per_cce; + return total_cces; +} + int get_nb_periods_per_frame(uint8_t tdd_period) { diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index bdd10e7896..7fc3450bc6 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -245,6 +245,7 @@ uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, ui int cce_to_reg_interleaving(const int R, int k, int n_shift, const int C, int L, const int N_regs); int get_SLIV(uint8_t S, uint8_t L); void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset); +int get_coreset_num_cces(uint8_t *FreqDomainResource, int duration); int get_nr_table_idx(int nr_bandP, uint8_t scs_index); int32_t get_delta_duplex(int nr_bandP, uint8_t scs_index); frame_type_t get_frame_type(uint16_t nr_bandP, uint8_t scs_index); diff --git a/doc/MAC/mac-usage.md b/doc/MAC/mac-usage.md index 8141e50df3..6804ca4543 100644 --- a/doc/MAC/mac-usage.md +++ b/doc/MAC/mac-usage.md @@ -43,10 +43,15 @@ The actual scheduler implementation can be found in functions `pf_dl()` and PDCCH aggregation level is selected using closed loop controller, where DL HARQ feedback is the controller feedback signal. It is used to increment `pdcch_cl_adjust` variable if no feedback is detected and decrement the variable when feedback is detected. -`pdcch_cl_adjust` is later mapped PDCCH aggregation level range. +`pdcch_cl_adjust` is later mapped to the PDCCH aggregation level range. The value of `pdcch_cl_adjust` is clamped to range <0,1>, the increment value is 0.05 while -the decrement value is 0.01. +the decrement value is 0.01. These values are selected to ensure PDCCH success rate is high. +See Examples below for futher explaination. + +The possible values of aggregation level on UE SS can be configured via `uess_agg_levels` configuration +option. By default the gNB uses only aggregation level 2 which translates to `uess_agg_levels` set to +`[0, 1, 0, 0, 0]`. For example, to enable aggregation level 2 and 4 set `uess_agg_levels` to `[0, 1, 1, 0, 0]`. ### Examples: #### Example 1: diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index ab3a044ac6..a3a182401c 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -671,7 +671,8 @@ printf("%d\n", slot); .timer_config.n310 = 10, .timer_config.t311 = 3000, .timer_config.n311 = 1, - .timer_config.t319 = 400}; + .timer_config.t319 = 400, + .num_agg_level_candidates = {0, 0, 1, 1, 0}}; RC.nb_nr_macrlc_inst = 1; RC.nb_nr_mac_CC = (int*)malloc(RC.nb_nr_macrlc_inst*sizeof(int)); diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 730f08dd7d..bd34f2407c 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -1129,11 +1129,25 @@ static NR_ServingCellConfigCommon_t *get_scc_config(configmodule_interface_t *cf AssertFatal(pcc != NULL && pcc->commonSearchSpaceList == NULL, "memory leak\n"); pcc->commonSearchSpaceList = calloc_or_fail(1, sizeof(*pcc->commonSearchSpaceList)); - NR_SearchSpace_t *ss1 = rrc_searchspace_config(true, 1, 0); + // TODO: Make CSS aggregation levels configurable + int css_num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS]; + css_num_agg_level_candidates[PDCCH_AGG_LEVEL1] = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0; + if (get_softmodem_params()->usim_test) { + css_num_agg_level_candidates[PDCCH_AGG_LEVEL2] = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0; + css_num_agg_level_candidates[PDCCH_AGG_LEVEL4] = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1; + css_num_agg_level_candidates[PDCCH_AGG_LEVEL8] = NR_SearchSpace__nrofCandidates__aggregationLevel8_n1; + } else { + css_num_agg_level_candidates[PDCCH_AGG_LEVEL2] = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0; + css_num_agg_level_candidates[PDCCH_AGG_LEVEL4] = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1; + css_num_agg_level_candidates[PDCCH_AGG_LEVEL8] = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0; + } + css_num_agg_level_candidates[PDCCH_AGG_LEVEL16] = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0; + + NR_SearchSpace_t *ss1 = rrc_searchspace_config(true, 1, 0, css_num_agg_level_candidates); asn1cSeqAdd(&pcc->commonSearchSpaceList->list, ss1); - NR_SearchSpace_t *ss2 = rrc_searchspace_config(true, 2, 0); + NR_SearchSpace_t *ss2 = rrc_searchspace_config(true, 2, 0, css_num_agg_level_candidates); asn1cSeqAdd(&pcc->commonSearchSpaceList->list, ss2); - NR_SearchSpace_t *ss3 = rrc_searchspace_config(true, 3, 0); + NR_SearchSpace_t *ss3 = rrc_searchspace_config(true, 3, 0, css_num_agg_level_candidates); asn1cSeqAdd(&pcc->commonSearchSpaceList->list, ss3); asn1cCallocOne(pcc->searchSpaceSIB1, 0); @@ -1501,6 +1515,34 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) } } + // Construct default aggragation level list or read from config + int uess_num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS]; + uess_num_agg_level_candidates[PDCCH_AGG_LEVEL1] = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0; + if (get_softmodem_params()->usim_test) { + uess_num_agg_level_candidates[PDCCH_AGG_LEVEL2] = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0; + uess_num_agg_level_candidates[PDCCH_AGG_LEVEL4] = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1; + uess_num_agg_level_candidates[PDCCH_AGG_LEVEL8] = NR_SearchSpace__nrofCandidates__aggregationLevel8_n1; + } else { + uess_num_agg_level_candidates[PDCCH_AGG_LEVEL2] = NR_SearchSpace__nrofCandidates__aggregationLevel2_n2; + uess_num_agg_level_candidates[PDCCH_AGG_LEVEL4] = NR_SearchSpace__nrofCandidates__aggregationLevel4_n0; + uess_num_agg_level_candidates[PDCCH_AGG_LEVEL8] = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0; + } + uess_num_agg_level_candidates[PDCCH_AGG_LEVEL16] = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0; + int* agg_level_list = uess_num_agg_level_candidates; + int num_agg_levels = 5; + if (GNBParamList.paramarray[0][GNB_UESS_AGG_LEVEL_LIST_IDX].numelt > 0) { + agg_level_list = GNBParamList.paramarray[0][GNB_UESS_AGG_LEVEL_LIST_IDX].iptr; + num_agg_levels = GNBParamList.paramarray[0][GNB_UESS_AGG_LEVEL_LIST_IDX].numelt; + } + memcpy(config.num_agg_level_candidates, agg_level_list, sizeof(int) * num_agg_levels); + LOG_I(NR_MAC, + "Candidates per PDCCH aggregation level on UESS: L1: %d, L2: %d, L4: %d, L8: %d, L16: %d\n", + config.num_agg_level_candidates[PDCCH_AGG_LEVEL1], + config.num_agg_level_candidates[PDCCH_AGG_LEVEL2], + config.num_agg_level_candidates[PDCCH_AGG_LEVEL4], + config.num_agg_level_candidates[PDCCH_AGG_LEVEL8], + config.num_agg_level_candidates[PDCCH_AGG_LEVEL16]); + NR_ServingCellConfigCommon_t *scc = get_scc_config(cfg, config.minRXTXTIME); //xer_fprint(stdout, &asn_DEF_NR_ServingCellConfigCommon, scc); NR_ServingCellConfig_t *scd = get_scd_config(cfg); diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index 57153698f1..ec5c8001e6 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -138,6 +138,7 @@ typedef enum { #define GNB_CONFIG_STRING_NUM_DL_HARQPROCESSES "num_dlharq" #define GNB_CONFIG_STRING_NUM_UL_HARQPROCESSES "num_ulharq" #define GNB_CONFIG_STRING_BEAM_WEIGHTS_LIST "beam_weights" +#define GNB_CONFIG_STRING_UESS_AGG_LEVEL_LIST "uess_agg_levels" #define GNB_CONFIG_HLP_STRING_ENABLE_SDAP "enable the SDAP layer\n" #define GNB_CONFIG_HLP_FORCE256QAMOFF "suppress activation of 256 QAM despite UE support" @@ -148,6 +149,7 @@ typedef enum { #define GNB_CONFIG_HLP_GNB_CU_UP_ID "defines the gNB-CU-UP ID (only applicable for CU-UP)" #define GNB_CONFIG_HLP_NUM_DL_HARQ "Set Num DL harq processes. Valid values 2,4,6,8,10,12,16,32. Default 16" #define GNB_CONFIG_HLP_NUM_UL_HARQ "Set Num UL harq processes. Valid values 16,32. Default 16" +#define GNB_CONFIG_HLP_UESS_AGG_LEVEL_LIST "List of aggregation levels with number of candidates per level. Element 0 - aggregation level 1" /*-----------------------------------------------------------------------------------------------------------------------------------------*/ /* cell configuration parameters */ @@ -191,6 +193,8 @@ typedef enum { {GNB_CONFIG_STRING_NUM_DL_HARQPROCESSES, GNB_CONFIG_HLP_NUM_DL_HARQ, 0, .iptr=NULL, .defintval=16, TYPE_INT, 0}, \ {GNB_CONFIG_STRING_NUM_UL_HARQPROCESSES, GNB_CONFIG_HLP_NUM_UL_HARQ, 0, .iptr=NULL, .defintval=16, TYPE_INT, 0}, \ {GNB_CONFIG_STRING_BEAM_WEIGHTS_LIST, NULL, 0, .iptr=NULL, .defintarrayval=0, TYPE_INTARRAY, 0}, \ +{GNB_CONFIG_STRING_UESS_AGG_LEVEL_LIST, \ + GNB_CONFIG_HLP_UESS_AGG_LEVEL_LIST, 0, .iptr=NULL, .defintarrayval=NULL, TYPE_INTARRAY, 0}, \ } // clang-format on @@ -231,6 +235,7 @@ typedef enum { #define GNB_NUM_DL_HARQ_IDX 33 #define GNB_NUM_UL_HARQ_IDX 34 #define GNB_BEAMWEIGHTS_IDX 35 +#define GNB_UESS_AGG_LEVEL_LIST_IDX 36 #define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD} #define NUM_DL_HARQ_OKVALUES {2,4,6,8,10,12,16,32} @@ -273,6 +278,7 @@ typedef enum { { .s1 = { config_check_intval, NUM_DL_HARQ_OKVALUES,8 } }, \ { .s1 = { config_check_intval, NUM_UL_HARQ_OKVALUES,2 } }, \ { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ } /*-------------------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 5abaa6f4c9..a464611ec8 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -125,15 +125,6 @@ typedef enum { nrRA_WAIT_Msg4_MsgB_ACK, } RA_gNB_state_t; -typedef enum { - PDCCH_AGG_LEVEL1 = 0, - PDCCH_AGG_LEVEL2, - PDCCH_AGG_LEVEL4, - PDCCH_AGG_LEVEL8, - PDCCH_AGG_LEVEL16, - NUM_PDCCH_AGG_LEVELS -} Pdcch_Aggregation_Level_t; - static const char *const nrra_text[] = {"IDLE", "Msg2", "WAIT_MsgA_PUSCH", "WAIT_Msg3", "Msg3_retransmission", "Msg3_dcch_dtch", "Msg4", "MsgB", "WAIT_Msg4_ACK"}; @@ -181,6 +172,7 @@ typedef struct nr_mac_config_t { /// beamforming weight matrix size int nb_bfw[2]; int32_t *bw_list; + int num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS]; } nr_mac_config_t; typedef struct NR_preamble_ue { diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index d2266a74f3..3ae9ac2279 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -72,6 +72,50 @@ static NR_BWP_t clone_generic_parameters(const NR_BWP_t *gp) return clone; } +/** + * @brief Verifies the aggregation level candidates + * + * This function checks the input aggregation level candidates and translates the value provided + * in the config to a valid field in RRC message. + * + * @param[in] num_cce_in_coreset number of CCE in coreset + * @param[in] in_num_agg_level_candidates input array of aggregation level candidates, interpreted as number of candidates. + * @param[in] coresetid coreset id + * @param[in] searchspaceid searchspace id + * @param[out] out_num_agg_level_candidates array of aggregation level candidates, output is a valid 3gpp field value. + * + */ +static void verify_agg_levels(int num_cce_in_coreset, + const int in_num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS], + int coresetid, + int searchspaceid, + int out_num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS]) +{ + int agg_level_to_n_cces[] = {1, 2, 4, 8, 16}; + for (int i = 0; i < NUM_PDCCH_AGG_LEVELS; i++) { + // 7 is not a valid value, the mapping in 38.331 is from 0-7 mapped to 0-8 candidates and value 7 means 8 candidates instead. If + // the user wants 7 candidates round it up to 8. + int num_agg_level_candidates = in_num_agg_level_candidates[i]; + if (num_agg_level_candidates == 7) { + num_agg_level_candidates = 8; + } + if (num_agg_level_candidates * agg_level_to_n_cces[i] > num_cce_in_coreset) { + int new_agg_level_candidates = num_cce_in_coreset / agg_level_to_n_cces[i]; + LOG_E(NR_RRC, + "Invalid configuration: Not enough CCEs in coreset %d, searchspace %d, agg_level %d, number of requested " + "candidates = %d, number of CCES in coreset %d. Aggregation level candidates limited to %d\n", + coresetid, + searchspaceid, + agg_level_to_n_cces[i], + in_num_agg_level_candidates[i], + num_cce_in_coreset, + new_agg_level_candidates); + num_agg_level_candidates = new_agg_level_candidates; + } + out_num_agg_level_candidates[i] = min(num_agg_level_candidates, 7); + } +} + static NR_SetupRelease_RACH_ConfigCommon_t *clone_rach_configcommon(const NR_SetupRelease_RACH_ConfigCommon_t *rcc) { if (rcc == NULL || rcc->present == NR_SetupRelease_RACH_ConfigCommon_PR_NOTHING) @@ -208,9 +252,11 @@ static int get_nb_pucch2_per_slot(const NR_ServingCellConfigCommon_t *scc, int b return nb_pucch2; } -NR_SearchSpace_t *rrc_searchspace_config(bool is_common, int searchspaceid, int coresetid) +NR_SearchSpace_t *rrc_searchspace_config(bool is_common, + int searchspaceid, + int coresetid, + const int num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS]) { - NR_SearchSpace_t *ss = calloc(1,sizeof(*ss)); ss->searchSpaceId = searchspaceid; ss->controlResourceSetId = calloc(1,sizeof(*ss->controlResourceSetId)); @@ -226,23 +272,12 @@ NR_SearchSpace_t *rrc_searchspace_config(bool is_common, int searchspaceid, int ss->monitoringSymbolsWithinSlot->buf[1] = 0x0; ss->monitoringSymbolsWithinSlot->bits_unused = 2; ss->nrofCandidates = calloc(1,sizeof(*ss->nrofCandidates)); - // TODO temporary hardcoded implementation - ss->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0; - if (get_softmodem_params()->usim_test) { - ss->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0; - ss->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1; - ss->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n1; - } else { - if (is_common) { - ss->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0; - ss->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1; - } else { - ss->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n2; - ss->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n0; - } - ss->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0; - } - ss->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0; + ss->nrofCandidates->aggregationLevel1 = num_agg_level_candidates[PDCCH_AGG_LEVEL1]; + ss->nrofCandidates->aggregationLevel2 = num_agg_level_candidates[PDCCH_AGG_LEVEL2]; + ss->nrofCandidates->aggregationLevel4 = num_agg_level_candidates[PDCCH_AGG_LEVEL4]; + ss->nrofCandidates->aggregationLevel8 = num_agg_level_candidates[PDCCH_AGG_LEVEL8]; + ss->nrofCandidates->aggregationLevel16 = num_agg_level_candidates[PDCCH_AGG_LEVEL16]; + ss->searchSpaceType = calloc(1,sizeof(*ss->searchSpaceType)); if (is_common) { ss->searchSpaceType->present = NR_SearchSpace__searchSpaceType_PR_common; @@ -1545,7 +1580,8 @@ static void config_downlinkBWP(NR_BWP_Downlink_t *bwp, int dl_antenna_ports, bool force_256qam_off, int bwp_loop, - bool is_SA) + bool is_SA, + const int num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS]) { bwp->bwp_Common = calloc(1,sizeof(*bwp->bwp_Common)); @@ -1577,8 +1613,12 @@ static void config_downlinkBWP(NR_BWP_Downlink_t *bwp, bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList=NULL; bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList)); - NR_SearchSpace_t *ss = rrc_searchspace_config(true, 5+bwp->bwp_Id, coreset->controlResourceSetId); - asn1cSeqAdd(&bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list,ss); + int searchspaceid = 5 + bwp->bwp_Id; + int rrc_num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS]; + int num_cces = get_coreset_num_cces(coreset->frequencyDomainResources.buf, coreset->duration); + verify_agg_levels(num_cces, num_agg_level_candidates, coreset->controlResourceSetId, searchspaceid, rrc_num_agg_level_candidates); + NR_SearchSpace_t *ss = rrc_searchspace_config(true, searchspaceid, coreset->controlResourceSetId, rrc_num_agg_level_candidates); + asn1cSeqAdd(&bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list, ss); bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1=NULL; bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceOtherSystemInformation=NULL; @@ -1613,7 +1653,11 @@ static void config_downlinkBWP(NR_BWP_Downlink_t *bwp, NR_ControlResourceSet_t *coreset2 = get_coreset_config(bwp->bwp_Id, curr_bwp, ssb_bitmap); asn1cSeqAdd(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list, coreset2); - NR_SearchSpace_t *ss2 = rrc_searchspace_config(false, 10+bwp->bwp_Id, coreset2->controlResourceSetId); + searchspaceid = 10 + bwp->bwp_Id; + num_cces = get_coreset_num_cces(coreset2->frequencyDomainResources.buf, coreset2->duration); + verify_agg_levels(num_cces, num_agg_level_candidates, coreset->controlResourceSetId, searchspaceid, rrc_num_agg_level_candidates); + NR_SearchSpace_t *ss2 = + rrc_searchspace_config(false, searchspaceid, coreset2->controlResourceSetId, rrc_num_agg_level_candidates); asn1cSeqAdd(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list, ss2); bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToReleaseList = NULL; @@ -3069,7 +3113,15 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid, asn1cSeqAdd(&bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list, coreset); - NR_SearchSpace_t *ss2 = rrc_searchspace_config(false, 5, coreset->controlResourceSetId); + int searchspaceid = 5; + int rrc_num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS]; + int num_cces = get_coreset_num_cces(coreset->frequencyDomainResources.buf, coreset->duration); + verify_agg_levels(num_cces, + configuration->num_agg_level_candidates, + coreset->controlResourceSetId, + searchspaceid, + rrc_num_agg_level_candidates); + NR_SearchSpace_t *ss2 = rrc_searchspace_config(false, searchspaceid, coreset->controlResourceSetId, rrc_num_agg_level_candidates); asn1cSeqAdd(&bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list, ss2); bwp_Dedicated->pdsch_Config = config_pdsch(bitmap, 0, pdsch_AntennaPorts); @@ -3113,7 +3165,7 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid, calloc(1, sizeof(*SpCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList)); for (int bwp_loop = 0; bwp_loop < n_dl_bwp; bwp_loop++) { NR_BWP_Downlink_t *bwp = calloc(1, sizeof(*bwp)); - config_downlinkBWP(bwp, scc, servingcellconfigdedicated, NULL, 0, false, bwp_loop, true); + config_downlinkBWP(bwp, scc, servingcellconfigdedicated, NULL, 0, false, bwp_loop, true, configuration->num_agg_level_candidates); asn1cSeqAdd(&SpCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list, bwp); } const NR_BWP_Id_t *firstActiveDownlinkBWP_Id = servingcellconfigdedicated->firstActiveDownlinkBWP_Id; @@ -3575,7 +3627,8 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC dl_antenna_ports, configuration->force_256qam_off, bwp_loop, - false); + false, + configuration->num_agg_level_candidates); asn1cSeqAdd(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list, bwp); } secondaryCellGroup->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id = diff --git a/openair2/RRC/NR/nr_rrc_config.h b/openair2/RRC/NR/nr_rrc_config.h index 3076b09f62..fe4bb99563 100644 --- a/openair2/RRC/NR/nr_rrc_config.h +++ b/openair2/RRC/NR/nr_rrc_config.h @@ -55,7 +55,10 @@ void nr_rrc_config_dl_tda(struct NR_PDSCH_TimeDomainResourceAllocationList *pdsc NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon, int curr_bwp); void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay); -NR_SearchSpace_t *rrc_searchspace_config(bool is_common, int searchspaceid, int coresetid); +NR_SearchSpace_t *rrc_searchspace_config(bool is_common, + int searchspaceid, + int coresetid, + const int num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS]); void prepare_sim_uecap(NR_UE_NR_Capability_t *cap, NR_ServingCellConfigCommon_t *scc, diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf index 388039579d..7f7054db31 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf @@ -20,6 +20,7 @@ gNBs = do_CSIRS = 1; do_SRS = 1; + #uess_agg_levels = [0,1,2,2,1] servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.yaml b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.yaml index f9a4797248..87ad6080a0 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.yaml +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.yaml @@ -19,6 +19,7 @@ gNBs: # Physical parameters: do_CSIRS: 1 do_SRS: 1 + #uess_agg_levels: [0,1,1,1,1] servingCellConfigCommon: #spCellConfigCommon - physCellId: 0