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; 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/) 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 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" diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 975d8ea26e..6012db86e0 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 == STREAM_STATUS_SYNCED) { + 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); } @@ -743,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"); @@ -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); @@ -796,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 @@ -826,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); openair0_write_reorder_clear_context(&UE->rfdevice); shiftForNextFrame = 0; // will be used to track clock drift @@ -938,25 +943,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 = stream_status; + stream_status = STREAM_STATUS_SYNCED; 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; } 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_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/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); 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_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; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index c746bd69b8..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,6 +644,7 @@ typedef struct nr_rxtx_thread_data_s { nr_phy_data_t phy_data; int tx_wait_for_dlsch; int rx_offset; + enum stream_status_e stream_status; } nr_rxtx_thread_data_t; typedef struct LDPCDecode_ue_s { 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/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); } } 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); } 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); } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 07861cf811..91dd4830ed 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -788,6 +788,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, @@ -1115,6 +1119,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, @@ -1852,10 +1862,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) @@ -2201,18 +2218,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); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index a94614446b..9e66064f3d 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; @@ -1007,6 +1009,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 +1470,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 +1485,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;