From 6fdb69a898666a5d8f2befcd85f69326386a7a2f Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 25 Apr 2024 15:24:36 +0200 Subject: [PATCH 01/14] fix for possible infinite loop in UE PUCCH multiplexing --- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 24 +++++++++----------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 5f0bc51e9a..fa845a21c5 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -1830,10 +1830,17 @@ void order_resources(PUCCH_sched_t *pucch, int num_res) } } -bool check_overlapping_resources(int curr_start, int curr_length, int next_start, int next_length) +bool check_overlapping_resources(PUCCH_sched_t *pucch, int j, int o) { // assuming overlapping means if two resources overlaps in time, // ie share a symbol in the slot regardless of PRB + NR_PUCCH_Resource_t *pucch_resource = pucch[j - o].pucch_resource; + int curr_start, curr_length; + get_pucch_start_symbol_length(pucch_resource, &curr_start, &curr_length); + pucch_resource = pucch[j + 1].pucch_resource; + int next_start, next_length; + get_pucch_start_symbol_length(pucch_resource, &next_start, &next_length); + if (curr_start == next_start) return true; if (curr_start + curr_length - 1 < next_start) @@ -2179,18 +2186,9 @@ void multiplex_pucch_resource(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch, int n int j = 0; int o = 0; while (j <= num_res - 1) { - if (j < num_res - 1) { - NR_PUCCH_Resource_t *pucch_resource = pucch[j - o].pucch_resource; - int curr_start, curr_length; - get_pucch_start_symbol_length(pucch_resource, &curr_start, &curr_length); - pucch_resource = pucch[j + 1].pucch_resource; - int next_start, next_length; - get_pucch_start_symbol_length(pucch_resource, &next_start, &next_length); - bool overlap = check_overlapping_resources(curr_start, curr_length, next_start, next_length); - if (overlap) { - o++; - j++; - } + if ((j < num_res - 1) && check_overlapping_resources(pucch, j, o)) { + o++; + j++; } else { if (o > 0) { merge_resources(&pucch[j - o], o + 1, pucch_Config); From 70f536a0f014dcf3f3f50d86ae83ed7d7ca6db95 Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Wed, 8 May 2024 12:19:08 +0200 Subject: [PATCH 02/14] Correct PRACH preamble tx power calculation. Removed arbitrary offset of 30dB. Changed sign for pathloss: pathloss calculated in compute_nr_SSB_PL is the difference between transmitted and received power. Transmission power for preamble should compensate the pathloss, therefore power should increase with pathloss. --- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 3cdcbf769d..4d74e4985a 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -45,7 +45,7 @@ int16_t get_prach_tx_power(NR_UE_MAC_INST_t *mac) { RA_config_t *ra = &mac->ra; int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm); - int16_t ra_preamble_rx_power = (int16_t)(ra->prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER - pathloss + 30); + int16_t ra_preamble_rx_power = (int16_t)(ra->prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER + pathloss); return min(ra->prach_resources.RA_PCMAX, ra_preamble_rx_power); } From 40b52bc8f494666e02026db2a76e69c0fd12bd62 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Fri, 10 May 2024 12:49:44 -0400 Subject: [PATCH 03/14] Use existing function for bits reversal --- openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index f60d9c89ea..b87fc9267c 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -508,12 +508,10 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue, #endif } - uint32_t payload = 0; result->xtra_byte = (out>>24)&0xff; - for (int i=0; i>i)&1)<<(NR_POLAR_PBCH_PAYLOAD_BITS-i-1); - + const uint64_t payload = reverse_bits(out, NR_POLAR_PBCH_PAYLOAD_BITS); + for (int i=0; i<3; i++) result->decoded_output[i] = (uint8_t)((payload>>((3-i)<<3))&0xff); From 17f2eaa558b90854740f18566978f172e9217237 Mon Sep 17 00:00:00 2001 From: Sreeshma Shiv Date: Wed, 15 May 2024 12:54:28 +0530 Subject: [PATCH 04/14] TAC-Octet String to integer conversion function corrections -Corrected the conversion function used in CU_handle_F1_SETUP_REQUEST -Corrected the conversion function in CU_handle_gNB_DU_CONFIGURATION_UPDATE --- openair2/F1AP/f1ap_cu_interface_management.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c index 92c1840350..360a2323aa 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.c +++ b/openair2/F1AP/f1ap_cu_interface_management.c @@ -158,7 +158,7 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint3 if (servedCellInformation->fiveGS_TAC) { req->cell[i].info.tac = malloc(sizeof(*req->cell[i].info.tac)); AssertFatal(req->cell[i].info.tac != NULL, "out of memory\n"); - OCTET_STRING_TO_INT16(servedCellInformation->fiveGS_TAC, *req->cell[i].info.tac); + OCTET_STRING_TO_INT24(servedCellInformation->fiveGS_TAC, *req->cell[i].info.tac); LOG_D(F1AP, "req->tac[%d] %d \n", i, *req->cell[i].info.tac); } @@ -636,7 +636,7 @@ int CU_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t asso if (servedCellInformation->fiveGS_TAC) { req->cell_to_modify[i].info.tac = malloc(sizeof(*req->cell_to_modify[i].info.tac)); AssertFatal(req->cell_to_modify[i].info.tac != NULL, "out of memory\n"); - OCTET_STRING_TO_INT16(servedCellInformation->fiveGS_TAC, *req->cell_to_modify[i].info.tac); + OCTET_STRING_TO_INT24(servedCellInformation->fiveGS_TAC, *req->cell_to_modify[i].info.tac); LOG_D(F1AP, "req->tac[%d] %d \n", i, *req->cell_to_modify[i].info.tac); } From 3e4526a6ad02021888277aab588a352991dd17ee Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Thu, 16 May 2024 14:05:39 +0200 Subject: [PATCH 05/14] rename persisted ul harq status per pid with a uniq name as this variable is persisted in memory and accessed by multiple threads, a uniq name helps to debug --- openair1/PHY/INIT/nr_init_ue.c | 2 +- openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h | 2 +- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 2 +- openair1/PHY/defs_nr_UE.h | 1 + openair1/SCHED_NR_UE/fapi_nr_ue_l1.c | 2 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 2 +- 6 files changed, 6 insertions(+), 5 deletions(-) diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 83b2bd75ac..5c7c667e29 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -645,7 +645,7 @@ void clean_UE_harq(PHY_VARS_NR_UE *UE) for (int harq_pid = 0; harq_pid < NR_MAX_ULSCH_HARQ_PROCESSES; harq_pid++) { NR_UL_UE_HARQ_t *ul_harq_process = &UE->ul_harq_processes[harq_pid]; ul_harq_process->tx_status = NEW_TRANSMISSION_HARQ; - ul_harq_process->status = SCH_IDLE; + ul_harq_process->ULstatus = SCH_IDLE; ul_harq_process->round = 0; } } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h index 8fea51ad75..05b7c9afd2 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h @@ -47,7 +47,7 @@ typedef struct { /// HARQ tx status harq_result_t tx_status; /// Status Flag indicating for this ULSCH (idle,active,disabled) - SCH_status_t status; + SCH_status_t ULstatus; /// Last TPC command uint8_t TPC; /// Length of ACK information (bits) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 2ac06bfe89..225a20aa36 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -557,7 +557,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, NR_UL_UE_HARQ_t *harq_process_ulsch = NULL; harq_process_ulsch = &UE->ul_harq_processes[harq_pid]; - harq_process_ulsch->status = SCH_IDLE; + harq_process_ulsch->ULstatus = SCH_IDLE; /////////// //////////////////////////////////////////////////////////////////////// } diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index c746bd69b8..93b9f360e5 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -642,6 +642,7 @@ typedef struct nr_rxtx_thread_data_s { nr_phy_data_t phy_data; int tx_wait_for_dlsch; int rx_offset; + int stream_status; } nr_rxtx_thread_data_t; typedef struct LDPCDecode_ue_s { diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 8560e3de82..84dd690a64 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -473,7 +473,7 @@ static void nr_ue_scheduled_response_ul(PHY_VARS_NR_UE *phy, fapi_nr_ul_config_r pdu->pusch_config_pdu.tx_request_body.pdu_length); } - harq_process_ul_ue->status = ACTIVE; + harq_process_ul_ue->ULstatus = ACTIVE; pdu->pdu_type = FAPI_NR_UL_CONFIG_TYPE_DONE; // not handle it any more } break; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 935563c35f..05c70542a5 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -294,7 +294,7 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, n start_meas(&ue->phy_proc_tx); for (uint8_t harq_pid = 0; harq_pid < NR_MAX_ULSCH_HARQ_PROCESSES; harq_pid++) { - if (ue->ul_harq_processes[harq_pid].status == ACTIVE) { + if (ue->ul_harq_processes[harq_pid].ULstatus == ACTIVE) { nr_ue_ulsch_procedures(ue, harq_pid, frame_tx, slot_tx, gNB_id, phy_data, (c16_t **)&txdataF); } } From e217980249241234bad82e61ea9a7899b3c13bd9 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Thu, 16 May 2024 14:06:24 +0200 Subject: [PATCH 06/14] simplify and make better performance the mutual exclusion of processSlotTX() function --- executables/nr-ue.c | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index fc9debee2b..68b747de32 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -526,6 +526,14 @@ void processSlotTX(void *arg) PHY_VARS_NR_UE *UE = rxtxD->UE; nr_phy_data_tx_t phy_data = {0}; + // Force sequential execution, even if we launch in // for all slots + // at least ULstatus variable is a pure race condition that is quickly detected by assert() in the code because one thread sets it + // to active, so the other thread try to steal&run the ul work + if (rxtxD->stream_status == 2) { + notifiedFIFO_elt_t *res = pullNotifiedFIFO(UE->tx_resume_ind_fifo + proc->nr_slot_tx); + delNotifiedFIFO_elt(res); + } + if (UE->if_inst) UE->if_inst->slot_indication(UE->Mod_id); @@ -560,11 +568,6 @@ void processSlotTX(void *arg) instead, we may run in place the processSlotTX() when the conditions are met (when a decreasing tx_wait_for_dlsch[slot] will become 0) It will remove the condition signals (for a thread safe semaphore or counter) and make the system simpler - This require also other modifications to - remove txFifo that is also a big issue - add out of order RF board sending, because, - if we encode and send tx slot as soon as we can, - it will be thrown out of order, especially in TDD mode */ notifiedFIFO_elt_t *res = pollNotifiedFIFO(UE->tx_resume_ind_fifo + proc->nr_slot_tx); if (res) @@ -590,6 +593,11 @@ void processSlotTX(void *arg) phy_procedures_nrUE_TX(UE, proc, &phy_data); } + notifiedFIFO_elt_t *newElt = newNotifiedFIFO_elt(sizeof(int), 0, NULL, NULL); + int *msgData = (int *)NotifiedFifoData(newElt); + int newslot = (proc->nr_slot_tx + 1) % UE->frame_parms.slots_per_frame; + *msgData = newslot; + pushNotifiedFIFO(UE->tx_resume_ind_fifo + newslot, newElt); RU_write(rxtxD); } @@ -755,9 +763,6 @@ void *UE_thread(void *arg) notifiedFIFO_t nf; initNotifiedFIFO(&nf); - notifiedFIFO_t txFifo; - initNotifiedFIFO(&txFifo); - notifiedFIFO_t freeBlocks; initNotifiedFIFO_nothreadSafe(&freeBlocks); @@ -937,25 +942,18 @@ void *UE_thread(void *arg) // Start TX slot processing here. It runs in parallel with RX slot processing // in current code, DURATION_RX_TO_TX constant is the limit to get UL data to encode from a RX slot - notifiedFIFO_elt_t *newTx = newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), curMsg.proc.nr_slot_tx, &txFifo, processSlotTX); + notifiedFIFO_elt_t *newTx = newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), curMsg.proc.nr_slot_tx, NULL, processSlotTX); nr_rxtx_thread_data_t *curMsgTx = (nr_rxtx_thread_data_t *)NotifiedFifoData(newTx); curMsgTx->proc = curMsg.proc; curMsgTx->writeBlockSize = writeBlockSize; curMsgTx->proc.timestamp_tx = writeTimestamp; curMsgTx->UE = UE; curMsgTx->tx_wait_for_dlsch = tx_wait_for_dlsch[curMsgTx->proc.nr_slot_tx]; + curMsgTx->stream_status = start_rx_stream; + start_rx_stream = 2; tx_wait_for_dlsch[curMsgTx->proc.nr_slot_tx] = 0; pushTpool(&(get_nrUE_params()->Tpool), newTx); - - // Wait for TX slot processing to finish - // Should be removed when bugs, race conditions, will be fixed - notifiedFIFO_elt_t *res; - res = pullTpool(&txFifo, &(get_nrUE_params()->Tpool)); - if (res == NULL) - LOG_E(PHY, "Tpool has been aborted\n"); - else - delNotifiedFIFO_elt(res); - } // while !oai_exit + } return NULL; } From f2213bf7922ad49abbc543c245a9da86af3be8f7 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 17 May 2024 11:19:38 +0200 Subject: [PATCH 07/14] fix a error that was created by over complexity in setting a pointer to null for a wrong later assert verification --- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 26 +++++++++++---------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index c18189a683..40c0f6a173 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -56,6 +56,11 @@ #include "LAYER2/RLC/rlc.h" //#define SRS_DEBUG +#define verifyMutex(a) \ + { \ + int ret = a; \ + AssertFatal(ret == 0, "Failure in mutex management ret=%d\n", a); \ + } static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, sub_frame_t slotP); static void schedule_ta_command(fapi_nr_dl_config_request_t *dl_config, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment); @@ -65,9 +70,9 @@ void clear_ul_config_request(NR_UE_MAC_INST_t *mac, int scs) int slots = nr_slots_per_frame[scs]; for (int i = 0; i < slots ; i++) { fapi_nr_ul_config_request_t *ul_config = mac->ul_config_request + i; - pthread_mutex_lock(&ul_config->mutex_ul_config); + verifyMutex(pthread_mutex_lock(&ul_config->mutex_ul_config)); ul_config->number_pdus = 0; - pthread_mutex_unlock(&ul_config->mutex_ul_config); + verifyMutex(pthread_mutex_unlock(&ul_config->mutex_ul_config)); } } @@ -81,7 +86,7 @@ fapi_nr_ul_config_request_pdu_t *lockGet_ul_config(NR_UE_MAC_INST_t *mac, frame_ AssertFatal(mac->ul_config_request != NULL, "mac->ul_config_request not initialized, logic bug\n"); fapi_nr_ul_config_request_t *ul_config = mac->ul_config_request + slot_tx; - pthread_mutex_lock(&ul_config->mutex_ul_config); + verifyMutex(pthread_mutex_lock(&ul_config->mutex_ul_config)); if (ul_config->number_pdus != 0 && (ul_config->frame != frame_tx || ul_config->slot != slot_tx)) { LOG_E(NR_MAC, "Error in ul config consistency, clearing slot %d\n", slot_tx); ul_config->number_pdus = 0; @@ -90,12 +95,11 @@ fapi_nr_ul_config_request_pdu_t *lockGet_ul_config(NR_UE_MAC_INST_t *mac, frame_ ul_config->slot = slot_tx; if (ul_config->number_pdus >= FAPI_NR_UL_CONFIG_LIST_NUM) { LOG_E(NR_MAC, "Error in ul config for slot %d, no memory\n", slot_tx); - pthread_mutex_unlock(&ul_config->mutex_ul_config); + verifyMutex(pthread_mutex_unlock(&ul_config->mutex_ul_config)); return NULL; } fapi_nr_ul_config_request_pdu_t *pdu = ul_config->ul_config_list + ul_config->number_pdus++; pdu->pdu_type = pdu_type; - AssertFatal(!pdu->lock, "no lock in fapi_nr_ul_config_request_pdu_t, aborting"); pdu->lock = &ul_config->mutex_ul_config; pdu->privateNBpdus = &ul_config->number_pdus; LOG_D(NR_MAC, "Added ul pdu for %d.%d, type %d\n", frame_tx, slot_tx, pdu_type); @@ -181,30 +185,28 @@ void remove_ul_config_last_item(fapi_nr_ul_config_request_pdu_t *pdu) void release_ul_config(fapi_nr_ul_config_request_pdu_t *configPerSlot, bool clearIt) { - pthread_mutex_t *lock = configPerSlot->lock; - configPerSlot->lock = NULL; if (clearIt) *configPerSlot->privateNBpdus = 0; - pthread_mutex_unlock(lock); + verifyMutex(pthread_mutex_unlock(configPerSlot->lock)); } fapi_nr_ul_config_request_pdu_t *fapiLockIterator(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx) { - pthread_mutex_lock(&ul_config->mutex_ul_config); + verifyMutex(pthread_mutex_lock(&ul_config->mutex_ul_config)); if (ul_config->number_pdus >= FAPI_NR_UL_CONFIG_LIST_NUM) { LOG_E(NR_MAC, "Error in ul config in slot %d no memory\n", ul_config->slot); - pthread_mutex_unlock(&ul_config->mutex_ul_config); + verifyMutex(pthread_mutex_unlock(&ul_config->mutex_ul_config)); return NULL; } if (ul_config->number_pdus != 0 && (ul_config->frame != frame_tx || ul_config->slot != slot_tx)) { LOG_E(NR_MAC, "Error in ul config consistency, clearing it slot %d\n", slot_tx); ul_config->number_pdus = 0; - pthread_mutex_unlock(&ul_config->mutex_ul_config); + verifyMutex(pthread_mutex_unlock(&ul_config->mutex_ul_config)); return NULL; } if (ul_config->number_pdus >= FAPI_NR_UL_CONFIG_LIST_NUM) { LOG_E(NR_MAC, "Error in ul config for slot %d, no memory\n", slot_tx); - pthread_mutex_unlock(&ul_config->mutex_ul_config); + verifyMutex(pthread_mutex_unlock(&ul_config->mutex_ul_config)); return NULL; } fapi_nr_ul_config_request_pdu_t *pdu = ul_config->ul_config_list + ul_config->number_pdus; From 3c6ae9c2cb4e56609420e6dac6bc550aa610c6a2 Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Thu, 9 May 2024 10:32:39 +0100 Subject: [PATCH 08/14] Tutorials: Fix multiple S-NSSAI redefinitions for the same S-NSSAI in the configuration file --- .../oai-cn5g/conf/config.yaml | 28 +++++-------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/doc/tutorial_resources/oai-cn5g/conf/config.yaml b/doc/tutorial_resources/oai-cn5g/conf/config.yaml index 4bdec06407..2a7002afe6 100644 --- a/doc/tutorial_resources/oai-cn5g/conf/config.yaml +++ b/doc/tutorial_resources/oai-cn5g/conf/config.yaml @@ -114,11 +114,7 @@ database: ## general single_nssai configuration ## Defines YAML anchors, which are reused in the config file snssais: - - &embb_slice1 - sst: 1 - - &embb_slice2 - sst: 1 - - &embb_slice3 + - &embb_slice sst: 1 ############## NF-specific configuration @@ -145,9 +141,7 @@ amf: mnc: 01 tac: 0x0001 nssai: - - *embb_slice1 - - *embb_slice2 - - *embb_slice3 + - *embb_slice supported_integrity_algorithms: - "NIA1" - "NIA2" @@ -178,29 +172,25 @@ smf: # follows the SmfInfo datatype from 3GPP TS 29.510 smf_info: sNssaiSmfInfoList: - - sNssai: *embb_slice1 + - sNssai: *embb_slice dnnSmfInfoList: - dnn: "oai" - - sNssai: *embb_slice2 - dnnSmfInfoList: - dnn: "openairinterface" - - sNssai: *embb_slice3 - dnnSmfInfoList: - dnn: "ims" local_subscription_infos: - - single_nssai: *embb_slice1 + - single_nssai: *embb_slice dnn: "oai" qos_profile: 5qi: 9 session_ambr_ul: "10Gbps" session_ambr_dl: "10Gbps" - - single_nssai: *embb_slice2 + - single_nssai: *embb_slice dnn: "openairinterface" qos_profile: 5qi: 9 session_ambr_ul: "10Gbps" session_ambr_dl: "10Gbps" - - single_nssai: *embb_slice3 + - single_nssai: *embb_slice dnn: "ims" qos_profile: 5qi: 9 @@ -216,14 +206,10 @@ upf: - host: oai-smf # To be used for PFCP association in case of no-NRF upf_info: sNssaiUpfInfoList: - - sNssai: *embb_slice1 + - sNssai: *embb_slice dnnUpfInfoList: - dnn: "oai" - - sNssai: *embb_slice2 - dnnUpfInfoList: - dnn: "openairinterface" - - sNssai: *embb_slice3 - dnnUpfInfoList: - dnn: "ims" ## DNN configuration From 246a8aff162f896566855fbb6ec8dce6f5fdde88 Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Thu, 9 May 2024 10:37:11 +0100 Subject: [PATCH 09/14] Tutorials: Rename OAI CN5G docker network interface name from 'demo-oai' to 'oai-cn5g' and remove commented lines --- doc/tutorial_resources/oai-cn5g/docker-compose.yaml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/doc/tutorial_resources/oai-cn5g/docker-compose.yaml b/doc/tutorial_resources/oai-cn5g/docker-compose.yaml index 83c871fb87..0baf032fbb 100644 --- a/doc/tutorial_resources/oai-cn5g/docker-compose.yaml +++ b/doc/tutorial_resources/oai-cn5g/docker-compose.yaml @@ -167,14 +167,11 @@ services: public_net: ipv4_address: 192.168.70.135 networks: - # public_net: - # external: - # name: demo-oai-public-net public_net: driver: bridge - name: demo-oai-public-net + name: oai-cn5g-public-net ipam: config: - subnet: 192.168.70.128/26 driver_opts: - com.docker.network.bridge.name: "demo-oai" + com.docker.network.bridge.name: "oai-cn5g" From 9278394f3c73c8a49ab822037fc56eaec2f59942 Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Thu, 9 May 2024 10:45:05 +0100 Subject: [PATCH 10/14] Tutorials: Update links for the latest Ubuntu 22.04 LTS iso file --- doc/NR_SA_Tutorial_COTS_UE.md | 2 +- doc/NR_SA_Tutorial_OAI_CN5G.md | 2 +- doc/NR_SA_Tutorial_OAI_nrUE.md | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/NR_SA_Tutorial_COTS_UE.md b/doc/NR_SA_Tutorial_COTS_UE.md index 7b7e235600..0924eee1b0 100644 --- a/doc/NR_SA_Tutorial_COTS_UE.md +++ b/doc/NR_SA_Tutorial_COTS_UE.md @@ -21,7 +21,7 @@ In this tutorial we describe how to configure and run a 5G end-to-end setup with Minimum hardware requirements: - Laptop/Desktop/Server for OAI CN5G and OAI gNB - - Operating System: [Ubuntu 22.04 LTS](https://releases.ubuntu.com/22.04/ubuntu-22.04.3-desktop-amd64.iso) + - Operating System: [Ubuntu 22.04 LTS](https://releases.ubuntu.com/22.04/ubuntu-22.04.4-desktop-amd64.iso) - CPU: 8 cores x86_64 @ 3.5 GHz - RAM: 32 GB - Laptop for UE diff --git a/doc/NR_SA_Tutorial_OAI_CN5G.md b/doc/NR_SA_Tutorial_OAI_CN5G.md index a07cf85631..07914b417a 100644 --- a/doc/NR_SA_Tutorial_OAI_CN5G.md +++ b/doc/NR_SA_Tutorial_OAI_CN5G.md @@ -21,7 +21,7 @@ In this tutorial we describe how to configure and run a 5G end-to-end setup with Minimum hardware requirements: - Laptop/Desktop/Server for OAI CN5G and OAI gNB - - Operating System: [Ubuntu 22.04 LTS](https://releases.ubuntu.com/22.04/ubuntu-22.04.3-desktop-amd64.iso) + - Operating System: [Ubuntu 22.04 LTS](https://releases.ubuntu.com/22.04/ubuntu-22.04.4-desktop-amd64.iso) - CPU: 8 cores x86_64 @ 3.5 GHz - RAM: 32 GB diff --git a/doc/NR_SA_Tutorial_OAI_nrUE.md b/doc/NR_SA_Tutorial_OAI_nrUE.md index be21f71097..30a8b52419 100644 --- a/doc/NR_SA_Tutorial_OAI_nrUE.md +++ b/doc/NR_SA_Tutorial_OAI_nrUE.md @@ -21,11 +21,11 @@ In this tutorial we describe how to configure and run a 5G end-to-end setup with Minimum hardware requirements: - Laptop/Desktop/Server for OAI CN5G and OAI gNB - - Operating System: [Ubuntu 22.04 LTS](https://releases.ubuntu.com/22.04/ubuntu-22.04.3-desktop-amd64.iso) + - Operating System: [Ubuntu 22.04 LTS](https://releases.ubuntu.com/22.04/ubuntu-22.04.4-desktop-amd64.iso) - CPU: 8 cores x86_64 @ 3.5 GHz - RAM: 32 GB - Laptop for UE - - Operating System: [Ubuntu 22.04 LTS](https://releases.ubuntu.com/22.04/ubuntu-22.04.3-desktop-amd64.iso) + - Operating System: [Ubuntu 22.04 LTS](https://releases.ubuntu.com/22.04/ubuntu-22.04.4-desktop-amd64.iso) - CPU: 8 cores x86_64 @ 3.5 GHz - RAM: 8 GB - [USRP B210](https://www.ettus.com/all-products/ub210-kit/), [USRP N300](https://www.ettus.com/all-products/USRP-N300/) or [USRP X300](https://www.ettus.com/all-products/x300-kit/) From 6379350f51ab9b39d1ee7f93be8b6cf1550955ab Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Thu, 16 May 2024 15:27:36 +0200 Subject: [PATCH 11/14] Correct data offset for unscrambling in PUSCH processing Correctly compute the offset of data to unscramble in PUSCH processing at the gNB. Rename variables to make them easier to spot (instead of "s"), and remove a global variable. Closes: #734 --- .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 36 +++++++++++++------ openair1/PHY/defs_gNB.h | 15 -------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 8ed0988ba6..723d13f65e 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -1389,6 +1389,20 @@ static void inner_rx(PHY_VARS_gNB *gNB, rel15_ul->qam_mod_order); } +typedef struct puschSymbolProc_s { + PHY_VARS_gNB *gNB; + NR_DL_FRAME_PARMS *frame_parms; + nfapi_nr_pusch_pdu_t *rel15_ul; + int ulsch_id; + int slot; + int startSymbol; + int numSymbols; + int16_t *llr; + int16_t **llr_layers; + int16_t *scramblingSequence; + uint32_t nvar; +} puschSymbolProc_t; + static void nr_pusch_symbol_processing(void *arg) { puschSymbolProc_t *rdata=(puschSymbolProc_t*)arg; @@ -1438,8 +1452,10 @@ static void nr_pusch_symbol_processing(void *arg) } // unscrambling int16_t *llr16 = (int16_t*)&rdata->llr[pusch_vars->llr_offset[symbol] * rel15_ul->nrOfLayers]; - for (int i = 0; i < (nb_re_pusch * rel15_ul->qam_mod_order * rel15_ul->nrOfLayers); i++) - llr16[i] = llr_ptr[i] * rdata->s[i]; + int16_t *s = rdata->scramblingSequence + pusch_vars->llr_offset[symbol] * rel15_ul->nrOfLayers; + const int end = nb_re_pusch * rel15_ul->qam_mod_order * rel15_ul->nrOfLayers; + for (int i = 0; i < end; i++) + llr16[i] = llr_ptr[i] * s[i]; } } @@ -1455,7 +1471,7 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB, NR_gNB_PUSCH *pusch_vars = &gNB->pusch_vars[ulsch_id]; pusch_vars->dmrs_symbol = INVALID_VALUE; - gNB->nbSymb = 0; + int nbSymb = 0; uint32_t bwp_start_subcarrier = ((rel15_ul->rb_start + rel15_ul->bwp_start) * NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size; LOG_D(PHY,"pusch %d.%d : bwp_start_subcarrier %d, rb_start %d, first_carrier_offset %d\n", frame,slot,bwp_start_subcarrier, rel15_ul->rb_start, frame_parms->first_carrier_offset); LOG_D(PHY,"pusch %d.%d : ul_dmrs_symb_pos %x\n",frame,slot,rel15_ul->ul_dmrs_symb_pos); @@ -1571,9 +1587,9 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB, gNB->ulsch[ulsch_id].unav_res = unav_res; // initialize scrambling sequence // - int16_t s[G+96] __attribute__((aligned(32))); + int16_t scramblingSequence[G + 96] __attribute__((aligned(32))); - nr_codeword_unscrambling_init(s, G, 0, rel15_ul->data_scrambling_id, rel15_ul->rnti); + nr_codeword_unscrambling_init(scramblingSequence, G, 0, rel15_ul->data_scrambling_id, rel15_ul->rnti); // first the computation of channel levels @@ -1674,23 +1690,23 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB, rdata->ulsch_id = ulsch_id; rdata->llr = pusch_vars->llr; rdata->llr_layers = pusch_vars->llr_layers; - rdata->s = &s[pusch_vars->llr_offset[symbol]*rel15_ul->nrOfLayers]; + rdata->scramblingSequence = scramblingSequence; rdata->nvar = nvar; if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { nr_pusch_symbol_processing(rdata); } else { pushTpool(&gNB->threadPool, req); - gNB->nbSymb++; + nbSymb++; } - LOG_D(PHY,"%d.%d Added symbol %d (count %d) to process, in pipe\n",frame,slot,symbol,gNB->nbSymb); + LOG_D(PHY, "%d.%d Added symbol %d (count %d) to process, in pipe\n", frame, slot, symbol, nbSymb); } } // symbol loop - while (gNB->nbSymb > 0) { + while (nbSymb) { notifiedFIFO_elt_t *req = pullTpool(&gNB->respPuschSymb, &gNB->threadPool); - gNB->nbSymb--; + nbSymb--; delNotifiedFIFO_elt(req); } diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index c31a5e007e..20413098bd 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -716,7 +716,6 @@ typedef struct PHY_VARS_gNB_s { notifiedFIFO_t L1_rx_out; notifiedFIFO_t resp_RU_tx; tpool_t threadPool; - int nbSymb; int num_pusch_symbols_per_thread; pthread_t L1_rx_thread; int L1_rx_thread_core; @@ -728,20 +727,6 @@ typedef struct PHY_VARS_gNB_s { rt_L1_profiling_t rt_L1_profiling; } PHY_VARS_gNB; -typedef struct puschSymbolProc_s { - PHY_VARS_gNB *gNB; - NR_DL_FRAME_PARMS *frame_parms; - nfapi_nr_pusch_pdu_t *rel15_ul; - int ulsch_id; - int slot; - int startSymbol; - int numSymbols; - int16_t *llr; - int16_t **llr_layers; - int16_t *s; - uint32_t nvar; -} puschSymbolProc_t; - struct puschSymbolReqId { uint16_t ulsch_id; uint16_t frame; From 7a631ce3a29ebbaef0ebe6391d6b5036b22c193a Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 23 May 2024 16:41:20 +0200 Subject: [PATCH 12/14] Use an enum for stream_status states --- executables/nr-ue.c | 14 +++++++------- openair1/PHY/defs_nr_UE.h | 4 +++- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 68b747de32..5b4326239b 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -529,7 +529,7 @@ void processSlotTX(void *arg) // Force sequential execution, even if we launch in // for all slots // at least ULstatus variable is a pure race condition that is quickly detected by assert() in the code because one thread sets it // to active, so the other thread try to steal&run the ul work - if (rxtxD->stream_status == 2) { + if (rxtxD->stream_status == STREAM_STATUS_SYNCED) { notifiedFIFO_elt_t *res = pullNotifiedFIFO(UE->tx_resume_ind_fifo + proc->nr_slot_tx); delNotifiedFIFO_elt(res); } @@ -751,7 +751,7 @@ void *UE_thread(void *arg) PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg; // int tx_enabled = 0; void *rxp[NB_ANTENNAS_RX]; - int start_rx_stream = 0; + enum stream_status_e stream_status = STREAM_STATUS_UNSYNC; fapi_nr_config_request_t *cfg = &UE->nrUE_config; int tmp = openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]); AssertFatal(tmp == 0, "Could not load the device\n"); @@ -801,7 +801,7 @@ void *UE_thread(void *arg) intialSyncOffset = syncMsg->rx_offset; } delNotifiedFIFO_elt(res); - start_rx_stream = 0; + stream_status = STREAM_STATUS_UNSYNC; } else { if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) { // For IQ recorder-player we force synchronization to happen in 280 ms @@ -831,8 +831,8 @@ void *UE_thread(void *arg) continue; } - if (start_rx_stream == 0) { - start_rx_stream=1; + if (stream_status == STREAM_STATUS_UNSYNC) { + stream_status = STREAM_STATUS_SYNCING; syncInFrame(UE, &sync_timestamp, intialSyncOffset); shiftForNextFrame = 0; // will be used to track clock drift // read in first symbol @@ -949,8 +949,8 @@ void *UE_thread(void *arg) curMsgTx->proc.timestamp_tx = writeTimestamp; curMsgTx->UE = UE; curMsgTx->tx_wait_for_dlsch = tx_wait_for_dlsch[curMsgTx->proc.nr_slot_tx]; - curMsgTx->stream_status = start_rx_stream; - start_rx_stream = 2; + curMsgTx->stream_status = stream_status; + stream_status = STREAM_STATUS_SYNCED; tx_wait_for_dlsch[curMsgTx->proc.nr_slot_tx] = 0; pushTpool(&(get_nrUE_params()->Tpool), newTx); } diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 93b9f360e5..f7eedcef3b 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -632,6 +632,8 @@ typedef struct nr_phy_data_s { sl_nr_rx_config_type_enum_t sl_rx_action; } nr_phy_data_t; + +enum stream_status_e { STREAM_STATUS_UNSYNC, STREAM_STATUS_SYNCING, STREAM_STATUS_SYNCED}; /* this structure is used to pass both UE phy vars and * proc to the function UE_thread_rxn_txnp4 */ @@ -642,7 +644,7 @@ typedef struct nr_rxtx_thread_data_s { nr_phy_data_t phy_data; int tx_wait_for_dlsch; int rx_offset; - int stream_status; + enum stream_status_e stream_status; } nr_rxtx_thread_data_t; typedef struct LDPCDecode_ue_s { From b5159b5e47e98da9d02545dbb0bf101fbb78ae9c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 24 May 2024 06:54:15 +0200 Subject: [PATCH 13/14] Revert "ci: set min_rxtxtime = 2 in OAIUE pipeline" This reverts commit 31b4f48e29170e25e5375e781860cf14eaebee43. --- ci-scripts/conf_files/gnb.sa.band78.106prb.n310.7ds2u.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/conf_files/gnb.sa.band78.106prb.n310.7ds2u.conf b/ci-scripts/conf_files/gnb.sa.band78.106prb.n310.7ds2u.conf index ce7b354eba..540774e2d1 100644 --- a/ci-scripts/conf_files/gnb.sa.band78.106prb.n310.7ds2u.conf +++ b/ci-scripts/conf_files/gnb.sa.band78.106prb.n310.7ds2u.conf @@ -19,7 +19,7 @@ gNBs = ////////// Physical parameters: - min_rxtxtime = 2; + min_rxtxtime = 5; do_SRS = 0; force_256qam_off = 1; pdsch_AntennaPorts_N1 = 1; From 58335443b132cbdfa2e473ca840ad7a7bfe5a143 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 24 May 2024 06:54:23 +0200 Subject: [PATCH 14/14] Revert "remove asserts on min RX/TX, set the RX/TX shift as 2 in the UE" This reverts commit 0d0e1111354877464a213663c60dfb45872e399e. It was set to UE RX to TX time to 2 as it was deemed that the UE could sustain this time. However, we noticed a degradation of performance, so reset the RX to TX time to something higher to ensure proper performance. --- openair1/PHY/impl_defs_top.h | 2 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 10 ++++++++++ openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 18 ++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/openair1/PHY/impl_defs_top.h b/openair1/PHY/impl_defs_top.h index e43100d32a..c06cd13ff7 100644 --- a/openair1/PHY/impl_defs_top.h +++ b/openair1/PHY/impl_defs_top.h @@ -272,7 +272,7 @@ /* - between reception of pdsch and tarnsmission of its acknowlegment */ /* - between reception of un uplink grant and its related transmission */ // should be 2 as per NR standard, but current UE is not able to perform this value -#define NR_UE_CAPABILITY_SLOT_RX_TO_TX (2) +#define NR_UE_CAPABILITY_SLOT_RX_TO_TX (3) #define DURATION_RX_TO_TX (NR_UE_CAPABILITY_SLOT_RX_TO_TX) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 60f0d2d5d3..490235445f 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -785,6 +785,10 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac, } if (dci_ind->rnti != mac->ra.ra_rnti && dci_ind->rnti != SI_RNTI) + AssertFatal(1 + dci->pdsch_to_harq_feedback_timing_indicator.val > DURATION_RX_TO_TX, + "PDSCH to HARQ feedback time (%d) needs to be higher than DURATION_RX_TO_TX (%d).\n", + 1 + dci->pdsch_to_harq_feedback_timing_indicator.val, + DURATION_RX_TO_TX); // set the harq status at MAC for feedback set_harq_status(mac, @@ -1112,6 +1116,12 @@ static int nr_ue_process_dci_dl_11(NR_UE_MAC_INST_t *mac, // according to TS 38.213 Table 9.2.3-1 uint8_t feedback_ti = pucch_Config->dl_DataToUL_ACK->list.array[dci->pdsch_to_harq_feedback_timing_indicator.val][0]; + AssertFatal(feedback_ti > DURATION_RX_TO_TX, + "PDSCH to HARQ feedback time (%d) needs to be higher than DURATION_RX_TO_TX (%d). Min feedback time set in config " + "file (min_rxtxtime).\n", + feedback_ti, + DURATION_RX_TO_TX); + // set the harq status at MAC for feedback set_harq_status(mac, dci->pucch_resource_indicator, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index c18189a683..d04fe1a295 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1007,6 +1007,9 @@ void nr_ue_aperiodic_srs_scheduling(NR_UE_MAC_INST_t *mac, long resource_trigger return; } + AssertFatal(slot_offset > DURATION_RX_TO_TX, + "Slot offset between DCI and aperiodic SRS (%d) needs to be higher than DURATION_RX_TO_TX (%d)\n", + slot_offset, DURATION_RX_TO_TX); int n_slots_frame = nr_slots_per_frame[current_UL_BWP->scs]; int sched_slot = (slot + slot_offset) % n_slots_frame; NR_TDD_UL_DL_ConfigCommon_t *tdd_config = mac->tdd_UL_DL_ConfigurationCommon; @@ -1465,6 +1468,13 @@ int nr_ue_pusch_scheduler(const NR_UE_MAC_INST_t *mac, AssertFatal(1 == 0, "Invalid numerology %i\n", mu); } + AssertFatal((k2 + delta) > DURATION_RX_TO_TX, + "Slot offset (%ld) for Msg3 needs to be higher than DURATION_RX_TO_TX (%d). Please set min_rxtxtime at least to %d in gNB config file or gNBs.[0].min_rxtxtime=%d via command line.\n", + k2, + DURATION_RX_TO_TX, + DURATION_RX_TO_TX, + DURATION_RX_TO_TX); + *slot_tx = (current_slot + k2 + delta) % nr_slots_per_frame[mu]; if (current_slot + k2 + delta >= nr_slots_per_frame[mu]){ *frame_tx = (current_frame + 1) % 1024; @@ -1473,6 +1483,14 @@ int nr_ue_pusch_scheduler(const NR_UE_MAC_INST_t *mac, } } else { + + AssertFatal(k2 > DURATION_RX_TO_TX, + "Slot offset K2 (%ld) needs to be higher than DURATION_RX_TO_TX (%d). Please set min_rxtxtime at least to %d in gNB config file or gNBs.[0].min_rxtxtime=%d via command line.\n", + k2, + DURATION_RX_TO_TX, + DURATION_RX_TO_TX, + DURATION_RX_TO_TX); + if (k2 < 0) { // This can happen when a false DCI is received LOG_W(PHY, "%d.%d. Received k2 %ld\n", current_frame, current_slot, k2); return -1;