diff --git a/CHANGELOG.md b/CHANGELOG.md index a9b355d079..c807b7f86a 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,71 @@ # RELEASE NOTES: # +## [v2.4.0](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v2.4.0) -> December 2025. ## + +General new features and improvements (both RAN and UE): +- Rework LDPC BBdev/AAL interface and support both AMD T2/Intel vRAN Boost + (VRB) 1 accelerators +- Add a taps client for vrtsim real-time simulator (check: vrtsim release?) +- Add new RFemulator virtual radio driver to emulate radio (including noise + generation) for gNB/UE standalone operation +- RLC AM reception improvements for high-throughput scenarios (!3512) +- Small NTN fixes (!3659, !3666, !3581, !3652) +- Improvements to imScope + +Stability and bug fixes: +- RFsimulator: fix concurrency problems during multi-client connection +- USRP driver: support synchronization of USRP B200 +- MAC scheduler improvements +- General L1 improvements for efficiency and stability +- Correct PRS bug and test in CI +- Upgrade Ubuntu container images to Ubuntu 24.04 +- All build system targets compile (`make/ninja all`) +- Minor cleanup, harmonization, and performance improvements all over the stack +- Simplify CI code + +RAN changes (gNB/CU/CU-CP/CU-UP/DU/DU-high/DU-low): +- Support of N2 handover +- Support of "UL-heavy" TDD patterns, e.g., DSUUU +- Open Fronthaul M-plane: CM improvements, PM implementation, and additional + v16.01 support +- Improve interoperability with Nvidia Aerial L1 to support 2 layer UL +- Add O-RAN OSC WLS library as FAPI transport and enable L1/L2 shared memory + split +- Implement FAPI Stop exchange +- Improve interoperability with srsRAN_Project DU +- Add new synchronized real-time data recording application (!3462) +- Support for measurement gaps and general handover fixes +- Support of RRC PDU session release procedure +- Add CU-UP load tester +- Correct BWP scheduling and support multiple BWPs per UE + +nrUE changes: +- Support one additional PDU session (see !3486) +- L3 measurements for A2 measurement reports +- Support for type0 PDSCH frequency allocation +- UE symbol based PDCCH receiver + +Regression or removals: +- No known regressions +- Unused L2 simulator code has been removed +- Unused Benetel radio driver code (not FHI 7.2!) has been removed + +Configuration file changes: +- `gNBs.[0].servingCellConfigCommon.[0].ra_ResponseWindow` is automatically + computed and can be removed +- `gNBs.[0].bwp_list` has been added (moved from entries in + `gNBs.[0].servingCellConfigDedicated`) +- `gNBs.[0].phaseTrackingRS` has been added (moved from entries in + `gNBs.[0].servingCellConfigDedicated`) +- `gNBs.[0].local_s_portc` and `gNBs.[0].remote_s_portc` have no effect and + should be removed +- `gNBs.[0].CSI_report_type` has been added +- `MACRLCs.[0].ulsch_max_frame_inactivity` is automatically computed and can be + removed +- `MACRLCs.[0].local_n_portc` and `MACRLCs.[0].remote_n_portc` have no effect and + should be removed +- `MACRLCs.[0].stats_max_ue` has been added + ## [v2.3.0](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v2.3.0) -> July 2025. ## General new features and improvements (both RAN and UE): diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f8a6006bf..70ea409d36 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -464,6 +464,9 @@ target_include_directories(f1ap PUBLIC F1AP_DIR) target_link_libraries(f1ap PUBLIC asn1_f1ap GTPV1U) target_link_libraries(f1ap PRIVATE ngap nr_rrc HASHTABLE f1ap_lib) target_include_directories(f1ap PRIVATE ${F1AP_DIR}/lib) +if(E2_AGENT) + target_compile_definitions(f1ap PRIVATE E2_AGENT) +endif() # LPP ############## @@ -1288,6 +1291,9 @@ add_library(L2 ) target_link_libraries(L2 PRIVATE x2ap s1ap lte_rrc m2ap) target_link_libraries(L2 PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) +if(E2_AGENT) + target_compile_definitions(L2 PRIVATE ${E2AP_VERSION} ${KPM_VERSION} E2_AGENT) +endif() add_library(MAC_UE_NR ${MAC_NR_SRC_UE}) target_link_libraries(MAC_UE_NR PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs PUBLIC nr_ue_power_procedures nr_ue_ra_procedures) @@ -1303,6 +1309,9 @@ add_library(L2_NR target_link_libraries(L2_NR PRIVATE ds alg) target_link_libraries(L2_NR PRIVATE f1ap_lib) target_include_directories(L2_NR PRIVATE ${F1AP_DIR}/lib) +if(E2_AGENT) + target_compile_definitions(L2_NR PRIVATE ${E2AP_VERSION} ${KPM_VERSION} E2_AGENT) +endif() add_library(e1_if ${NR_RRC_DIR}/cucp_cuup_direct.c diff --git a/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf b/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf index 4daf7c62fd..58ba62696a 100644 --- a/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf +++ b/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf @@ -146,7 +146,11 @@ gNBs = ); first_active_bwp = 1; - bwp_list = ({ scs = 1; bwpStart = 0; bwpSize = 106;}); + bwp_list = ( + { scs = 1; bwpStart = 0; bwpSize = 106;}, + { scs = 1; bwpStart = 0; bwpSize = 36;}, + { scs = 1; bwpStart = 36; bwpSize = 70;} + ); # ------- SCTP definitions SCTP : diff --git a/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml b/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml index 89a5ebfd6c..836143431a 100644 --- a/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml +++ b/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml @@ -30,20 +30,28 @@ 310000 800813 330101 - 330102 - 330103 310001 400001 350000 - 370001 - 370000 - 370002 370003 370004 + 370002 360001 100002 360002 350000 + 410002 + 370012 + 400002 + 410003 + 370013 + 400003 + 410000 + 350000 + 400000 + 410001 + 350000 + 400001 310011 310002 330201 @@ -88,24 +96,10 @@ Deploy_Object - Deploy gNB-CU-CP in a container + Deploy gNB-CU-CP/gNB-CU-UP/gNB-DU (TDD/n76/40MHz/B200) ofqot ci-scripts/yaml_files/sa_e1_b200_gnb - gnb_cucp - - - Deploy_Object - Deploy gNB-CU-UP in a container - ofqot - ci-scripts/yaml_files/sa_e1_b200_gnb - gnb_cuup - - - Deploy_Object - Deploy gNB-DU (TDD/Band78/40MHz/B200) in a container - ofqot - ci-scripts/yaml_files/sa_e1_b200_gnb - gnb_du_tdd + gnb_cucp gnb_cuup gnb_du_tdd @@ -132,16 +126,6 @@ 25 - - Iperf - iperf (DL/80Mbps/UDP)(30 sec) - -u -b 80M -t 30 -R - idefix - sabox-nepes - 10 - 95 - - Custom_Command Check UE is on dedicated BWP ID 1 @@ -149,19 +133,76 @@ echo ci get_current_bwp | nc -N 127.0.0.1 9091 | grep 'DL BWP ID 1 (dedicated) UL BWP ID 1 (dedicated)' - + + Custom_Command + Switch to dedicated BWP ID 1 + ofqot + echo ci trigger_bwp_switch 1 | nc -N 127.0.0.1 9091 | grep 'triggered BWP switch to BWP ID 1 for UE' + + + + Custom_Command + Check UE is on initial BWP ID 0 + ofqot + echo ci get_current_bwp | nc -N 127.0.0.1 9091 | grep 'DL BWP ID 0 (initial) UL BWP ID 0 (initial)' + + + + Custom_Command + Switch to dedicated BWP ID 2 + ofqot + echo ci trigger_bwp_switch 2 | nc -N 127.0.0.1 9091 | grep 'triggered BWP switch to BWP ID 2 for UE' + + + Iperf - iperf (UL/8Mbps/UDP)(30 sec) - -u -b 8M -t 30 + iperf (DL/TCP)(10 sec)(single-ue profile) + -t 10 -R idefix sabox-nepes - 1 - 95 + 35 + + + + Custom_Command + Check UE is on dedicated BWP ID 2 + ofqot + echo ci get_current_bwp | nc -N 127.0.0.1 9091 | grep 'DL BWP ID 2 (dedicated) UL BWP ID 2 (dedicated)' + + + + Custom_Command + Switch to dedicated BWP ID 3 + ofqot + echo ci trigger_bwp_switch 3 | nc -N 127.0.0.1 9091 | grep 'triggered BWP switch to BWP ID 3 for UE' + + + + Iperf + iperf (DL/TCP)(10 sec)(single-ue profile) + -t 10 -R + idefix + sabox-nepes + 85 + + + + Custom_Command + Check UE is on dedicated BWP ID 3 + ofqot + echo ci get_current_bwp | nc -N 127.0.0.1 9091 | grep 'DL BWP ID 3 (dedicated) UL BWP ID 3 (dedicated)' + + + + Custom_Command + Switch to initial BWP ID 0 + ofqot + echo ci trigger_bwp_switch 0 | nc -N 127.0.0.1 9091 | grep 'triggered BWP switch to BWP ID 0 for UE' Iperf - iperf (BIDIR TCP)(10 sec)(single-ue profile) + iperf (BIDIR TCP)(20 sec)(single-ue profile) -t 20 --bidir idefix sabox-nepes @@ -169,17 +210,17 @@ Iperf - iperf (DL/TCP)(30 sec)(single-ue profile) - -t 30 -R + iperf (DL/TCP)(20 sec)(single-ue profile) + -t 20 -R idefix sabox-nepes - 30 + 140 Iperf - iperf (UL/TCP)(30 sec)(single-ue profile) - -t 30 + iperf (UL/TCP)(20 sec)(single-ue profile) + -t 20 idefix sabox-nepes 15 diff --git a/ci-scripts/yaml_files/sa_gnb_aerial/docker-compose.yaml b/ci-scripts/yaml_files/sa_gnb_aerial/docker-compose.yaml index f04beeb6c2..4050fa5310 100644 --- a/ci-scripts/yaml_files/sa_gnb_aerial/docker-compose.yaml +++ b/ci-scripts/yaml_files/sa_gnb_aerial/docker-compose.yaml @@ -33,7 +33,7 @@ services: timeout: 5s retries: 5 oai-gnb-aerial: - cpuset: "13-14" + cpuset: "13-16" image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb-aerial}:${TAG:-develop} depends_on: nv-cubb: diff --git a/common/utils/telnetsrv/telnetsrv_ci.c b/common/utils/telnetsrv/telnetsrv_ci.c index 8b00d529c5..10f9626ef0 100644 --- a/common/utils/telnetsrv/telnetsrv_ci.c +++ b/common/utils/telnetsrv/telnetsrv_ci.c @@ -38,6 +38,7 @@ #include "openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h" #include "openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h" #include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" +#include "openair2/LAYER2/NR_MAC_gNB/mac_config.h" #include "openair2/RRC/NR/rrc_gNB_mobility.h" #include "openair3/NGAP/ngap_gNB_ue_context.h" @@ -276,6 +277,8 @@ static int get_current_bwp(char *buf, int debug, telnet_printfunc_t prnt) if (rnti < 0) ERROR_MSG_RET("could not identify UE (no UE, no such RNTI, or multiple UEs)\n"); NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, rnti); + if (!UE) + ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti); int dl_bwp = UE->current_DL_BWP.bwp_id; const char *dl_bwp_text = dl_bwp > 0 ? "dedicated" : "initial"; int ul_bwp = UE->current_UL_BWP.bwp_id; @@ -348,7 +351,7 @@ static int trigger_ngap_pdu_session_release(char *buf, int debug, telnet_printfu if (sid < 1 || sid > 255) { ERROR_MSG_RET("Invalid pdusession_id(int): %s (must be between 1 and 255)\n", tokens[i]); } - msg->pdusession_release_params[nb_sessions++].pdusession_id = sid; + msg->pdusession_ids[nb_sessions++] = sid; } msg->nb_pdusessions_torelease = nb_sessions; @@ -356,7 +359,7 @@ static int trigger_ngap_pdu_session_release(char *buf, int debug, telnet_printfu if (prnt) { prnt("Triggering NGAP PDU Session Release for gNB_ue_ngap_id=%d: releasing pdusession_id=%d", gNB_ue_ngap_id); for (int i = 0; i < nb_sessions; ++i) { - prnt(" %d,", msg->pdusession_release_params[i].pdusession_id); + prnt(" %d,", msg->pdusession_ids[i]); } prnt("\n"); } @@ -365,6 +368,24 @@ static int trigger_ngap_pdu_session_release(char *buf, int debug, telnet_printfu return 0; } +static int trigger_bwp_switch(char *buf, int debug, telnet_printfunc_t prnt) +{ + char *sbwpId = strtok(buf, " "); + int bwpId = atoi(sbwpId); + char *srnti = strtok(NULL, " "); + prnt("bwpId %d rnti %s\n", bwpId, srnti); + int rnti = fetch_rnti(srnti, prnt); + if (rnti < 0) + ERROR_MSG_RET("could not identify UE (no UE, no such RNTI, or multiple UEs)\n"); + if (!nr_trigger_bwp_switch(rnti, bwpId)) { + prnt("failed trigger BWP switch for UE %04x BWP ID %d\n", rnti, bwpId); + return -1; + } else { + prnt("triggered BWP switch to BWP ID %d for UE %04x\n", bwpId, rnti); + return 0; + } +} + static telnetshell_cmddef_t cicmds[] = { {"get_single_rnti", "", get_single_rnti}, {"force_reestab", "[rnti(hex,opt)]", trigger_reestab}, @@ -374,6 +395,7 @@ static telnetshell_cmddef_t cicmds[] = { {"trigger_f1_ho", "[rrc_ue_id(int,opt)]", rrc_gNB_trigger_f1_ho}, {"fetch_du_by_ue_id", "[rrc_ue_id(int,opt)]", fetch_du_by_ue_id}, {"get_current_bwp", "[rnti(hex,opt)]", get_current_bwp}, + {"trigger_bwp_switch", "newBWPId [rnti(hex,opt)]", trigger_bwp_switch}, {"trigger_n2_ho", "[neighbour_pci(uint32_t),ueId(uint32_t)]", rrc_gNB_trigger_n2_ho}, {"pdu_session_release", "[gNB_ue_ngap_id(int,opt)]", trigger_ngap_pdu_session_release}, {"", "", NULL}, diff --git a/doc/Aerial_FAPI_Split_Tutorial.md b/doc/Aerial_FAPI_Split_Tutorial.md index 6eef02dc34..23ce37312d 100644 --- a/doc/Aerial_FAPI_Split_Tutorial.md +++ b/doc/Aerial_FAPI_Split_Tutorial.md @@ -82,7 +82,7 @@ of the FAPI 10.04 version of the SRS PDU, and RX_Beamforming PDU. | Applicative Threads | Allocated CPUs | |------------------------|----------------| | PTP & PHC2SYS Services | 41 | -| OAI `nr-softmodem` | 13-14 | +| OAI `nr-softmodem` | 13-16 | ## PTP configuration diff --git a/doc/MAC/mac-usage.md b/doc/MAC/mac-usage.md index a3b174f50c..2fa56c2ce4 100644 --- a/doc/MAC/mac-usage.md +++ b/doc/MAC/mac-usage.md @@ -420,3 +420,29 @@ Note that you should increase the aggregation level candidates as described in [the corresponding section above](#pdcch-aggregation-level). This is because the scheduler has to schedule multiple DCIs in a single DL slots for multiple UL slots. As a suggestion, you could try `uess_agg_levels = [4, 2, 2, 0, 0]`. + +## Multiple Dedicated BWPs + +A maximum of 4 dedicated BWPs can be configured for a UE per standard, but only +1 BWP can be active in UL and DL direction at a given time. In the code we +only configure a single BWP for the UE at a given time and we would switch by +reconfiguring this BWP. All this procedure is transparent for users and LOGs +mark BWP switching according to the configuration file enumeration. It is +possible to configure multiple dedicated BWPs and 1st active BWP via +configuration file. + +### Setup of the Configuration files ## + +In the configuration file you have the option to select the 1st active BWP, the +BWP location and SCS of each BWP in the following way (example with 2 +additional BWPs): + +``` + first_active_bwp = 1; + bwp_list = ({ scs = 1; bwpStart = 0; bwpSize = 106;}, + { scs = 1; bwpStart = 0; bwpSize = 24;}); +``` + +This example configures 3 additional BWPs, with IDs from 1 to 3. A similar +example can be found in configuration file +`ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf` tested in CI. diff --git a/doc/RUN_NR_multiple_BWPs.md b/doc/RUN_NR_multiple_BWPs.md deleted file mode 100644 index e8598a0445..0000000000 --- a/doc/RUN_NR_multiple_BWPs.md +++ /dev/null @@ -1,44 +0,0 @@ -# Procedure to add dedicated Bandwidth part (BWP) - -## Contributed by 5G Testbed IISc - -### Developers: Abhijith A, Shruthi S - -# Terminology # - -## Bandwidth part (BWP) ## -Bandwidth Part (BWP) is a set of contiguous Resource Blocks in the resource grid. - -Parameters of a BWP are communicated to UE using RRC parameters: BWP-Downlink and BWP-Uplink. - -A UE can be configured with a set of 4 BWPs in uplink (UL) and downlink (DL) direction (3GPP TS 38.331 Annex B.2 Description of BWP configuration options). But only 1 BWP can be active in UL and DL direction at a given time. - -# Procedure to run multiple dedicated BWPs # - -A maximum of 4 dedicated BWPs can be configured for a UE. - -To configure multiple BWPs, add the following parameters in the physical parameters section: - -## Setup of the Configuration files ## - -In the configuration file you have the option to select the 1st active BWP, the RIV and SCS of each BWP in the following way (example with 3 additional BWPs): -``` - first_active_bwp = 1; - bwp_list = ({ scs = 1; bwpStart = 0; bwpSize = 106;}, - { scs = 1; bwpStart = 0; bwpSize = 51;}, - { scs = 1; bwpStart = 0; bwpSize = 24;}); -``` - -This example configures 3 additional BWPs, with IDs from 1 to 3. Find these parameters in this configuration file: "ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.neighbour.conf" - -# Testing gNB and UE in RF simulator - -## gNB command: -``` - sudo ./nr-softmodem -O ../../../ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.neighbour.conf --rfsim --rfsimulator.serveraddr server -``` - -## UE command: -``` - sudo ./nr-uesoftmodem -C 3319680000 -r 106 --numerology 1 --ssb 516 --band 78 --rfsim --rfsimulator.serveraddr 127.0.0.1 -``` diff --git a/doc/environment-variables.md b/doc/environment-variables.md index 767afa6db4..6fb7b884ae 100644 --- a/doc/environment-variables.md +++ b/doc/environment-variables.md @@ -9,7 +9,8 @@ OAI uses/supports a number of environment variables, documented in the following - `NVRAM_DIR`: directory to read/write NVRAM data in (5G) `nvram` tool; if not defined, will use `PWD` (working directory) - `OAI_CONFIGMODULE`: can be used to pass the configuration file instead of `-O` - `OAI_GDBSTACKS`: if defined when hitting an assertion (`DevAssert()`, `AssertFatal()`, ...), OAI will load `gdb` and provide a backtrace for every thread -- `OAI_RNGSEED`: overwrites any seed for random number generators (RNG) in simulators +- `OAI_RNGSEED`: provide a fixed seed for random number generators (RNG). If + this variable is absent, a random seed will be read (from `/dev/urandom`). - `USIM_DIR`: directory to read/write USIM data in (4G) `usim` tool; if not defined, will use `PWD` (working directory) Furthermore, these variables appear in code that is not maintained and maybe not even compiled anywhere: diff --git a/doc/nfapi.md b/doc/nfapi.md index b901b15269..5f2d8a35da 100644 --- a/doc/nfapi.md +++ b/doc/nfapi.md @@ -1,3 +1,5 @@ +# FAPI/nFAPI split in OAI + This document describes the SmallCellForum (SCF) (n)FAPI split in 5G, i.e., between the MAC/L2 and PHY/L1. It also describes how to make use of the multiple transport mechanisms between the 2. @@ -10,7 +12,7 @@ about nFAPI can be found in SCF 225.2.0. [[_TOC_]] -# Quickstart +## Quickstart Compile OAI as normal. Start the CN and make sure that the VNF configuration matches the PLMN/IP addresses. Then, run the VNF @@ -29,7 +31,7 @@ VNF!) You should not observe a difference between nFAPI split and monolithic. -# Status +## Status All FAPI message can be transferred between VNF and PNF. This is because OAI uses FAPI with its corresponding messages internally, whether a split is in use @@ -54,7 +56,7 @@ When using RFsim, the system might run slower than in monolithic. This is because the PNF needs to slow down the execution time of a specific slot, because it has to send a Slot.indication to the VNF for scheduling. -# Configuration +## Configuration Both PNF and VNF are run through the `nr-softmodem` executable. The type of mode is switched through the `--nfapi` switch, with options `MONOLITHIC` @@ -173,6 +175,26 @@ After installing WLS, you can run the build command as shown below: Refer to the above steps in [Quickstart](#quickstart), but run the PNF first as it is the WLS "master". +To optimize the performance of your setup, you can provide the option +`--thread-pool ` in the PNF command line. This allows +you to pin PNF processing threads to specific CPU cores, as they might +otherwise interfere with DPDK used by WLS. + +Before selecting which CPU cores to allocate: run `nr-softmodem` without the +`--thread-pool` option and use a process monitoring tool such as htop to check +CPU availability. Check for lightly loaded cores, and use them in the +thread-pool for the PNF. + +Example commands for running an OTA test with USRP B200 on 40MHz: + +Run PNF + + sudo NFAPI_TRACE_LEVEL=info ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-pnf.band78.rfsim.conf --nfapi PNF --continuous-tx -E --thread-pool 1,2,3,4,5 + +Run VNF + + sudo NFAPI_TRACE_LEVEL=info ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.band78.106prb.nfapi.conf --nfapi VNF + #### How to run OAI PNF with OSC/Radisys O-DU Set up the hugepages for DPDK (1GB page size, 6 pages; this only needs to be @@ -236,7 +258,7 @@ Run the OAI-UE sudo ./nr-uesoftmodem -r 273 --numerology 1 --band 78 -C 3400140000 --ssb 1518 --uicc0.imsi 001010000000001 --rfsim -# nFAPI logging system +## nFAPI logging system nFAPI has its own logging system, independent of OAI's. It can be activated by setting the `NFAPI_TRACE_LEVEL` environment variable to an appropriate value; @@ -263,3 +285,26 @@ done over virtual time, i.e., frames/slots as executed by the 5G Systems. For instance, these numbers might be slightly higher or slower in RFsim than in wall-clock time, depending if the system advances faster or slower than wall-clock time. + +## Troubleshoot + +When operating using the FAPI split, the PNF needs to give the VNF extra time +to schedule the next slot. Especially since the current nFAPI split still +relies on slot indications, extra time due to transport delays need to be +accounted for. Currently, this delay is set conservatively, meaning that it +should work for most systems, but can create problems during random access: + + [NR_MAC] exceeded RA window: preamble at 411.19 now 413.0 (diff 21), ra_ResponseWindow 5/20 slots + [NR_MAC] sfn: 413.0 UE RA-RNTI 010b TC-RNTI 5d82: exceeded RA window, cannot schedule Msg2 + +means that the VNF received a preamble (411.19), but the current slot to be +scheduled (413.0) is beyond the random access response window (20 slots). In +this case, try one of the following: + +- If the radio allows, reduce the L1 TX advance `RUs.[0].sl_ahead` by some + slots, but note that this could make the system less stable. +- Change the code to reduce `sl_ahead` inside function `handle_nr_slot_ind()`, + to reduce the FAPI scheduling slot time budget. +- Non-standard: You can manually increase the response window by setting + `gNBs.[0].servingCellConfigCommon.[0].ra_ResponseWindow` to, e.g., 6. Note + that the maximum allowed response window is 10ms. diff --git a/docker/Dockerfile.base.rhel9 b/docker/Dockerfile.base.rhel9 index dde540556b..e57c705471 100644 --- a/docker/Dockerfile.base.rhel9 +++ b/docker/Dockerfile.base.rhel9 @@ -73,6 +73,10 @@ ENV TINI_VERSION=v0.19.0 ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-${TARGETARCH} /tini RUN chmod +x /tini +ENV YQ_VERSION=v4.2.0 +RUN wget https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_${TARGETARCH} -O /usr/local/bin/yq &&\ + chmod +x /usr/local/bin/yq + # In some network environments, GIT proxy is required RUN /bin/bash -c "if [[ -v NEEDED_GIT_PROXY ]]; then git config --global http.proxy $NEEDED_GIT_PROXY; fi" diff --git a/docker/Dockerfile.base.rocky b/docker/Dockerfile.base.rocky index 98a9ef703a..d34dcdafc6 100644 --- a/docker/Dockerfile.base.rocky +++ b/docker/Dockerfile.base.rocky @@ -66,6 +66,10 @@ ENV TINI_VERSION=v0.19.0 ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-${TARGETARCH} /tini RUN chmod +x /tini +ENV YQ_VERSION=v4.2.0 +RUN wget https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_${TARGETARCH} -O /usr/local/bin/yq &&\ + chmod +x /usr/local/bin/yq + # Copying only the needed files to create ran-base WORKDIR /oai-ran/cmake_targets/tools COPY cmake_targets/tools/build_helper \ diff --git a/docker/Dockerfile.base.ubuntu b/docker/Dockerfile.base.ubuntu index 34dadd1757..ee42085a40 100644 --- a/docker/Dockerfile.base.ubuntu +++ b/docker/Dockerfile.base.ubuntu @@ -60,6 +60,10 @@ RUN apt-get update && \ ENV TINI_VERSION=v0.19.0 RUN wget https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-${TARGETARCH} -O /tini && chmod +x /tini +ENV YQ_VERSION=v4.2.0 +RUN wget https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_${TARGETARCH} -O /usr/local/bin/yq &&\ + chmod +x /usr/local/bin/yq + # In some network environments, GIT proxy is required RUN /bin/bash -c "if [[ -v NEEDED_GIT_PROXY ]]; then git config --global http.proxy $NEEDED_GIT_PROXY; fi" diff --git a/docker/Dockerfile.gNB.aerial.ubuntu b/docker/Dockerfile.gNB.aerial.ubuntu index 04bed658fe..b79ab78fa8 100644 --- a/docker/Dockerfile.gNB.aerial.ubuntu +++ b/docker/Dockerfile.gNB.aerial.ubuntu @@ -110,6 +110,8 @@ RUN ldconfig && \ /usr/local/lib/libnvipc.so WORKDIR /opt/oai-gnb + +COPY --from=ran-build /usr/local/bin/yq /usr/local/bin/yq COPY --from=ran-build /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] CMD ["/opt/oai-gnb/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.aw2s.rhel9 b/docker/Dockerfile.gNB.aw2s.rhel9 index 65eafac37b..e35b0a7690 100644 --- a/docker/Dockerfile.gNB.aw2s.rhel9 +++ b/docker/Dockerfile.gNB.aw2s.rhel9 @@ -101,6 +101,7 @@ RUN ln -s /usr/local/lib/libaw2sori_transpro.so /usr/local/lib/libthirdparty_tra WORKDIR /opt/oai-gnb-aw2s +COPY --from=gnb-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb-aw2s/bin/entrypoint.sh"] CMD ["/opt/oai-gnb-aw2s/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.aw2s.rocky b/docker/Dockerfile.gNB.aw2s.rocky index 1c0adfccd8..d1f567cb42 100644 --- a/docker/Dockerfile.gNB.aw2s.rocky +++ b/docker/Dockerfile.gNB.aw2s.rocky @@ -51,7 +51,8 @@ RUN dnf update -y && \ lksctp-tools \ tzdata \ net-tools \ - iputils && \ + iputils \ + yaml-cpp-devel && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf @@ -95,6 +96,7 @@ RUN ln -s /usr/local/lib/libaw2sori_transpro.so /usr/local/lib/libthirdparty_tra WORKDIR /opt/oai-gnb-aw2s +COPY --from=gnb-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb-aw2s/bin/entrypoint.sh"] CMD ["/opt/oai-gnb-aw2s/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.aw2s.ubuntu b/docker/Dockerfile.gNB.aw2s.ubuntu index b55977dfab..840b4a8a28 100644 --- a/docker/Dockerfile.gNB.aw2s.ubuntu +++ b/docker/Dockerfile.gNB.aw2s.ubuntu @@ -95,6 +95,7 @@ RUN /bin/bash -c "ln -s /usr/local/lib/libaw2sori_transpro.so /usr/local/lib/lib WORKDIR /opt/oai-gnb-aw2s +COPY --from=gnb-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb-aw2s/bin/entrypoint.sh"] CMD ["/opt/oai-gnb-aw2s/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.fhi72.rhel9 b/docker/Dockerfile.gNB.fhi72.rhel9 index 122b3b668d..bda79eba28 100644 --- a/docker/Dockerfile.gNB.fhi72.rhel9 +++ b/docker/Dockerfile.gNB.fhi72.rhel9 @@ -126,6 +126,8 @@ RUN ldconfig && \ /opt/phy/fhi_lib/lib/build/libxran.so WORKDIR /opt/oai-gnb + +COPY --from=gnb-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] CMD ["/opt/oai-gnb/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.fhi72.rocky b/docker/Dockerfile.gNB.fhi72.rocky index f95310059d..ba7861d1bf 100644 --- a/docker/Dockerfile.gNB.fhi72.rocky +++ b/docker/Dockerfile.gNB.fhi72.rocky @@ -49,7 +49,8 @@ RUN dnf update -y && \ python3 \ python3-pip \ net-tools \ - iputils && \ + iputils \ + yaml-cpp-devel && \ pip3 install six && \ pip3 install requests && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ @@ -114,6 +115,8 @@ RUN ldconfig && \ /opt/phy/fhi_lib/lib/build/libxran.so WORKDIR /opt/oai-gnb + +COPY --from=gnb-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] CMD ["/opt/oai-gnb/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.fhi72.ubuntu b/docker/Dockerfile.gNB.fhi72.ubuntu index fb9d1d43f7..09af53eed5 100644 --- a/docker/Dockerfile.gNB.fhi72.ubuntu +++ b/docker/Dockerfile.gNB.fhi72.ubuntu @@ -111,6 +111,8 @@ RUN ldconfig && \ /opt/phy/fhi_lib/lib/build/libxran.so WORKDIR /opt/oai-gnb + +COPY --from=gnb-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] CMD ["/opt/oai-gnb/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.rhel9 b/docker/Dockerfile.gNB.rhel9 index 1c201eeeab..4e766bd011 100644 --- a/docker/Dockerfile.gNB.rhel9 +++ b/docker/Dockerfile.gNB.rhel9 @@ -130,6 +130,7 @@ WORKDIR /opt/oai-gnb #EXPOSE 50000/udp # IF5 / ORI (control) #EXPOSE 50001/udp # IF5 / ECPRI (data) +COPY --from=gnb-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] CMD ["/opt/oai-gnb/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.rocky b/docker/Dockerfile.gNB.rocky index d005c36c9f..641dddfc0b 100644 --- a/docker/Dockerfile.gNB.rocky +++ b/docker/Dockerfile.gNB.rocky @@ -47,7 +47,8 @@ RUN dnf update -y && \ python3 \ python3-pip \ net-tools \ - iputils && \ + iputils \ + yaml-cpp-devel && \ pip3 install six && \ pip3 install requests && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ @@ -124,6 +125,7 @@ WORKDIR /opt/oai-gnb #EXPOSE 50000/udp # IF5 / ORI (control) #EXPOSE 50001/udp # IF5 / ECPRI (data) +COPY --from=gnb-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] CMD ["/opt/oai-gnb/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.ubuntu b/docker/Dockerfile.gNB.ubuntu index 2259aa39c9..c88857f2d6 100644 --- a/docker/Dockerfile.gNB.ubuntu +++ b/docker/Dockerfile.gNB.ubuntu @@ -128,6 +128,7 @@ WORKDIR /opt/oai-gnb #EXPOSE 50000/udp # IF5 / ORI (control) #EXPOSE 50001/udp # IF5 / ECPRI (data) +COPY --from=gnb-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] CMD ["/opt/oai-gnb/bin/nr-softmodem"] diff --git a/docker/Dockerfile.nr-cuup.rhel9 b/docker/Dockerfile.nr-cuup.rhel9 index b1b083e57c..e21c084c52 100644 --- a/docker/Dockerfile.nr-cuup.rhel9 +++ b/docker/Dockerfile.nr-cuup.rhel9 @@ -35,6 +35,9 @@ RUN cp /oai-ran/docker/scripts/gnb_entrypoint.sh /oai-ran/docker/scripts/entrypo FROM registry.access.redhat.com/ubi9/ubi:latest AS oai-nr-cuup ENV TZ=Europe/Paris +# Install EPEL +RUN dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm + RUN yum repolist --disablerepo=* && \ yum update -y && \ yum install -y \ @@ -42,7 +45,8 @@ RUN yum repolist --disablerepo=* && \ lksctp-tools \ tzdata \ net-tools \ - iputils && \ + iputils \ + yaml-cpp-devel && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf @@ -55,6 +59,7 @@ COPY --from=gnb-build \ COPY --from=gnb-build \ /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_yaml.so \ /usr/local/lib/ COPY --from=gnb-base \ @@ -73,6 +78,7 @@ WORKDIR /opt/oai-gnb/etc WORKDIR /opt/oai-gnb +COPY --from=gnb-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] CMD ["/opt/oai-gnb/bin/nr-cuup", "-O", "/opt/oai-gnb/etc/gnb.conf"] diff --git a/docker/Dockerfile.nr-cuup.rocky b/docker/Dockerfile.nr-cuup.rocky index 7f0e8fc2f1..4e87797fd0 100644 --- a/docker/Dockerfile.nr-cuup.rocky +++ b/docker/Dockerfile.nr-cuup.rocky @@ -43,7 +43,8 @@ RUN yum repolist --disablerepo=* && \ lksctp-tools \ tzdata \ net-tools \ - iputils && \ + iputils \ + yaml-cpp-devel && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf @@ -56,6 +57,7 @@ COPY --from=gnb-build \ COPY --from=gnb-build \ /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_yaml.so \ /usr/local/lib/ COPY --from=gnb-base \ @@ -71,6 +73,7 @@ WORKDIR /opt/oai-gnb/etc WORKDIR /opt/oai-gnb +COPY --from=gnb-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] CMD ["/opt/oai-gnb/bin/nr-cuup", "-O", "/opt/oai-gnb/etc/gnb.conf"] diff --git a/docker/Dockerfile.nr-cuup.ubuntu b/docker/Dockerfile.nr-cuup.ubuntu index 2c3c58e7e3..33fd01ab0e 100644 --- a/docker/Dockerfile.nr-cuup.ubuntu +++ b/docker/Dockerfile.nr-cuup.ubuntu @@ -42,7 +42,8 @@ RUN apt-get update && \ libconfig9 \ iproute2 \ net-tools \ - openssl && \ + openssl \ + libyaml-cpp-dev && \ # if the --sanitize option was used to build, additional packages are required /bin/bash -c 'if [[ "$BUILD_OPTION" = "--sanitize" ]]; then DEBIAN_FRONTEND=noninteractive apt-get install --yes \ libasan8 \ @@ -61,6 +62,7 @@ COPY ./docker/scripts/gnb_entrypoint.sh ./entrypoint.sh COPY --from=gnb-build \ /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_yaml.so \ /usr/local/lib/ RUN ldconfig && ldd /opt/oai-gnb/bin/nr-cuup @@ -69,6 +71,8 @@ RUN ldconfig && ldd /opt/oai-gnb/bin/nr-cuup WORKDIR /opt/oai-gnb/etc WORKDIR /opt/oai-gnb + +COPY --from=gnb-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] CMD ["/opt/oai-gnb/bin/nr-cuup", "-O", "/opt/oai-gnb/etc/gnb.conf"] diff --git a/docker/Dockerfile.nrUE.rhel9 b/docker/Dockerfile.nrUE.rhel9 index 0929ab3df0..79f44dfafb 100644 --- a/docker/Dockerfile.nrUE.rhel9 +++ b/docker/Dockerfile.nrUE.rhel9 @@ -122,6 +122,8 @@ RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai /usr/local/lib64/libuhd.so.4.8.0 WORKDIR /opt/oai-nr-ue + +COPY --from=nr-ue-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=nr-ue-base /tini /tini CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem"] ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-nr-ue/bin/entrypoint.sh"] diff --git a/docker/Dockerfile.nrUE.rocky b/docker/Dockerfile.nrUE.rocky index bfe84dc011..6575d1e3bf 100644 --- a/docker/Dockerfile.nrUE.rocky +++ b/docker/Dockerfile.nrUE.rocky @@ -48,7 +48,8 @@ RUN dnf update -y && \ python3 \ python3-pip \ libXpm \ - libX11 && \ + libX11 \ + yaml-cpp-devel && \ pip3 install six && \ pip3 install requests && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ @@ -119,6 +120,8 @@ RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai /usr/local/lib64/libuhd.so.4.8.0 WORKDIR /opt/oai-nr-ue + +COPY --from=nr-ue-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=nr-ue-base /tini /tini CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem"] ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-nr-ue/bin/entrypoint.sh"] diff --git a/docker/Dockerfile.nrUE.ubuntu b/docker/Dockerfile.nrUE.ubuntu index a395004cc1..3b55a64acd 100644 --- a/docker/Dockerfile.nrUE.ubuntu +++ b/docker/Dockerfile.nrUE.ubuntu @@ -119,6 +119,8 @@ RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai /usr/local/lib/libuhd.so.4.8.0 WORKDIR /opt/oai-nr-ue + +COPY --from=nr-ue-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=nr-ue-base /tini /tini CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem"] ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-nr-ue/bin/entrypoint.sh"] diff --git a/executables/lte-softmodem.c b/executables/lte-softmodem.c index 6ff535fb5b..e2c4144707 100644 --- a/executables/lte-softmodem.c +++ b/executables/lte-softmodem.c @@ -405,7 +405,6 @@ int main ( int argc, char **argv ) #if T_TRACER T_Config_Init(); #endif - //randominit (0); set_taus_seed (0); printf("configuring for RAU/RRU\n"); diff --git a/executables/lte-uesoftmodem.c b/executables/lte-uesoftmodem.c index f36bdde2b5..fc741ec300 100644 --- a/executables/lte-uesoftmodem.c +++ b/executables/lte-uesoftmodem.c @@ -492,7 +492,6 @@ int main( int argc, char **argv ) { #if T_TRACER T_Config_Init(); #endif - //randominit (0); set_taus_seed (0); cpuf=get_cpu_freq_GHz(); pthread_cond_init(&sync_cond,NULL); diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 3e22659400..8a57b21af1 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -546,7 +546,6 @@ int main( int argc, char **argv ) { #if T_TRACER T_Config_Init(); #endif - //randominit (0); set_taus_seed (0); cpuf=get_cpu_freq_GHz(); diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index ca6c48dbef..f1cc659cae 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -340,7 +340,6 @@ int main(int argc, char **argv) T_Config_Init(); #endif initTpool(get_softmodem_params()->threadPoolConfig, &(nrUE_params.Tpool), cpumeas(CPUMEAS_GETSTATE)); - //randominit (0); set_taus_seed (0); if (!has_cap_sys_nice()) diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c index 7a6e4f7657..8b07bea297 100644 --- a/nfapi/oai_integration/nfapi_pnf.c +++ b/nfapi/oai_integration/nfapi_pnf.c @@ -2315,7 +2315,7 @@ void handle_nr_slot_ind(uint16_t sfn, uint16_t slot, NR_Sched_Rsp_t *sched_resp) #ifndef ENABLE_WLS int slot_ahead = 2 << mu; #else - int slot_ahead = 1; + int slot_ahead = 1 << mu; #endif uint16_t sfn_tx = sfn; uint16_t slot_tx = slot; diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c index af02ef7a4e..d2006170f0 100644 --- a/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c +++ b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c @@ -268,8 +268,8 @@ int nfapi_pnf_p7_nr_rx_data_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rx_data_ pnf_p7_t* _this = (pnf_p7_t*)(config); AssertFatal(_this->_public.send_p7_msg, "Function pointer must be configured|"); - int ret = _this->_public.send_p7_msg(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_rx_data_indication_t)); - if (ret == 0) { + bool ret = _this->_public.send_p7_msg(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_rx_data_indication_t)); + if (ret) { for (int i = 0; i < ind->number_of_pdus; ++i) _this->nr_stats.ul.bytes += ind->pdu_list[i].pdu_length; } diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c index 97b39beaf8..4dddaf7e7e 100644 --- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c +++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c @@ -438,7 +438,7 @@ int main(int argc, char *argv[]) int n_trials = 1; double SNR_step = 0.1; - randominit(0); + randominit(); int test_uncoded = 0; n_iter_stats_t dec_iter[400] = {0}; diff --git a/openair1/PHY/CODING/TESTBENCH/ltetest.c b/openair1/PHY/CODING/TESTBENCH/ltetest.c index 45abec1697..97d66de486 100644 --- a/openair1/PHY/CODING/TESTBENCH/ltetest.c +++ b/openair1/PHY/CODING/TESTBENCH/ltetest.c @@ -72,7 +72,7 @@ void lte_param_init(unsigned char N_tx, unsigned char N_rx,unsigned char transmi PHY_vars_UE = malloc(sizeof(PHY_VARS_UE)); mac_xface = malloc(sizeof(MAC_xface)); - randominit(0); + randominit(); set_taus_seed(0); lte_frame_parms = &(PHY_vars_eNB->lte_frame_parms); @@ -367,7 +367,7 @@ int main(int argc, char *argv[]) int num_pdcch_symbols = 1; int subframe = 6; - randominit(0); + randominit(); logInit(); lte_param_init(1,1,1,0,0,3); diff --git a/openair1/PHY/CODING/TESTBENCH/pdcch_test.c b/openair1/PHY/CODING/TESTBENCH/pdcch_test.c index 873e9e19bc..2a752bfee8 100644 --- a/openair1/PHY/CODING/TESTBENCH/pdcch_test.c +++ b/openair1/PHY/CODING/TESTBENCH/pdcch_test.c @@ -47,7 +47,7 @@ void lte_param_init(unsigned char N_tx, unsigned char N_rx) PHY_config = malloc(sizeof(PHY_CONFIG)); mac_xface = malloc(sizeof(MAC_xface)); - randominit(0); + randominit(); set_taus_seed(0); lte_frame_parms = &(PHY_config->lte_frame_parms); @@ -241,8 +241,7 @@ int main(int argc, char *argv[]) PHY_vars = malloc(sizeof(PHY_VARS)); mac_xface = malloc(sizeof(MAC_xface)); - - randominit(0); + randominit(); set_taus_seed(0); ccodelte_init(); diff --git a/openair1/PHY/CODING/TESTBENCH/polartest.c b/openair1/PHY/CODING/TESTBENCH/polartest.c index e84a62775b..cb51f85aca 100644 --- a/openair1/PHY/CODING/TESTBENCH/polartest.c +++ b/openair1/PHY/CODING/TESTBENCH/polartest.c @@ -125,7 +125,7 @@ int main(int argc, char *argv[]) cpu_meas_enabled = 1; reset_meas(&timeEncoder); reset_meas(&timeDecoder); - randominit(0); + randominit(); crcTableInit(); if (polarMessageType == 0) { // PBCH diff --git a/openair1/PHY/CODING/TESTBENCH/smallblocktest.c b/openair1/PHY/CODING/TESTBENCH/smallblocktest.c index a701a49d1a..275262428c 100644 --- a/openair1/PHY/CODING/TESTBENCH/smallblocktest.c +++ b/openair1/PHY/CODING/TESTBENCH/smallblocktest.c @@ -13,7 +13,7 @@ int main(int argc, char *argv[]) cpu_meas_enabled = 1; reset_meas(&timeEncoder); reset_meas(&timeDecoder); - randominit(0); + randominit(); int ret = 1; int arguments, iterations = 1000, messageLength = 11; diff --git a/openair1/PHY/INIT/lte_param_init.c b/openair1/PHY/INIT/lte_param_init.c index 81177a63cb..d2d963ade4 100644 --- a/openair1/PHY/INIT/lte_param_init.c +++ b/openair1/PHY/INIT/lte_param_init.c @@ -77,7 +77,7 @@ void lte_param_init(PHY_VARS_eNB **eNBp, eNB->RU_list[0] = ru; ru->num_eNB=1; srand(0); - randominit(0); + randominit(); set_taus_seed(0); frame_parms = &(eNB->frame_parms); frame_parms->N_RB_DL = N_RB_DL; //50 for 10MHz and 25 for 5 MHz diff --git a/openair1/PHY/TOOLS/tests/test_dft.c b/openair1/PHY/TOOLS/tests/test_dft.c index 8b4c344c6c..abcb0c05f7 100644 --- a/openair1/PHY/TOOLS/tests/test_dft.c +++ b/openair1/PHY/TOOLS/tests/test_dft.c @@ -70,6 +70,7 @@ void math_dft(cd_t *in, cd_t *out, int len) int main(void) { int ret = 0; + randominit(); load_dftslib(); c16_t *d16 = malloc16(12 * dftFtab[sizeofArray(dftFtab) - 1].size * sizeof(*d16)); c16_t *o16 = malloc16(12 * dftFtab[sizeofArray(dftFtab) - 1].size * sizeof(*d16)); diff --git a/openair1/SIMULATION/LTE_PHY/framegen.c b/openair1/SIMULATION/LTE_PHY/framegen.c index fe1c4b49b7..30fc6d5745 100644 --- a/openair1/SIMULATION/LTE_PHY/framegen.c +++ b/openair1/SIMULATION/LTE_PHY/framegen.c @@ -378,7 +378,7 @@ void lte_param_init( unsigned char transmission_mode, mac_xface->get_dci_sdu = get_dci; mac_xface->get_dlsch_sdu = get_DLSCH_pdu; - randominit(0); + randominit(); set_taus_seed(0); lte_frame_parms = &(PHY_vars_eNB_g[0]->lte_frame_parms); diff --git a/openair1/SIMULATION/LTE_PHY/syncsim.c b/openair1/SIMULATION/LTE_PHY/syncsim.c index ccdac230f8..456bc53a2c 100644 --- a/openair1/SIMULATION/LTE_PHY/syncsim.c +++ b/openair1/SIMULATION/LTE_PHY/syncsim.c @@ -249,7 +249,7 @@ void lte_param_init(unsigned char N_tx, unsigned char N_rx,unsigned char transmi PHY_vars_UE[1] = malloc(sizeof(PHY_VARS_UE)); //PHY_config = malloc(sizeof(PHY_CONFIG)); mac_xface = malloc(sizeof(MAC_xface)); - randominit(0); + randominit(); set_taus_seed(0); lte_frame_parms = &(PHY_vars_eNB->lte_frame_parms); lte_frame_parms->N_RB_DL = N_RB_DL; //50 for 10MHz and 25 for 5 MHz diff --git a/openair1/SIMULATION/LTE_PHY/test.c b/openair1/SIMULATION/LTE_PHY/test.c index 6b78dad4e7..b292279860 100644 --- a/openair1/SIMULATION/LTE_PHY/test.c +++ b/openair1/SIMULATION/LTE_PHY/test.c @@ -174,7 +174,7 @@ int main(int argc, char **argv) for (i = 0; i<4; i++) ch[i] = (struct complexd*) malloc(channel_length * sizeof(struct complexd)); - randominit(0); + randominit(); set_taus_seed(0); #ifdef RF diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 76cc2e0716..7a442a4082 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -839,8 +839,7 @@ int main(int argc, char **argv) { ack_errors=0; cqi_crc_falsepositives=0; cqi_crc_falsenegatives=0; - round=0; - //randominit(0); + round = 0; harq_pid = subframe2harq_pid(&UE->frame_parms,proc_rxtx_ue->frame_tx,subframe); input_buffer_length = UE->ulsch[0]->harq_processes[harq_pid]->TBS/8; diff --git a/openair1/SIMULATION/LTE_PHY/ulsim2.c b/openair1/SIMULATION/LTE_PHY/ulsim2.c index e994d4fc36..32c0d4d8e9 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim2.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim2.c @@ -232,7 +232,7 @@ int main(int argc, char **argv) //LOG_M("txsig1.m","txs1", txdata[1],FRAME_LENGTH_COMPLEX_SAMPLES,1,1); // multipath channel - randominit(0); + randominit(); for (i=0; inb_antennas_tx; aa++) { diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index ea4a068b6e..d760e2394b 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -141,7 +141,7 @@ int main(int argc, char **argv) } // logInit(); - randominit(0); + randominit(); int c; while ((c = getopt(argc, argv, "--:O:df:hpVg:i:j:n:l:m:r:s:S:y:z:M:N:F:R:P:L:X:")) != -1) { diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 82984657d3..a8926e7a44 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -118,6 +118,15 @@ void nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t { } +/* this is a hack, but necessary for E2 agent. We compile in all of RRC + * (because of CMakeLists.txt), but we don't need it (only nr_radio_config.c). + * however, if E2 agent is defined, the following functions are used in + * rrc_gNB.c, but defined in RAN functions. In order to avoid pulling this in + * here as well, only provide a prototype (and abort if they are ever called). */ +void signal_rrc_msg(void /*const nr_rrc_class_e nr_channel, const uint32_t rrc_msg_id, const byte_array_t rrc_ba*/ ) { abort(); } +void signal_rrc_state_changed_to(void /* const gNB_RRC_UE_t *rrc_ue_context, const rrc_state_e2sm_rc_e rrc_state */) { abort(); } +void signal_ue_id(void /* const gNB_RRC_UE_t *rrc_ue_context, const uint16_t class, const uint32_t msg_id */) { abort(); } + /* Function to set or overwrite PTRS DL RRC parameters */ static void rrc_config_dl_ptrs_params(NR_BWP_Downlink_t *bwp, long *ptrsNrb, long *ptrsMcs, long *epre_Ratio, long *reOffset) { @@ -393,7 +402,7 @@ int main(int argc, char **argv) exit_fun("[NR_DLSIM] Error, configuration module init failed\n"); } - randominit(0); + randominit(); int print_perf = 0; diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index c86744afaa..30905619a7 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -176,8 +176,6 @@ int main(int argc, char **argv) float target_error_rate = 0.01; - int seed = 0; - cpuf = get_cpu_freq_GHz(); if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == 0) { @@ -185,8 +183,7 @@ int main(int argc, char **argv) } int c; - while ((c = getopt (argc, argv, "--:O:c:F:g:hIL:m:M:n:N:o:P:r:R:s:S:x:y:z:")) != -1) { - + while ((c = getopt(argc, argv, "--:O:c:F:g:hIL:m:M:n:N:o:P:R:s:S:x:y:z:")) != -1) { /* ignore long options starting with '--', option '-O' and their arguments that are handled by configmodule */ /* with this opstring getopt returns 1 for non-option arguments, refer to 'man 3 getopt' */ if (c == 1 || c == '-' || c == 'O') @@ -312,20 +309,6 @@ int main(int argc, char **argv) printf("Illegal PBCH phase (0-3) got %d\n",pbch_phase); break; - /* - case 'r': - ricean_factor = pow(10,-.1*atof(optarg)); - if (ricean_factor>1) { - printf("Ricean factor must be between 0 and 1\n"); - exit(-1); - } - break; - */ - - case 'r': - seed = atoi(optarg); - break; - case 'R': N_RB_DL = atoi(optarg); break; @@ -379,8 +362,10 @@ int main(int argc, char **argv) default: case 'h': - printf("%s -F input_filename -g channel_mod -h(elp) -I(nitial sync) -L log_lvl -n n_frames -M SSBs -n frames -N cell_id -o FO -P phase -r seed -R RBs -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant\n", - argv[0]); + printf( + "OAI_RNGSEED=xxx ./%s -F input_filename -g channel_mod -h(elp) -I(nitial sync) -L log_lvl -n n_frames -M SSBs -n frames " + "-N cell_id -o FO -P phase -R RBs -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant\n", + argv[0]); //printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n"); printf("-c SSB subcarrier offset\n"); //printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n"); @@ -401,7 +386,6 @@ int main(int argc, char **argv) //printf("-O oversampling factor (1,2,4,8,16)\n"); //printf("-p Use extended prefix mode\n"); printf("-P PBCH phase, allowed values 0-3\n"); - printf("-r set the random number generator seed (default: 0 = current time)\n"); printf("-R N_RB_DL\n"); printf("-s Starting SNR, runs from SNR0 to SNR0 + 10 dB if not -S given. If -n 1, then just SNR is simulated\n"); printf("-S Ending SNR, runs from SNR0 to SNR1\n"); @@ -414,7 +398,7 @@ int main(int argc, char **argv) } } - randominit(seed); + randominit(); logInit(); set_glog(loglvl); diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index aba532a80d..9fd9757f9d 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -162,7 +162,7 @@ int main(int argc, char **argv){ exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); } - randominit(0); + randominit(); int c; while ((c = getopt (argc, argv, "--:O:hHaA:Cc:l:r:p:g:m:n:s:S:t:x:y:v:V:z:N:F:d:Z:L:R:E")) != -1) { diff --git a/openair1/SIMULATION/NR_PHY/psbchsim.c b/openair1/SIMULATION/NR_PHY/psbchsim.c index 17c3473eb8..fc5280559e 100644 --- a/openair1/SIMULATION/NR_PHY/psbchsim.c +++ b/openair1/SIMULATION/NR_PHY/psbchsim.c @@ -325,15 +325,13 @@ int main(int argc, char **argv) // int frame_length_complex_samples_no_prefix; NR_DL_FRAME_PARMS *frame_parms; - int seed = 0; - cpuf = get_cpu_freq_GHz(); if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == 0) { exit_fun("[NR_PSBCHSIM] Error, configuration module init failed\n"); } - randominit(0); + randominit(); int c; while ((c = getopt(argc, argv, "--:O:c:hn:o:s:FIL:N:R:S:T:")) != -1) { @@ -456,7 +454,7 @@ int main(int argc, char **argv) } } - randominit(seed); + randominit(); logInit(); set_glog(loglvl); diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index 8c9f2961c4..21d43f48ad 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -151,7 +151,7 @@ int main(int argc, char **argv) exit_fun("[NR_PUCCHSIM] Error, configuration module init failed\n"); } - randominit(0); + randominit(); logInit(); int c; diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index 77a0046e1f..3705df3b2c 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -139,7 +139,7 @@ int main(int argc, char **argv) } //logInit(); - randominit(0); + randominit(); int c; while ((c = getopt(argc, argv, "--:O:hg:n:s:S:py:z:M:N:R:F:m:l:q:r:W:")) != -1) { diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 85c165b00d..a9a2ec3b76 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -120,6 +120,15 @@ void nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t { } +/* this is a hack, but necessary for E2 agent. We compile in all of RRC + * (because of CMakeLists.txt), but we don't need it (only nr_radio_config.c). + * however, if E2 agent is defined, the following functions are used in + * rrc_gNB.c, but defined in RAN functions. In order to avoid pulling this in + * here as well, only provide a prototype (and abort if they are ever called). */ +void signal_rrc_msg(void /*const nr_rrc_class_e nr_channel, const uint32_t rrc_msg_id, const byte_array_t rrc_ba*/ ) { abort(); } +void signal_rrc_state_changed_to(void /* const gNB_RRC_UE_t *rrc_ue_context, const rrc_state_e2sm_rc_e rrc_state */) { abort(); } +void signal_ue_id(void /* const gNB_RRC_UE_t *rrc_ue_context, const uint16_t class, const uint32_t msg_id */) { abort(); } + extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) { abort(); } @@ -348,7 +357,7 @@ int main(int argc, char *argv[]) } int ul_proc_error = 0; // uplink processing checking status flag //logInit(); - randominit(0); + randominit(); /* initialize the sin-cos table */ InitSinLUT(); diff --git a/openair1/SIMULATION/RF/rf.c b/openair1/SIMULATION/RF/rf.c index 081a102bbb..e9b49ed8f2 100644 --- a/openair1/SIMULATION/RF/rf.c +++ b/openair1/SIMULATION/RF/rf.c @@ -248,7 +248,7 @@ int main(int argc, char* argv[]) channel_desc_t *channel; srand(0); - randominit(0); + randominit(); set_taus_seed(0); channel = new_channel_desc_scm(nb_antennas, diff --git a/openair1/SIMULATION/TOOLS/ch_desc_proto.c b/openair1/SIMULATION/TOOLS/ch_desc_proto.c index b1e71fcfb4..dbc77a9b9b 100644 --- a/openair1/SIMULATION/TOOLS/ch_desc_proto.c +++ b/openair1/SIMULATION/TOOLS/ch_desc_proto.c @@ -93,7 +93,7 @@ int main() { {3420,2820},{1580,3940},{660,2100},{2740,1180},{2500,2500}, {3580,3580},{3740,3140},{3020,3020},{4340,4140},{980,4300} }; - randominit(0); + randominit(); ///////////////////////////////////////////////////////////////////////////////////////////////// int tabl_len=0; double local_table[MCS_COUNT][9][9]; diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index d13cfd8921..bed23968e4 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -572,11 +572,6 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, double path_loss_dB, float noise_power_dB) { - // To create tables for normal distribution - struct timespec t; - clock_gettime(CLOCK_MONOTONIC, &t); - tableNor((long) (t.tv_nsec % INT_MAX)); - channel_desc_t *chan_desc = (channel_desc_t *)calloc(1,sizeof(channel_desc_t)); for(int i=0; iittiMsg.ngap_ue_cap_info_ind #define NGAP_INITIAL_CONTEXT_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.ngap_initial_context_setup_resp #define NGAP_INITIAL_CONTEXT_SETUP_FAIL(mSGpTR) (mSGpTR)->ittiMsg.ngap_initial_context_setup_fail -#define NGAP_UE_CONTEXT_RELEASE_RESP(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_release_resp #define NGAP_NAS_NON_DELIVERY_IND(mSGpTR) (mSGpTR)->ittiMsg.ngap_nas_non_delivery_ind #define NGAP_UE_CTXT_MODIFICATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_ctxt_modification_resp #define NGAP_UE_CTXT_MODIFICATION_FAIL(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_ctxt_modification_fail @@ -733,12 +732,6 @@ typedef struct ngap_ue_ctxt_modification_resp_s { uint32_t gNB_ue_ngap_id; } ngap_ue_ctxt_modification_resp_t; -typedef struct ngap_ue_release_complete_s { - uint32_t gNB_ue_ngap_id; - int num_pdu_sessions; - uint32_t pdu_session_id[256]; -} ngap_ue_release_complete_t; - //-------------------------------------------------------------------------------------------// // NGAP -> RRC messages typedef struct ngap_downlink_nas_s { @@ -862,20 +855,24 @@ typedef struct ngap_ue_release_command_s { //-------------------------------------------------------------------------------------------// // NGAP <-- RRC messages -typedef struct pdusession_release_s { - /* Unique pdusession_id for the UE. */ - uint8_t pdusession_id; - byte_array_t data; -} pdusession_release_t; - typedef struct ngap_ue_release_req_s { - uint32_t gNB_ue_ngap_id; - /* Number of pdusession resource in the list */ + // RAN UE NGAP ID (mandatory) + uint32_t gNB_ue_ngap_id; + // PDU Session Resource List (optional) uint16_t nb_of_pdusessions; - /* list of pdusession resource by RRC layers */ - pdusession_release_t pdusessions[NGAP_MAX_PDU_SESSION]; + uint8_t pdusession_ids[NGAP_MAX_PDU_SESSION]; + // Cause (mandatory) ngap_cause_t cause; -} ngap_ue_release_req_t, ngap_ue_release_resp_t; +} ngap_ue_release_req_t; + +typedef struct { + // RAN UE NGAP ID (mandatory) + uint32_t gNB_ue_ngap_id; + // PDU Session Resource List (optional) + uint16_t num_pdu_sessions; + // PDU Session ID (mandatory) + uint8_t pdu_session_id[NGAP_MAX_PDU_SESSION]; +} ngap_ue_release_complete_t; typedef struct ngap_pdusession_modify_req_s { /* AMF UE id */ @@ -915,14 +912,19 @@ typedef struct ngap_pdusession_release_command_s { /* The NAS PDU should be forwarded by the RRC layer to the NAS layer */ byte_array_t nas_pdu; - /* Number of pdusession to be released in the list */ + // PDU Session Resource to Release List (mandatory) uint16_t nb_pdusessions_torelease; - - /* PDUSession release command */ - pdusession_release_t pdusession_release_params[NGAP_MAX_PDU_SESSION]; + uint16_t pdusession_ids[NGAP_MAX_PDU_SESSION]; } ngap_pdusession_release_command_t; +typedef struct pdusession_release_s { + // PDU Session ID (mandatory) + uint8_t pdusession_id; + // PDU Session Resource Release Response Transfer (mandatory) + byte_array_t pdusession_release_response_transfer; +} pdusession_release_t; + typedef struct ngap_pdusession_release_resp_s { // AMF UE NGAP ID uint64_t amf_ue_ngap_id; diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 081ce8607f..1f641fc6d9 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -1368,7 +1368,7 @@ void nfapi_stop_l1() } } -static void get_bwp_config(nr_mac_config_t *configuration) +static void get_bwp_config(nr_mac_config_t *configuration, const NR_ServingCellConfigCommon_t *scc) { char path[MAX_OPTNAME_SIZE * 2 + 8]; snprintf(path, sizeof(path), "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0); @@ -1377,10 +1377,13 @@ static void get_bwp_config(nr_mac_config_t *configuration) AssertFatal(configuration->num_additional_bwps >= 0 && configuration->num_additional_bwps <= 4, "Invalid number of additional BWPs %d\n", configuration->num_additional_bwps); + int bw = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; for (int i = 0; i < configuration->num_additional_bwps; i++) { configuration->bwp_config[i].id = i + 1; int bwp_start = *BWPParamList.paramarray[i][GNB_BWP_START_IDX].iptr; + AssertFatal(bwp_start >= 0 && bwp_start < bw, "Invalid BWP start value %d\n", bwp_start); int bwp_size = *BWPParamList.paramarray[i][GNB_BWP_SIZE_IDX].iptr; + AssertFatal(bwp_start + bwp_size <= bw, "BWP start %d and BWP size %d exceeds full BW %d\n", bwp_start, bwp_size, bw); configuration->bwp_config[i].location_and_bw = PRBalloc_to_locationandbandwidth(bwp_size, bwp_start); configuration->bwp_config[i].scs = *BWPParamList.paramarray[i][GNB_BWP_SCS_IDX].iptr; LOG_I(GNB_APP, @@ -1418,12 +1421,6 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) config.pdsch_AntennaPorts.XP, config.pusch_AntennaPorts); - // BWP - get_bwp_config(&config); - AssertFatal(config.num_additional_bwps <= 4, "Impossible to configure more than 4 additional BWPs\n"); - config.first_active_bwp = *GNBParamList.paramarray[0][GNB_1ST_ACTIVE_BWP_IDX].iptr; - AssertFatal(config.first_active_bwp <= config.num_additional_bwps, "1st active BWP does not belog to the configured BWPs\n"); - // RU GET_PARAMS_LIST(RUParamList, RUParams, RUPARAMS_DESC, CONFIG_STRING_RU_LIST, NULL); int num_tx = 0; @@ -1524,7 +1521,11 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) config.num_agg_level_candidates[PDCCH_AGG_LEVEL16]); NR_ServingCellConfigCommon_t *scc = get_scc_config(cfg, config.minRXTXTIME, config.do_SRS); - //xer_fprint(stdout, &asn_DEF_NR_ServingCellConfigCommon, scc); + // BWP + get_bwp_config(&config, scc); + AssertFatal(config.num_additional_bwps <= 4, "Impossible to configure more than 4 additional BWPs\n"); + config.first_active_bwp = *GNBParamList.paramarray[0][GNB_1ST_ACTIVE_BWP_IDX].iptr; + AssertFatal(config.first_active_bwp <= config.num_additional_bwps, "1st active BWP does not belog to the configured BWPs\n"); if (MacRLC_ParamList.numelt > 0) { /* NR RLC config is needed by mac_top_init_gNB() */ diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 13f2eca955..563b3f2ca2 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -2781,7 +2781,6 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP, nr_dci_format_t format, nr_rnti_type_t rnti_type, NR_ControlResourceSet_t *coreset, - int bwp_id, int ss_type, uint16_t cset0_bwp_size, uint16_t alt_size) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index f76f54b158..8f795452b8 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -159,7 +159,6 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP, nr_dci_format_t format, nr_rnti_type_t rnti_type, NR_ControlResourceSet_t *coreset, - int bwp_id, int ss_type, uint16_t cset0_bwp_size, uint16_t alt_size); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index 8a2074422e..7d630c3002 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -198,7 +198,6 @@ static void config_dci_pdu(NR_UE_MAC_INST_t *mac, NR_UL_DCI_FORMAT_0_0, rnti_type, coreset, - dl_bwp_id, ss->searchSpaceType->present, mac->type0_PDCCH_CSS_config.num_rbs, 0); @@ -211,7 +210,6 @@ static void config_dci_pdu(NR_UE_MAC_INST_t *mac, NR_DL_DCI_FORMAT_1_0, rnti_type, coreset, - dl_bwp_id, ss->searchSpaceType->present, mac->type0_PDCCH_CSS_config.num_rbs, 0); @@ -225,7 +223,6 @@ static void config_dci_pdu(NR_UE_MAC_INST_t *mac, dci_format[i], rnti_type, coreset, - dl_bwp_id, ss->searchSpaceType->present, mac->type0_PDCCH_CSS_config.num_rbs, alt_size); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index bd9ea09041..e566f3db9e 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -586,11 +586,10 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, pusch_config_pdu->pusch_uci.harq_ack_bit_length = 0; + pusch_config_pdu->bwp_start = current_UL_BWP->BWPStart; if (dci_format == NR_UL_DCI_FORMAT_0_0 && ss_type == NR_SearchSpace__searchSpaceType_PR_common) { - pusch_config_pdu->bwp_start = sc_info->initial_ul_BWPStart; pusch_config_pdu->bwp_size = sc_info->initial_ul_BWPSize; } else { - pusch_config_pdu->bwp_start = current_UL_BWP->BWPStart; pusch_config_pdu->bwp_size = current_UL_BWP->BWPSize; } diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 893a94147e..35b6fa509a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -1065,6 +1065,24 @@ bool nr_update_sib19(const gnb_sat_position_update_t *sat_position) return true; } +bool nr_trigger_bwp_switch(uint16_t rnti, int bwp_id) +{ + gNB_MAC_INST *nrmac = RC.nrmac[0]; + NR_SCHED_LOCK(&nrmac->sched_lock); + NR_UE_info_t *UE = find_nr_UE(&nrmac->UE_info, rnti); + bool success = false; + if (!UE) { + LOG_W(NR_MAC, "could not find UE for RNTI %04x\n", rnti); + } else if (UE->current_DL_BWP.bwp_id == bwp_id) { + LOG_W(NR_MAC, "UE %04x is already on BWP ID %d, not triggering reconfiguration\n", rnti, bwp_id); + } else { // UE != NULL && current_DL_BWP.bwp_id != bwp_id + nr_mac_trigger_reconfiguration(nrmac, UE, bwp_id); + success = true; + } + NR_SCHED_UNLOCK(&nrmac->sched_lock); + return success; +} + void prepare_du_configuration_update(gNB_MAC_INST *mac, f1ap_served_cell_info_t *info, NR_BCCH_BCH_Message_t *mib, @@ -1116,8 +1134,9 @@ bool nr_mac_add_test_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t NR_SCHED_LOCK(&nrmac->sched_lock); NR_UE_info_t *UE = get_new_nr_ue_inst(&nrmac->UE_info.uid_allocator, rnti, CellGroup); - DevAssert(UE->uid < MAX_MOBILES_PER_GNB); // test-mode: we assume we can always create a UE - free_and_zero(UE->ra); // test-mode (sims, phy-test): UE will not do RA + DevAssert(UE->uid < MAX_MOBILES_PER_GNB); // physical simulators: we assume we can always create a UE + free_and_zero(UE->ra); // physical simulators: UE will not do RA + UE->local_bwp_id = 1; // for physical simulators bool res = add_connected_nr_ue(nrmac, UE); if (!res) { LOG_E(NR_MAC, "Error adding UE %04x\n", rnti); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index f8df95f679..e50358ae10 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -958,7 +958,6 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, &uldci_payload, NR_UL_DCI_FORMAT_0_0, TYPE_TC_RNTI_, - ul_bwp->bwp_id, ss, coreset, 0, // parameter not needed for DCI 0_0 @@ -1385,7 +1384,6 @@ static void prepare_dl_pdus(gNB_MAC_INST *nr_mac, &dci_payload, NR_DL_DCI_FORMAT_1_0, rnti_type, - dl_bwp->bwp_id, sched_ctrl->search_space, coreset, 0, // parameter not needed for DCI 1_0 diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 1f6fb64181..eb063b48ef 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -473,7 +473,6 @@ static void nr_fill_nfapi_dl_SIB_pdu(gNB_MAC_INST *gNB_mac, &dci_payload, dci_format, rnti_type, - 0, search_space, coreset, 0, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 86eed9d575..d5c1048ad6 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -398,7 +398,8 @@ bwp_info_t get_pdsch_bwp_start_size(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE) // except for the case when DCI format 1_0 is decoded in any common search space in which case the size of CORESET 0 shall be // used if CORESET 0 is configured for the cell and the size of initial DL bandwidth part shall be used if CORESET 0 is not // configured for the cell. - if (dl_bwp->dci_format == NR_DL_DCI_FORMAT_1_0 && sched_ctrl->search_space->searchSpaceType + if (dl_bwp->dci_format == NR_DL_DCI_FORMAT_1_0 + && sched_ctrl->search_space->searchSpaceType && sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common) { if (sched_ctrl->coreset->controlResourceSetId == 0) { bwp_info.bwpStart = nr_mac->cset0_bwp_start; @@ -406,9 +407,9 @@ bwp_info_t get_pdsch_bwp_start_size(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE) bwp_info.bwpStart = dl_bwp->BWPStart + sched_ctrl->sched_pdcch.rb_start; } if (nr_mac->cset0_bwp_size > 0) { - bwp_info.bwpSize = min(dl_bwp->BWPSize - bwp_info.bwpStart, nr_mac->cset0_bwp_size); + bwp_info.bwpSize = min(dl_bwp->BWPSize, nr_mac->cset0_bwp_size); } else { - bwp_info.bwpSize = min(dl_bwp->BWPSize - bwp_info.bwpStart, UE->sc_info.initial_dl_BWPSize); + bwp_info.bwpSize = min(dl_bwp->BWPSize, UE->sc_info.initial_dl_BWPSize); } } else { bwp_info.bwpSize = dl_bwp->BWPSize; @@ -592,6 +593,21 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac, return true; } +static void ack_reconfig(gNB_MAC_INST *mac, NR_UE_info_t *UE) +{ + if (UE->reconfigSpCellConfig) { + // in case of reestablishment, the spCellConfig had to be released + // temporarily. Reapply now before doing the reconfiguration. + UE->CellGroup->spCellConfig = UE->reconfigSpCellConfig; + // UE->reconfigSpCellConfig to be NULLed after receiving reconfiguration complete + } + NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon; + /* clean BWP structures */ + clean_bwp_structures(UE->CellGroup->spCellConfig); + configure_UE_BWP(mac, scc, UE, false, NR_SearchSpace__searchSpaceType_PR_common, -1, -1); + UE->await_reconfig = false; +} + typedef struct UEsched_s { float coef; NR_UE_info_t * UE; @@ -866,6 +882,12 @@ static void pf_dl(gNB_MAC_INST *mac, .tda_info = tda_info, }; + sched_pdsch.action = NULL; + int srb1 = 1; + /* everything that's only 3 bytes is an ack. To be safe, use a bit more. */ + if (iterator->UE->await_reconfig && sched_ctrl->rlc_status[srb1].bytes_in_buffer > 10) + sched_pdsch.action = ack_reconfig; + // Fix me: currently, the RLC does not give us the total number of PDUs // awaiting. Therefore, for the time being, we put a fixed overhead of 12 // (for 4 PDUs) and optionally + 2 for TA. Once RLC gives the number of @@ -1191,7 +1213,6 @@ void post_process_dlsch(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pdsch, NR_UE &dci_payload, current_BWP->dci_format, rnti_type, - bwp_id, sched_ctrl->search_space, sched_ctrl->coreset, UE->pdsch_HARQ_ACK_Codebook, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index a68c12092b..14dedb1de9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -907,8 +907,10 @@ dci_pdu_rel15_t prepare_dci_dl_payload(const gNB_MAC_INST *gNB_mac, dci_payload.dai[0].val = pucch ? (pucch->dai_c - 1) & 3 : 0; // bwp indicator // as per table 7.3.1.1.2-1 in 38.212 - if (dl_BWP) - dci_payload.bwp_indicator.val = UE->sc_info.n_dl_bwp < 4 ? dl_BWP->bwp_id : dl_BWP->bwp_id - 1; + if (dl_BWP) { + int ext_bwp_id = dl_BWP->bwp_id ? 1 : 0; // BWP-ID sent to the UE is always 1 except for BWP 0 + dci_payload.bwp_indicator.val = UE->sc_info.n_dl_bwp < 4 ? ext_bwp_id : ext_bwp_id - 1; + } return dci_payload; } @@ -1182,7 +1184,6 @@ void config_uldci(const NR_UE_ServingCell_Info_t *sc_info, NR_UE_UL_BWP_t *ul_bwp, NR_SearchSpace__searchSpaceType_PR ss_type) { - int bwp_id = ul_bwp->bwp_id; nr_dci_format_t dci_format = ul_bwp->dci_format; // 3GPP TS 38.214 Section 6.1.2.2.2 Uplink resource allocation type 1 @@ -1214,7 +1215,8 @@ void config_uldci(const NR_UE_ServingCell_Info_t *sc_info, LOG_D(NR_MAC,"Configuring DCI Format 0_1\n"); dci_pdu_rel15->dai[0].val = 0; //TODO // bwp indicator as per table 7.3.1.1.2-1 in 38.212 - dci_pdu_rel15->bwp_indicator.val = sc_info->n_ul_bwp < 4 ? bwp_id : bwp_id - 1; + int ext_bwp_id = ul_bwp->bwp_id ? 1 : 0; // BWP-ID sent to the UE is always 1 except for BWP 0 + dci_pdu_rel15->bwp_indicator.val = sc_info->n_ul_bwp < 4 ? ext_bwp_id : ext_bwp_id - 1; // SRS resource indicator if (pusch_Config && pusch_Config->txConfig != NULL) { AssertFatal(*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook, @@ -1640,7 +1642,6 @@ void fill_dci_pdu_rel15(const NR_UE_ServingCell_Info_t *servingCellInfo, dci_pdu_rel15_t *dci_pdu_rel15, int dci_format, int rnti_type, - int bwp_id, NR_SearchSpace_t *ss, NR_ControlResourceSet_t *coreset, long pdsch_HARQ_ACK_Codebook, @@ -1671,7 +1672,6 @@ void fill_dci_pdu_rel15(const NR_UE_ServingCell_Info_t *servingCellInfo, NR_UL_DCI_FORMAT_0_0, rnti_type, coreset, - bwp_id, ss->searchSpaceType->present, cset0_bwp_size, 0); @@ -1685,7 +1685,6 @@ void fill_dci_pdu_rel15(const NR_UE_ServingCell_Info_t *servingCellInfo, NR_DL_DCI_FORMAT_1_0, rnti_type, coreset, - bwp_id, ss->searchSpaceType->present, cset0_bwp_size, 0); @@ -1702,10 +1701,10 @@ void fill_dci_pdu_rel15(const NR_UE_ServingCell_Info_t *servingCellInfo, dci_format, rnti_type, coreset, - bwp_id, ss->searchSpaceType->present, cset0_bwp_size, alt_size); + if (dci_size == 0) return; pdcch_dci_pdu->PayloadSizeBits = dci_size; @@ -2703,38 +2702,26 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, AssertFatal(dl_bwp_switch == ul_bwp_switch, "Different UL and DL BWP not supported\n"); DL_BWP->bwp_id = dl_bwp_switch; UL_BWP->bwp_id = ul_bwp_switch; + UE->local_bwp_id = dl_bwp_switch; // assuming they are the same } else { - // (re)configuring BWP - // TODO BWP switching not via RRC reconfiguration - // via RRC if firstActiveXlinkBWP_Id is NULL, MAC stays on the same BWP as before - if (servingCellConfig->firstActiveDownlinkBWP_Id) - DL_BWP->bwp_id = *servingCellConfig->firstActiveDownlinkBWP_Id; - if (servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id) - UL_BWP->bwp_id = *servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id; + DL_BWP->bwp_id = UE->local_bwp_id; + UL_BWP->bwp_id = UE->local_bwp_id; } const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig->downlinkBWP_ToAddModList; if(bwpList) - sc_info->n_dl_bwp = bwpList->list.count; - if (DL_BWP->bwp_id>0) { - for (int i=0; ilist.count; i++) { - dl_bwp = bwpList->list.array[i]; - if(dl_bwp->bwp_Id == DL_BWP->bwp_id) - break; - } - AssertFatal(dl_bwp!=NULL,"Couldn't find DLBWP corresponding to BWP ID %ld\n",DL_BWP->bwp_id); + sc_info->n_dl_bwp = 1; + if (DL_BWP->bwp_id > 0) { + dl_bwp = bwpList->list.array[0]; + AssertFatal(dl_bwp, "Couldn't find DLBWP corresponding to BWP ID %ld\n", DL_BWP->bwp_id); } const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList; if(ubwpList) - sc_info->n_ul_bwp = ubwpList->list.count; - if (UL_BWP->bwp_id>0) { - for (int i=0; ilist.count; i++) { - ul_bwp = ubwpList->list.array[i]; - if(ul_bwp->bwp_Id == UL_BWP->bwp_id) - break; - } - AssertFatal(ul_bwp!=NULL,"Couldn't find ULBWP corresponding to BWP ID %ld\n",UL_BWP->bwp_id); + sc_info->n_ul_bwp = 1; + if (UL_BWP->bwp_id > 0) { + ul_bwp = ubwpList->list.array[0]; + AssertFatal(ul_bwp, "Couldn't find ULBWP corresponding to BWP ID %ld\n", UL_BWP->bwp_id); } // selection of dedicated BWPs @@ -2762,12 +2749,12 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, } // TDA lists - if (DL_BWP->bwp_id>0) + if (DL_BWP->bwp_id > 0) DL_BWP->tdaList_Common = dl_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; else DL_BWP->tdaList_Common = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - if(UL_BWP->bwp_id>0) + if(UL_BWP->bwp_id > 0) UL_BWP->tdaList_Common = ul_bwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; else UL_BWP->tdaList_Common = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; @@ -3217,9 +3204,10 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, slot_t slot, nfapi_nr_dl_tt NR_NZP_CSI_RS_ResourceSetId_t *nzp = NULL; for (int csi_list=0; csi_listcsi_ResourceConfigToAddModList->list.count; csi_list++) { NR_CSI_ResourceConfig_t *csires = csi_measconfig->csi_ResourceConfigToAddModList->list.array[csi_list]; - if(csires->bwp_Id == dl_bwp->bwp_id && - csires->csi_RS_ResourceSetList.present == NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB && - csires->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList) { + if (csires->bwp_Id > 1) + LOG_E(NR_MAC, "Invalid CSI resource BWP ID %ld, we only configure BWP up to 1\n", csires->bwp_Id); + else if (csires->csi_RS_ResourceSetList.present == NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB && + csires->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList) { nzp = csires->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0]; } } @@ -3456,46 +3444,11 @@ void nr_measgap_scheduling(gNB_MAC_INST *nr_mac, frame_t frame, sub_frame_t slot void clean_bwp_structures(NR_SpCellConfig_t *spCellConfig) { NR_ServingCellConfig_t *spCellConfigDedicated = spCellConfig->spCellConfigDedicated; - if (spCellConfigDedicated->downlinkBWP_ToReleaseList) { - struct NR_ServingCellConfig__downlinkBWP_ToReleaseList *rel_dl = spCellConfigDedicated->downlinkBWP_ToReleaseList; - struct NR_ServingCellConfig__downlinkBWP_ToAddModList *add_dl = spCellConfigDedicated->downlinkBWP_ToAddModList; - int num_rel = rel_dl->list.count; - int num_add = add_dl->list.count; - for (int i = 0; i < num_rel; i++) { - NR_BWP_Id_t *rel_id = rel_dl->list.array[i]; - for (int j = 0; j < num_add; j++) { - NR_BWP_Downlink_t *dl_bwp = add_dl->list.array[j]; - if (*rel_id == dl_bwp->bwp_Id) { - asn_sequence_del(&add_dl->list, j, 1); - } - } - asn_sequence_del(&rel_dl->list, i, 1); - } - if (rel_dl->list.count == 0) - free_and_zero(rel_dl); - if (add_dl->list.count == 0) - free_and_zero(add_dl); - } - if (spCellConfigDedicated->uplinkConfig->uplinkBWP_ToReleaseList) { - struct NR_UplinkConfig__uplinkBWP_ToReleaseList *rel_ul = spCellConfigDedicated->uplinkConfig->uplinkBWP_ToReleaseList; - struct NR_UplinkConfig__uplinkBWP_ToAddModList *add_ul = spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList; - int num_rel = rel_ul->list.count; - int num_add = add_ul->list.count; - for (int i = 0; i < num_rel; i++) { - NR_BWP_Id_t *rel_id = rel_ul->list.array[i]; - for (int j = 0; j < num_add; j++) { - NR_BWP_Uplink_t *ul_bwp = add_ul->list.array[j]; - if (*rel_id == ul_bwp->bwp_Id) { - asn_sequence_del(&add_ul->list, j, 1); - } - } - asn_sequence_del(&rel_ul->list, i, 1); - } - if (rel_ul->list.count == 0) - free_and_zero(rel_ul); - if (add_ul->list.count == 0) - free_and_zero(add_ul); - } + if (spCellConfigDedicated->downlinkBWP_ToAddModList && spCellConfigDedicated->downlinkBWP_ToAddModList->list.count > 1) + asn_sequence_del(&spCellConfigDedicated->downlinkBWP_ToAddModList->list, 0, 1); + if (spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList + && spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count > 1) + asn_sequence_del(&spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list, 0, 1); } void nr_mac_clean_cellgroup(NR_CellGroupConfig_t *cell_group) @@ -3517,8 +3470,6 @@ void nr_mac_clean_cellgroup(NR_CellGroupConfig_t *cell_group) /* remove reestablishRLC, we don't need it anymore */ for (int i = 0; i < cell_group->rlc_BearerToAddModList->list.count; ++i) free_and_zero(cell_group->rlc_BearerToAddModList->list.array[i]->reestablishRLC); - /* clean BWP structures */ - clean_bwp_structures(spCellConfig); } int nr_mac_get_reconfig_delay_slots(NR_SubcarrierSpacing_t scs) @@ -3818,6 +3769,7 @@ bool prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE) NR_CellGroupConfig_t *cellGroupConfig = get_initial_cellGroupConfig(UE->uid, scc, &mac->radio_config, &mac->rlc_config); ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); UE->CellGroup = cellGroupConfig; + UE->local_bwp_id = mac->radio_config.first_active_bwp; if (!cellGroupConfig) return true; @@ -3922,15 +3874,35 @@ bool nr_mac_check_ul_failure(gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ctrl_t * return false; } -void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_t *UE, int new_bwp_id) +static bool verify_bwp_switch(const NR_UE_info_t *UE, const nr_mac_config_t *configuration, int new_bwp_id) +{ + if (new_bwp_id == UE->current_DL_BWP.bwp_id) { + LOG_E(NR_MAC, "Source BWP ID and target BWP ID are the same, can't perform switch\n"); + return false; + } + + if (new_bwp_id == 0) + return true; + for (int i = 0; i < configuration->num_additional_bwps; i++) { + const nr_bwp_config_t *bwp_config = &configuration->bwp_config[i]; + if (bwp_config->id == new_bwp_id) + return true; + } + LOG_E(NR_MAC, "New BWP %d does not belong to the list of configured BWPs, can't perform switch\n", new_bwp_id); + return false; +} + +void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, NR_UE_info_t *UE, int new_bwp_id) { DevAssert(UE->CellGroup != NULL); NR_CellGroupConfig_t *cellGroup_for_UE = NULL; if (new_bwp_id >= 0) { AssertFatal(UE->current_DL_BWP.bwp_id == UE->current_UL_BWP.bwp_id, "We only support same BWP for UL and DL\n"); - if (new_bwp_id == UE->current_DL_BWP.bwp_id) - LOG_E(NR_MAC, "Source BWP ID and target BWP ID are the same, can't perform switch\n"); - else + if (!verify_bwp_switch(UE, &nrmac->radio_config, new_bwp_id)) + return; + else { + UE->sc_info.csi_MeasConfig = NULL; // to avoid segfault when freeing csi_MeasConfig in configDedicated + UE->local_bwp_id = new_bwp_id; cellGroup_for_UE = update_cellGroupConfig_for_BWP_switch(UE->CellGroup, &nrmac->radio_config, UE->capability, @@ -3938,6 +3910,7 @@ void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_ UE->uid, UE->current_DL_BWP.bwp_id, new_bwp_id); + } } uint8_t buf[2048]; asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, @@ -3946,6 +3919,7 @@ void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_ buf, sizeof(buf)); AssertFatal(enc_rval.encoded > 0, "ASN1 encoding of CellGroupConfig failed, failed type %s\n", enc_rval.failed_type->name); + UE->await_reconfig = true; du_to_cu_rrc_information_t du2cu = { .cellGroupConfig = buf, .cellGroupConfig_length = (enc_rval.encoded + 7) >> 3, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 27ecbdcbd0..eb32fde2e6 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -253,9 +253,10 @@ void nr_csi_meas_reporting(int Mod_idP,frame_t frame, slot_t slot) "Only periodic CSI reporting is implemented currently\n"); const NR_PUCCH_CSI_Resource_t *pucchcsires = csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.array[0]; - if(pucchcsires->uplinkBandwidthPartId != ul_bwp->bwp_id) + if(pucchcsires->uplinkBandwidthPartId > 1) { + LOG_E(NR_MAC, "Invalid PUCCH BWP ID %ld, we only configure BWP up to 1\n", pucchcsires->uplinkBandwidthPartId); continue; - + } // we schedule CSI reporting max_fb_time slots in advance int period, offset; csi_period_offset(csirep, NULL, &period, &offset); @@ -393,16 +394,15 @@ int get_pucch_resourceid(NR_PUCCH_Config_t *pucch_Config, int O_uci, int pucch_r return *resource_id; } -static void handle_dl_harq(NR_UE_info_t * UE, - int8_t harq_pid, - bool success, - int harq_round_max) +static void handle_dl_harq(gNB_MAC_INST *mac, NR_UE_info_t * UE, int8_t harq_pid, bool success, int harq_round_max) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_harq_t *harq = &sched_ctrl->harq_processes[harq_pid]; harq->feedback_slot = -1; harq->is_waiting = false; if (success) { + if (harq->sched_pdsch.action) + harq->sched_pdsch.action(mac, UE); finish_nr_dl_harq(sched_ctrl, harq_pid); } else if (harq->round >= harq_round_max - 1) { abort_nr_dl_harq(UE, harq_pid); @@ -749,7 +749,6 @@ static void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR reportQuantity_type_r16 = NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_NOTHING; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP; const int n_slots_frame = nrmac->frame_structure.numb_slots_frame; int cumul_bits = 0; @@ -764,8 +763,10 @@ static void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_CSI_ReportConfig_t *csirep = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]; uint8_t cqi_table = (dl_bwp->dci_format == NR_DL_DCI_FORMAT_1_1 && csirep->cqi_Table) ? *csirep->cqi_Table : NR_CSI_ReportConfig__cqi_Table_table1; const NR_PUCCH_CSI_Resource_t *pucchcsires = csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.array[0]; - if(pucchcsires->uplinkBandwidthPartId != ul_bwp->bwp_id) + if(pucchcsires->uplinkBandwidthPartId > 1) { + LOG_E(NR_MAC, "Invalid PUCCH BWP ID %ld, we only configure BWP up to 1\n", pucchcsires->uplinkBandwidthPartId); continue; + } int period, offset; csi_period_offset(csirep, NULL, &period, &offset); // verify if report with current id has been scheduled for this frame and slot @@ -873,7 +874,7 @@ static NR_UE_harq_t *find_harq(frame_t frame, slot_t slot, NR_UE_info_t * UE, in frame, slot); remove_front_nr_list(&sched_ctrl->feedback_dl_harq); - handle_dl_harq(UE, pid, 0, harq_round_max); + handle_dl_harq(NULL, UE, pid, false, harq_round_max); pid = sched_ctrl->feedback_dl_harq.head; if (pid < 0) return NULL; @@ -930,7 +931,7 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, frame_t frame, slot_t slot, con 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); bool success = harq_value == 0 && harq_confidence == 0; - handle_dl_harq(UE, pid, success, nrmac->dl_bler.harq_round_max); + handle_dl_harq(nrmac, UE, pid, success, nrmac->dl_bler.harq_round_max); if (is_ra) { bool ue_rejected = nr_check_Msg4_MsgB_Ack(mod_id, frame, slot, UE, success); if (ue_rejected) { @@ -1009,7 +1010,7 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, frame_t frame, slot_t slot, c 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, acknack); - handle_dl_harq(UE, pid, uci_234->harq.harq_crc != 1 && acknack, nrmac->dl_bler.harq_round_max); + handle_dl_harq(nrmac, UE, pid, uci_234->harq.harq_crc != 1 && acknack, nrmac->dl_bler.harq_round_max); } free(uci_234->harq.harq_payload); } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 9904067aa5..abe5cd8361 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -163,7 +163,8 @@ bwp_info_t get_pusch_bwp_start_size(NR_UE_info_t *UE) // contiguously allocated non-interleaved virtual resource blocks within the active bandwidth part of size PRBs except for the // case when DCI format 0_0 is decoded in any common search space in which case the size of the initial UL bandwidth part shall // be used. - if (ul_bwp->dci_format == NR_UL_DCI_FORMAT_0_0 && sched_ctrl->search_space->searchSpaceType + if (ul_bwp->dci_format == NR_UL_DCI_FORMAT_0_0 + && sched_ctrl->search_space->searchSpaceType && sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common) { bwp_info.bwpSize = min(ul_bwp->BWPSize, UE->sc_info.initial_ul_BWPSize); } else { @@ -772,10 +773,9 @@ static void nr_rx_ra_sdu(const module_id_t mod_id, nr_mac_reset_ul_failure(sched_ctrl); reset_dl_harq_list(sched_ctrl); reset_ul_harq_list(sched_ctrl); - // we configure the UE using common search space with DCIX0 while waiting for a reconfiguration in SA - // in NSA (or do-ra) there is no reconfiguration in NR - int ss_type = IS_SA_MODE(get_softmodem_params()) ? NR_SearchSpace__searchSpaceType_PR_common - : NR_SearchSpace__searchSpaceType_PR_ue_Specific; + // we configure the UE using dedicated search space: In SA (CFRA used for + // handover) and NSA (or do-ra), the UE has the full config already. + int ss_type = NR_SearchSpace__searchSpaceType_PR_ue_Specific; configure_UE_BWP(mac, scc, UE, false, ss_type, -1, -1); // initialize ta_frame in case there is no Msg3 received UE->UE_sched_ctrl.ta_frame = (frame + 100) % MAX_FRAME_NUMBER; @@ -2606,7 +2606,6 @@ void post_process_ulsch(gNB_MAC_INST *nr_mac, post_process_pusch_t *pusch, NR_UE &uldci_payload, current_BWP->dci_format, TYPE_C_RNTI_, - current_BWP->bwp_id, ss, coreset, UE->pdsch_HARQ_ACK_Codebook, diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_config.h b/openair2/LAYER2/NR_MAC_gNB/mac_config.h index 1fdbe62115..6089d39975 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_config.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_config.h @@ -43,4 +43,6 @@ typedef struct gnb_sat_position_update_s { bool nr_update_sib19(const gnb_sat_position_update_t *sat_position); +bool nr_trigger_bwp_switch(uint16_t rnti, int bwp_id); + #endif /*__LAYER2_NR_MAC_CONFIG_H__*/ diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index e280a8cbe2..af0d102212 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -258,7 +258,6 @@ void fill_dci_pdu_rel15(const NR_UE_ServingCell_Info_t *servingCellInfo, dci_pdu_rel15_t *dci_pdu_rel15, int dci_format, int rnti_type, - int bwp_id, NR_SearchSpace_t *ss, NR_ControlResourceSet_t *coreset, long pdsch_HARQ_ACK_Codebook, @@ -478,7 +477,7 @@ void nr_mac_trigger_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpac void nr_mac_reset_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl); bool nr_mac_check_ul_failure(gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ctrl_t *sched_ctrl); -void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_t *UE, int new_bwp_id); +void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, NR_UE_info_t *UE, int new_bwp_id); bool nr_mac_add_lcid(NR_UE_sched_ctrl_t *sched_ctrl, const nr_lc_config_t *c); nr_lc_config_t *nr_mac_get_lc_config(NR_UE_sched_ctrl_t* sched_ctrl, int lcid); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 8f98aabbee..6d105078b7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -576,6 +576,7 @@ static NR_UE_info_t *create_new_UE(gNB_MAC_INST *mac, uint32_t cu_id, const NR_C cellGroupConfig->spCellConfig->reconfigurationWithSync = get_reconfiguration_with_sync(UE->rnti, UE->uid, scc, mac->frame); // TODO: in NSA we assign capabilities here, otherwise outside => not logic UE->capability = cap; + UE->local_bwp_id = 1; // get_default_secondaryCellGroup sets 1st active BWP as 1 } // note: we don't pass the cellGroupConfig to add_new_nr_ue() because we need // the uid to create the CellGroupConfig (which is in the UE context created @@ -770,9 +771,12 @@ void ue_context_modification_request(const f1ap_ue_context_mod_req_t *req) } else if (req->reconfig_compl) { LOG_I(NR_MAC, "DU received confirmation of successful RRC Reconfiguration\n"); if (UE->reconfigSpCellConfig) { - // in case of reestablishment, the spCellConfig had to be released - // temporarily. Reapply now before doing the reconfiguration. - UE->CellGroup->spCellConfig = UE->reconfigSpCellConfig; + if (UE->await_reconfig) { + // in case of reestablishment, the spCellConfig had to be released + // temporarily. Reapply now before doing the reconfiguration. + UE->CellGroup->spCellConfig = UE->reconfigSpCellConfig; + UE->await_reconfig = false; + } UE->reconfigSpCellConfig = NULL; for (int i = 1; i < seq_arr_size(&UE->UE_sched_ctrl.lc_config); ++i) { nr_lc_config_t *c = seq_arr_at(&UE->UE_sched_ctrl.lc_config, i); @@ -971,6 +975,7 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc) * reconfiguration has succeeded (indicated by the CU) */ UE->reconfigSpCellConfig = UE->CellGroup->spCellConfig; UE->CellGroup->spCellConfig = NULL; + UE->await_reconfig = true; mac_remove_nr_ue(mac, *dl_rrc->old_gNB_DU_ue_id); pthread_mutex_unlock(&mac->sched_lock); nr_rlc_remove_ue(dl_rrc->gNB_DU_ue_id); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index aa8b2b8644..1a4ea9f3af 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -475,6 +475,9 @@ typedef struct NR_pdsch_dmrs { NR_PTRS_DownlinkConfig_t *phaseTrackingRS; } NR_pdsch_dmrs_t; +struct NR_UE_info; +struct gNB_MAC_INST_s; +typedef void (*feedback_action_t)(struct gNB_MAC_INST_s *mac, struct NR_UE_info *ue); typedef struct NR_sched_pdsch { /// RB allocation within active BWP uint16_t rbSize; @@ -501,6 +504,7 @@ typedef struct NR_sched_pdsch { // time_domain_allocation is the index of a list of tda int time_domain_allocation; NR_tda_info_t tda_info; + feedback_action_t action; } NR_sched_pdsch_t; typedef struct NR_UE_harq { @@ -772,7 +776,7 @@ typedef struct measgap_config { } measgap_config_t; /*! \brief UE list used by gNB to order UEs/CC for scheduling*/ -typedef struct { +typedef struct NR_UE_info { rnti_t rnti; uid_t uid; // unique ID of this UE /// scheduling control info @@ -795,7 +799,13 @@ typedef struct { float dl_thr_ue; long pdsch_HARQ_ACK_Codebook; bool is_redcap; + bool await_reconfig; NR_RA_t *ra; + // 3GPP mandates that BWPs are enumerated consecutively, but we only send one (dedicated) + // BWP to the UE (and modify that BWP on reconfiguration); consequently, the BWP ID for a + // dedicated BWP is always 1 from the UE's point of view, even if the gNB has multiple BWPs. + // The below ID is the "true" (non-consecutive) BWP ID from the gNB's point of view + NR_BWP_Id_t local_bwp_id; } NR_UE_info_t; typedef struct { diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c index 3d0e3ed246..3cd448b216 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c @@ -1505,10 +1505,38 @@ static NR_PTRS_UplinkConfig_t *config_ulptrs(const nr_ptrs_config_t *ptrs) return ulptrs; } -static NR_SetupRelease_PUSCH_Config_t *config_pusch(const bool use_deltaMCS, +long ue_supported_ul_layers(const NR_UE_NR_Capability_t *uecap) +{ + long ul_max_layers = 1; + if (uecap + && uecap->featureSets + && uecap->featureSets->featureSetsUplinkPerCC + && uecap->featureSets->featureSetsUplinkPerCC->list.count > 0) { + NR_FeatureSetUplinkPerCC_t *ul_feature_setup_per_cc = uecap->featureSets->featureSetsUplinkPerCC->list.array[0]; + if (ul_feature_setup_per_cc->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH) { + switch (*ul_feature_setup_per_cc->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH) { + case NR_MIMO_LayersUL_twoLayers: + ul_max_layers = 2; + break; + case NR_MIMO_LayersUL_fourLayers: + ul_max_layers = 4; + break; + default: + ul_max_layers = 1; + } + } + } + return ul_max_layers; +} + +static long set_ul_max_layers(const nr_mac_config_t *configuration, const NR_UE_NR_Capability_t *uecap) +{ + return min(ue_supported_ul_layers(uecap), configuration->pusch_AntennaPorts); +} + +static NR_SetupRelease_PUSCH_Config_t *config_pusch(const nr_mac_config_t *configuration, const NR_ServingCellConfigCommon_t *scc, - const NR_UE_NR_Capability_t *uecap, - const nr_ptrs_config_t *ptrs) + const NR_UE_NR_Capability_t *uecap) { NR_SetupRelease_PUSCH_Config_t *setup_puschconfig = calloc(1, sizeof(*setup_puschconfig)); setup_puschconfig->present = NR_SetupRelease_PUSCH_Config_PR_setup; @@ -1526,8 +1554,8 @@ static NR_SetupRelease_PUSCH_Config_t *config_pusch(const bool use_deltaMCS, if (!pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup) pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup = calloc(1, sizeof(*pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup)); NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup; - if (ptrs) { - NR_PTRS_UplinkConfig_t *ptrs_config = config_ulptrs(ptrs); + if (configuration->ptrs) { + NR_PTRS_UplinkConfig_t *ptrs_config = config_ulptrs(configuration->ptrs); NR_SetupRelease_PTRS_UplinkConfig_t *phaseTrackingRS = calloc(1, sizeof(*phaseTrackingRS)); phaseTrackingRS->present = NR_SetupRelease_PTRS_UplinkConfig_PR_setup; phaseTrackingRS->choice.setup = ptrs_config; @@ -1569,7 +1597,7 @@ static NR_SetupRelease_PUSCH_Config_t *config_pusch(const bool use_deltaMCS, asn1cSeqAdd(&pusch_Config->pusch_PowerControl->pathlossReferenceRSToAddModList->list, plrefRS); pusch_Config->pusch_PowerControl->pathlossReferenceRSToReleaseList = NULL; pusch_Config->pusch_PowerControl->twoPUSCH_PC_AdjustmentStates = NULL; - if (use_deltaMCS) { + if (configuration->use_deltaMCS) { if (!pusch_Config->pusch_PowerControl->deltaMCS) pusch_Config->pusch_PowerControl->deltaMCS = calloc(1, sizeof(*pusch_Config->pusch_PowerControl->deltaMCS)); *pusch_Config->pusch_PowerControl->deltaMCS = NR_PUSCH_PowerControl__deltaMCS_enabled; @@ -1582,14 +1610,14 @@ static NR_SetupRelease_PUSCH_Config_t *config_pusch(const bool use_deltaMCS, pusch_Config->resourceAllocation = NR_PUSCH_Config__resourceAllocation_resourceAllocationType1; pusch_Config->pusch_TimeDomainAllocationList = NULL; pusch_Config->pusch_AggregationFactor = NULL; - set_ul_mcs_table(uecap, scc, pusch_Config); + set_ul_mcs_table(configuration->force_UL256qam_off ? NULL : uecap, scc, pusch_Config); pusch_Config->transformPrecoder = NULL; if (!pusch_Config->codebookSubset) pusch_Config->codebookSubset = calloc(1, sizeof(*pusch_Config->codebookSubset)); *pusch_Config->codebookSubset = NR_PUSCH_Config__codebookSubset_nonCoherent; if (!pusch_Config->maxRank) pusch_Config->maxRank = calloc(1, sizeof(*pusch_Config->maxRank)); - *pusch_Config->maxRank = 1; + *pusch_Config->maxRank = set_ul_max_layers(configuration, uecap); pusch_Config->rbg_Size = NULL; pusch_Config->uci_OnPUSCH = NULL; pusch_Config->tp_pi2BPSK = NULL; @@ -1696,20 +1724,18 @@ static NR_BWP_Downlink_t *config_downlinkBWP(const NR_ServingCellConfigCommon_t const NR_UE_NR_Capability_t *uecap, int dl_antenna_ports, bool force_256qam_off, - int bwp_loop, bool is_SA, const nr_mac_config_t *configuration) { NR_BWP_Downlink_t *bwp = calloc_or_fail(1, sizeof(*bwp)); + bwp->bwp_Id = 1; bwp->bwp_Common = calloc(1,sizeof(*bwp->bwp_Common)); - if(configuration->num_additional_bwps > 0) { - const nr_bwp_config_t *bwp_config = &configuration->bwp_config[bwp_loop]; - bwp->bwp_Id = bwp_config->id; + if(configuration->num_additional_bwps > 0 && configuration->first_active_bwp > 0) { + const nr_bwp_config_t *bwp_config = &configuration->bwp_config[configuration->first_active_bwp - 1]; bwp->bwp_Common->genericParameters.locationAndBandwidth = bwp_config->location_and_bw; bwp->bwp_Common->genericParameters.subcarrierSpacing = bwp_config->scs; bwp->bwp_Common->genericParameters.cyclicPrefix = NULL; } else { - bwp->bwp_Id=bwp_loop+1; bwp->bwp_Common->genericParameters.locationAndBandwidth = PRBalloc_to_locationandbandwidth(scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth,0); bwp->bwp_Common->genericParameters.subcarrierSpacing = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing; bwp->bwp_Common->genericParameters.cyclicPrefix = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.cyclicPrefix; @@ -1743,7 +1769,7 @@ static NR_BWP_Downlink_t *config_downlinkBWP(const NR_ServingCellConfigCommon_t agg_level_candidates[PDCCH_AGG_LEVEL4] = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1; agg_level_candidates[PDCCH_AGG_LEVEL8] = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0; agg_level_candidates[PDCCH_AGG_LEVEL16] = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0; - ss = rrc_searchspace_config(true, searchspaceid, 0, agg_level_candidates); + ss = rrc_searchspace_config(true, searchspaceid, coreset->controlResourceSetId, agg_level_candidates); } asn1cSeqAdd(&bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list, ss); @@ -1784,7 +1810,7 @@ static NR_BWP_Downlink_t *config_downlinkBWP(const NR_ServingCellConfigCommon_t verify_agg_levels(num_cces, configuration->num_agg_level_candidates, coreset2->controlResourceSetId, rrc_num_agg_level_candidates); searchspaceid = 10 + bwp->bwp_Id; - NR_SearchSpace_t *ss2 = rrc_searchspace_config(true, searchspaceid, is_SA ? 0 : coreset2->controlResourceSetId, agg_level_candidates); + NR_SearchSpace_t *ss2 = rrc_searchspace_config(true, searchspaceid, coreset2->controlResourceSetId, agg_level_candidates); asn1cSeqAdd(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list, ss2); searchspaceid = 20 + bwp->bwp_Id; @@ -1802,8 +1828,7 @@ static NR_BWP_Downlink_t *config_downlinkBWP(const NR_ServingCellConfigCommon_t return bwp; } -static NR_BWP_Uplink_t *config_uplinkBWP(long bwp_loop, - bool is_SA, +static NR_BWP_Uplink_t *config_uplinkBWP(bool is_SA, int uid, int maxMIMO_Layers, const nr_mac_config_t *configuration, @@ -1811,14 +1836,14 @@ static NR_BWP_Uplink_t *config_uplinkBWP(long bwp_loop, const NR_UE_NR_Capability_t *uecap) { NR_BWP_Uplink_t *ubwp = calloc_or_fail(1, sizeof(*ubwp)); + ubwp->bwp_Id = 1; ubwp->bwp_Common = calloc(1, sizeof(*ubwp->bwp_Common)); - if(configuration->num_additional_bwps > 0) { - ubwp->bwp_Id = configuration->bwp_config[bwp_loop].id; - ubwp->bwp_Common->genericParameters.locationAndBandwidth = configuration->bwp_config[bwp_loop].location_and_bw; - ubwp->bwp_Common->genericParameters.subcarrierSpacing = configuration->bwp_config[bwp_loop].scs; + if(configuration->num_additional_bwps > 0 && configuration->first_active_bwp > 0) { + int bwp_idx = configuration->first_active_bwp - 1; + ubwp->bwp_Common->genericParameters.locationAndBandwidth = configuration->bwp_config[bwp_idx].location_and_bw; + ubwp->bwp_Common->genericParameters.subcarrierSpacing = configuration->bwp_config[bwp_idx].scs; ubwp->bwp_Common->genericParameters.cyclicPrefix = NULL; } else { - ubwp->bwp_Id=bwp_loop+1; ubwp->bwp_Common->genericParameters.locationAndBandwidth = PRBalloc_to_locationandbandwidth(scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth,0); ubwp->bwp_Common->genericParameters.subcarrierSpacing = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; ubwp->bwp_Common->genericParameters.cyclicPrefix = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.cyclicPrefix; @@ -1855,16 +1880,13 @@ static NR_BWP_Uplink_t *config_uplinkBWP(long bwp_loop, scheduling_request_config(scc, pucch_Config, ubwp->bwp_Common->genericParameters.subcarrierSpacing); set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME, ubwp->bwp_Common->genericParameters.subcarrierSpacing); - ubwp->bwp_Dedicated->pusch_Config = config_pusch(configuration->use_deltaMCS, - scc, - configuration->force_UL256qam_off ? NULL : uecap, - configuration->ptrs); + ubwp->bwp_Dedicated->pusch_Config = config_pusch(configuration, scc, uecap); ubwp->bwp_Dedicated->srs_Config = get_config_srs(scc, NULL, curr_bwp, uid, - bwp_loop + 1, + ubwp->bwp_Id, maxMIMO_Layers, configuration->minRXTXTIME, configuration->do_SRS); @@ -3268,6 +3290,7 @@ static void fill_harq_IEs(NR_ServingCellConfig_t *scc, int num_dlharq, int num_u static NR_BWP_UplinkDedicated_t *configure_initial_ul_bwp(const NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *configuration, int maxMIMO_Layers, + const NR_UE_NR_Capability_t *uecap, int id) { NR_BWP_UplinkDedicated_t *initialUplinkBWP = calloc(1, sizeof(*initialUplinkBWP)); @@ -3282,14 +3305,14 @@ static NR_BWP_UplinkDedicated_t *configure_initial_ul_bwp(const NR_ServingCellCo pucch_Config->resourceToAddModList = calloc(1, sizeof(*pucch_Config->resourceToAddModList)); pucch_Config->resourceToReleaseList = NULL; int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp); - config_pucch_resset0(pucch_Config, id, curr_bwp, num_pucch2, NULL); - config_pucch_resset1(pucch_Config, id, num_pucch2, NULL); + config_pucch_resset0(pucch_Config, id, curr_bwp, num_pucch2, uecap); + config_pucch_resset1(pucch_Config, id, num_pucch2, uecap); set_pucch_power_config(pucch_Config, configuration->do_CSIRS); - initialUplinkBWP->pusch_Config = config_pusch(configuration->use_deltaMCS, scc, NULL, configuration->ptrs); + initialUplinkBWP->pusch_Config = config_pusch(configuration, scc, uecap); // We are using do_srs = 0 here because the periodic SRS will only be enabled in update_cellGroupConfig() if do_srs == 1 - initialUplinkBWP->srs_Config = get_config_srs(scc, NULL, curr_bwp, id, 0, maxMIMO_Layers, configuration->minRXTXTIME, 0); + initialUplinkBWP->srs_Config = get_config_srs(scc, uecap, curr_bwp, id, 0, maxMIMO_Layers, configuration->minRXTXTIME, 0); scheduling_request_config(scc, pucch_Config, scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing); set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME, genericParameters->subcarrierSpacing); @@ -3299,6 +3322,7 @@ static NR_BWP_UplinkDedicated_t *configure_initial_ul_bwp(const NR_ServingCellCo static NR_BWP_DownlinkDedicated_t *configure_initial_dl_bwp(const NR_ServingCellConfigCommon_t *scc, const int pdsch_AntennaPorts, uint64_t bitmap, + const NR_UE_NR_Capability_t *uecap, const nr_mac_config_t *configuration) { NR_BWP_DownlinkDedicated_t *bwp_Dedicated = calloc(1, sizeof(*bwp_Dedicated)); @@ -3330,6 +3354,11 @@ static NR_BWP_DownlinkDedicated_t *configure_initial_dl_bwp(const NR_ServingCell bwp_Dedicated->pdcch_Config->choice.setup = pdcch_Config; bwp_Dedicated->pdsch_Config = config_pdsch(bitmap, 0, pdsch_AntennaPorts, configuration->ptrs); + // we might call configuration of initial BWP for BWP switch when we already have UE capabilities + set_dl_mcs_table(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing, + configuration->force_256qam_off ? NULL : uecap, + bwp_Dedicated, + scc); return bwp_Dedicated; } @@ -3367,10 +3396,14 @@ static NR_CSI_MeasConfig_t *get_csiMeasConfig(const NR_ServingCellConfig_t *conf pdsch_Config = configDedicated->initialDownlinkBWP->pdsch_Config; curr_bwp = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); } else { - NR_BWP_Downlink_t *bwp = configDedicated->downlinkBWP_ToAddModList->list.array[0]; + NR_BWP_Downlink_t *bwp = NULL; + for (int i = 0; i < configDedicated->downlinkBWP_ToAddModList->list.count; i++) { + if (bwp_id == configDedicated->downlinkBWP_ToAddModList->list.array[i]->bwp_Id) + bwp = configDedicated->downlinkBWP_ToAddModList->list.array[i]; + } + AssertFatal(bwp, "BWP ID doesn't match\n"); pdsch_Config = bwp->bwp_Dedicated->pdsch_Config; curr_bwp = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - AssertFatal(bwp_id == bwp->bwp_Id, "BWP ID doesn't match\n"); } const int pdsch_AntennaPorts = @@ -3501,25 +3534,24 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid, uint64_t bitmap = get_ssb_bitmap(scc); int first_active_bwp = 0; if (configuration->num_additional_bwps > 0) - first_active_bwp = configuration->first_active_bwp; + first_active_bwp = configuration->first_active_bwp > 0 ? 1 : 0; asn1cCallocOne(configDedicated->firstActiveDownlinkBWP_Id, first_active_bwp); asn1cCallocOne(uplinkConfig->firstActiveUplinkBWP_Id, first_active_bwp); if (first_active_bwp == 0) { - uplinkConfig->initialUplinkBWP = configure_initial_ul_bwp(scc, configuration, maxMIMO_Layers, uid); - configDedicated->initialDownlinkBWP = configure_initial_dl_bwp(scc, pdsch_AntennaPorts, bitmap, configuration); + uplinkConfig->initialUplinkBWP = configure_initial_ul_bwp(scc, configuration, maxMIMO_Layers, NULL, uid); + configDedicated->initialDownlinkBWP = configure_initial_dl_bwp(scc, pdsch_AntennaPorts, bitmap, NULL, configuration); } else { configDedicated->downlinkBWP_ToAddModList = calloc(1, sizeof(*configDedicated->downlinkBWP_ToAddModList)); NR_BWP_Downlink_t *bwp = config_downlinkBWP(scc, NULL, 0, false, - first_active_bwp - 1, true, configuration); asn1cSeqAdd(&configDedicated->downlinkBWP_ToAddModList->list, bwp); uplinkConfig->uplinkBWP_ToAddModList = calloc(1, sizeof(*uplinkConfig->uplinkBWP_ToAddModList)); - NR_BWP_Uplink_t *ubwp = config_uplinkBWP(first_active_bwp - 1, true, uid, maxMIMO_Layers, configuration, scc, NULL); + NR_BWP_Uplink_t *ubwp = config_uplinkBWP(true, uid, maxMIMO_Layers, configuration, scc, NULL); asn1cSeqAdd(&uplinkConfig->uplinkBWP_ToAddModList->list, ubwp); } @@ -3739,75 +3771,22 @@ NR_CellGroupConfig_t *get_initial_cellGroupConfig(int uid, return cellGroupConfig; } -long ue_supported_ul_layers(const NR_UE_NR_Capability_t *uecap) -{ - long ul_max_layers = 1; - if (uecap - && uecap->featureSets - && uecap->featureSets->featureSetsUplinkPerCC - && uecap->featureSets->featureSetsUplinkPerCC->list.count > 0) { - NR_FeatureSetUplinkPerCC_t *ul_feature_setup_per_cc = uecap->featureSets->featureSetsUplinkPerCC->list.array[0]; - if (ul_feature_setup_per_cc->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH) { - switch (*ul_feature_setup_per_cc->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH) { - case NR_MIMO_LayersUL_twoLayers: - ul_max_layers = 2; - break; - case NR_MIMO_LayersUL_fourLayers: - ul_max_layers = 4; - break; - default: - ul_max_layers = 1; - } - } - } - return ul_max_layers; -} - -static long set_ul_max_layers(const nr_mac_config_t *configuration, const NR_UE_NR_Capability_t *uecap) -{ - return min(ue_supported_ul_layers(uecap), configuration->pusch_AntennaPorts); -} - -NR_CellGroupConfig_t * update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t *cellGroupConfig, - const nr_mac_config_t *configuration, - const NR_UE_NR_Capability_t *uecap, - const NR_ServingCellConfigCommon_t *scc, - int uid, - int old_bwp, - int new_bwp) +NR_CellGroupConfig_t *update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t *cellGroupConfig, + const nr_mac_config_t *configuration, + const NR_UE_NR_Capability_t *uecap, + const NR_ServingCellConfigCommon_t *scc, + int uid, + int old_bwp, + int new_bwp) { NR_SpCellConfig_t *spCellConfig = cellGroupConfig->spCellConfig; NR_ServingCellConfig_t *configDedicated = spCellConfig->spCellConfigDedicated; - *configDedicated->firstActiveDownlinkBWP_Id = new_bwp; + *configDedicated->firstActiveDownlinkBWP_Id = new_bwp != 0; // 1 for any BWP != 0 NR_UplinkConfig_t *uplinkConfig = configDedicated->uplinkConfig; - *uplinkConfig->firstActiveUplinkBWP_Id = new_bwp; + *uplinkConfig->firstActiveUplinkBWP_Id = new_bwp != 0; // 1 for any BWP != 0 + nr_mac_config_t local_config = *configuration; long ul_maxMIMO_Layers = set_ul_max_layers(configuration, uecap); - - // release old BWP - struct NR_ServingCellConfig__downlinkBWP_ToAddModList *dl_BWP_list = configDedicated->downlinkBWP_ToAddModList; - struct NR_UplinkConfig__uplinkBWP_ToAddModList *ul_BWP_list = uplinkConfig->uplinkBWP_ToAddModList; - if (old_bwp > 0) { // we need to remove old BWP only if it is not the initial - AssertFatal(dl_BWP_list, "Source BWP %d should be present in the list\n", old_bwp); - AssertFatal(ul_BWP_list, "Source BWP %d should be present in the list\n", old_bwp); - NR_BWP_Id_t id = dl_BWP_list->list.array[0]->bwp_Id; - if (!configDedicated->downlinkBWP_ToReleaseList) - configDedicated->downlinkBWP_ToReleaseList = calloc_or_fail(1, sizeof(*configDedicated->downlinkBWP_ToReleaseList)); - asn1cSequenceAdd(configDedicated->downlinkBWP_ToReleaseList->list, NR_BWP_Id_t, rel_id); - *rel_id = id; - AssertFatal(configDedicated->downlinkBWP_ToReleaseList->list.count == 1, - "logic error: there shouldn't be more than 1 BWP to release, but downlinkBWP_ToReleaseList has %d\n", - configDedicated->downlinkBWP_ToReleaseList->list.count); - - id = ul_BWP_list->list.array[0]->bwp_Id; - if (!uplinkConfig->uplinkBWP_ToReleaseList) - uplinkConfig->uplinkBWP_ToReleaseList = calloc_or_fail(1, sizeof(*uplinkConfig->uplinkBWP_ToReleaseList)); - asn1cSequenceAdd(uplinkConfig->uplinkBWP_ToReleaseList->list, NR_BWP_Id_t, ul_rel_id); - *ul_rel_id = id; - AssertFatal(uplinkConfig->uplinkBWP_ToReleaseList->list.count == 1, - "logic error: there shouldn't be more than 1 BWP to release, but uplinkBWP_ToReleaseList has %d\n", - uplinkConfig->uplinkBWP_ToReleaseList->list.count); - } - + local_config.first_active_bwp = new_bwp; uint64_t bitmap = get_ssb_bitmap(scc); const int pdsch_AntennaPorts = configuration->pdsch_AntennaPorts.N1 * configuration->pdsch_AntennaPorts.N2 * configuration->pdsch_AntennaPorts.XP; @@ -3817,23 +3796,22 @@ NR_CellGroupConfig_t * update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_ configDedicated->initialDownlinkBWP = calloc_or_fail(1, sizeof(*configDedicated->initialDownlinkBWP)); if (!uplinkConfig->initialUplinkBWP) uplinkConfig->initialUplinkBWP = calloc_or_fail(1, sizeof(*uplinkConfig->initialUplinkBWP)); - uplinkConfig->initialUplinkBWP = configure_initial_ul_bwp(scc, configuration, ul_maxMIMO_Layers, uid); - configDedicated->initialDownlinkBWP = configure_initial_dl_bwp(scc, pdsch_AntennaPorts, bitmap, configuration); + uplinkConfig->initialUplinkBWP = configure_initial_ul_bwp(scc, &local_config, ul_maxMIMO_Layers, uecap, uid); + configDedicated->initialDownlinkBWP = configure_initial_dl_bwp(scc, pdsch_AntennaPorts, bitmap, uecap, &local_config); } else { if (!configDedicated->downlinkBWP_ToAddModList) configDedicated->downlinkBWP_ToAddModList = calloc_or_fail(1, sizeof(*configDedicated->downlinkBWP_ToAddModList)); NR_BWP_Downlink_t *dl_bwp = config_downlinkBWP(scc, uecap, pdsch_AntennaPorts, - configuration->force_256qam_off, - new_bwp - 1, + local_config.force_256qam_off, true, - configuration); + &local_config); asn1cSeqAdd(&configDedicated->downlinkBWP_ToAddModList->list, dl_bwp); if (!uplinkConfig->uplinkBWP_ToAddModList) uplinkConfig->uplinkBWP_ToAddModList = calloc_or_fail(1, sizeof(*uplinkConfig->uplinkBWP_ToAddModList)); - NR_BWP_Uplink_t *ul_bwp = config_uplinkBWP(new_bwp - 1, true, uid, ul_maxMIMO_Layers, configuration, scc, uecap); + NR_BWP_Uplink_t *ul_bwp = config_uplinkBWP(true, uid, ul_maxMIMO_Layers, &local_config, scc, uecap); asn1cSeqAdd(&uplinkConfig->uplinkBWP_ToAddModList->list, ul_bwp); } @@ -3841,9 +3819,9 @@ NR_CellGroupConfig_t * update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_ configDedicated->csi_MeasConfig->choice.setup = get_csiMeasConfig(configDedicated, uecap, scc, - configuration, + &local_config, uid, - new_bwp, + *uplinkConfig->firstActiveUplinkBWP_Id, bitmap); // we temporarily need to keep both the old and the new BWP in the CG used by the gNB @@ -4055,10 +4033,7 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC ulConfig->initialUplinkBWP = initialUplinkBWP; initialUplinkBWP->pucch_Config = NULL; - initialUplinkBWP->pusch_Config = config_pusch(configuration->use_deltaMCS, - servingcellconfigcommon, - uecap, - configuration->ptrs); + initialUplinkBWP->pusch_Config = config_pusch(configuration, servingcellconfigcommon, uecap); long maxMIMO_Layers = set_ul_max_layers(configuration, uecap); int curr_bwp = NRRIV2BW(servingcellconfigcommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, @@ -4073,44 +4048,27 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC configuration->do_SRS); // Downlink BWPs - int n_dl_bwp = 1; int firstActiveDownlinkBWP_Id = 1; - if (configuration->num_additional_bwps > 0) { - n_dl_bwp = configuration->num_additional_bwps; - firstActiveDownlinkBWP_Id = configuration->first_active_bwp; - } configDedicated->downlinkBWP_ToAddModList = calloc(1, sizeof(*configDedicated->downlinkBWP_ToAddModList)); - for (int bwp_loop = 0; bwp_loop < n_dl_bwp; bwp_loop++) { - NR_BWP_Downlink_t *bwp = config_downlinkBWP(servingcellconfigcommon, - uecap, - dl_antenna_ports, - configuration->force_256qam_off, - bwp_loop, - false, - configuration); - asn1cSeqAdd(&configDedicated->downlinkBWP_ToAddModList->list, bwp); - configDedicated->firstActiveDownlinkBWP_Id = calloc(1, sizeof(*configDedicated->firstActiveDownlinkBWP_Id)); - *configDedicated->firstActiveDownlinkBWP_Id = firstActiveDownlinkBWP_Id; - configDedicated->defaultDownlinkBWP_Id = calloc(1, sizeof(*configDedicated->defaultDownlinkBWP_Id)); - *configDedicated->defaultDownlinkBWP_Id = 1; - } + NR_BWP_Downlink_t *bwp = config_downlinkBWP(servingcellconfigcommon, + uecap, + dl_antenna_ports, + configuration->force_256qam_off, + false, + configuration); + asn1cSeqAdd(&configDedicated->downlinkBWP_ToAddModList->list, bwp); + configDedicated->firstActiveDownlinkBWP_Id = calloc(1, sizeof(*configDedicated->firstActiveDownlinkBWP_Id)); + *configDedicated->firstActiveDownlinkBWP_Id = firstActiveDownlinkBWP_Id; + configDedicated->defaultDownlinkBWP_Id = calloc(1, sizeof(*configDedicated->defaultDownlinkBWP_Id)); + *configDedicated->defaultDownlinkBWP_Id = 1; // Uplink BWPs - int n_ul_bwp = 1; int firstActiveUplinkBWP_Id = 1; - if (configuration->num_additional_bwps > 0) { - n_ul_bwp = configuration->num_additional_bwps; - firstActiveUplinkBWP_Id = configuration->first_active_bwp; - } - if (n_ul_bwp > 0) { - ulConfig->uplinkBWP_ToAddModList = calloc(1, sizeof(*ulConfig->uplinkBWP_ToAddModList)); - for (int bwp_loop = 0; bwp_loop < n_ul_bwp; bwp_loop++) { - NR_BWP_Uplink_t *ubwp = config_uplinkBWP(bwp_loop, false, uid, maxMIMO_Layers, configuration, servingcellconfigcommon, uecap); - asn1cSeqAdd(&ulConfig->uplinkBWP_ToAddModList->list, ubwp); - } - ulConfig->firstActiveUplinkBWP_Id = calloc(1, sizeof(*ulConfig->firstActiveUplinkBWP_Id)); - *ulConfig->firstActiveUplinkBWP_Id = firstActiveUplinkBWP_Id; - } + ulConfig->uplinkBWP_ToAddModList = calloc(1, sizeof(*ulConfig->uplinkBWP_ToAddModList)); + NR_BWP_Uplink_t *ubwp = config_uplinkBWP(false, uid, maxMIMO_Layers, configuration, servingcellconfigcommon, uecap); + asn1cSeqAdd(&ulConfig->uplinkBWP_ToAddModList->list, ubwp); + ulConfig->firstActiveUplinkBWP_Id = calloc(1, sizeof(*ulConfig->firstActiveUplinkBWP_Id)); + *ulConfig->firstActiveUplinkBWP_Id = firstActiveUplinkBWP_Id; configDedicated->bwp_InactivityTimer = NULL; configDedicated->downlinkBWP_ToReleaseList = NULL; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h index 270aed4b71..b776d667d6 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h @@ -124,13 +124,13 @@ NR_RLC_BearerConfig_t *get_DRB_RLC_BearerConfig(long lcChannelId, NR_RLC_Config_PR rlc_conf, long priority, const nr_rlc_configuration_t *default_rlc_config); -NR_CellGroupConfig_t * update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t *cellGroupConfig, - const nr_mac_config_t *configuration, - const NR_UE_NR_Capability_t *uecap, - const NR_ServingCellConfigCommon_t *scc, - int uid, - int old_bwp, - int new_bwp); +NR_CellGroupConfig_t *update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t *cellGroupConfig, + const nr_mac_config_t *configuration, + const NR_UE_NR_Capability_t *uecap, + const NR_ServingCellConfigCommon_t *scc, + int uid, + int old_bwp, + int new_bwp); NR_MeasurementTimingConfiguration_t *get_nr_mtc(uint8_t *buf, uint32_t len); measgap_config_t create_measgap_config(const NR_MeasurementTimingConfiguration_t *mtc, int scs, int min_rxtxtime); int encode_measgap_config(const measgap_config_t *c, uint8_t *buf); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index e1d2dbe841..4d28d66b69 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -3182,10 +3182,6 @@ void *rrc_gnb_task(void *args_p) { rrc_gNB_process_dc_overall_timeout(instance, &X2AP_ENDC_DC_OVERALL_TIMEOUT(msg_p)); break; - case NGAP_UE_CONTEXT_RELEASE_REQ: - rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ(msg_p, instance); - break; - case NGAP_UE_CONTEXT_RELEASE_COMMAND: rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(msg_p, instance); break; diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 979fe0ac5e..5c212438e1 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -1049,7 +1049,8 @@ int rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE return 0; } -//------------------------------------------------------------------------------ +/** @brief Send UE Context Release Request (NG-RAN node initiated) + * Direction: NG-RAN node -> AMF (8.3.2.2 3GPP TS 38.413) */ void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(const module_id_t gnb_mod_idP, const rrc_gNB_ue_context_t *const ue_context_pP, const ngap_cause_t causeP) @@ -1068,40 +1069,12 @@ void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(const module_id_t gnb_mod_idP, // PDU Session Resource List (optional) FOR_EACH_SEQ_ARR(rrc_pdu_session_param_t *, session, &UE->pduSessions) { DevAssert(req->nb_of_pdusessions < NGAP_MAX_PDU_SESSION); - req->pdusessions[req->nb_of_pdusessions].pdusession_id = session->param.pdusession_id; + req->pdusession_ids[req->nb_of_pdusessions] = session->param.pdusession_id; req->nb_of_pdusessions++; } itti_send_msg_to_task(TASK_NGAP, GNB_MODULE_ID_TO_INSTANCE(gnb_mod_idP), msg); } } -/*------------------------------------------------------------------------------*/ -int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ(MessageDef *msg_p, instance_t instance) -{ - uint32_t gNB_ue_ngap_id; - gNB_ue_ngap_id = NGAP_UE_CONTEXT_RELEASE_REQ(msg_p).gNB_ue_ngap_id; - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], gNB_ue_ngap_id); - - if (ue_context_p == NULL) { - /* Can not associate this message to an UE index, send a failure to ngAP and discard it! */ - MessageDef *msg_fail_p; - LOG_W(RRC, "[gNB %ld] In NGAP_UE_CONTEXT_RELEASE_REQ: unknown UE from gNB_ue_ngap_id (%u)\n", - instance, - gNB_ue_ngap_id); - msg_fail_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_RESP); /* TODO change message ID. */ - NGAP_UE_CONTEXT_RELEASE_RESP(msg_fail_p).gNB_ue_ngap_id = gNB_ue_ngap_id; - // TODO add failure cause when defined! - itti_send_msg_to_task(TASK_NGAP, instance, msg_fail_p); - return (-1); - } else { - - /* Send the response */ - MessageDef *msg_resp_p; - msg_resp_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_RESP); - NGAP_UE_CONTEXT_RELEASE_RESP(msg_resp_p).gNB_ue_ngap_id = gNB_ue_ngap_id; - itti_send_msg_to_task(TASK_NGAP, instance, msg_resp_p); - return (0); - } -} /** @brief Sends the NG Handover Failure from the Target NG-RAN to the AMF */ void rrc_gNB_send_NGAP_HANDOVER_FAILURE(gNB_RRC_INST *rrc, ngap_handover_failure_t *msg) @@ -1557,9 +1530,9 @@ int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(ngap_pdusession_release_comm cmd->nb_pdusessions_torelease); e1ap_bearer_mod_req_t req = {0}; for (int pdusession = 0; pdusession < cmd->nb_pdusessions_torelease; pdusession++) { - rrc_pdu_session_param_t *pduSession = find_pduSession(&UE->pduSessions, cmd->pdusession_release_params[pdusession].pdusession_id); + rrc_pdu_session_param_t *pduSession = find_pduSession(&UE->pduSessions, cmd->pdusession_ids[pdusession]); if (!pduSession) { - LOG_E(NR_RRC, "Failed to release non-existing PDU Session %d\n", cmd->pdusession_release_params[pdusession].pdusession_id); + LOG_E(NR_RRC, "Failed to release non-existing PDU Session %d\n", cmd->pdusession_ids[pdusession]); continue; } if (pduSession->status == PDU_SESSION_STATUS_TORELEASE) { diff --git a/openair3/NGAP/ngap_gNB_context_management_procedures.c b/openair3/NGAP/ngap_gNB_context_management_procedures.c index 7f114d5bf6..57b7780d4f 100644 --- a/openair3/NGAP/ngap_gNB_context_management_procedures.c +++ b/openair3/NGAP/ngap_gNB_context_management_procedures.c @@ -191,7 +191,7 @@ int ngap_ue_context_release_req(instance_t instance, for (int i = 0; i < ue_release_req_p->nb_of_pdusessions; i++) { NGAP_PDUSessionResourceItemCxtRelReq_t *item; item = (NGAP_PDUSessionResourceItemCxtRelReq_t *)calloc(1,sizeof(NGAP_PDUSessionResourceItemCxtRelReq_t)); - item->pDUSessionID = ue_release_req_p->pdusessions[i].pdusession_id; + item->pDUSessionID = ue_release_req_p->pdusession_ids[i]; asn1cSeqAdd(&ie->value.choice.PDUSessionResourceListCxtRelReq.list, item); } } diff --git a/openair3/NGAP/ngap_gNB_handlers.c b/openair3/NGAP/ngap_gNB_handlers.c index 95c2dd45a7..a58c98508b 100644 --- a/openair3/NGAP/ngap_gNB_handlers.c +++ b/openair3/NGAP/ngap_gNB_handlers.c @@ -1390,9 +1390,20 @@ static int ngap_gNB_handle_pdusession_release_command(sctp_assoc_t assoc_id, uin for (i = 0; i < ie->value.choice.PDUSessionResourceToReleaseListRelCmd.list.count; i++) { NGAP_PDUSessionResourceToReleaseItemRelCmd_t *item_p; item_p = ie->value.choice.PDUSessionResourceToReleaseListRelCmd.list.array[i]; - pdusession_release_t *r = &msg->pdusession_release_params[i]; - r->pdusession_id = item_p->pDUSessionID; - r->data = create_byte_array(item_p->pDUSessionResourceReleaseCommandTransfer.size, item_p->pDUSessionResourceReleaseCommandTransfer.buf); + msg->pdusession_ids[i] = item_p->pDUSessionID; + + /* PDUSessionResourceReleaseCommandTransfer (Mandatory) */ + void *decoded = decode_pdusession_transfer(&asn_DEF_NGAP_PDUSessionResourceReleaseCommandTransfer, + item_p->pDUSessionResourceReleaseCommandTransfer); + if (!decoded) { + NGAP_ERROR("Failed to decode PDUSessionResourceReleaseCommandTransfer for PDU Session %d\n", msg->pdusession_ids[i]); + return -1; + } + NGAP_PDUSessionResourceReleaseCommandTransfer_t *transfer = decoded; + ngap_cause_t cause = decode_ngap_cause(&transfer->cause); + NGAP_INFO("PDU Session %d release command: Cause type=%d value=%d\n", msg->pdusession_ids[i], cause.type, cause.value); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceReleaseCommandTransfer, transfer); + free(transfer); } itti_send_msg_to_task(TASK_RRC_GNB, ue_desc_p->gNB_instance->instance, message_p); diff --git a/openair3/NGAP/ngap_gNB_nas_procedures.c b/openair3/NGAP/ngap_gNB_nas_procedures.c index 7dd6359b7a..2218155c61 100644 --- a/openair3/NGAP/ngap_gNB_nas_procedures.c +++ b/openair3/NGAP/ngap_gNB_nas_procedures.c @@ -594,6 +594,24 @@ static byte_array_t encode_ngap_pdusession_setup_response_transfer(const pdusess return out; } +/** @brief PDU Session Resource Release Response Transfer encoding (9.3.4.21 3GPP TS 38.413) + * The transfer structure contains only an optional Secondary RAT Usage Information IE. + * Since we don't use secondary RAT (MR-DC), we encode an empty structure. */ +static byte_array_t encode_ngap_pdusession_release_response_transfer(void) +{ + NGAP_PDUSessionResourceReleaseResponseTransfer_t pdusessionTransfer = {0}; + + // Encode + asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, + ATS_ALIGNED_CANONICAL_PER, + &asn_DEF_NGAP_PDUSessionResourceReleaseResponseTransfer, + &pdusessionTransfer); + AssertFatal(res.buffer, "ASN1 message encoding failed (%s, %lu)!\n", res.result.failed_type->name, res.result.encoded); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceReleaseResponseTransfer, &pdusessionTransfer); + byte_array_t out = {.buf = res.buffer, .len = res.result.encoded}; + return out; +} + //------------------------------------------------------------------------------ int ngap_gNB_initial_ctxt_resp(instance_t instance, ngap_initial_context_setup_resp_t *initial_ctxt_resp_p) //------------------------------------------------------------------------------ @@ -1200,22 +1218,28 @@ int ngap_gNB_pdusession_release_resp(instance_t instance, ngap_pdusession_releas ie->value.choice.RAN_UE_NGAP_ID = pdusession_release_resp_p->gNB_ue_ngap_id; } - /* optional */ - if (pdusession_release_resp_p->nb_of_pdusessions_released > 0) { + /* PDU Session Resource Released List (mandatory) */ + { asn1cSequenceAdd(out->protocolIEs.list, NGAP_PDUSessionResourceReleaseResponseIEs_t, ie); ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceReleasedListRelRes; ie->criticality = NGAP_Criticality_ignore; ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_PDUSessionResourceReleasedListRelRes; - + for (i = 0; i < pdusession_release_resp_p->nb_of_pdusessions_released; i++) { - asn1cSequenceAdd(ie->value.choice.PDUSessionResourceReleasedListRelRes.list, NGAP_PDUSessionResourceReleasedItemRelRes_t, item); + NGAP_PDUSessionResourceReleasedListRelRes_t *list = &ie->value.choice.PDUSessionResourceReleasedListRelRes; + asn1cSequenceAdd(list->list, NGAP_PDUSessionResourceReleasedItemRelRes_t, item); pdusession_release_t *r = &pdusession_release_resp_p->pdusession_release[i]; + /* PDU Session ID (mandatory) */ item->pDUSessionID = r->pdusession_id; - OCTET_STRING_fromBuf(&item->pDUSessionResourceReleaseResponseTransfer, (const char *)r->data.buf, r->data.len); - NGAP_DEBUG("pdusession_release_resp: pdusession ID %ld\n", item->pDUSessionID); + /* PDU Session Resource Release Response Transfer (mandatory) */ + // Empty transfer is valid since Secondary RAT Usage Information is optional and not used + byte_array_t transfer = encode_ngap_pdusession_release_response_transfer(); + OCTET_STRING_fromBuf(&item->pDUSessionResourceReleaseResponseTransfer, (const char *)transfer.buf, transfer.len); + free_byte_array(transfer); + NGAP_DEBUG("PDU Session Resource Release Response: pdusession ID %ld\n", item->pDUSessionID); } } - + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { NGAP_ERROR("Failed to encode release response\n"); /* Encode procedure has failed... */ diff --git a/openair3/NGAP/ngap_msg_includes.h b/openair3/NGAP/ngap_msg_includes.h index 816cdfb979..2a861e2e32 100644 --- a/openair3/NGAP/ngap_msg_includes.h +++ b/openair3/NGAP/ngap_msg_includes.h @@ -58,6 +58,8 @@ #include "NGAP_PDUSessionResourceSetupResponseTransfer.h" #include "NGAP_PDUSessionResourceSetupUnsuccessfulTransfer.h" #include "NGAP_PDUSessionResourceToReleaseItemRelCmd.h" +#include "NGAP_PDUSessionResourceReleaseCommandTransfer.h" +#include "NGAP_PDUSessionResourceReleaseResponseTransfer.h" #include "NGAP_PLMNSupportItem.h" #include "NGAP_ProtocolIE-Field.h" #include "NGAP_QosFlowAddOrModifyResponseItem.h" diff --git a/radio/emulator/rf_emulator.c b/radio/emulator/rf_emulator.c index 861daab2ba..e73e9bf3d6 100644 --- a/radio/emulator/rf_emulator.c +++ b/radio/emulator/rf_emulator.c @@ -364,6 +364,8 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) device->trx_read_func = emulator_read; emulator_readconfig(emulator_state); + if (emulator_state->enable_noise) + randominit(); // for noise device return 0; } diff --git a/radio/rfsimulator/simulator.c b/radio/rfsimulator/simulator.c index 94234a755f..c9093be912 100644 --- a/radio/rfsimulator/simulator.c +++ b/radio/rfsimulator/simulator.c @@ -199,20 +199,6 @@ static buffer_t *allocCirBuf(rfsimulator_state_t *bridge, int sock) if (bridge->channelmod > 0) { // create channel simulation model for this mode reception - static bool init_done = false; - - if (!init_done) { - uint64_t rand; - FILE *h = fopen("/dev/random", "r"); - - if (1 != fread(&rand, sizeof(rand), 1, h)) - LOG_W(HW, "Can't read /dev/random\n"); - - fclose(h); - randominit(rand); - tableNor(rand); - init_done = true; - } char modelname[30]; snprintf(modelname, sizeofArray(modelname), @@ -1170,7 +1156,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { AssertFatal((rfsimulator->epollfd = epoll_create1(0)) != -1, "epoll_create1() failed, errno(%d)", errno); // we need to call randominit() for telnet server (use gaussdouble=>uniformrand) - randominit(0); + randominit(); set_taus_seed(0); /* look for telnet server, if it is loaded, add the channel modeling commands to it */ add_telnetcmd_func_t addcmd = (add_telnetcmd_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_ADDCMD_FNAME);