this keeps the same logic as before, the understanding is that executing the GPIO command requires time or at least have an impact on the timing, so it is better not to execute it if not necessary
Signed-off-by: francescomani <email@francescomani.it>
Remove unnecessary log
We already check for number of received samples above after receiving.
When aligned to the slot boundary for synchronization, this length of
the samples is no longer samples_per_slot. # Please enter a commit
message to explain why this merge is necessary,
We already check for number of received samples above after receiving.
When aligned to the slot boundary for synchronization, this length
of the samples is no longer samples_per_slot.
Signed-off-by: Rakesh Mundlamuri <rakesh.mundlamuri@openairinterface.org>
Validate signed MR commits and update contribution guidelines
This MR adds validation for signed merge request commits and updates the
contributing guidelines including the requirement for signing commits.
- The CI will warn in the Verify Guidelines stage if any commit in the
merge request is unsigned.
- Checks all commits in the MR source branch that are not present in
the target branch
- It then verifies if all these commits are signed
- Update contributing guidelines to include commit rules and signing
commits using git commit -s.
- The CI will also check if there are any merge commits and fail the
pipeline in that case.
fix (F1 Handover): do not trigger when no DRB is configured
Prevent triggering F1 handover for UEs without any DRB, to align with
3GPP TS 38.473 clause 8.3.1.2 and avoid initiating an invalid UE Context
Setup Request in the F1 handover flow.
Changes:
- Add a preliminary check in nr_rrc_trigger_f1_ho() to verify at least
one DRB exists in ue->drbs
- Abort F1 HO trigger early when no DRB is present, with warning
spsc_q: make compile on older compilers
While compiling the spsc_q unit tests on older compilers, some complain
with
/openairinterface5g/common/utils/ds/tests/test_spsc_q.cpp:11:44: error: use of deleted function ‘spsc_q::spsc_q(spsc_q&&)’
spsc_q_t rb = spsc_q_alloc(2, sizeof(int));
/openairinterface5g/common/utils/ds/spsc_q.h:19:16: error: use of deleted function ‘std::atomic<long unsigned int>::atomic(const std::atomic<long unsigned int>&)’
These compiles cannot copy the atomic. Change the API to avoid this
copy.
"Older" compiler here means g++-11/12.
- Add a new script to validate for signed commits
- Post a GitLab MR Warning comment listing the unsigned commit details
Signed-off-by: Shubhika Garg <shubhika.garg@openairinterface.org>
Prevent triggering F1 handover for UEs without any DRB, to align
with 3GPP TS 38.473 clause 8.3.1.2 and avoid initiating an invalid
UE Context Setup Request in the F1 handover flow.
Changes:
- Add a preliminary check in `nr_rrc_trigger_f1_ho()` to verify at
least one DRB exists in ue->drbs
- Abort F1 HO trigger early when no DRB is present, with warning
Add 200MHz DDDSU Liteon configuration file
Adding 200MHz DDDSU 2x2 Liteon configuration file. I think we should keep
only 200 MHz configuration for both FR2 RUs: Liteon and Microamp.
Achieved throughputs are DL: 980 Mbps UL 90 Mbps
While compiling the spsc_q unit tests on some compilers, some
complain with
/openairinterface5g/common/utils/ds/tests/test_spsc_q.cpp:11:44: error: use of deleted function ‘spsc_q::spsc_q(spsc_q&&)’
spsc_q_t rb = spsc_q_alloc(2, sizeof(int));
/openairinterface5g/common/utils/ds/spsc_q.h:19:16: error: use of deleted function ‘std::atomic<long unsigned int>::atomic(const std::atomic<long unsigned int>&)’
These compiles cannot copy the atomic. Change the API to avoid this
copy.
"Older" compiler here means g++-11/12.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Move the subframe scaling logic outside the PRACH slot loop to prevent the
subframe index from being incorrectly multiplied multiple times when there
are multiple PRACH slots per subframe.
Add AoA selection to vrtsim
Adds AoA as a selection parameter in vrtsim. Different UEs can be
configured at different arrival angles, emulating distinct spatial
locations, which can serve as an enabler for beamforming evaluation.
fix(nrLDPC_coding): Remove ldpc_xdma
Arguments for removing:
- There are no resources to maintain it. Including no machine with the
board.
- There is no clue that someone is actually using it.
- The library is not standard/cannot be generalized. It was designed for
a specific solution and cannot be used for another.
- The standard AAL (BBDev or other) should be privileged for LDPC offload
to a hardware accelerator.
Integration `2026.w17`
* !4054 Minor fixes to gNB/UE behavior in RFsim
* !4062 Minor fixes/cleanup in NGAP lib
* !4036 Fix CSI-RS estimation
* !4055 fix (RRC): do not trigger N2 HO when no active PDU sessions are present
* !3988 asn1c inside local tree
* !3762 L1 gNB type0 PDSCH
* !4069 ctest: fix tests when compiling with sanitizers, ignore build directories, fix spsc_q build
* !4067 Small compilation fixes
* !3444 7.2 FHI with XRAN K release
* !4061 T-Tracer & Data Recording v1.1: UL PHY trace modularization and recording enhancements
* !3975 ZMQ radio
* Increase PRACH queue capacity from 8 to 16
* !4059 CI: Various CI adjustments
Closes#1074 and #1073
See merge request oai/openairinterface5g!4063
CI: Various CI adjustments
- RAN-SA-FHI72-CN5G: activate/inactive carriers on VVDN RU - to check if
it improves reliability and stability of the pipeline
- RAN-SA-FHI72-CN5G: update CN with new IP range - avoid IP address
overlap with CN used in RAN-SA-AERIAL-XXX pipelines
- RAN-SA-B200-Module-SABOX-Container: test with deltaMCS in SC-FDMA test
case
- RAN-NSA-B200-Module-LTEBOX-Container: adjust PRACH DTX threshold to
reduce number of false RA attempts on eNB
- remove retx check in RAN-SA-Multi-Antenna-CN5G and RAN-SA-AERIAL-CN5G -
to avoid false CI failure caused by unsuccessful retx check of
interfering UE
- adjust RAN-SA-Multi-Antenna-CN5G and RAN-SA-AERIAL-CN5G configs to
improve UL throughput
Manual testing showed that lowering the RX gain reduces UL
retransmissions and improves overall UL throughput in the 100 MHz 2x2
test case of the SA-Multi-Antenna CN5G pipeline.
Add vvdn-activate-carriers.sh to verify RU PTP synchronization and
configuration. Activates carriers on VVDN RU by editing sysrepo running
datastore (INACTIVE->ACTIVE).
Add vvdn-inactive-carriers.sh to reverse the operation, setting all
carriers back to INACTIVE via sysrepocfg.
After the changes introduced in !3991, multiple PRACH PDUs can be
pushed from L2 to L1 before being processed. This leads to the PRACH
queues filling up and triggering "PRACH occ queue is full" issues on
the gNB.
This commit increases the queue size from 8 to 16, providing additional
buffering and preventing queue overflows as reported in #1072.
ZMQ radio
This is a zmq radio implementation that attempts to integrate NR UE with
the ocudu project.
OAI integration status:
This can currently be used to connect OAI gnb and OAI UE.
Compilation:
cmake --build . --target nr-softmodem nr-uesoftmodem ldpc params_libconfig zmq_radio
Running
- gNB command:
sudo ./nr-softmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf --gNBs.[0].min_rxtxtime 6 --device.name zmq_radio --zmq.[0].tx_channels tcp://127.0.0.1:4556 --zmq.[0].rx_channels tcp://127.0.0.1:4557
- UE command:
sudo ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --ssb 516 --device.name zmq_radio --zmq.[0].tx_channels tcp://127.0.0.1:4557 --zmq.[0].rx_channels tcp://127.0.0.1:4556
A new CI testcase for 2x2 configuration was added.
OCUDU integration status:
The OAI NR UE enters RRC Connected state.
For more details, please refer to the description of MR !3975.
T-Tracer & Data Recording v1.1: UL PHY trace modularization and recording
enhancements
Based on the plan with @schmidtr and @roux-cedric, we agreed to enhance
the data recording in two phases:
- Phase 1: Update Data Recording framework to get All internal Massive
Updates and enhancements through the whole framework public
- Phase2: Restructure T-Tracer Apps and remove all Mems in gNB and UE
Softmodems to Get data on T-tarcer Apps for all activated Messages
symbol-by-symbol, and related Meta-data, then do the aggregation on
the T-tracer App. So, there is No Memory Creation at all on the 5G NR
Stack.
This Merge Request is for Phase 1. We address the comments given in: !3632
Summary: Refactor T-Tracer instrumentation for UL PHY data capture and
improve the data recording application (v1.0 → v1.1). This MR extracts
inline T() macro calls into modular wrapper functions, adds Unix timestamp
fields to trace messages, implements a 4-state shared memory protocol for
gNB/UE tracers, and delivers an improved synchronized recording architecture
in Python.
Changes:
- T-Tracer: Modular UL PHY trace wrappers
- Add T_messages_creator.c/.h with 7 wrapper functions (log_ul_fd_dmrs,
log_ul_fd_chan_est_dmrs_pos, log_ul_fd_pusch_iq,
log_ul_fd_chan_est_dmrs_interpl, log_ul_payload_rx_bits,
log_ul_payload_tx_bits, log_ul_scrambled_tx_bits) and a static
log_ul_common() helper
- Register T_messages_creator.c in the T library CMake build
- Update T_messages.txt definitions: Remove string timestamps and get
time stamp directly from sending_time of T-macro.
- PHY: Replace inline T() calls with wrappers
- gNB (nr_ulsch_demodulation.c, nr_ul_channel_estimation.c,
phy_procedures_nr_gNB.c): replace inline T() calls with
T_messages_creator wrappers
- UE (nr_ulsch_coding.c, nr_ulsch_ue.c): replace inline T() calls with
log_ul_payload_tx_bits and log_ul_scrambled_tx_bits wrappers
- Remove deprecated log_tools.c/.h and its CMake reference
- T-Tracer gNB & UE apps: Enhancements
- Implement 4-state shared memory protocol (WAIT → CONFIG → RECORD → STOP)
for coordination with the data recording app
- Add event_trace_msg_ul_data struct with 27 UL metadata fields
- Refactor event loop to poll()-based with proper signal handling
- Separate project IDs (gNB=2335, UE=2336) and ftok paths for independent
shared memory segments
- Update shared memory sizing: Limit number of records to
NUM_MESSAGES_PER_SLOT=5, 100 slots
- Data Recording App v1.1
- Improved architecture with thread pool and barrier synchronization
- Frame/slot-based message grouping with per-slot validation
- atexit/signal-based cleanup for graceful shared memory detach
- Delete legacy data_recording_app_v1.0.py
- Library improvements
- config_interface.py: remove legacy YAML config reader, streamline to
JSON-only
- shared_memory_interface.py: new module for shared memory
attach/read/protocol
- wireless_parameters_mapper.py: new module for NR parameter mapping
- data_recording_messages_def.py: updated message definitions for
27-field struct
- sigmf_interface.py, sync_service.py, common_utils.py: remove unused
imports and dead code
- Documentation
- Update data_recording.md for v1.1 architecture and usage
Arguments for removing:
1. There are no resources to maintain it.
Including no machine with the board.
2. There is no clue that someone is actually using it.
3. AAL is privileged for LDPC offload to a hardware accelerator.
7.2 FHI with XRAN K release
Purpose:
Implement the O-RAN 7.2 Fronthaul interface using O-RAN Software Community's
XRAN release K. The new features of the release K can be leveraged and it is
compatible with DPDK version 24.11.4.
For more details please refer to the MR !3444 description.
- refactor timestamp handling
- Replace string-based SENDING_TIME with integer SEC/NSEC fields.
- Designed the shared memory protocol with a 4-state machine (STATE_WAIT=0, STATE_CONFIG=1, STATE_RECORD=2, STATE_STOP=3) for command/control between the recording app and the T-Tracer service
- Implemented two shared memory segments: one for reading commands (addr_rd) and one for writing captured data (addr_wr)
- Created event_trace_msg_ul_data struct mapping all 27 UL metadata fields (frame, slot, datetime, MCS, DMRS parameters, etc.) by name from the T-Tracer database
- Implemented setup_trace_msg_ul_data() using the G() macro to map field names to indices at startup
- Wrote the main event loop using poll() to avoid busy-waiting, with get_event() to receive T-Tracer events from the softmodem socket
Use log_ul_fd_dmrs, log_ul_fd_pusch_iq, log_ul_fd_chan_est_dmrs_pos,
log_ul_fd_chan_est_dmrs_interpl, log_ul_payload_rx_bits.
Remove redundant T_ACTIVE() guards and old timestamp formatting.
ctest: fix tests when compiling with sanitizers, ignore build directories,
fix spsc_q build
- Fix the directory to the current build directory to enable running with
sanitizers with ctest
- add build* to .gitignore to close#1074
- fix spsc_q compilation on non-C++23 compilers to close#1073
This commit was tested with MicroAmp FR2 with 2x2 MIMO,
where PRACH Rx antennas used is 1.
OAI L1 sets the number of PRACH antennas to be the same as for PUSCH.
Ideally, this should be properly fixed. In the meantime, I modified the
logging to debug to reduce noise.
Signed-off-by: Teodora Vladić <teodora.vladic@openairinterface.org>
First process PUSCH and then PRACH because the PUSCH callback
is called before PRACH callback.
Signed-off-by: Teodora Vladić <teodora.vladic@openairinterface.org>
* rename read_prach_data() to xran_rx_prach_read_slot()
* in F release, there is no PRACH queue so `frame` and `slot` are
passed as input; in K release, `frame` and `slot` are taken from the PRACH
queue
Note: since the PUSCH callback is the called before PRACH callback, this
commit is correct but the timing for PRACH processing is just a little
bit late. In previous state, PRACH processing was done inside the
function of PUSCH processing.
=> next commit will just reverse the order.
Signed-off-by: Teodora Vladić <teodora.vladic@openairinterface.org>
* Move PRACH callback in the oaioran.h/c since now used in K release.
* Reset the number of PRACH packets.
* Handle PRACH queue in the same manner as for PUSCH (95c8fa46).
Co-authored-by: Romain Beurdouche <romain.beurdouche@eurecom.fr>
Signed-off-by: Teodora Vladić <teodora.vladic@openairinterface.org>
K releases added RX error counters
This commits adds a printing of these counters with LOG_I
Signed-off-by: Teodora Vladić <teodora.vladic@openairinterface.org>
* Initialize leak detector
* Fill IO config field holding the number of mbufs to be allocated
* Allocate and fill `activeMUs` in the FH config
* Start timing source, worker thread and activate CCs upon starting the FH
* Fill `mu_number[0]` in FH config
* Invert trx_oran end and stop
* Set `neAxcUl`
* Delete duplicated oran_eth_state_t struct definition
* gxran_handle is an array which length is equal to the number of RUs
* Fill BBDev VF token in fh_init
Co-authored-by: Romain Beurdouche <romain.beurdouche@eurecom.fr>
Signed-off-by: Teodora Vladić <teodora.vladic@openairinterface.org>
stdatomic.h is a C++23 feature [1]. Thus, "older" compilers such as
gcc-11 (default in Ubuntu 22) do not know this, and can therefore not
correctly compile spsc_q. Fix this by alternatively including atomic for
C++.
Fixes errors such as
stdatomic.h:40:9: error: ‘_Atomic’ does not name a type
[1] https://en.cppreference.com/cpp/header/stdatomic.h
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
When compiling with sanitizers that require LD_LIBRARY_PATH (see
documentation), ctest could not drive tests as the executables did not
find shared objects. Fix the directory to the current build directory to
enable running with sanitizers.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
L1 gNB type0 PDSCH
PDSCH type0 allows frequency allocation via PRB bitmap (type1 is via
start and number of PRBs) allowing for non contiguous allocation in
frequency domain
Adapt the oran_fhlib_5g code to compile with xran K release.
Like previously E and F, uses preprocessor directives to separate codes for different xran releases.
Notes:
1. Release K of the FHI library supports many numerologies on one instance.
As of now the integration supports only one numerology.
2. Several arrays in the xran interface are indexed by the numerology.
It was ambiguous whether they were indexed by the actual numerology number or by the index of the relevant numerology within the numerology array.
They are actually indexed by the numerology number so that when one is using only numerlogy 1 for example, he should only use perMu[1], fftSize[1], ...
Signed-off-by: Teodora Vladić <teodora.vladic@openairinterface.org>
* create the xran forked repo as a cmake external project - easier to maintain and track the changes
we applied to the original repo
* add xran_DOWNLOAD option - clones and builds latest supported K release
* update the FHI README for K release
Signed-off-by: Teodora Vladić <teodora.vladic@openairinterface.org>
asn1c inside local tree
when /opt/asn1c/bin/asn1c does not exist, we download and use the right
asn1c version locally in the build tree. This simplifies dependancies
management
fix (RRC): do not trigger N2 HO when no active PDU sessions are present
Prevent triggering N2 handover when the UE has no active PDU session by
adding an early check in nr_rrc_trigger_n2_ho(), so we avoid building an
invalid HO Required. This aligns with 3GPP TS 38.413 (§9.2.3.1), where
HANDOVER REQUIRED carries a PDU Session Resource List with at least one
PDU Session Resource Item (range 1..maxnoofPDUSessions).
Relates to #1062 (closed)
Fix CSI-RS estimation
Changed channel estimates buffer to store RB 0 from start of buffer instead
of FFT shift offset. This simplifies channel estimation implementation. There
is also no need to add padding because each symbol/antenna start from offset
0 and/or OFDM symbol size always 32 byte aligned.
This also fixes buffer overflow detected when running UE with OCUDU gNB.
Changed channel estimates buffer to store RB 0 from start of buffer instead of
FFT shift offset. This simplifies channel estimation implementation. There is
also no need to add padding because each symbol/antenna start from offset 0
and/or OFDM symbol size always 32 byte aligned.
This also fixes buffer overflow detected when running UE with OCUDU gNB.
Make sure the radio libs are stopped before `end()` call. This allows
for a cleaner exit under most circumstances. Some libraries like zmq_radio
don't exit cleanly without it.
This commit introduces ZMQ-based radio library. Each pair of RX/TX antennas is
represented by a ZMQ REQ/REP socket pair which streams continuous IQ samples
from radio start until stop.
Usage:
Simplest configuration is to connect OAI NR UE to OAI GNB with the same number
of antennas - by inverting the RX and TX channels in ZMQ radio configuration the
gNBs TX is mapped to UEs RX antennas and vice versa.
Minor fixes/cleanup in NGAP lib
This MR is about a small NGAP-focused cleanup, mainly to reduce clang
warnings and remove dead code.
- Handle unused input parameters in ngap_gNB.c and ngap_gNB_handlers.c.
- Fix clang warning in common/utils/time_meas.h (extra semicolon).
- Removes unused NGAP trace/overload code and related references
(ngap_gNB_trace, ngap_gNB_overload).
Minor fixes to gNB/UE behavior in RFsim
While testing with RFsim thw following issues where found:
- gNB config: wrong PCI was printed during F1 Setup Request preparation
- UE PHY: missing rxdata allocation was causing a crash during intra-freq
measurements
Prevent triggering N2 handover when the UE has no active PDU session
by adding an early check in nr_rrc_trigger_n2_ho(), so we avoid building
an invalid HO Required. This aligns with 3GPP TS 38.413 (§9.2.3.1), where
HANDOVER REQUIRED carries a PDU Session Resource List with at least one
PDU Session Resource Item (range 1..maxnoofPDUSessions).
Retx check frequently fails in OTA pipelines, particularly for interfering
UEs attempting to connect to the cell. This leads to job failures in OTA
pipelines.
Remove the retx check from Multi-Antenna and Aerial pipelines to improve
CI stability and avoid false failures. In these pipelines, iperf test
already validates correct funtionality, making the retx check redundant.
Integration `2026.w16`
* !4040 fix: issue 911 - replace timer oneshot to periodic.
* !4041 Compilation without T: move to physims
* !4046 fix(record_db doc): correct the path for T_messages.txt and mention use of ninja/make
* !3994 Update CN5G images to release v2.2.0 and update traffic generator image
* !4024 Fix fill_srs_channel_matrix
* !3983 Add SIB 3,4 support, configurable SIB2 and refactor CU/DU SIB management
* !4030 Miscellaneous code improvements
* !4039 Verify consistency of CSI report in L2 instead of RRC
* !3991 L1 RX: use queues instead of arrays and linear search for PUCCH, PUSCH, SRS, PRACH
* !4011 CI: remove cppcheck, cleanup in build and license checks
* !4051 Fix EMA cold-start for noise and SNR/RSSI measurements
Closes#1063
See merge request oai/openairinterface5g!4048
Fix EMA cold-start for noise and SNR/RSSI measurements
Initialize n0_subband_power and power control avg_snr/avg_rssi directly
from the first measurement instead of starting from zero.
Starting from zero causes the EMA to converge slowly, leading to
underestimated noise power at gNB startup. This results in inflated SNR
estimates, which triggers UE uplink power ramp-up, antenna saturation,
and a positive feedback loop of increasing noise.
CI: remove cppcheck, cleanup in build and license checks
Remove cppcheck. For those who want to use it, it's now in tools/cppcheck/,
and likely easier to use locally.
Clean up some code for CI build and license check. Remove global variable.
We don't enforce cppcheck through the CI, although it's there since
years. It runs on Ubuntu 18/20, so it's old. For folks, it's likely not
discoverable on how to run it locally. Let's make a fresh start.
This removes cppcheck from all CI-related code. Instead, it adds it
under tools/cppcheck/, including documentation on how to run it locally,
bare-matel or in docker.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Fix a UE crash in the neighbor-measurement task setup by allocating the per-antenna
rxdata pointer array before indexing it in pbch_processing(), and freeing it in
nr_ue_meas_neighboring_cell() after measurements complete.
The crash is triggered by intra-frequency neighbor measurements.
L1 RX: use queues instead of arrays and linear search for PUCCH, PUSCH, SRS, PRACH
This MR is an attempt to reduce the time L1 RX searches in array for the
next job to process, and instead use a queue. This queue is a FIFO,
because the various jobs (FAPI messages) to process come in order, and
need to be processed in order. The MR (hopefully, to be measured)
reduces the amount of time spent searching for the next UE (because the
next job is always at the beginning of the queue), and should scale
better for many UEs.
It does the following:
- introduce two helper libraries for (1) Frame.Slot calculation (sfn_t),
already introduced in !3521 (merged) commit 3102068e, and (2) a ring
buffer with fixed size
- use sfn_t and ring buffer (gNB->pucch_queue) to remove the linear
array for PUCCH (gNB->pucch)
- use sfn_t and ring buffer (gNB->pusch_queue) for some PUSCH lookups.
Because we need to still store PUSCH contexts, gNB->pusch is still
there
- use sfn_t and ring buffer (gNB->srs_queue) to remove the linear array
for SRS (gNB->srs)
- use sfn_t and ring buffers (gNB->prach_ru_queue and
gNB->prach_l1rx_queue) to remove the linear array for PRACH
(gNB->prach_list)
- some minor cleanups, e.g., additional loops over the PUSCH array,
using const, using pointers instead of indices, etc
Miscellaneous code improvements
- A fix in a yaml config file as reported by @Abdo-Gaber
- proper positioning of static functions in a couple of gNB scheduler
files
- some effort to split NR from LTE code in compilation
- harmonization of macros for unused variables
Add SIB 3,4 support, configurable SIB2 and refactor CU/DU SIB management
This MR makes neighbour and inter-frequency configuration drive how
SIB2/SIB3/SIB4 are built and sent from CU to DUs. It standardizes SIB
payloads as byte_array_t with typed SIB IDs across RRC, F1AP and MAC,
reducing ad‑hoc buffer handling. Neighbour parsing, validation and
lookup are tightened.
Changes
- Minor refactor to gNB neighbour parsing and storage (shared PLMN
extraction, safer allocation, etc).
- Represent SIB containers uniformly as byte_array_t plus nr_sib_type_t,
and adapt F1AP, MAC and RRC users to the new container API.
- Make SIB2 cell-reselection information fully config-driven with
explicit bounds checking and SIB2 ASN.1 building from that config.
- Generate SIB3 intra-frequency neighbours from the per-cell neighbour
list and propagate them from CU to DU over F1, with MAC
decoding/attaching them to SystemInformation.
- Generate SIB4 inter-frequency neighbours from a new frequency_list
plus neighbour SIB3/SIB4 offsets, and propagate them from CU to DU
over F1, with MAC decoding/attaching them.
- Add basic ASN.1 round-trip tests for SIB2/SIB3/SIB4 and SIB4 range
checks, and update RRC docs to describe the neighbour/inter-frequency
configuration model.
Testing:
1. in gNB conf file:
cu_sibs = (2, 3, 4);
2. Update neighbour config file with SIB3/SIB4 conf:
(see documentation)
3. run gNB and UE as usual
---
Logs & configs: see MR on Gitlab
Use two queues for PRACH processing:
- prach_ru_queue: pass jobs from TX thread (scheduler) to RU thread. For
split 8, the RU thread itself handles PRACH processing; for split 7.2,
it is the library that is responsible for handling PRACH messages (see
oran_fh_if4p5_south_in())
- prach_l1rx_queue: after jobs have been handled in RU thread, use this
queue to pass jobs to the RX thread. There, preamble detection is
performed, and RACH.indication FAPI messages are filled if a preamble
has been detected.
Together, these queues replace a linear search in a global array that
has been modified by three threads at the same time. The design ensures
that access now is thread-safe, and with less overhead.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Expand RRC usage and handover documentation to describe the two-level
neighbour configuration layout, lookup-key semantics,
and config-time SIB4 grouping behaviour. Expand the example config
to include a `frequency_list` block and per-neighbour SIB3/SIB4
offset fields. Add SIB2 config example.
Update handover-tutorial.md to describe the same nested model and
note that F1 and N2 handover share the same serving-cell keyed
mapping.
Add documentation about SIB3/SIB4 and MeasGaps implementation
in OAI with stress on the shared neighbour configuration data model.
Update FEATURE_SET.
Use the spsc queue to pass jobs from TX thread (scheduler) to RX thread
(handling those jobs), reducing the amount spent searching for SRS jobs,
clarifying the design, and making it thread-safe.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
The structure in which was snr will be a "SRS job" in a follow-up
commit, so the snr parameter cannot be stored in there (and it is also
not necessary to do so, as it can be local to the function handling
nr_srs_rx_procedures()).
Correctly read SRS SNR through FAPI message in nr_ulsim. Switch to SRS
BEAMMANAGEMENT as only this message returns the actual SNR (unlike
CODEBOOK). Add asserts to check what is returned is valid data in the
sense of the test.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Remove useless logging defines. Move srs_estimated_channel_time to where
it is used. Prepare for the next commit by moving UL_INFO to earlier
inside phy_procedures_gNB_uespec_RX().
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
- calculation in float: should be enough precision (it'll go into 16bit
ints later...)
- avoid round: the lower 15bits will be shifted away, the rounding will
have no effect
- group some multiplications to avoid re-computation of the same
results.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
This means that as of this commit, the signal has to be permanently
regenerated. In fact, with the SRS queue to be introduced in a follow-up
commit, we don't have an easy way to cache the sequence generation, as
there is no "index" to which we could refer to (hence, caching would be
tricky).
Instead, the next commits further refactor this to reduce the time for
SRS sequence generation as well as the memory footprint.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Use the spsc queue to pass jobs from TX thread (scheduler) to RX thread
(handling those jobs), reducing the amount spent searching for PUSCH
jobs, clarifying the design, and making it thread-safe.
Since the PUSCH contexts have to be stored somewhere, there is still a
single iteration over all contexts. Removing that is left for future
work. Thus, this commit (together with previous commits) reduces the
number of iterations over all PUSCH entries, only iterating over the
actually requested PUSCH jobs. On the other hand, because only the RX
thread iterates over PUSCH contexts, it should be thread-safe.
Remove flag "handled", which is always 0.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Pass pointers directly instead of ULSCH_id. Put const where possible and
applicable.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Set the FAPI message in nr_ulschsim correctly in line with what
nr_ulsch_procedures() expected. Add an AssertFatal() to verify that the
assumed length of DMRS in the simulator and what is actually set in the
FAPI message matches. Finally, the internal nr_get_G() code (looping
over all PUSCH) does not double the DMRS because Nl == 3 || Nl == 4, so
harmonize in the simulator.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
It is pointless to iterate ulsch_to_decode to find the number of jobs if
we can simply pass it to the function.
Use an additional {} block to limit the amount of indentation.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Amidst all these unnecessary pointers, the pointer on
pusch_vars->ptrs_symbols is necessary to reset the PTRS number of
symbols. For clarity, remove this pointer and use
pusch_vars->ptrs_symbols directly.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Pass pointer to data. This necessitates to move delay from
NR_gNB_ULSCH_t (ULSCH data, including transport channels etc) to
NR_gNB_PUSCH (lower-PHY PUSCH data):
1. This allows to pass a single pointer to nr_pusch_channel_estimation()
2. To me, delay estimation seems to be a lower-PHY calculation, so it
fits better anyway.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Use the spsc queue to pass jobs from TX thread (scheduler) to RX thread
(handling those jobs), reducing the amount spent searching for PUCCH
jobs in an array, clarifying the design, and making it thread-safe.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Because it is SPSC, atomic variables are enough to synchronize the two
threads. Concretely put() is modified to ensure that read_idx is
"acquired" so that the read index has been written, including memory, by
the other thread. "Release" ensures that the write operation (including
the memory to the buffer) is written before it is visible to the other
thread in get() (which in turn "acquires" it). For more information, see
also [1].
The rest of the library has been simplified to work only with put() and
get(), reducing total code and the surface for possible bugs.
This (and the previous) version has been tested with the
threadSanitizer:
TSAN_OPTIONS=halt_on_error=1 ./common/utils/ds/tests/test_spsc_q_perf
On my machine, using Google Benchmark, I measure a considerable 5x speed
improvement:
$ /tmp/benchmark/tools/compare.py benchmarks pthread.json atomic.json
Comparing pthread.json to atomic.json
Benchmark Time CPU Time Old Time New CPU Old CPU New
--------------------------------------------------------------------------------------------------------------
BM_spsc_q/10 -0.8201 -0.0740 266779912 47989020 52387 48512
BM_spsc_q/16 -0.8301 -0.0520 249656592 42428540 51462 48784
BM_spsc_q/32 -0.8003 -0.0841 230248798 45972155 53841 49311
BM_spsc_q/64 -0.7995 -0.0506 210429791 42199674 50690 48124
BM_spsc_q/128 -0.7930 -0.1101 205212273 42483155 52745 46936
BM_spsc_q/160 -0.7880 -0.1663 216644738 45938247 53400 44518
OVERALL_GEOMEAN -0.8057 -0.0904 0 0 0 0
[1] https://en.cppreference.com/w/c/atomic/memory_order.html
Assisted-By: Claude:claude-sonnet-4-6
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Fix fill_srs_channel_matrix
Fix incorrect SRS subcarrier mapping in fill_srs_channel_matrix
The previous implementation of fill_srs_channel_matrix assumed an incorrect
SRS subcarrier mapping, leading to wrong indexing of the estimated channel
in frequency domain.
Update CN5G images to release v2.2.1 and update traffic generator image
- Updated all CN5G image tags to v2.2.1
- Updated image oaisoftwarealliance/trf-gen-cn5g to latest tag supporting
multi-architecture platforms See here
- Enabled iperf3 server in daemon mode in oai-ext-dn
- Handover: Since MR oai/cn5g/oai-cn5g-amf!372 has been merged, the AMF
image tag is updated to the latest release v2.2.1
- upgrade MySQL image to 9.6
This data structure is designed to support the use cases of the L1,
i.e., provide a queue which can be quickly used to order L1 jobs in FIFO
order with simple iteration of jobs to treat. It is a Single-Consumer
Single-Producer queue library.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
phy_procedures_nr_gNB.c calls pack_srs() functions to pack individual
SRS "subPDUs". Correspondingly, the library depends on NFAPI_LIB. In
nr_ulsim, in a later commit, we will need to unpack the SRS.indication,
so remove dummy functions and implement correctly.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
fix(record_db doc): correct the path for T_messages.txt and mention use of ninja/make
The commit !4038 (51d84419) provided the wrong path for T_messages.txt. The path
it provided holds if the T tracer is built manually using make.
A note to explicitly mention the path for T_messages.txt when T tracer is built
using make.
Signed-off-by: Sagar Arora sagar.arora@openairinterface.org
fix: issue 911 - replace timer oneshot to periodic.
Updated SCTP reconnect timer from TIMER_ONE_SHOT to TIMER_PERIODIC so gNB
continuously retries AMF lookup every 30 seconds after disconnect.
Timer is now removed only when ngap_amf_associated_nb > 0, AMF association
is actually back.
Updated SCTP reconnect timer from TIMER_ONE_SHOT to
TIMER_PERIODIC so gNB continuously retries AMF lookup every
30 seconds after disconnect.
Timer is now removed only when ngap_amf_associated_nb > 0,
AMF association is actually back.
at RRC we don't store CSI-MeasConfig information so in some scenarios (see #1063) we may not have the full pictures to understand if what RRC received is a valid configuration
we verify at L2 instead after updating CSI-MeasConfig and if it fails we send a message to RRC
Update the shared neighbour config used by the F1 rfsim pipeline to
enable CU-provided SIB2 and neighbour-derived SIB3/SIB4 inputs.
In `ci-scripts/conf_files/gnb-cu.sa.band78.106prb.conf`
- Add `cu_sibs = (2, 3, 4)
In `ci-scripts/conf_files/neighbour-config.conf`:
- Add a complete `sib2_config` block
- Add `frequency_list` / `frequency_config` for inter-frequency SIB4 fields
- Extend both neighbour entries with per-cell offsets
Add encode/decode helpers and basic round-trip tests for NR SIB2, SIB3
and SIB4 in test_asn1_msg.cpp to ensure we produce decodable messages
with expected fields. Extend SIB4 coverage with an
inter_freq_carrier_freq_info_ranges test that exercises boundary and
out-of-range values for carrier reselection parameters and checks
encoder failures for invalid configurations.
Changes:
- Introduce encode_and_decode_sib2, encode_and_decode_sib3 and
encode_and_decode_sib4 helpers that call do_SIB2_NR, do_SIB3_NR,
do_SIB4_NR and uper_decode and assert non-empty, non-null byte
arrays and successful decoding.
- Add sib2_basic_encode_decode, sib3_basic_encode_decode and
sib4_basic_encode_decode tests that populate minimal but
representative NR_SIB2_t, NR_SIB3_t and NR_SIB4_t instances and
verify selected decoded fields match the originals.
- Add inter_freq_carrier_freq_info_ranges test that builds an NR_SIB4_t
with NR_InterFreqCarrierFreqInfo_t and varies different offsets and
thresholds to confirm valid combinations encode and invalid ones
are rejected.
- Add comprehensive documentation header explaining the structure's role
as single source of truth for neighbor cell information across multiple
protocols (NGAP/XnAP handover, measurement config, DU validation, SIB3/SIB4)
- Add detailed field comments documenting protocol-specific mappings:
* Core identification fields (gNB_ID, nrcell_id, physicalCellId)
* Frequency/RF parameters (absoluteFrequencySSB, subcarrierSpacing, band)
* Handover target identification (plmn, tac)
- Document NGAP/XnAP IE mappings for plmn and tac fields
Remove the isIntraFrequencyNeighbour field and all code that sets or
uses it, simplifying neighbour cell handling and avoiding redundant
state in the RRC gNB code. The flag duplicated information that can be
derived from the neighbour absoluteFrequencySSB and the serving cell
SSB ARFCN, and intra-frequency neighbours are logged in the SIB3
preparation flow.
Changes:
- Remove isIntraFrequencyNeighbour from nr_neighbour_cell_t in
openair2/RRC/NR/nr_rrc_defs.h
- Delete is_intra_frequency_neighbour() and
label_intra_frequency_neighbours() helpers from
openair2/RRC/NR/rrc_gNB_du.c
- Remove calls to label_intra_frequency_neighbours() from
rrc_gNB_process_f1_setup_req() and
rrc_gNB_process_f1_du_configuration_update() in rrc_gNB_du.c
- Stop setting .isIntraFrequencyNeighbour in the local
nr_neighbour_cell_t neighbourConfig initializer in
openair2/RRC/NR/rrc_gNB_mobility.c
Add SIB4 encode/decode helpers and populate SIB4 from configured
inter-frequency carriers and neighbour cells, wiring it into DU F1
Setup handling and MAC SystemInformation.
Changes:
- Add do_SIB4_NR() and NR_SIB4.h inclusion in asn1_msg.c/asn1_msg.h to
UPER-encode NR_SIB4_t into a byte_array_t.
- Extend nr_mac_configure_other_sib() in NR_MAC_gNB/config.c with an
NR_SIB_4 case that validates the SIB container, decodes NR_SIB4_t via
uper_decode, logs failures, and appends SIB4 to SystemInformation.
- Introduce build_inter_freq_carrier_from_cfg() and
get_sib4_inter_freq_neighbors() in rrc_gNB_du.c to build
NR_InterFreqCarrierFreqInfo_t and NR_SIB4_t from inter-frequency and
neighbour cell configuration, skipping invalid or empty carriers.
- Handle NR_SIB_4 in rrc_gNB_process_f1_setup_req() by deriving SIB4
from neighbour/inter-frequency configuration, encoding it with
do_SIB4_NR(), validating the resulting byte_array_t and adding the SI
message for the DU cell when encoding succeeds.
Introduce NR SIB3 encoding in RRC and wire SIB3 neighbour information
into CU–DU F1 Setup and DU SystemInformation. Extend MAC to decode NR
SIB3 from CU-provided SIB containers and attach the decoded SIB3 to the
DU SystemInformation structure.
Changes:
- Add NR_SIB3 ASN.1 include and a do_SIB3_NR() encoder in asn1_msg
so SIB3 can be serialized into a byte_array_t buffer.
- Introduce get_q_offset_asn1() and get_sib3_intra_freq_neighbors() in
rrc_gNB_du.c to build an intra-frequency neighbour cell list for SIB3,
mapping q_OffsetCell dB values to NR_Q_OffsetRange and optionally
filling q_RxLevMinOffsetCell and q_QualMinOffsetCell.
- Limit the number of intra-frequency neighbours in SIB3 to
NR_maxCellIntra, logging a warning and skipping additional cells when
the limit is reached.
- Hook SIB3 construction and encoding into rrc_gNB_process_f1_setup_req()
so SIB type 3 entries are added to the F1 Setup Response when
neighbour configuration and matching neighbours are available.
- Handle NR_SIB_3 in nr_mac_configure_other_sib() by validating the CU
SIB3 container buffer, decoding it with uper_decode into an NR_SIB3_t,
and attaching the resulting SIB3 to the MAC SystemInformation via
add_sib_to_systeminformation().
Introduce typed SIB3/SIB4 neighbour and inter-frequency carrier
configuration structures, wire them into the RRC neighbour and gNB
instances, and centralise parsing and bounds checking of per-frequency
SIB4 parameters from the gNB frequency list.
Changes:
- Define SIB3/SIB4 reselection and offset bound macros in gnb_config.c
and apply them when parsing SIB4 frequency_config and
per-carrier q_RxLevMin/t_ReselectionNR.
- Add add_inter_freq and parse_inter_freq_list helpers in gnb_config.c
to populate a shared inter_freqs seq_arr_t from gNB_CONFIG_STRING_GNB_LIST
frequency_list entries, enforcing unique (ARFCN,SCS) combinations and
logging duplicates.
- Extend neighbour cell parameters in gnb_paramdef.h with SIB3 per-
neighbour offset fields and define frequency_list/frequency_config
option names, descriptor tables, and index constants for SIB4 inter-
frequency configuration.
- Introduce nr_neighbour_cell_neighbor_offset_t, nr_neighbour_cell_sib3_t,
nr_neighbour_cell_sib4_freq_t, nr_neighbour_cell_sib4_t, and
nr_inter_freq_cfg_t in nr_rrc_defs.h, and extend nr_neighbour_cell_t
and gNB_RRC_INST with sib3/sib4 and inter_freqs members respectively.
- udpated fill_neighbour_cell_configuration to use GET_PARAMS_LIST
with params bound check
Introduce a typed SIB2 cell reselection configuration, load it from the
gNB configuration into the RRC gNB instance, and use it to build and
encode SIB2 instead of relying on a fixed SIB2 definition.
Validate SIB2 parameters against explicit bounds and make the SIB2
encoder consume a pre-built ASN.1 structure with safer error handling.
Changes:
- Add SIB2 mobility timer and q-HystSF enums plus SIB2 config structs
(`sib2_speed_state_reselection_pars_t`, `sib2_config_t`) and a
`sib2_config` field on `gNB_RRC_INST` in `nr_rrc_defs.h`.
- Define SIB2 configuration option names, defaults
(`GNB_CONFIG_STRING_SIB2_*`, `GNBSIB2PARAMS_DESC`)
in `gnb_paramdef.h` for q_Hyst, thresholds, mobility timers, scaling
factors and deriveSSB_IndexFromCell.
- Add `sib2_config` parameter keys, defaults, and range/value checks in
`gnb_paramdef.h` (`GNBSIB2PARAMS_DESC`).
- Add SIB2 `fill_sib2_configuration()` in `gnb_config.c` to read SIB2
parameters from the config file log the resulting configuration and
store it in `rrc->sib2_config` via `RCconfig_NRRRC()`.
- Add `get_q_hyst_asn1()` and `get_sib2_from_cfg()` in `rrc_gNB_du.c`, and
update `rrc_gNB_process_f1_setup_req()` to encode/add SIB2 from config with
explicit encode-failure handling and logging.
- Change `do_SIB2_NR` signature in `asn1_msg.h/.c` to
`byte_array_t do_SIB2_NR(const NR_SIB2_t *sib2)`, remove internal default
SIB2 construction, and add ASN.1 constraint/encode error logging.
Unify SIB container handling by introducing a typed SIB enum and storing
SIB payloads as byte_array_t across common NR types, F1AP helpers, MAC,
and RRC DU setup code.
Changes:
- Include byte_array support in nr_common.h, add nr_sib_type_t (NR_SIB_1–NR_SIB_21),
and change nr_SIBs_t to hold only nr_sib_type_t SIB_type.
- Switch f1ap_sib_msg_t in f1ap_messages_types.h to use a byte_array_t SI_container
instead of raw pointer and length fields.
- Update F1AP encode/decode, equality, copy, and free helpers in
f1ap_interface_management.c to work on SI_container.buf / SI_container.len and
use eq_byte_array, copy_byte_array, and free_byte_array.
- Adapt F1AP tests in f1ap_lib_test.c to build and inspect SIB containers via
SI_container.buf and SI_container.len.
- Replace magic SIB numbers with nr_sib_type_t values in gnb_config.c
(get_sys_info and fill_du_sibs) to validate and configure DU SIBs.
- Rework nr_mac_configure_other_sib in NR_MAC_gNB/config.c to decode SIB2
from a byte_array_t container, fix freeing by releasing the decoded sib2 on
failure, and use NR_SIB_2 / NR_SIB_19 for CU/DU SIB selection.
- Add an add_si_msg helper in rrc_gNB_du.c and refactor the SIB2 branch of
rrc_gNB_process_f1_setup_req to populate cell->SI_msg from encoded local
byte array while iterating SIBs with FOR_EACH_SEQ_ARR.
Tighten neighbour-cell config parsing by enforcing parameter constraints in
the descriptor and switching parsing code to name-based lookups with gpd.
Changes:
- Update `GNBNEIGHBOURCELLPARAMS_DESC` in `openair2/GNB_APP/gnb_paramdef.h`
to add checks for `physical id`, `absoluteFrequencySSB`, `scs`, `band`
`tracking_area_code`.
- Remove neighbour-cell parameter index macros.
- Refactor `parse_neighbour_cells_list` in `openair2/GNB_APP/gnb_config.c`
to use `gpd()` lookups for neighbour fields instead of fixed indexes.
- Extend `parse_neighbour_cells_list` with an `n_cell_params` argument and
update `fill_neighbour_cell_configuration` to pass
`sizeofArray(ncell_params)`.
Inline neighbour cell arrays into the RRC neighbour configuration and
update RRC/DU helpers to use const-aware access and shared iteration
helpers when walking neighbour lists and building measurement configs.
Changes:
- Change neighbour_cells in neighbour_cell_configuration_t from a
seq_arr_t * to an embedded seq_arr_t field.
- Initialize and populate the embedded neighbour_cells directly in
parse_neighbour_cells_list in gnb_config.c, dropping dynamic
allocation of the neighbour list container.
- Refactor get_neighbour_cell_by_pci and nr_rrc_get_measconfig in
rrc_gNB.c to access the embedded neighbour_cells via const pointers,
introduce a local meas_cfg and a3_event_list, and iterate neighbour
cells with FOR_EACH_SEQ_ARR.
- Treat neighbour cell configuration entries as const in rrc_gNB_du.c
(get_cell_neighbour_list, label_intra_frequency_neighbours,
valid_du_in_neighbour_configs) and iterate neighbour lists with
FOR_EACH_SEQ_ARR instead of index-based loops.
Outer gNB neighbour_list entries now only declare the serving cell
nr_cellid. The code resolves that field with gpd instead of a fixed column
index.
Changes:
- gnb_paramdef.h: remove unused NEIGHBOUR_CELL_PHYSICAL_ID from
GNB_NEIGHBOUR_LIST_PARAM_LIST (keep NRCELLID only).
- gnb_config.c: in fill_neighbour_cell_configuration, set nr_cell_id
from gpd
Refactor gNB configuration code to share PLMN extraction logic and to
split neighbour-cell configuration into smaller helpers with safer
allocation and clearer list handling.
Changes:
- Add `extract_plmn_from_params()` in `gnb_config_common.c` and declare
it in `gnb_config_common.h` to centralize PLMN extraction from
`paramdef_t`.
- Update `set_plmn_config()` to use `extract_plmn_from_params()` when
filling the PLMN array instead of duplicating field assignments.
- Refactor `fill_neighbour_cell_configuration()` in `gnb_config.c` to
delegate per-cell neighbour parsing to
`parse_neighbour_cells_list()` and sorting to
`sort_neighbour_configuration()`, simplifying the main loop.
- Use `extract_plmn_from_params()` when parsing neighbour PLMNs in
`parse_neighbour_cells_list()` and log each neighbour with its PLMN,
PCI, and other radio parameters before adding it to the sequence.
- Switch allocation of `rrc->neighbour_cell_configuration` in
`fill_neighbour_cell_configuration()` from `malloc` to
`malloc_or_fail()` to enforce consistent handling of allocation
failures.
Change 1: config_check_intval() now uses the correct integer pointer for TYPE_INT
Problem: config_check_intval() previously dereferenced param->uptr regardless
of param->type. For parameters declared as signed (TYPE_INT / TYPE_INT32), the
active union member is param->iptr, and param->uptr may be NULL -> using uptr
makes validation unsafe and type-inconsistent.
What changed: Updated config_check_intval() behavior (signature unchanged).
Handle both param->type, param->iptr and param->uptr.
Change 1: new config_check_uintrange() for unsigned range constraints
Problem: there was a signed range checker (config_check_intrange()) that reads
param->iptr, but there was no dedicated unsigned range validator using param->uptr.
What changed: added config_check_uintrange() in config_userapi.h/.c
The new function reads param->uptr as uint32_t and validates against
param->chkPptr->s2.okintrange[] endpoints.
Change 3: constify input params for f2 function pointers
Problem: checkedparam_t.s2.f2 was typed with non-const input params, even though
range checks only read. A safer const-safe signature is required.
What changed: s2.f2 now takes const configmodule_interface_t *
and const paramdef_t *. config_check_intrange() and config_check_uintrange() use
the same const-qualified parameters.
Integration `2026.w15`
* !4014 Microamp FR2 configuration file and documentation
* !4029 nr rlc: tolerate bogus data
* !4032 build_oai fixes: harmonize duplicate options, remove wrong --build-lib handling
* !3977 Further unused arguments cleanup
* !4009 Fix for NULL pucch-ResourceCommon at MSG4
* !4037 Increase reliability of ltebox start
* !4034 Prevent infinite loop on Single Entry PHR handling
* !4038 doc(record_db): explain how to use record_db
* fix compilation of T tracers with 'make'
* !3489 Thread-pool support for TX symbol processing.
See merge request oai/openairinterface5g!4033
Thread-pool support for TX symbol processing.
This MR adds thread-pool support for TX symbol processing. It allows modulation
/mapping/layer-precoding to run in parallel and offers a speedup of around 3
compared to single-thread execution. This is particularly important for large
bandwidths and 4 or more TX antenna ports where the precoding operation is quite
computationally-intensive.
Please see the description of !3489 for the performance comparison results and
the nr_dlsim timing measurements.
Extend the performance tuning section of documentation
to include explanation on the `--L1s.L1_num_tx_sym_per_thread` option
and on the AMD EPYC core complex behavior
Increase reliability of ltebox start
The existing ltebox startup sequence on nepes occasionally fails. Running
sudo su -c 'screen -dm -S simulated_hss /opt/hss_sim0609/starthss' \
&& sleep 1 && sudo /opt/ltebox/tools/start_mme && sudo /opt/ltebox/tools/start_xGw \
& sleep 1 && ip a show dev tun1
Reliably shows that no tun1 interface is created, because that takes around
1s itself. Increasing the second sleep to 2 reliably deploys it correctly.
Do the same for sabox and ltebox on nano for consistency.
Fix for NULL pucch-ResourceCommon at MSG4
Field pucch-ResourceCommon, used for ACK of MSG4, in some scenarios was
overwritten by RRCSetup before being used. Storing it in advance prevents
the segfault. In addition there is a clenaup of similar procedures at gNB.
* Add option `--L1s.L1_num_tx_sym_per_thread` for the softmodems and `-Y` for `nr_dlsim`
to provide the number of symbols processed per thread.
It defaults to 0 which makes that every symbols are processed in one thread.
* The last symbol processing task is processed in the L1 TX thread.
When receiving single-entry PHR with HARQ PID -1
(nr_mac_process_mac_pdu() is called with such parameter in at least two
places), the error handling path calls continue skipping the accounting
of the current sub-pdu (pduP and pdu_len). This results in an infinite
loop. Fix by moving functionality into a separate function.
Fixes: 2e0493632d ("RLC data ind: single call for complete TB at gNB")
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Further unused arguments cleanup
More fixes for unused function arguments (see #1057),
add_compile_options(-Wunused-parameter) added in folders:
- nfapi
- openair2
- openair3
- USRP
- rfsimulator
build_oai fixes: harmonize duplicate options, remove wrong --build-lib handling
Correctly handle --build-lib such that missing arguments are still handled
properly. Harmonize, and remove useless code.
The existing ltebox startup sequence on nepes occasionally fails.
Running
sudo su -c 'screen -dm -S simulated_hss /opt/hss_sim0609/starthss' \
&& sleep 1 && sudo /opt/ltebox/tools/start_mme && sudo /opt/ltebox/tools/start_xGw \
& sleep 1 && ip a show dev tun1
Reliably shows that no tun1 interface is created, because that takes
around 1s itself. Increasing the second sleep to 2 reliably deploys it
correctly.
Do the same for sabox and ltebox on nano for consistency.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Functionality existed to print all output of asn1c on error, but the
form
asn1c || cat X
makes the command exit with a 0 exit code (success). Fix by explicitly
returning non-zero exit code in this case:
asn1c || ( cat X && false )
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Both do practically the same. Harmonize them into one while guaranteeing
backwards compatibility.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
This fixes two problem:
1. an omitted --build-lib library could yield strange grep errors. For
instance, calling build_oai --build-lib --cmake-opt OPTION passed
"--cmake-opt" to grep, that does not know this option. Handle by
explicitly separating options and search pattern through --.
2. Even with this fixed, set -e triggered an exit because grep exits
with non-zero error code. Remove set -e to have the error handling
code pass.
With set -e removed, properly check that the build passes.
Update a log line to make it clearer.
Assisted-by: Claude:claude-sonnet-4-6
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
nr rlc: tolerate bogus data
Some unfriendly entity may play with the RLC module and send bogus data to
trigger funky behaviors here and there.
A report sent by Dhanish indentifies one such issue.
From analyzing this report, a possible scenario is the following. Unfriendly
entity sends an RLC PDU with: is_first=0 is_last=0 so=15 lenght of data,
whatever, let's say 1.
This PDU is put in the RX list.
Then later it sends another PDU (for the same SN, obviously), with: is_first=1
is_last=1 so=0 (well, since is_first=1, necessarily so=0; it is not transmitted,
see 38.322 6.2.2.3 for UM and 38.322 6.2.2.4 for AM) length=10, let's say.
This PDU is also put in the RX list, before the previous one.
Then the function sdu_full() returns 1, so reassemble_and_deliver() is called
and the 'while (pdu)' loop is executed for both PDUs. When the second (bogus
one) is processed, so==10 (after processing the first PDU) and the line: int
len = pdu->size - (so - pdu->so) is: int len = 1 - (10 - 15) which is not good.
So we detect the case 'pdu->so > so' and reject the SDU. We could label the
other entity as bogus, since no standard RLC implementation will produce such a
case, but let's remain friendly, even with unfriendly entities. (To be changed
later if needed.)
The problem was reported for RLC AM but is also present in RLC UM. (Not in RLC
TM, where there is no segmentation.) Note: according to the report, this bug was
found using a fuzzer described as 'AI-assisted custom 5G NR protocol fuzzer'. It
had to be said.
* Global timers were started and stopped
in the TX symbol processing tasks
which is not thread safe
* gNBs nrL1_stats.log now shows
PDSCH generation time rather than
layer mapping and precoding times
There was an indexing error in the calculation of the symbol offset `re_beginning_of_symbol`.
The symbol was tested to hold PTRS or DMRS based on the index of the
first symbol processed in the task and not based on the index of the
symbol as it should be.
Then PDSCH generation was not working properly for more than one symbol
per task.
The previous implementation of fill_srs_channel_matrix assumed an incorrect SRS subcarrier mapping, leading to wrong indexing of the estimated channel in frequency domain
CI: Add stage to push to local git repository
This MR includes minor code cleanup and fixes for warnings reported by Jenkins.
It also introduces a new stage in ci-scripts/Jenkinsfile-GitLab-Container that
pushes the branch to a local repository after the merge. In a follow-up MR,
this local repository will be used as the source for cloning the branch,
replacing direct access to GitLab/GitHub.
Did you forget the `def` keyword? WorkflowScript seems to be setting a field named JOB_TIMESTAMP (to a value of type String) which could lead to memory leaks or other issues.
Did you forget the `def` keyword? WorkflowScript seems to be setting a field named MR_NUMBER (to a value of type String) which could lead to memory leaks or other issues.
Some unfriendly entity may play with the RLC module and send bogus data to
trigger funky behaviors here and there.
A report sent by Dhanish, India, indentifies one such issue.
From analyzing this report, a possible scenario is the following.
Unfriendly entity sends an RLC PDU with:
is_first=0
is_last=0
so=15
lenght of data, whatever, let's say 1.
This PDU is put in the RX list.
Then later it sends another PDU (for the same SN, obviously), with:
is_first=1
is_last=1
so=0 (well, since is_first=1, necessarily so=0; it is not transmitted,
see 38.322 6.2.2.3 for UM and 38.322 6.2.2.4 for AM)
length=10, let's say.
This PDU is also put in the RX list, before the previous one.
Then the function sdu_full() returns 1, so reassemble_and_deliver() is
called and the 'while (pdu)' loop is executed for both PDUs. When the
second (bogus one) is processed, so==10 (after processing the first
PDU) and the line: int len = pdu->size - (so - pdu->so)
is: int len = 1 - (10 - 15)
which is not good.
So we detect the case 'pdu->so > so' and reject the SDU. We could label
the other entity as bogus, since no standard RLC implementation will
produce such a case, but let's remain friendly, even with unfriendly
entities. (To be changed later if needed.)
The problem was reported for RLC AM but is also present in RLC UM.
(Not in RLC TM, where there is no segmentation.)
Note: according to the report, this bug was found using a fuzzer
described as 'AI-assisted custom 5G NR protocol fuzzer'. It had
to be said.
Cleanup common_lib.h
This change reduces the number of dependecies of common_lib.h and simplifies
the task of implementing an external OAI radio library.
Remove a lot of unused code, defines, and config options
Remove unused header files and defines.
Slightly clean up gnb_config.c by removing all _IDX variables. Remove
these unused parameters:
- MACRLCs.[0].num_cc
- MACRLCs.[0].local_n_portc
- MACRLCs.[0].remove_n_portc
- MACRLCs.[0].remote_s_portc
- MACRLCs.[0].remote_s_portd
- L1s.[0].num_cc
- L1s.[0].local_n_portc
Declare `localStatus` and `localResult` as local variables in `triggerSlaveJob`
and `triggerCN5GSlaveJob` functions by adding `def`.
This prevents unintended use of global variables in pipeline and avoids
potential variable leakage or conflicts between stages.
Follows the Jenkins recommendation:
Did you forget the `def` keyword? WorkflowScript seems to be setting a field named localStatus (to a value of type RunWrapper) which could lead to memory leaks or other issues.
Did you forget the `def` keyword? WorkflowScript seems to be setting a field named localResult (to a value of type String) which could lead to memory leaks or other issues.
Remove the gNB_MAC_INST.eth_params_s, since it's only purpose is to
store what can be on the stack.
For the Aerial log message, don't print an empty prefix but what is
actually used for Aerial.
- remove test_multipath and test_noise from ChanelSim tests of
RAN-Channel-Simulation pipeline - will be executed together with the
other CUDA-enabled unit tests
- enable configurable dockerfile, runtime-opt, and ctest-opt parameters in
the XML file for the Build_Run_Tests step
- pass runtime options to `docker run` to support ctest execution with CUDA
- allow additional ctest options for selective test execution and labeling
- add benchmark_channel_pipeline to CTest
- add test_channel_pipeline to CTest
- add `cuda` label to CUDA-dependent tests for easier execution and
filtering
This change removes the cudaDevAttrIntegrated check and only requires
pageable memory access. This change allows to run GPU accelerated
channel convolution on GH machines.
The indices are brittle and might be wrong. Instead, use the option name
(via gpd()) to look up config options. This will also simplify the
removal of unused parameters, as we don't have to update all indices.
Remove leading CONFIG_STRING_, as it is just repetitive and adds noise.
The constants are both short(er) and sufficiently self-explanatory
without it.
Update doc: split RUNMODEM.md, clarify USRP-specific workarounds
This reworks the documentation:
- split up RUNMODEM.md into separate documents for gNB, UE, NTN
- explains USRP workaround and patches
- makes a standalone UE doc file that explains UE-specific configuration
& modes
- better explains physical simulators
- adds a document on tracy
- cleanup
It can happen that a message is delayed, but then no UE is found for
such message, e.g., something is delayed but the UE context is deleted
in the meantime:
[02:23:16.320730] [NR_RRC] I [--] (UE ID 3 RNTI d2b1) Remove UE context
Assertion (ue_context_p) failed!
In rrc_delay_transaction() /oai-ran/openair2/RRC/NR/rrc_gNB.c:191
In that case, don't delay the message further -- all handlers gated by
this function will check for the UE context and abort the transaction if
not present.
It can happen that no PDU session can be setup (e.g., PDU session
already setup). Check that there is at least one before triggering the
message.
Also initialize bearer_req.gNB_cu_cp_ue_id early to avoid uninitialized
IDs (e.g., when no PDU session to be setup).
More compilation improvements
Mostly to decouple NR files from LTE headers.
At least in one instance, ulsch_input_buffer_array, using an LTE constant in
NR code was quite dangerous because the buffer in NR could easily be larger
than what the LTE constant foresee.
UE: Fix CSI RS Measurement
1. Fix regression introduced in !3834.
2. ZMQ has no interference or artificial noise so the interference plus noise
measured is always 0. nr_csi_rs_pmi_estimation() returns SINR as 0 if noise
is 0 which reports CQI as 0. This fix computes SINR if noise is 0 instead of
returning.
UE: Implement SUCI Profile Scheme A
This MR modifies the nrUE to support Profile Scheme A based SUCI generation as
outlined in TS 33.501 §C.3 Elliptic Curve Integrated Encryption Scheme (ECIES),
this further extends SUCI generation, which currently only supports the NULL
Scheme.
Changes:
- Extend UICC structure for SUCI parameters.
- Add cryptographic primitives (Curve25519, X9.63 KDF).
- Add an abstracted function to transfer digit strings into their corresponding
BCD value.
- Updates SUCI generation to support Profile Scheme A.
- Updates NAS SUCI encoding to support hexadecimal cryptographic output in
addition to BCD encoded MSINs.
Notes:
When a configuration file specifies an unsupported Profile Scheme, the NAS layer
triggers a fatal error. This occurs either because Profile Scheme B is
unimplemented or the build uses OpenSSL < 3.0, which lacks Curve25519 and X9.63
KDF support, ensuring users are informed of the incompatibility. Support for
Profile Scheme B (TS 33.501 §C.3.4.2 Profile B) can be implemented at a later
stage using P-256-based encryption.
The implementation of SUCI Profile Scheme A was tested against Open5GS’s core
implementation. OpenAirInterface’s cn5G does not yet support Scheme A and should
be extended to include it in a future update.
This allows to compile physical simulators by compiling only tests with
"ninja tests". It fixes a regression.
Fixes: ec8efe1b7e ("Unify physim test definition")
hotfix for 4 layer mapping on aarch64
This hotfix fixes a small bug appearing on aarch64 in the 4-layer PDSCH mapping
function. It was an error in the original implemntation.
Extend UICC configuration parsing to provide: routing_indicator,
protection_scheme, home_network_public_key, and home_network_public_key_id.
Use the protection_scheme value to decide what SUCI Profile Scheme to
apply during SUCI generation. Add support for Profile Scheme A which
provides ECIES-based encryption using Curve25519 and X9.63 KDF as outlined
in TS 33.501 Section C.3.4.1 Profile A.
When a configuration file specifies an unsupported Profile Scheme,
the NAS layer triggers a fatal error. This occurs either because
Profile Scheme B is unimplemented or the build uses OpenSSL < 3.0,
which lacks Curve25519 and X9.63 KDF support, ensuring users are
informed of the incompatibility.
Split out to make a standalone NTN configuratio page that would be
easier to find. I only modify the headings in the new file and write an
introductory sentence of the tutorial, the rest is unchanged.
Integrate channel pipeline library with vrtsim with two acceleration
options chosen at compile time:
- threadpool if CUDA support is disabled
- CUDA otherwise
Added two versions of channel convolution and noise generation:
- accelerated via threadpool
- accelerated using CUDA
The main difference between this and previous versions of channel
convolution implementations is that these functions take a real-world
approach to input/output where both could be split unevenly over a set of
buffers, e.g. ring buffers used in vrtsim.
The CUDA-accelerated version only works on systems with unified memory, e.g. NVidia
DGX Spark or GH
- all RAN code, CI code, configuration files, dockerfiles, in CSSL v1.0
- all deployment code (openshift, charts, ancillary files like shell
scripts), in MIT
- documentation in CC-BY-4.0
- exceptions might apply and are listed in NOTICE
- there is a new LICENSES folder with all licenses
- CONTRIBUTIONS.md has been updated accordingly
For automated changes based on OAI PL v1.1:
perl -i~ -0pe 's/\/\*.*Licensed to the OpenAirInterface.*openairinterface.org\n#?/\/*\n * SPDX-License-Identifier: LicenseRef-CSSL-1.0\n/s' **/*.{c,h,cpp}
perl -i~ -0pe 's/\/\*.*Licensed to the OpenAirInterface.*openairinterface.org\n#?/\/*\n * SPDX-License-Identifier: LicenseRef-CSSL-1.0\n/s' **/*.ts
perl -i~ -0pe 's/<!--.*Licensed to the OpenAirInterface.*openairinterface.org\n.*-->/<!-- SPDX-License-Identifier: LicenseRef-CSSL-1.0 -->/s' **/*.xml
The rest (cmake, files with missing license, cmake) manually.
Remove the \file directive, as it is always superfluous because the
current file is implicit [1]:
> If the file name is omitted (i.e. the line after \file is left blank)
> then the documentation block that contains the \file command will belong
> to the file it is located in.
Author names and e-mails are not relevant for us: it can always be
inferred from git blame, and is often outdated.
Eurecom code has been contributed and was under OAI PL v1.0/v1.1.
For the cpack package contact: put generic email address that is
independent of an individual and that will remain reachable.
[1] https://www.doxygen.nl/manual/commands.html#cmdfile
Integration `2026.w13`
* !4004 Remove OSD, some scripts, oaisim references
* !3968 Fix DAS via index based beamforming
* !3982 UE: update pdcch config only after mib read
* !3851 Bugfix in UE DLSCH LLR functions
* !3933 mac: fixes to prevent prb overlapping
* !4006 Update cir-generator image tag to v0.0.1
* !4007 Remove old CUDA LDPC implementation
* !4005 FHI72: handle more than 64 cores
* !3805 \[E2 agent\] Refactor E2SM-KPM and implement support for REPORT style 1
* !3973 Introduce UE NAS Simulator
* !3966 PUCCH Format 1 decoder implementation and validation with nr_pucchsim
* !3681 Configure DigitalBeamTable in OAI and pass down to Aerial L1
* !3912 Fix Delta MCS mode, reimplement UL power control
* CI: Tune VNF configuration files in Aerial pipeline
Closes#1044
See merge request oai/openairinterface5g!4008
Adjust target SNR values and introduce RSSI thresholds in the VNF configuration
files to prevent UL saturation. These changes improve uplink stability and
performance for tests with Aerial and WNC RU.
Fix Delta MCS mode, reimplement UL power control
This change set fixes the "delta-MCS" mode, and reimplements the UL power
control loops at gNB, i.e., for PUSCH and PUCCH. It further adds new T traces
to log PUSCH/PUCCH power infrmation, and cleans up code.
The "delta-MCS" mode in OAI refers to configuring a UE with deltaMCS in the
PUSCH-PowerControl IE (see TS 38.331). In this mode, the UE adjusts the PUSCH
power for transmissions to take into account for MCS (see TS 38.213 Sec. 7.1).
In other words, the target SNR can be set to a somewhat low value, and the UE
will still use the right power for UL transmissions. Note that the spec only
foresees this adjustment of UL power when using one layer. In contrast, in the
"normal" mode, the gNB sends TPC commands to keep a UE at a fixed target SNR
(default: 20dB), regardless of the MCS or number of layers. Future work is
planned to completely remove this fixed target SNR, which is not done in this
MR yet.
Further, there is a new power control loop implementation. Prior to this MR, on
each UL transmissions, the gNB uses the SNR to decide about TPC sent to a UE in
the next transmissions. The new implementation relies on averaging the SNR, and
a "TPC in flight" average to account for the slow reaction of the average SNR.
The sum of both quantities is the current SNR that is used by the UE. See the
commit messages or documentation for more information.
Further cleanup to group data (e.g., power control configuration, refactoring of
code to save space, ...) is done. Two new T traces GNB_MAC_PUSCH_POWER_CONTROL
and GNB_MAC_PUCCH_POWER_CONTROL are added; documentation exists to explain how
to graphically plot corresponding graphs.
Configure DigitalBeamTable in OAI and pass down to Aerial L1
With this MR it will be possible to define a Beamtable in OAI and pass it down
to a L1 (Aerial or OAI) which then will either use them locally to apply
static beamforming (Split 8 with USRP) or pass them down to the RU using 7.2
split with Section Extension 1.
PUCCH Format 1 decoder implementation and validation with nr_pucchsim
This is the implementation of the PUCCH Format 1 decoder, validated with
pucchsim in the current branch.
Build:
./build_oai --nrUE --gNB --ninja --phy_simulators
Run tests:
ctest -L nr_pucchsim -j 8
Introduce UE NAS Simulator
This MR introduces a simple standalone tester for 5G UE NAS signaling and NGAP
messages. It connects to the AMF to perform NGAP and NAS encoding/decoding and
validates the UE Registration and PDU Session Establishment processes without
the overhead of a full Radio Access Network (PHY/MAC/RLC).
The motivation for this tester is as follows,
- This tester is a lightweight, deterministic tool to test the UE NAS layer
directly.
- Developers can easily inject specific NAS messages depending on the use-case.
- Developers can validate custom NAS/NGAP messages without the need to implement
complete RRC/MAC etc procedures.
Start the 5G Core network to test the UE NAS simulator. The compiling and
testing procedure is described below.
To compile:
mkdir build && cd build && cmake .. -GNinja && ninja nr-ue-nas-simulator-test
To run:
LD_LIBRARY_PATH=. ./tests/nr-ue-nas-simulator/nr-ue-nas-simulator-test -O ../tests/nr-ue-nas-simulator/test.conf
This commit completes the PUCCH Format 1 decoder implementation using
maximum-likelihood detection with RE averaging across symbols/RB (and
hop-wise averaging for intra-slot hopping). It also updates the PUCCH
simulation/test flow to align with the decoder changes, including
payload and logging consistency fixes needed for correct validation.
Do not limit DL power, because it is not done in the other pipelines
either. Set the UL target power high, as this increases the achievable
throughput high (PUCCH can be normal). Finally, increase BLER thresholds
to improve the MCS a bit.
[E2 agent] Refactor E2SM-KPM and implement support for REPORT style 1
- Refactor E2SM-KPM to:
- better handle different supported REPORT styles needed for "E2 Setup
Request"
- pass "Measurement Label" for calculating the measurement values
- Implement Subscription for E2SM-KPM REPORT style 1 and fill the PDSCH MCS
distribution measurement (CARR.PDSCHMCSDist)
- Fix the memory leakage caused by the UEs filtering based on NSSAI for REPORT
style 4
Tested successfully with and without ASan:
- in rfsim mode: gNB-mono, CU/DU and CU-CP/CU-UP/DU
- with the USRP B210: gNB-mono
and xapp_kpm_moni, xapp_rc_moni and xapp_kpm_rc xApps.
1. Allocate memory for the ue_id and ue_info_list arrays on the stack.
Explanation:
Every granularity period, the program passes through the fp_match_cond_type,
then through match_s_nssai_test_cond_type function pointers. Based on the node type,
the function used calloc() for these arrays.
=> the longer a connection with an E2SM-KPM xApp was, the more memory leakage occured.
2. If matched UEs > 0, only free the memory of ue_id content after each
Indication Message was sent.
Remove old CUDA LDPC implementation
A new implementation is under way in !3955. To simplify the MR, remove the old
LDPC CUDA implementation in a first step.
mac: fixes to prevent prb overlapping
- this patch fixes a bug in the MAC where the scheduled PRB resources can
overlap
- at the same time, we try to enforce the same semantics for "rbStart" (which
should be relative to the BWP) across the code as much as possible
Introduce new data structures to track the average SNR and RSSI, and
that allow to dynamically modify the target SNR (per UE) as well as
continuously get TPC updates based on the average SNR. The target SNR is
per power control loop (which a future commit will extend to use for
PUCCH).
Concretely, it maintains an average of measured SNR and RSSI. It also
updates "tpc_in_flight", which tracks TPC changes that don't show up in
the average yet. For instance, imagine that the target SNR of 15 changes
to 20. Three successive TPC commands need to be sent (+3, +1, +1), but
it will take time to show up in the average SNR. To account for this,
tpc_in_flight is updated by the TPCs sent, and an average will make it
go down back to zero at the same pace as the average SNR approaches the
target SNR. The sum of average SNR and tpc_in_flight sums up to the
actual, current SNR, which approximates the target SNR.
The SNR is kept within -1<=targetSNR<=+2dB to avoid too many TPC
changes.
The current average SNR (sum of average SNR and tpc_in_flight) is used
to continuously get TPC updates, taking into account recent TPCs sent,
the difference to target SNR, and RSSI.
If there is DTX, tpc_in_flight is modified to artificially introduce TPC
commands which increase the currently used SNR of the UE. This is
temporary, as tpc_in_flight eventually will go back to zero. If the DTX
was due to sudden SNR drop (e.g., higher path loss), this will allow to
quickly adapt the UE's SNR to new conditions.
The periodical logs are extended to not only show the current SNR, but
also the difference from the target for better analysis.
Co-authored-by: Maxime Elkael <m.elkael@northeastern.edu>
The phr_txpower_calc field actually needs to be saved in the HARQ
process for later retrieval, so set sched_pusch after phr_txpower_calc
has been calculated.
UE: update pdcch config only after mib read
- In MR !3929, this change was done to call update_pdcch_config if mac
configuration is changed.
- Observed that the issue related to RAR after handover if SSB position changes
occurs also in develop 2026_w10 where MR !3929 is merged.
- update_pdcch_config should be done only after sync obtained.
- this fix is similar to the fix in initial commits of MR !3929
* Option to build ldpc_cuda was remaining in the build script
* Build script option to build ldpc_cuda was still used in CI
* Mentions of ldpc_cuda were remaining in the documentation
Note: In the documentation, the example of ldpctest usage that was
loading ldpc_cuda was replaced by an example in which it is loading
ldpc_orig even though this is pointless as it makes ldpctest compare
ldpc_orig with ldpc_orig. On the other hand, it is the only library
other than the default ldpc that uses the former interface.
Remove OSD, some scripts, oaisim references
The README says:
It is just generating the XML file and it is placing it in
$(OPENAIR_TARGETS)/SIMU/EXAMPLE/OSD/WEBXML/ or http://localhost/xmlfile/
so that the oaisim could pars and run the simulation/emulation
oaisim does not exist anymore, and corresponding simulation cannot be done.
Also, it requires XAMPP and similar technologies, that I think nobody uses
in the context of OAI.
Remove also most references to oaisim.
Remove some scripts that are likely not used by anybody, or straight useless.
Integration `2026.w12`
* !3985 Fix XNAP to avoid recompilation and unnecessary includes
* !3724 Better c style pss sss
* !3972 Resolve "Demote AssertFatal `PUCCH list is full` message to a warning"
* !3956 [FHI72] [xran F] Revert and simplify the code for Liteon FR2 interoperability
* !3970 Fix for NTN phy-test mode
* !3987 T: minor: remove target record_db from automatic building
* !3993 UE: Derive Serving Network Name from SIB1 PLMN
* !3997 vrtsim doc: clarify container requirements
* !3935 [FHI72] Fix long PRACH format
* !3998 Set rxgain to 0 in vrtsim
* !3964 CI: Add FHI7.2 phytest pipeline
* !4001 Remove unused ci-scripts/mysql4testresults/ dir and content
* !3999 bugfix: use proper pointer
* !3986 handle start symbol on non-zeroth downlink symbol for SIB1 for multiplexing pattern 3 configuration.
* !3957 replace static allocation of max antennas in a dynamic structure for gnb rach
* !3859 Delay compensation in SRS
* !3909 Adjust ssPBCH_BlockPower in FHI7.2 configs
Closes#1058
See merge request oai/openairinterface5g!3989
Adjust ssPBCH_BlockPower in FHI7.2 configs
ssPBCH_BlockPower is the average EPRE of the resources elements that carry
secondary synchronization signals in dBm. In OAI, the SSB is the same level
as all the rest, so we can compute ssPBCH_BlockPower from RU TX power and
bandwidth using:
ssPBCH_BlockPower = P_TX(dBm) − 10 x log10(N_RB x 12)
where:
- P_TX is the RU transmit power
- 24 dBm for indoor RUs (configurable on the RU)
- 35 dBm for outdoor RUs (configurable on the RU)
- N_RB is the number of resource blocks for the configured bandwidth
- 12 corresponds to the number of subcarriers per RB
replace static allocation of max antennas in a dynamic structure for gnb rach
NB_ANTENNAS_RX was used in 5G by mistake
there was also a error in O-RU implementation, with no consequences
(index not in right order)
Meson configuration was configuring a wrong maximum number of lcores on
the Arm platforms we are using (Neoverse V2 & NVIDIA Grace) as no
configuration is provided for these platforms with DPDK 20.11.9.
This commit solves this issue by requesting meson to use a generic
config that sets a high maximum number of lcores.
handle start symbol on non-zeroth downlink symbol for SIB1 for multiplexing
pattern 3 configuration.
This MR adds support for handling a non-zero start symbol for SIB1 when using
multiplexing pattern 3 with the per-slot CP format.
Previously, the implementation assumed that the first downlink symbol used by
a PDU always starts at symbol 0. However, this assumption does not hold for
SIB1 under multiplexing pattern 3, where the start symbol can be non-zero.
This issue does not apply to the per-symbol CP format.
Testing:
a. Microamp using the branch microamp_1048: UE registration ok. end-to-end ok.
b. Benetel: UE registration ok. end-to-end ok.
xran needs to be informed about the cores to use for packet processing.
Prior to this change, we only filled the first 64bits, but it can go up
to 128 in xran. Change the helper accordingly to support all.
The README says:
> It is just generating the XML file and it is placing it in
> $(OPENAIR_TARGETS)/SIMU/EXAMPLE/OSD/WEBXML/ or http://localhost/xmlfile/
> so that the oaisim could pars and run the simulation/emulation
oaisim does not exist anymore, and corresponding simulation cannot be
done. Also, it requires XAMPP and similar technologies, that I think
nobody uses in the context of OAI.
PTRS phase error is estimated in each symbol and should be compesation in the
last symbol. So far nr_dlsch_llr() used rxdataF_comp before PTRS phase
correction for all symbol except the last one. This commit fixes it by calling
nr_dlsch_llr() for all symbols after rxdataF_comp is compensated for PTRS phase
error. To do so, dl_ch_mag arrays are moved out of nr_rx_pdsch() to hold values
of all symbols.
put symbol index as first dimension. It is necessary because the offset for
the buffer to start of a symbol can be arbitrary and hence not aligned to 32
byte boundary. Having each symbol in a separate dimension ensures alignment.
CI: Add FHI7.2 phytest pipeline
This MR consists of multiple changes related to FHI7.2 setups in CI.
- remove unused fhi72 configurations in CI
- introduce dpdk-init service in fhi72 deployments to setup sriov on the machine
- update phytest fhi72 configurations for running on bulbul
- add phytest fhi72 to RAN-SA-FHI72-CN5G pipeline
Set rxgain to 0 in vrtsim
Set rxgain to 0 in vrtsim to match rfsimulator behavior
This addresses the issue where RSRP is different between rfsim and vrtsim. With
this RSRP values between rfsim and vrtsim should be similar.
[FHI72] Fix long PRACH format
The problem was that xran_is_prach_slot() compared if the current slot is the
scheduled one. However, this becomes irrelevant if long PRACH format used.
Successfully tested end-to-end the PRACH index 7 with TDD DDDDDDDSUU and Benetel
v2.0.5.
- Introduce dpdk-init service for SR-IOV initialization within the container
- Execute script to enable low-latency RT performance (restored after tests)
When running phytest with FHI7.2 in Docker, two services are deployed:
dpdk-init and oai-gnb. Previously, AnalyzeRTStatsObject selected the
first deployed service for RT stats analysis.
Allow to explicitly select the service used for RT stats analysis instead
of relying on the first deployed service.
vrtsim doc: clarify container requirements
Describe how to set up vrtsim in containers, e.g., docker, and link to an
example. Add a minor clarification for the connection descriptor as well.
UE: Derive Serving Network Name from SIB1 PLMN
This MR modifies the nrUE to use the Serving Network Name derived from data
communicated by the Serving Network instead of data stored in the UICC.
Previously, the Serving Network Name (SNN) used during authentication was
constructed from the IMSI, implicitly assuming the UE was attached to its
home network. In roaming scenarios, this produced an incorrect SNN, causing
authentication and key derivation failures.
Changes:
- Extract the MCC and MNC from the SIB1 PLMN identity communicated by the
serving network.
- Store these values in the UE NAS context in order to propogate them from
RCC to NAS.
- The NAS key derivation functions (transferRES, derive_kausf, derive_kseaf)
now build the SNN based on the MCC/MNC broadcast in SIB1.
Extract MCC and MNC from the SIB1 PLMN identity and store them in the
UE NAS context to propogate them to NAS security procedures.
Previously, the Serving Network Name (SNN) used during authentication
was constructed from the IMSI, implicitly assuming the UE was attached
to its home network. In roaming scenarios, this produced an incorrect
SNN, causing authentication and key derivation failures.
The NAS key derivation functions (transferRES, derive_kausf, derive_kseaf)
now build the SNN using the MCC/MNC broadcast by the serving network in SIB1,
ensuring that authentication uses the correct serving PLMN during roaming.
T: minor: remove target record_db from automatic building
We don't install clickhouse by default, so simply running make inside
common/utils/T/ would fail. Remove record_db to not build automatically.
Fix for NTN phy-test mode
- Corrected the initialisation of ntn params changed flag. Before this change on
UE, Phy-test was not running in NTN mode.
- Removed the assert wrt slot > 64 to run FR2-NTN in phy-test
- SIB2, 19 required only in SA mode like SIB1
- Introduced new method to schedule a slot in UL/DL in Phy-test mode. Dmod/ Umod
option in the command line with a value.
- This ensures that the slot n (in slots per frame) will be scheduled if
n % value == 0
- For ex: --Dmod 1 means every slot will be scheduled
- --Dmod 2 means every 2nd slot will be scheduled, like 0,2,4,6 until the
slots per frame 1.
- this can be used for testing FDD FR2 where slots go beyond 64 which is a
limitation of -D/-U option.
[FHI72] [xran F] Revert and simplify the code for Liteon FR2 interoperability
The MR !3668 introduced a lot of unnecessary changes. This MR removes useless
code in both OAI and xran F release library.
1. Remove modifications done in the following xran functions:
process_mbuf_batch();
xran_process_srs_sym().
=> not even used with OAI 7.2 interface.
2. Also, remove xran_fs_get_num_dl_sym_sp() and xran_fs_get_num_ul_sym_sp() introduced in the same MR.
3. Remove LiteOnIgnoreUPSectionIdEnable parameter. Instead, use RunSlotPrbMapBySymbolEnable in a simple way
for xran_process_rx_sym() function.
Explanation: The xran expects UL UP packets with the same section IDs as indicated per UL CP message.
However, the section IDs of received packets are 3 for mixed slot and 13 for UL slot.
If the PRACH offset is set explicitely via config file, then its value will be used.
Otherwise, eAxC_offset = max(Nrx,Ntx).
Co-authored-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Better c style pss sss
there is a commit to simplify code for pss and sss detection
then a second commit to test a idea: detect SSS with a advantage for SSS
in phase with PSS
Only static long PRACH configuration verified, i.e. PRACH C-plane
is ignored by the RU.
Note: Introducing `N_ZC` and `num_prbu` parameters is needed for testing
with xran F release. However, in the K release, this information is
stored in xran_rx_packet_ctl struct.
Move PRACH slot checking from oaioran.c to oran_isolate.c because
xran_is_prach_slot() compared the current slot instead of the scheduled.
The current and the scheduled slot are the same in case of short format,
but different in case of format 0. Therefore, with this commit, in xran_is_prach_slot()
we check the `prach_id->slot` and not `slot`.
the code use a precomputed table of rotations: 16 steaps between -PI/3 and +PI/3
This commit replaces the precomputed table by in code computation.
This version improves code understanding, while it won't make any significant difference
Notably, remove asn_codecs_prim_xer.h from the list of files, triggering
problems when re-running ninja, because the "canonical OAI asn1c"
(https://github.com/mouse07410/asn1c, commit ID
940dd5fa9f3917913fd487b13dfddfacd0ded06e) does not generate it:
ninja explain: output openair2/XNAP/MESSAGES/asn_codecs_prim_xer.h doesn't exist
In this version, a couple of files are not generated, so remove them
from the list.
Also, leave the files in the order as shown by ls.
Integration `2026.w11`
* !3864 remove xran_fh_tx_send_slot_BySymbol() and xran_fh_rx_read_slot_BySymbol()
* !3967 Harmonize the use of definition for number of symbols per slot
* !3971 Limit dl_DataToUL_ACK values to 15 as per standard
* !3414 Added NTN-FR2 FDD bands defined in release 18 in Ka-band range
* !3919 Reduce number of mutex locking in MAC->RLC direction
* !3923 XNAP: Add encode/decode and unit tests for Xn Setup Request/Response/Failure
* !3965 Enable BladeRF support in gNB Docker image
* !3904 add multi-ue support to vrtsim
* !3980 SDR reordering: correct warning, and USRP: return samples written
* !3834 Use flat buffer for txdataF in gNB L1
* !3981 Bugfix: make longer telnet cmdfunc names
* Reduce timing reference value for feptx_total in 40 MHz phytest
See merge request oai/openairinterface5g!3976
--Dmod option/--Umod option,
for example --Dmod 1 will schedule every slot in slots per frame
--Dmod 3 will schedule every 3rd slot. You can use --Dmod option togethor with -D option
same for uplink scheduling too.
for FR2 with 120Khz scs, there are 80 slots. Removed the assert such that FR2 config
can be tested in phy-test, currently bitmap works only until 64 slots.
Bugfix: make longer telnet cmdfunc names
The maximum number of cmdfunc names is 20, which IMO is too low. Worse, if it's
longer, nothing will warn us because C will just fill the array to it's end
(without \0 at the end). To remedy this:
- Allow longer names till 64 bytes (I hit the previous limit of 20)
- Check that the name is within the length limit: if somebody wants a very long
name, the strnlen() will return the maximum length, hitting that assertion.
- When reading a command during runtime, allow the corresponding maximum length.
On that occasion, also increase total number of permitted cmdfuncs.
Use flat buffer for txdataF in gNB L1
This MR changes txdataF buffer format to hold freq domain data starting from
PRB0 instead of circular buffer that starts from PRB N/2. The motive is to
simplify RE mapping function in L1 and copying data to xran lib.
- Add num_ues and ue_id parameters for server and client configuration
- Implement ul combining and dl distribution to all ues
- Each ue uses dedicated antenna offsets based on ue_id
- Works with no-chanmod mode only and with uniform antenna dimensions across all ues
The maximum number of cmdfunc names is 20, which IMO is too low. Worse,
if it's longer, nothing will warn us because C will just fill the array
to it's end (without \0 at the end). To remedy this:
- Allow longer names till 64 bytes (I hit the previous limit of 20)
- Check that the name is within the length limit: if somebody wants a
very long name, the strnlen() will return the maximum length, hitting
that assertion.
- When reading a command during runtime, allow the corresponding maximum
length.
On that occasion, also increase total number of permitted cmdfuncs.
The original error was simply "failed to write to RF", which is not very
precise. Update with sample numbers for context, and add it in another
similar case for consistency.
Co-authored-by: Sagar Arora <sagar.arora@openairinterface.org>
At least writerProcessWaitingQueue() checks for the exact number of
samples written. In many other places, we check that the return is
non-zero.
The usrp-tx-write-thread functionality returned 0, which triggers
various problems. Return the number of samples, as in the "direct write"
case (if-block before else-block).
Co-authored-by: Sagar Arora <sagar.arora@openairinterface.org>
XNAP: Add encode/decode and unit tests for Xn Setup Request/Response/Failure
This MR adds complete support for the following in accordance with
3GPP TS 38.423 v16.2.0
- Add Xn Setup Request, Response, and Failure message type definitions
- Implement ASN.1 encode/decode for all Xn Setup messages
- Add equality checks and memory management helpers
- Create XNAP unit test infrastructure
Co-author: @venkatareddy
Acknowledgement
This work was carried out as part of research and development at Indian
Institute of Science (IISc), Bengaluru.
Reduce number of mutex locking in MAC->RLC direction
Currently, the scheduler locks RLC for each operation. Concretely
- for RLC status indication (to get amount of bytes per LC), it locks per LC
- for RLC indication (UL traffic), it locks for each MAC SDU of which there can
be multiple in a TB
- for RLC data req (getting data from RLC to put into a transport block), it
locks for each LCID and PDU to get.
This can have a certain overhead, because we need to re-lock RLC multiple times
instead of once (per operation above). In this MR, rework the interfaces such
that it is possible to get all information/data in a single lock-unlock cycle,
which should also help with "spikes" of scheduler times (in some scenarios, it
seems the scheduler takes longer than 0.5ms, and while it's not only locking,
re-locking might contribute), and an increase of number of UEs (e.g., instead
of doing 3 * N UEs lock cycles for getting status of SRB1, SRB2, DRB1, we do
only N times). Concretely, for each UEs RLC status indication, we lock once,
only once per LCID when filling a TB (in particular for LCID 4, on high
throughput, it might be many times), and only once per UL TB (for the common
case of UL data).
Minor fixes include the increase of the Aerial VNF thread priority, and reducing
the maximum RLC indication size to reduce excessive computation (we can't have
1MB in one TB, it is too much).
Adds the API, which will always prepend a 3 byte header before writing a
PDU. This can be used to call less often into RLC, and avoid potential
locking.
The API is used at the gNB DLSCH scheduler. Also, this removes the
"overhead" calculation: since we fill the entire TB at once, RLC will
leave space for headers as necessary.
- Add Xn Setup Response message type definitions
- Implement encoder and decoder for Xn Setup Response
Xn Setup Response (3GPP TS 38.423v16.2.0 §9.1.3.2)
- Global NG-RAN Node ID (M)
- TAI Support List (M)
- Add equality check and memory management helpers
- Extend XNAP library unit tests to cover Setup Response
- Add initial XnAP library structure under openair2/XNAP/lib
- Implement common XnAP helper utilities (xnap_lib_common)
- Add gNB interface management module for Xn Setup procedures
- Introduce XnAP message type definitions in xnap_messages_types.h
- Integrate XnAP library into build system (CMakeLists.txt)
- Add standalone XnAP library unit test (xnap_lib_test)
- Implement encoder, decoder + test for Xn Setup Request
Xn Setup Request (3GPP TS 38.423v16.2.0 §9.1.3.1)
- Global NG-RAN Node ID (M)
- TAI Support List (M)
- AMF Region Information (M)
- Extend conversions.h with MACRO_BIT_STRING_TO_GNB_ID utility
Co-authored-by: Sreeshma Shiv <sreeshmau@iisc.ac.in>
Added NTN-FR2 FDD bands defined in release 18 in Ka-band range
* NTN-FR2 bands 510, 511, 512 added. TS 38.101-5 v 18.9 defines these 3 FR2-FDD
bands for NTN operation.
* These bands are defined in Ka band range (17.3Ghz - 31Ghz).
* Tested using the added conf files using RFSIM and GEO configuration.
* There were some inconsistencies observed when testing with RFSimulator before UE
Syncs to the gNB in terms of samples being written for FR2 configurations. Once
the UE syncs, the inconsistencies disappear.
* this is the problem - UE writes incorrect number of samples and gNB complains
about getting samples in past
* The above inconsistencies were also fixed in this merge request.
* These commits solving above inconsistencies were removed from this MR and a
different MR was raised. MR with those commits: !3928.
So far txdataF buffer has DC RE as the first element. This was prefered
most likely to avoid memcpy before iFFT but comes with a small
complexity in RE mapping functions.
Instead, we use a flat buffer that holds freq domain data starting from
first negative SC. After resource mapping is done on all channels, each
OFDM symbol is shifted before iFFT so that the buffer start with DC RE.
This reduces complexity in mapping functions and later on when passing
beam IDs to 7.2 split RU especially when a beam is associated to
interleaved RB and/or REs.
There is already a memcpy in place to copy txdataF from gNB stuct to RU
struct. So this change does not introduce new memcpy.
Limit dl_DataToUL_ACK values to 15 as per standard
If min feedback time is high enough otherwise we might fail to encode/decode
pucch-Config
Assertion (enc_rval.encoded > 0 && enc_rval.encoded <= max_buffer_size * 8) failed!
In encode_cellGroupConfig() /home/francesco/openairinterface5g/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c:4029
ASN1 message encoding failed (dl-DataToUL-ACK, 18446744073709551615)!
remove xran_fh_tx_send_slot_BySymbol() and xran_fh_rx_read_slot_BySymbol()
We have separate functions ran_fh_tx_send_slot_BySymbol() and
xran_fh_rx_read_slot_BySymbol() for liteon. This MR is to remove those separate
functions.
Main author: Teodora Vladić
Co-author: Mario Joa-Ng
Changes:
xran_fh_tx_send_slot() is using if then else to handle per slot and per symbol
logic. xran_fh_rx_read_slot() is straightforward.
Testing:
- Liteon: Verified end-to-end.
- Benetel: (per slot without beam_id): Verified end-to-end.
- Microamp: (per slot with beam_id): Verified end-to-end. The branch
microamp_F_harmonize is used instead as microamp could not be run with develop
branch.
params_changed flag is set to true when reconfig.raw file gets processed,
as NTN config is present in reconfiguration.
but due to this initialisation happening at a later point
params_changed is reset which results in incorrect writes on RFsimulator
Even though the NR ARFCN uses a 15 kHz raster until 24250 MHz,
the ssb_offset_point_a is still scaled by 60 kHz for FR2.
So we need two different scaling factors.
NTN-FR2 bands 510, 511, 512 added.
TS 38.101-5 v 18.9 defines these 3 FR2-FDD bands for NTN operation.
These bands are defined in Ka band range (17.3Ghz - 31Ghz)
UL STEPSIZE, UL NOFFS added into band table
Integration `2026.w10`
* !3946 UE L1 cleanup
* !3929 UE: Fix if target cell during handover has SSB at a different offset as in source cell
* !3961 Remove Ubuntu 20 and RHEL/Rocky 8 support, increase cmake min version
* !3884 Integrate NRPPA and NGAP messages required for positioning
* !3784 CI: Create new pipeline for testing with Aerial and Jetson
* !3697 fix: issue 911 - OAI gNB hangs when AMF connection goes down
* !3914 Fix dB_fixed() function
* !3800 Add tracer to record configured events to database
* !3954 UHD streamer thread priorities in nrUE
* !3846 rename with distinct names structs and related typedefs, remove spread struct keyword
* !3958 Remove unused function arguments
Closes#911
See merge request oai/openairinterface5g!3962
Remove unused function arguments
Some of them, because there are hundreds if not thousands. Warnings at compilation time can be enabled using -Wunused-parameter.
Fix dB_fixed() function
- dB_fixed(0) returns 0 in develop branch;
- 0 in dB is -INF, but since we're dealing with integer variables, we'll put
20*log10(2^-15) in the output of dB_fixed() function, instead of 0.
- make all users use signed variables
fix: issue 911 - OAI gNB hangs when AMF connection goes down
Once the AMF is down, based on the AMF UE NGAP ID and RAN UE NGAP ID,
the UE associated with the AMF is found
All the contexts related to the UE are released and the timer is started
in the NGAP to look up for the SCTP association. The AMF-gNB reconnection
is made if an SCTP connection is found, also the registration of multiple
UE is triggered
These actions are based on the reference from 4.2.6 AN release Specs
TS 123 502 V16.7.0 (2021-01)
When the NG-AP signalling connection is lost due to (R)AN or AMF failure,
the AN release is performed locally by the AMF or the (R)AN as described
in the procedure flow below without using or relying on any of the signalling
shown between (R)AN and AMF. The AN release causes all UP connections of the UE
to be deactivated.
closes#911
Integrate NRPPA and NGAP messages required for positioning
This MR integrates NRPPA and NGAP messages required for positioning.
The following NGAP messages are integrated (3GPP 38.413 Version 16.0.0):
NGAP UPLINK UE ASSOCIATED NRPPA TRANSPORT
NGAP UPLINK NON UE ASSOCIATED NRPPA TRANSPORT
NGAP DOWNLINK UE ASSOCIATED NRPPA TRANSPORT
NGAP DOWNLINK NON UE ASSOCIATED NRPPA TRANSPORT
The following NRPPA messages are integrated (3GPP 38.455 Version 16.7.1):
TRP Information Request
TRP Information Response
Positioning Information Request
Positioning Information Response
Positioning activation request
Positioning Activation Response
Measurement Request
Measurement Response
This MR tests these messages via a standalone tester nr-cu-nrppa-test that
connects to the AMF to perform NGAP enc/dec and NRPPA enc/dec
Core Network:
To pull the docker images:
docker pull oaisoftwarealliance/ims:latest
docker pull oaisoftwarealliance/oai-amf:develop
docker pull oaisoftwarealliance/oai-nrf:develop
docker pull oaisoftwarealliance/oai-smf:develop
docker pull oaisoftwarealliance/oai-udr:develop
docker pull oaisoftwarealliance/oai-upf:develop
docker pull oaisoftwarealliance/oai-udm:develop
docker pull oaisoftwarealliance/oai-ausf:develop
docker pull oaisoftwarealliance/oai-lmf:develop
openairinterface5g$ cd doc/tutorial_resources/oai-cn5g
To deploy:
openairinterface5g/doc/tutorial_resources/oai-cn5g$ docker compose -f docker-compose-positioning.yaml up -d
To undeploy:
openairinterface5g/doc/tutorial_resources/oai-cn5g$ docker compose -f docker-compose-positioning.yaml down -t 0
RAN:
To compile:
openairinterface5g$ mkdir build
openairinterface5g$ cd build
openairinterface5g/build$ cmake .. -GNinja
openairinterface5g/build$ ninja nr-cu-nrppa-test
To run:
openairinterface5g/build$ LD_LIBRARY_PATH=. ./tests/nr-cu-nrppa/nr-cu-nrppa-test -O ../tests/nr-cu-nrppa/nr-nrppa-test.conf
To initiate positioning procedure:
openairinterface5g$ cd doc/tutorial_resources/positioning/
openairinterface5g/doc/tutorial_resources/positioning$ curl --http2-prior-knowledge -H "Content-Type: application/json" -d "@InputData.json" -X POST http://192.168.70.141:8080/nlmf-loc/v1/determine-location
This extends the functionality provided by record in that it allows
collection of data into a Clickhouse database, allowing aggregation of
data from gNB and UE for functions like channel estimation for PUSCH
transmissions that did not decode successfully at the gNB.
It is intended to be used in conjunction with Aerial Data Lake but is
not limited to it. Data access is simpler than in !3462, but could be
improved using the metadata approach from !3462.
The integration uses logfmt for fast logging, and a clickhouse DB
client, both integrated using CPM.
This change set also adds a docker-compose file for a UE on 100MHz, to
be used with Aerial configurations, and builds the tracer for Aerial and
nrUE docker files.
- Extended fix to support multiple UEs instead of single UE
- Actions now trigger upon AMF reconnection
Per 3GPP TS 123 502 V16.7.0 (2021-01) Section 4.2.6 (AN Release):
When NG-AP signalling connection is lost due to (R)AN or AMF failure,
AN release is performed locally by AMF or (R)AN without relying on
signalling between (R)AN and AMF. This deactivates all UP connections.
Remove Ubuntu 20 and RHEL/Rocky 8 support, increase cmake min version
Ubuntu 20 is EOL [1]. This was the version with the lowest CMake version, so
we can increment the minimum CMake version to 3.19 as well. Increasing the
minimum version will in particular help with the integration of CUDA (updates
in 3.17 and 3.18), the current 3.19 brings better support for apple silicon.
Some minor CMake updates (removing superfluous files and dependencies).
[1] https://ubuntu.com/blog/ubuntu-20-04-lts-end-of-life-standard-support-is-coming-to-an-end-heres-how-to-prepare
UE: Fix if target cell during handover has SSB at a different offset as in source cell
These changes fixed these observed issues:
- If target cell has a different SSB position compared to source cell during
ho - sync was not successful.
- RAR does not get decoded if SSB position has changed on the target cell
compared to source cell.
0 in dB is -INF, but since we're dealing with integer variables, we'll put 10*log10(2^-30) in the output, which corresponds to the symmetrical maximum output of the function.
without this fix, after sync is successful, RAR is not getting decoded.
PDCCH area also changes as SSB offset can change. if MAC configuration changes.
Actual problem is that SYNC does not happen on the target cell as frame parameters is not updated
and ssb start carrier is not correct in the UE frame parameters
function nr_get_ssb_start_sc to determine ssb_start_subcarrier
Ubuntu 20 is EOL [1] unless people pay for support. Therefore, remove it
from build_helper. People can still use it, but might need to install a
more recent cmake version (which the next commit will upgrade). The rest
should be the same.
[1] https://ubuntu.com/about/release-cycle
- Performs NGAP setup request and handles NGAP setup response
- This is introduced to test NGAP enc/dec of the NRPPa messages
To compile:
openairinterface5g$ mkdir build
openairinterface5g$ cd build
openairinterface5g/build$ cmake .. -GNinja
openairinterface5g/build$ ninja nr-cu-nrppa-test
To run:
openairinterface5g/build$ LD_LIBRARY_PATH=. ./tests/nr-cu-nrppa/nr-cu-nrppa-test -O ../tests/nr-cu-nrppa/nr-nrppa-test.conf
Integration `2026.w09`
* !3944 Fail early if configuration module can not initialize properly
* !3945 gNB: Reset NDI only after usage in case of disable HARQ
* !3822 NR UE: fix PRACH k1 calculation at MAC when handover
* !3874 print better message for rsrp: invalid doesn't mean it is not measures, it...
* !3928 NR UE: correctly compute writeTimestamp for SCS > 30 kHz with rf-simulator
* !3949 fix: removed the nssai_sd parameter in the ue.conf file
* !3897 Change Aerial config file in targets to match Nvidia's CI setup
* !3951 Fix handling of IPv4v6 PDU sessions
* !3940 IPV6 support for telnet socket binding
* !3947 Add missing packing for CONFIG.request parameter BetaPSS
* !3871 Support for up to 12 ports in NR gNB
* !3943 Remove L1 dependence from NR band number
* !3892 Synchronize multiple gNBs by aliging their the slot boundaries
* !3952 Fixes for Initial UE Context Setup
* !3953 Improvements in compilation dependence
* change dl_absoluteFrequencyPointA in targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf to 640032
* !3900 [CI] Pull Ubuntu base image from internal registry
* !3910 GPU Channel Simulation: nr_dlsim/nr_ulsim Integration + CI Test
* !3942 CI: rework log analysis to simplify and allow new use cases
* !3870 Configure CSI-RS according to beam_id used by UE
Closes#897 and #834
See merge request oai/openairinterface5g!3950
Configure CSI-RS according to beam_id used by UE
This MR is to configure CSI-RS according to beam_id used by UE and
reconfigure upon beam change.
It has been tested with RFSIM, Liteon and Microamp under multiple beams.
CI: rework log analysis to simplify and allow new use cases
The CI has some log analysis, but it is unmaintainable (huge functions
that mix eNB/gNB or lteUE/nrUE, are not tested, most of it is not used
or useful...) or limited to specific use cases (the timing-phytest time
analysis is hardcoded to source builds instead of also handling analysis
when running from docker images). This MR reimplements both functions.
For the log analysis, the CI team decided to throw away the old
analysis, and reimplement a mechanism that checks the couple of things
we care for.
- Allow to analyze phy-test timing analysis from docker files, and add a
unit test
- Rework existing log analysis to remove useless checks, and make it
more composable
* The undeployment steps (Undeploy_Object(), Terminate_eNB()) take an
<analysis> XML object which then either has a <services> subelement
with check that are whitespace delimited (similar to how other xml
task steps have <services>). For checks that contain whitespace,
they can use <service> (singular) that encodes a single check, such
that e.g., arguments could include spaces.
* Each check is of form service=check[=arguments], where service is
the docker services, check is a checking function (implemented as a
class with run(file, options) function inside cls_loganalysis.py,
and options arguments after the second = that is to be read by run()
(basically, options will contain arguments that can be freeform)
* these definitions can occur multiple times, e.g., it could be
serviceA=Check1 and serviceA=Check2=Args and it will execute both
Check1 and Check2
* if a service is declared, it will execute alse the Default check
which currently checks for an assertion
* Implemented (and inspired from the existing CI analysis) are:
- Default check to check for assertions (will be extended, to e.g.,
address/undefined behavior sanitizer analysis)
- RetxCheck: retransmission check as used in the CI
- LastLineContains to check the last line containes a specific
string
- ContainsString to check a specific string appears in logs
- EndsWithBye: check that towards the end (but not necessarily the
last line), there is a Bye. string (a workaround since we don't
always terminate with 0)
- There is a plan to use return codes after stopping in docker, but most
executables do not end with 0 most of the time, such that we needed to
abandon this plan.
- Additional fixes (see commit messages) and delete unused code
GPU Channel Simulation: nr_dlsim/nr_ulsim Integration + CI Test
This MR is a follow-up to !3886 (merged) and extends CUDA-based channel
simulation support to nr_dlsim and nr_ulsim, together with the
corresponding CI tests.
The MR incorporates:
- Cherry-picked commits e0c204f7 and 5f344876 from !3588
- Integration of new CI physim tests using GPU-accelerated channel
simulation in nr_dlsim and nr_ulsim tests, see commit c727b3bb
New CI job: RAN-Channel-Simulation
https://jenkins-oai.eurecom.fr/job/RAN-Channel-Simulation/
[CI] Pull Ubuntu base image from internal registry
This MR updates the Docker build process for OAI images to use a private
registry for the Ubuntu base image ubuntu:noble. This will reduce the
possibility for CI disruption if no internet connection exists.
- Replace FROM ubuntu:noble with FROM <DEFAULT_REGISTRY>/ubuntu:noble in Ubuntu Dockerfiles
This change overcomes the pull rate limit issues from DockerHub in the
CI.
The <DEFAULT_REGISTRY> contains a multi-architecture image (arm64 and
amd64)
$ docker buildx imagetools inspect gracehopper3-oai.sboai.cs.eurecom.fr/ubuntu:noble | grep Platform
Platform: linux/amd64
Platform: linux/arm64
- The scripts run from the jenkins server everyday using a crontab.
- It pulls the AMD and ARM ubuntu:noble image on respective servers and
checks if the internal registry is in sync.
- If not, it pushes the ubuntu:noble image to the registry to remain in
sync with dockerhub.
It was initially foreseen to just check the program exit code, but most
executables don't return with 0 (so the CI would always fail). Add a
separate check that will check for the Bye., only going through the last
X lines instead of the entire file.
- we agreed to basically throw away the old log checker (as it is
unmaintainable)
- now: provide list of analysis to do
* all checkers in cls_log_analysis, can be unit tested (see also next
commit)
* looked up dynamically to simplify adding of new tests + config
* configured with
<analysis>
<services>DESCRIPTION [DESCRIPTION...]</services>
<service>DESCRIPTION</service>
...
</analysis>
where DESCRIPTION follows service=func[=options]:
- service is name of service to check
- func is function to call, which receives filename
- option are arbitary options to pass to func
<services> is whitespace delimited (so can take multiple service
analysis definitions)
<service> exists to allow service definitions with whitespace
changes that would not work in <services>
- I initially planned to check return code, but most softmodems actually
exit with non-zero return code, so this is still TODO
- Default analyzer (checking for assertions, ...) is always run if a
service is listed
- checks for file size
- add unit tests
- it is spaghetti code: difficult to understand which code paths are
taken
- the only effect seems to be in the UE log analysis function: it might
make the log fail. However, we test that iperf is successful
(Iperf2_Unidir()), and would detect before the log analysis if MBMS
traffic does not work
- the rest is only messages that likely nobody reads
The real reason for this change is to reduce the number of class members
in the ran.py class, to simplify the functioning of the eNB analysis
function (no self) to reduce dependencies on the ran.py class.
set -e makes the script exit on error. However, there is code to handle
a non-zero return code of the script, and -e prevents from writing the
footer.
add set -x to see all the commands that are being executed.
Use a raw string as suggested:
ci-scripts/cls_static_code_analysis.py:93: SyntaxWarning: invalid escape sequence '\:'
result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository)
ci-scripts/cls_static_code_analysis.py:125: SyntaxWarning: invalid escape sequence '\.'
ret = re.search('cppcheck version="(?P<version>[0-9\.]+)"', str(line))
ci-scripts/cls_oai_html.py:221: SyntaxWarning: invalid escape sequence '\/'
cmd = "sed -i -e 's/__STATE_" + self.htmlTabNames[0] + "__/<span class=\"glyphicon glyphicon-remove\"><\/span>/' test_results.html"
ci-scripts/ran.py:428: SyntaxWarning: "\[" is an invalid escape sequence. Such sequences will not work in the future. Did you mean "\\["? A raw string is also an option.
result = re.search('\[gNB [0-9]+\]\[RAPROC\] PUSCH with TC_RNTI 0x[0-9a-fA-F]+ received correctly, adding UE MAC Context RNTI 0x[0-9a-fA-F]+', str(line))
ci-scripts/ran.py:457: SyntaxWarning: "\[" is an invalid escape sequence. Such sequences will not work in the future. Did you mean "\\["? A raw string is also an option.
result = re.search('\[PHY\]\s+problem receiving samples', str(line))
ci-scripts/ran.py:461: SyntaxWarning: "\[" is an invalid escape sequence. Such sequences will not work in the future. Did you mean "\\["? A raw string is also an option.
result = re.search('\[MAC\]\s+Removing UE', str(line))
I am not sure we ever need the millisecond output. The date is typically
also clear from the output (we could print the date at the beginning,
once, instead, but this is not done here. Finally, in Jenkins, we
typically get time stamps. Thus, it's not necessary to print this by
default.
On the other hand, since it might be useful when running locally, make
time stamps in logs configurable.
Fix compilation error:
/oai-ran/openair1/SIMULATION/NR_PHY/dlsim.c:932:42: error: variable 'h_channel_coeffs' set but not used [-Werror,-Wunused-but-set-variable]
932 | float *h_channel_coeffs = NULL;
| ^
- Introduce usage of the -f option in ulsim to allow enabling specific
feature flags at runtime.
- Add support for the "cuda" flag to enable CUDA channel simulation when
compiled with CUDA support. If an unsupported flag is provided, nr_ulsim
reports an error.
This commit integrates the GPU-based channel simulation pipeline into
the ulsim.
A `--cuda` command-line flag is added to enable the GPU path at
runtime. When activated, the simulator will:
- Allocate all necessary GPU and pinned host memory via the
`init_cuda_chsim_buffers` helper function.
- In the main simulation loop, call the `run_channel_pipeline_cuda`
function to perform the channel simulation on the GPU, bypassing the
CPU-based functions.
- Clean up all CUDA resources on exit using the
`free_cuda_chsim_buffers` helper.
The cpu path is also updated to use multipath_channel_float and add_noise_float.
- Replace previous handling of -f with a generic feature flag option.
- Add support for the "cuda" flag to enable CUDA channel simulation when
compiled with ENABLE_CUDA.
- Remove unused SCGroupConfig file handling (scg_fd) and related code.
- Clean up deprecated code and variables associated with SCG reading - not
required anymore after b232be94ed
Fixes for Initial UE Context Setup
This MR fixes DRB aggregation from E1 so DRBs from multiple PDU sessions
are appended correctly into the F1 DRB array instead of overwriting
existing entries. It also makes NGAP Initial Context Setup skip PDU
sessions that are already established for the UE, only setting up new
sessions.
DRB aggregation from E1: Adjust fill_drb_to_be_setup_from_e1_resp to
pass &drbs[nb_drb] into fill_f1_drbs_from_e1, ensuring DRBs from later
PDU sessions are appended after the current count.
Duplicate PDU sessions in NGAP Initial Context Setup: In
rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ, detect requested PDU
session IDs that already exist with PDU_SESSION_STATUS_ESTABLISHED, log
a warning, and skip them so they are not added to UE->initial_pdus.
Synchronize multiple gNBs by aligning the slot boundaries
Currently, we derive frame and slot number based on proc->timestamp_rx
using
proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_subframe*10))&1023;
proc->tti_rx = get_slot_from_timestamp(proc->timestamp_rx, fp);
This ignores the samples
proc->timestamp_rx % fp->samples_per_frame
while computing the frame and slot number creating a mis-alignment with
the slot boundaries. A detailed description of the slot misalignment
in a pictorial representation can be seen in an attachment in the MR [1].
We fix this alignment issue by compensating these samples during the
first reception.
We can test the synchronization of the multiple gNBs from the estimated
ToAs from the PRS in the Downlink and the estimated ToAs from the SRS in
the Uplink using rfsim.
In order to test this, make sure you build gNB and nrUE along with the
telnetsrv flag using the option --build-lib telnetsrv.
Also, enable the following log in the function
nr_est_srs_timing_advance_offset() in
openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c to observe SRS ToAs
LOG_I(NR_PHY, "SRS estimatd ToA %d [RX ant %d]: TA offset %d, TA offset ns %d (max_val %ld, mean_val %ld, max_idx %d)\n", srs_toa, ant, *ta_offset, *ta_offset_nsec, max_val, mean_val, max_idx);
Furthermore, update the option Active_gNBs = 2; in
targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.nr.prs.fr1.106prb.conf to enable
decoding PRS transmitted from two gNBs
To run:
nrUE:
sudo ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --uicc0.imsi 001010000000001 --rfsim --phy-test -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.nr.prs.fr1.106prb.conf --rfsimulator.serveraddr server
gNB 0:
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf --gNBs.[0].min_rxtxtime 6 --rfsim --phy-test --rfsimulator.[0].serveraddr 127.0.0.1 --rfsimulator.[0].options chanmod --rfsimulator.[0].modelname AWGN --telnetsrv
gNB 1:
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band78.fr1.106PRB.usrpx310.conf --gNBs.[0].min_rxtxtime 6 --rfsim --phy-test --rfsimulator.[0].serveraddr 127.0.0.1 --rfsimulator.[0].options chanmod --rfsimulator.[0].modelname AWGN --telnetsrv
When we run the nrUE, gNB0 and gNB1, we can see the following logs
nrUE:
[PHY] [gNB 0][rsc 0][Rx 0][sfn 976][slot 2] DL PRS ToA ==> 0.0 / 2048 samples, peak channel power -16.4 dBm, SNR +4.0 dB, rsrp -42.2 dBm
[PHY] [gNB 1][rsc 0][Rx 0][sfn 976][slot 3] DL PRS ToA ==> 0.0 / 2048 samples, peak channel power -16.4 dBm, SNR +4.0 dB, rsrp -42.2 dBm
gNB 0:
[NR_PHY] SRS estimatd ToA 0 [RX ant 0]: TA offset 31, TA offset ns 0 (max_val 99820162, mean_val 80176, max_idx 0)
gNB 1:
[NR_PHY] SRS estimatd ToA 0 [RX ant 0]: TA offset 31, TA offset ns 0 (max_val 98784562, mean_val 79369, max_idx 0)
From the above logs, when we run the rfsim and when no delays introduced, we can observe the following results
In the Downlink at the UE, the estimated ToAs using PRS from both gNB0
and gNB1 are 0 and in the uplink, the ToA estimated from the SRS
transmitted by the UE at both the gNBs are also 0. This indicates that
both the gNBs are synchronized along with their slot boundaries. We also
highlight that this is not the case in the current develop branch since
the slot boundaries are not aligned.
We also can test the multi gNB synchronization by introducing delays
using telnet as follows,
Introduce new_offset (delay) of 4 samples to the gNB 0 from UE in the
uplink as follows,
openairinterface5g$ echo rfsimu setdistance rfsimu_channel_enB0 20 | ncat --idle 1 127.0.0.80 9080
softmodem_gnb> rfsimu_setdistance_cmd: new_offset 4, new (exact) distance 19.518 m, new delay 0.000065 ms
Ncat: Idle timeout expired (1000 ms).
We can oberve this delay of 4 samples being reflected in the estimated
SRS ToAs at gNB 0 while not changing the ToA in gNB 1
[NR_PHY] SRS estimatd ToA 4 [RX ant 0]: TA offset 31, TA offset ns 65 (max_val 98803636, mean_val 79430, max_idx 8)
similarly, Introduce new_offset (delay) of 2 samples to the gNB 1 from
UE in the uplink as follows,
openairinterface5g$ echo rfsimu setdistance rfsimu_channel_enB0 10 | ncat --idle 1 127.0.0.81 9081
softmodem_gnb> rfsimu_setdistance_cmd: new_offset 2, new (exact) distance 9.759 m, new delay 0.000033 ms
Ncat: Idle timeout expired (1000 ms).
We can oberve this delay of 2 samples being reflected in the estimated
SRS ToAs at gNB 1 while not changing the ToA in gNB 0
[NR_PHY] SRS estimatd ToA 2 [RX ant 0]: TA offset 31, TA offset ns 32 (max_val 98962768, mean_val 79552, max_idx 4)
Closes#897
[1] https://gitlab.eurecom.fr/oai/openairinterface5g/-/merge_requests/3892
Remove L1 dependence from NR band number
L1 band information relied on get_band function that couldn't provide an
unambiguous result. Also there is no SCF compliant parameter for L1 and
generally we don't really need that information in L1.
The MR also remove a RU section that used nr_band but was never really
accessed in NR.
Add missing packing for CONFIG.request parameter BetaPSS
Adds the packing procedure for the parameter BetaPSS, as well as adding this
parameter to the utility functions where it is missing
IPV6 support for telnet socket binding
Now, the listening telnet socket is only bound to the dedicated interface IPs in
config file, both for V4 and V6
Closes#834
Fix handling of IPv4v6 PDU sessions
The code previously checked that the supplied PDU sessions's type is
exactly what we requested. However, at least OAI 5GC will only give us
an IPv4 PDU session if we request IPv4v6 (so the check would fail).
Extend the validation to either check exact match, or, if IPv4v6
requested, that it is either IPv4 or IPv6.
Fix error
openair1/SIMULATION/NR_PHY/dlsim.c:1057:37: runtime error: member access within misaligned address 0x7f8a67e01010 for type 'struct NR_Sched_Rsp_t', which requires 32 byte alignment
Prior to this commit, constants NB_ANTENNAS_RX/TX are provided on the
command line to each compiler invocation. This has the drawback (1) that
also files that don't need that get the constants, and (2) it is not
easy to find them using ctags or similar, as the only definition is in
CMakeLists.txt (where it is not found).
In this commit, use cmake configure_file() to write a header file with
these constants. The file will be generated during cmake invocation, and
written to <build-dir>/common/cmake_defs.h. The relevant files that
need this definition will pick it from the header.
This has been used previously also in a commit to write git information.
See-also: 8bffd1666d ("Avoid complete rebuild on cmake run with git info change")
Ensure the CU-CP only sets up PDU sessions that are not already
established for the UE, skipping duplicates while keeping the NG UE
context valid. This aligns with 3GPP TS 38.413 PDU Session setup
semantics for duplicate session IDs
Changes:
- Change rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ to scan requested
PDU sessions and detect IDs that already exist in UE->pduSessions with
PDU_SESSION_STATUS_ESTABLISHED
- Log a warning and skip already established PDU session IDs so they are
not added to UE->initial_pdus
- Collect only non-established PDU sessions into a temporary stack array,
allocate UE->initial_pdus with the exact count, copy them in, update
UE->n_initial_pdu, and only refresh UE AMBR when there is at least one
session to set up
Since the grand-parent commit, if possible, the gNBs synchronize on a
slot-level boundary. Some configuration files/command line overrides
left the same SSB position for two DUs in RFsim-based handover
scenarios, which then makes that the UE cannot decode the SSB.
This commit changes the positions such that this is possible again. In
the F1 HO docker-compose
(ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml), we set it
to 2 to send only one SSB (not 2 with bitmap 3).
Ensure DRBs from multiple PDU sessions are appended into the F1 DRB array
without overwriting previously filled entries.
Update fill_drb_to_be_setup_from_e1_resp to call fill_f1_drbs_from_e1
with &drbs[nb_drb] so each PDU session’s DRBs are written after the
current count
fix: removed the nssai_sd parameter in the ue.conf file
Following the tutorial in the RF simulator, the PDU session cannot
be established because the Slice Differentiator to request(nssai_sd)
parameter in the ue.conf file is 1(integer) but in the documentation
the default value of the nssai_sd is 0xFFFFF(meaning "no SD")
Now the nssai_sd parameter is removed in the ue.conf to establish the
PDU session.
NR UE: correctly compute writeTimestamp for SCS > 30 kHz with rf-simulator
Contains also two minor cleanups for nr-ue.c:
- make fp point to constant NR_DL_FRAME_PARMS where possible
- use c16_t type for I/Q sample arrays
print better message for rsrp: invalid doesn't mean it is not measured
print better message for rsrp: invalid doesn't mean it is not measured,
it means it is out of usable range
NR UE: fix PRACH k1 calculation at MAC when handover
The k1 for PRACH calculation in config_common_ue() should be the same as in
config_common_ue_sa(), otherwise k1 is wrong when handover to target cell if
msg1-FDM not 0 in reconfigurationWithSync.
Verified with 3rd-party gNB.
The code previously checked that the supplied PDU sessions's type is
exactly what we requested. However, at least OAI 5GC will only give us
an IPv4 PDU session if we request IPv4v6 (so the check would fail).
Extend the validation to either check exact match, or, if IPv4v6
requested, that it is either IPv4 or IPv6.
Similarly to gNB, eNB, lteUE, end with a "Bye." that the CI (will) check
for.
The right way to do this would be to use the exit code, but most
executables do not actually end with 0, such that we need to check for
this. Thus, this commit is only to harmonize with other executables.
Following the tutorial in the RF simulator, the PDU session cannot
be established because the Slice Differentiator to request(nssai_sd)
parameter in the ue.conf file is 1(integer) but in the documentation
the default value of the nssai_sd is 0xFFFFF(meaning "no SD")
Now the nssai_sd parameter is removed in the ue.conf to establish the
PDU session.
This commit integrates the CUDA-based channel simulation pipeline into
the nr_dlsim.
A new `--cuda` command-line flag is added to enable the GPU path at
runtime. When activated, the simulator will:
- Allocate all necessary GPU and pinned host memory via the new
`init_cuda_chsim_buffers` helper function.
- In the main simulation loop, call the `run_channel_pipeline_cuda`
function to perform the channel simulation on the GPU, bypassing the
CPU-based functions.
- Clean up all CUDA resources on exit using the
`free_cuda_chsim_buffers` helper.
Additionally, dlsim is now using the float version of channel_multipath and add_noise functions.
Also, The input data is formatted as interleaved IQ, with separate antennas to ensure a fair comparison with the GPU operation.
gNB: Reset NDI only after usage in case of disable HARQ
Solves this warnings seen in the UE trace:
NDI indicates re-transmission but computed TBS 3968 doesn't match with what previously stored 3368
Issue happens only if feature disable_harq is enabled. GNB resets the harq
process (including NDI) as PUCCH will not be sent for this harq process, but
before the harq process is used in DCI payload preparation.
Fix is to reset the harq process after harq process in case of no PUCCH.
Fail early if configuration module can not initialize properly
In the case that the config module cannot load the driver for libconfig or yaml,
currently, there might be a cascade of errors that are difficult for users to
understand. For instance (partially redacted for clarity):
[CONFIG] Error calling dlopen(libparams_libconfig.so): libparams_libconfig.so: cannot open shared object file: No such file or directory
[CONFIG] config module "libconfig" couldn't be loaded
[CONFIG] config_get, section log_config skipped, config module not properly initialized
[LOG] init aborted, configuration couldn't be performed
[CONFIG] config_get, section (null) skipped, config module not properly initialized
[CONFIG] /home/francesco/openairinterface5g/common/config/config_userapi.c 68 nfapi has no processed integer availablle
[CONFIG] config_get, section (null) skipped, config module not properly initialized
Assertion (get_softmodem_params()->default_pdu_session_id == -1) failed!
In get_common_options() /home/francesco/openairinterface5g/executables/softmodem-common.c:161
Use uicc0.pdu_sessions.[0].id to change the requested PDU session ID (is 0)
Here, the error is the missing shared object, but a user is more likely to look
at the last error instead of the first.
This commit addresses it by checking early for CONFIG_ISFLAGSET(CONFIG_ABORT),
and stopping if it is set. Additionally changes include making functions static,
removing late CONFIG_ISFLAGSET() checks, and the CONFIG_ISFLAGSET() in
load_configmodule(), because at that time "uniqCfg" is not set yet and thus does
not do anything (this is likely a regression of an earlier cleanup).
See-also: f50d5f5a ("make multiple config instead of one implicit global")
Currently, we derive frame and slot number based on `proc->timestamp_rx`
using
`proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_subframe*10))&1023;` and
`proc->tti_rx = get_slot_from_timestamp(proc->timestamp_rx, fp);`
This ignores the samples `proc->timestamp_rx % fp->samples_per_frame`
while computing the frame and slot number creating a mis-alignment with the slot boundaries.
We fix this alignment by compensating these samples during the first reception.
Integration: `2026.w08`
* !3934 Fix Ubuntu build: reinstate -Werror
* !3803 remove cblas and atlas dependancy
* !3918 Add a simple GTP unit test
* !3924 T: macpdu2wireshark: gentle exit (and some other minor work in the T tracer)
* !3925 Fix race condition on double RA during RRC reestablishment
* !3930 bugfix: add PCell to serving_cells in fallback path and refactor update logic
* !3936 [FHI72] Remove support for xran E release
* !3893 NR Paging on CU
See merge request oai/openairinterface5g!3939
In the case that the config module cannot load the driver for libconfig
or yaml, currently, there might be a cascade of errors that are
difficult for users to understand. For instance (partially redacted for
clarity):
[CONFIG] Error calling dlopen(libparams_libconfig.so): libparams_libconfig.so: cannot open shared object file: No such file or directory
[CONFIG] config module "libconfig" couldn't be loaded
[CONFIG] config_get, section log_config skipped, config module not properly initialized
[LOG] init aborted, configuration couldn't be performed
[CONFIG] config_get, section (null) skipped, config module not properly initialized
[CONFIG] /home/francesco/openairinterface5g/common/config/config_userapi.c 68 nfapi has no processed integer availablle
[CONFIG] config_get, section (null) skipped, config module not properly initialized
Assertion (get_softmodem_params()->default_pdu_session_id == -1) failed!
In get_common_options() /home/francesco/openairinterface5g/executables/softmodem-common.c:161
Use uicc0.pdu_sessions.[0].id to change the requested PDU session ID (is 0)
Here, the error is the missing shared object, but a user is more likely
to look at the last error instead of the first.
This commit addresses it by checking early for
CONFIG_ISFLAGSET(CONFIG_ABORT), and stopping if it is set. Additionally
changes include making functions static, removing late
CONFIG_ISFLAGSET() checks, and the CONFIG_ISFLAGSET() in
load_configmodule(), because at that time "uniqCfg" is not set yet and
thus does not do anything (this is likely a regression of an earlier
cleanup).
See-also: f50d5f5a9b ("make multiple config instead of one implicit
global")
NR Paging on CU
Implements the NR paging path on the CU:
- NGAP Paging is decoded and passed to RRC
- RRC builds F1AP Paging, and distributes it to DUs via F1 callback
Changes:
- Refactor and extend F1AP Paging encode/decode libraries
* add missing enc/dec/eq/cp functions
* add unit test
* IEs: CN UE 5G-S-TMSI, RAN UE I-RNTI; optional DRX/priority/origin)
- Refactor CU callback CU_send_Paging
- Refactor DU handler DU_handle_Paging
- Refactor old F1 callback for Paging indication, extend it and align
with existing F1 callbacks in stack
- Refactor and extend NGAP Paging encode/decode lib
* add missing enc/dec/eq/cp functions
* add unit test
* Fixes NGAP paging to accept Paging only on SCTP stream 0 per TS
38.412
- Includes supporting refactors (PDU session split, shared 5G-S-TMSI
helpers, NGAP/F1AP cleanups)
Testing
- NGAP and F1AP Paging lib unit tests (enc/dec)
- Stream-0 fix validated with Open5GS AMF
This MR does not address the DU changes besides the F1 handler. F1AP
Paging does not have an RRC container to pass the PCCH message to the
DU, and F1 DL RRC Message Transfer does not apply to PCCH. PCCH-Message
shall be built at DU per TS 38.331 §5.3.2, with padding as per §8.5 and
delivered as RLC SDU per §8.2. For each cell in Paging Cell List that
belongs to this DU, queue for MAC. MAC schedules at PF/PO per TS 38.304
§7.
Refs:
- F1AP 3GPP TS 38.473 version 16.21.0 Release 16
- NGAP 3GPP TS 38.413 version 16.17.0 Release 16
[FHI72] Remove support for xran E release
All the use cases we tested with E release are working end-to-end with F release.
The near future plan is to support K release which is ongoing in the MR !3444.
bugfix: add PCell to serving_cells in fallback path and refactor update logic
Fix assertion failure in rrc_gNB_send_NGAP_NAS_FIRST_REQ() when RRC
Reestablishment falls back to RRC Setup. The fallback path was not
adding the PCell to the UE's serving_cells array, causing
rrc_get_pcell_for_ue() to return NULL.
Major changes:
- Add rrc_update_ue_pcell() helper function that handles PCell updates
for both new UEs (fallback) and existing UEs (normal reestablishment)
- Refactor normal reestablishment path to use rrc_update_ue_pcell()
helper instead of manual cleanup + add sequence
- Add PCell update to fallback_rrc_setup path using the same helper
- Move C-RNTI validation after current_cell fetch to ensure current_cell
is initialized before fallback_rrc_setup label
- Change error handling: return instead of fallback when PCell add fails
in normal reestablishment path
Fixes CI failure in !3908
All the use cases we tested so far, are supported with xran F release.
Therefore, we can proceed with removing the support with E release.
In addition, our plan is to bring the support for K release which is ongoing activity in
the MR https://gitlab.eurecom.fr/oai/openairinterface5g/-/merge_requests/3444.
Fix race condition on double RA during RRC reestablishment
Sometimes, especially in poor channel conditions, a UE can trigger
multiple RA procedures during RRC reestablishment, causing
reconfigCellGroup to be overwritten with a CellGroup that already has
spCellConfig removed, leading to an assertion failure in
update_cellgroup_for_reestablishment(). See logs below
[NR_MAC] 456.13 UE 991d: Received Ack of Msg4. CBRA procedure succeeded (UE Connected)
[NR_MAC] Adding new UE context with RNTI 0x991d
[NR_PHY] [RAPROC] 461.9 Initiating RA procedure with preamble 8, energy 48.0 dB (I0 274, thres 130), delay 21 start symbol 2 freq index 0
[NR_MAC] 461.9 UE RA-RNTI 0081 TC-RNTI ecd8: initiating RA procedure
[NR_MAC] UE ecd8: Sync beam index 0
[NR_MAC] UE ecd8: Msg3 scheduled at 462.3 (461.18 TDA 2) start 0 RBs 8
[NR_MAC] UE ecd8: 461.18 Generating RA-Msg2 DCI, RA RNTI 0x81, state 1, preamble_index(RAPID) 8, timing_offset = 21 (estimated distance 820.3 [m])
[NR_MAC] 462. 3 PUSCH with TC_RNTI 0xecd8 received correctly
[NR_MAC] Received a MAC CE for C-RNTI with 991d
[NR_MAC] Remove NR rnti 0xecd8
[NR_MAC] 462. 3 RA with C-RNTI 991d complete
[NR_PHY] [RAPROC] 471.19 Initiating RA procedure with preamble 6, energy 51.0 dB (I0 276, thres 130), delay 21 start symbol 2 freq index 0
[NR_MAC] 471.19 UE RA-RNTI 010d TC-RNTI 022d: initiating RA procedure
[NR_MAC] UE 022d: Sync beam index 0
[NR_MAC] UE 022d: Msg3 scheduled at 472.13 (472.8 TDA 2) start 0 RBs 8
[NR_MAC] UE 022d: 472.8 Generating RA-Msg2 DCI, RA RNTI 0x10d, state 1, preamble_index(RAPID) 6, timing_offset = 21 (estimated distance 820.3 [m])
[NR_MAC] 472.13 PUSCH with TC_RNTI 0x022d received correctly
[NR_MAC] Received a MAC CE for C-RNTI with 991d
[NR_MAC] Remove NR rnti 0x022d
[NR_MAC] 472.13 RA with C-RNTI 991d complete
[NR_RRC] [UL] (cellID 1, UE ID 1 RNTI 991d) Received RRCReestablishmentComplete
[NR_RRC] UE 1 Processing NR_RRCReestablishmentComplete from UE
[NR_MAC] UE 991d: gNB-DU Configuration Query received, will include CellGroupConfig in response
Assertion (new_CellGroup->spCellConfig) failed!
In update_cellgroup_for_reestablishment() /phy/openairinterface5g/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c:666
This MR solves it by skipping the reconfigCellGroup overwrite when it
already holds a valid config with spCellConfig, and by replacing the
fatal assertion on missing spCellConfig with an early return.
T: macpdu2wireshark: gentle exit (and some other minor work in the T tracer)
When outputting to a file, typing ctrl+c exits the program without
calling fclose(), leading to loss of traces in the output file.
Let's intercept ctrl+c and exit gently, calling fclose().
Also include a small fix for compilation of _check_vcd, some work on
extract and hacks/plot-ofdm, minor stuff.
Add a simple GTP unit test
Add a simple unit test for GTP that as of now tests the main
functionality, i.e., for a single UE, set up a bearer between two
endpoints and checking that traffic sending works. This is a start to
extend it further, e.g., with API changes, extensions to support new
functionality such as IPv6, and refactorings.
A number of supporting cleanup has been done as well.
remove cblas and atlas dependancy
With new Fedora, we have again the cblas.h place not working
cblas+atlas dependancy is annoying for years
i start this MR to remove this dependancy
first commit: only cleaning: remove dead code, make static functions,
simplify code
after this commit, we see we use blas only in: conjugate_transpose()
that is a quite trivial function H_hermH_plus_sigma2I() a bit more
complex, but still possible to recode mutl_matrix_matrix_col_based() i
think we have the same elsewhere in OAI
atlas is used only in: lin_eq_solver() in don't know if replacement is
hard
We can observe all is related to MMSE, that is also coded in OAI 5G, so
maybe the solution is to use 5G code in 4G
Since nothing seems to be used, we can remove it.
The k1 for PRACH calculation in config_common_ue() should be the same as in config_common_ue_sa(),
otherwise k1 is wrong when handover to target cell if msg1-FDM not 0 in reconfigurationWithSync.
For unit testing, allow to remove endpoints such that we could reuse a
port/IP combination.
The function does not take care of endpoints that are still "dangling",
it is the user's responsibility to remove all existing TEIDs.
Add a simple unit test that tests sending unidirectional traffic. So
far, it merely replicates what is already in nr-cuup-load-test, but it's
a single executable (so easier to handle), and could be more easily
extended to further tests (e.g., IPv6).
A couple of ideas for refactoring/improvements have been added in
comments in the test.
Paging messages are classified as non-UE-associated signalling per
3GPP TS 38.412 clause 7 (TL), which requires them to be sent on
stream 0 (or a reserved stream pair).
Paging message is received when UE is in RRC_IDLE or RRC_INACTIVE
state, as the RAN has no active UE context and paging targets the
UE by 5G-S-TMSI rather than RAN-UE-NGAP-ID.
The previous implementation incorrectly rejected paging messages
received on stream 0, causing paging failures when using Open5GS AMF.
Changes:
- Accept paging on stream 0 (non-UE-associated signalling)
- Reject paging on non-zero streams (UE-associated streams)
- Add documentation
RRC now builds F1AP paging messages directly by calling F1AP/direct
callbacks and aligning the CU/DU intergace with the F1AP design in the CU.
Messages are forwarded based on TAI-based cell matching across DUs.
- Remove F1AP_PAGING_IND message def and f1ap_paging_ind_t.
RRC no longer sends ITTI F1AP_PAGING_IND; it builds f1ap_paging_t
and passes it to the DU path.
- rrc_gNB_process_PAGING_IND: new signature (rrc, instance, msg)
with const where appropriate; call in rrc_gnb_task() updated.
- NGAP handler logic: For each TAI, match (PLMN + TAC) to
rrc->configuration; collect matching TAIs. Build one f1ap_paging_t
(5G-S-TMSI via nr_construct_5g_s_tmsi(), identity type
F1AP_PAGING_IDENTITY_CN_UE, optional drx/priority/origin copied
from ngap_paging_ind_t), call rrc_send_paging_to_dus(), then
free_f1ap_paging(). Remove the previous AssertFatal stub, CC loop,
NODE_IS_CU branch, and UE lookup logic: it is now handled by
F1AP/direct CU callbacks.
- rrc_gNB_du: Add rrc_send_paging_to_dus(rrc, tais, n_tai, msg).
Iterate DUs with RB_FOREACH; for each DU, fill msg->cells from
du->cells whose (PLMN + TAC) matches any requested TAI, set
n_cells, then call rrc->mac_rrc.paging_transfer(du->assoc_id,
msg). Skip DUs with no matching cells. Prevents duplicate paging
when multiple TAIs map to the same PLMN.
Introduce paging_transfer in the mac_rrc_dl interface so the CU can pass
paging to the DU (F1 or direct). Use the F1AP paging lib on both CU and DU
for decode/free and to avoid leaking the message after send.
- Add f1_paging_transfer_func_t and paging_transfer to nr_mac_rrc_dl_if_s
(mac_rrc_dl.h, nr_rrc_defs.h).
- F1AP path: paging_f1ap() allocates F1AP_PAGING, copies with cp_f1ap_paging(),
sends via ITTI to TASK_CU_F1. Direct path: f1_paging_transfer_direct() stub
- CU task: call free_f1ap_paging() after CU_send_Paging() to release the message.
- DU: DU_handle_Paging() uses decode_f1ap_paging()/free_f1ap_paging() from lib,
returns on decode failure; remove inline ASN.1 IE parsing.
- cleanup outdated header comments in header files
- Left a TODO not in DU code to build PCCH (in F1 and direct paths)
- Add F1AP_PAGING message type and macro; F1AP defines Paging, not
Paging Indication. CU task now handles F1AP_PAGING instead of
F1AP_PAGING_IND.
- In CU_send_Paging(): take const f1ap_paging_t *; replace inline
ASN.1 encoding with encode_f1ap_paging(); refine memory management;
clean up in the process
Note: F1AP_PAGING_IND definitions left in place and still used in the
RRC callback - to be removed in a follow-up commit.
Add F1AP Paging library and new message type to follow the existing F1AP
library pattern and to support multi-cell paging and both RAN UE (I-RNTI)
and CN UE (5G-S-TMSI) paging identities at the library level per TS 38.473.
* New library (f1ap_paging.c/h, f1ap_lib_includes.h, CMakeLists.txt)
- Implement encode/decode/copy/eq/free for F1AP Paging (procedure 9.2.6).
- Add ASN.1 includes for Paging, PagingIdentity, CN/RAN UE identities.
- Enables unit testing of Paging enc/dec in f1ap_lib_test.c.
* New types in f1ap_messages_types.h (existing f1ap_paging_ind_t unchanged)
- f1ap_paging_t: UE Identity Index, paging identity (union + type enum),
optional paging_drx, paging_priority, paging_origin, and paging_cells[].
- f1ap_paging_cell_item_t, f1ap_paging_identity_type_t, f1ap_paging_identity_t
for multi-cell list and RAN/CN identity discrimination.
- Paging Origin IE is optional per F1AP 8.7.1.2.
Tests: test_f1ap_paging() roundtrip and copy for CN UE (5G-S-TMSI) and
RAN UE (I-RNTI) cases, with optional IEs.
- Refactor ngap_paging_ind_t (openair2/COMMON/ngap_messages_types.h):
- optional paging_drx and paging_priority as pointers
- TAI list as tai_list[] and n_tai
- add optional IEs: Paging Origin, Paging Attempt Information,
UE Radio Capability for Paging.
- Introduce nr_tai_t, ngap_paging_attempt_info_t, ngap_paging_origin_t;
- generate paging enums via FOREACH macros.
- Add NGAP Paging encode/decode/eq/free in openair3/NGAP/ngap_gNB_paging.c
(encode_ng_paging, decode_ng_paging, eq_ng_paging, free_ng_paging).
- Replace inline Paging decode in ngap_gNB_handle_paging() with
decode_ng_paging() and add error handling; add eq_ngap_plmn() in
ngap_common.
- Update rrc_gNB_NGAP.c to use tai_list/n_tai and optional paging_drx
when forwarding paging to F1AP.
- Add ASN.1 includes for Paging in ngap_msg_includes.h; register
ngap_gNB_paging.c in root CMakeLists.txt.
- Add NGAP unit test (openair3/NGAP/tests/ngap_lib_test.c): encode/decode
roundtrip for Paging; tests subdirectory and executable under
ENABLE_TESTS in openair3/NGAP/CMakeLists.txt.
ngap_common.h is for common IEs enc/dec functions, utilities
should go into a separate file. Changes in this commit:
* Add ngap_utils.h (utilities)
* Move helper macros (NGAP_ERROR, NGAP_DEBUG, NGAP_FIND_PROTOCOLIE_BY_ID, etc.) to ngap_utils.h
* Move equality check macros (_NGAP_EQ_CHECK_*) to ngap_utils.h
* Clean up includes
This change is preparatory to the introduction the paging lib with unit
tests, with the goal of reducing the inter-dependency between concurrent
NGAP libs.
TO_ENUM/TO_TEXT are already used in NAS, and can be adopted in NGAP.
To avoid duplication, the following changes are introduced:
* Move text_info_t, TO_ENUM, TO_TEXT to common/utils/utils.h
* Include utils.h include to ngap_messages_types.h, fgs_nas_utils.h, and fgmm_lib.h
* RRC establishment cause: refactor to FOREACH_RRC_ESTABLISHMENT_CAUSE macro
* Cause Group: refactor to FOREACH_CAUSE_GROUP macro
* Radio Network Cause: refactor to FOREACH_CAUSE_RADIO_NETWORK macro
* Protocol Cause: refactor to FOREACH_CAUSE_PROTOCOL macro
This change is preparatory to the introduction the paging lib with unit
tests, with the goal of reducing the inter-dependency between concurrent
NGAP libs.
These conversion functions will be needed across different
NGAP libraries upon refactoring: tnl_to_bitstring, bitstring_to_tnl
Therefore, they are moved to the common lib.
PDU session related NGAP messages do not belong to NAS procedures lib.
* Create ngap_gNB_pdu_session_management.c and .h
* Move out ngap_gNB_pdusession_setup_resp, ngap_gNB_pdusession_modify_resp,
ngap_gNB_pdusession_release_resp from ngap_gNB_nas_procedures.c
* Move encode_ngap_pdusession_setup_response_transfer to ngap_common.c:
this transfer IE is common used both in PDU Session Management and
Initial Context Setup, so it's moved to the common lib
* Add ngap_gNB_pdu_session_management.c to CMakeLists.txt
This commit centralizes equality-check behavior and removes duplicated
macro implementations across protocol stacks.
Major changes:
- add `common/utils/eq_check.h` with shared `_EQ_CHECK_*`,
`EQ_CHECK_GENERIC`, and optional-IE pointer helpers
- replace E1AP/F1AP/NAS local equality macros and call sites with
the shared helpers
- remove duplicated layer-specific error/equality macro definitions from
common headers and switch includes to `eq_check.h`
- update CMake test flags to define `ENABLE_TESTS` for `e1ap_lib`,
and 5GS NAS libraries; drop `E1AP_LOG_ERRORS` - equality-check/error
printing is now consistently controlled by `ENABLE_TESTS`
Centralizes 5G-S-TMSI bit manipulation logic for consistency and
maintainability. All manual bit operations replaced with documented
helper functions following TS 23.003 bit layout specification.
- Add helper functions for 5G-S-TMSI operations:
* nr_construct_5g_s_tmsi_part1: 5G-S-TMSI construction is defined
in 3GPP TS 23.003 and relevant at both gNB and UE side
* Add helper functions to be later used in NG Paging
* Adopt in NAS UE
* nr_extract_5g_s_tmsi_part1() - extract Part1 (39 bits) from full
* nr_extract_5g_s_tmsi_part2() - extract Part2 (9 bits) from full
* nr_build_full_5g_s_tmsi() - reconstruct full from Part1+Part2
* nr_deconstruct_5g_s_tmsi() - deconstruct into components
- Refactor manual bit manipulation to use helper functions:
* asn1_msg.c: use nr_extract_5g_s_tmsi_part1() in RRCSetupRequest
* asn1_msg.c: use nr_extract_5g_s_tmsi_part2() in RRCSetupComplete
* rrc_gNB.c: use nr_build_full_5g_s_tmsi() when reconstructing from parts
* rrc_gNB.c: use nr_deconstruct_5g_s_tmsi() when extracting components
- Optimize nr_construct_5g_s_tmsi_part1() to reuse extract function
There is no such thing as NG Register message, the naming is
inaccurate, however the goal of this commit is only to clarify that
and major refactoring is not yet carried out.
Move rrc_update_ue_pcell() from static function in rrc_gNB.c to public
function in rrc_cell_management.c, making it reusable across RRC code
paths. Replace duplicate PCell addition logic in handover paths
(intra-CU and inter-CU) and RRCSetup path with calls to this shared
function.
This eliminates code duplication between handover and RRCSetup paths,
centralizes PCell update logic (including cleanup of old PCell's DU
serving cells) in a single reusable function and makes the function
available for future use in other RRC procedures
Fix assertion failure in rrc_gNB_send_NGAP_NAS_FIRST_REQ() when RRC
Reestablishment falls back to RRC Setup. The fallback path was not
adding the PCell to the UE's serving_cells array, causing
rrc_get_pcell_for_ue() to return NULL.
Major changes:
- Add rrc_update_ue_pcell() helper function that handles PCell updates
for both new UEs (fallback) and existing UEs (normal reestablishment)
- Refactor normal reestablishment path to use rrc_update_ue_pcell()
helper instead of manual cleanup + add sequence
- Add PCell update to fallback_rrc_setup path using the same helper
- Move C-RNTI validation after current_cell fetch to ensure current_cell
is initialized before fallback_rrc_setup label
- Change error handling: return instead of fallback when PCell add fails
in normal reestablishment path
When outputting to a file, typing ctrl+c exits the program without calling
fclose(), leading to loss of traces in the output file.
Let's intercept ctrl+c and exit gently, calling fclose().
Since the parent commit, USE_MMSE is not defined. Thus, the
corresponding code is commented out. Since there are no linker problems,
it is obvious that this code is never called, and we can remove it.
This reverts commit 16c333b1a3.
I tried to build everything in Ubuntu images, but
- this introduced a regression (ignores $BUILD_OPTION)
- made that we don't use -Werror (when we should)
I tried to fix the use of the first, but it would involve more changes
than I prefer. On the second, we cannot enable -Werror, as FlexRIC does
not build warning-free (in Release mode). We thus have to build only the
targets that we require, and therefore we can keep using build_oai,
which is the simplest option (cf. the first point).
Integration: `2026.w07`
* !3899 Solving issues caused by invalid RRC configuration
* !3905 Add undocumented Aerial ERROR.indication vendor specific error codes
* !3896 Add fallbacks for ARMv8a to make it compile
* !3734 vrtsim: add CIR DB playback with CLI flags
* !3886 Integrate GPU-Accelerated Channel Simulation + CI Test Pipeline
* !3907 RRC QoS refactor: PDU Session Modify support, SDAP fixes, and code improvements
* !3891 Fix for split 7.2 DU configurations including DU & RU ethernet addresses
* !3913 Remove VCD signal dumper from NR code
* !3783 RRC: Multi-cell handling architecture
* !3916 CI: Rename RAN-SA-2x2-Module-CN5G pipeline
* !3922 Fix and update tracy tag to v0.13.1
* !3917 Fix SRS power computation
* !3915 Cleanup Cmake: remove some double compilation
* !3883 Improvements in handling beamforming inputs
* !3906 fix(ci): remove git reset command from Jenkinsfile
* !3894 Reimplement BladeRF radio driver, make it work for 5G
Closes#845
See merge request oai/openairinterface5g!3908
fix(ci): remove git reset command from Jenkinsfile
- By default, the variable eNB_CommitID is set as 'develop' in the
config
- When OAI-FLEXRIC-RAN-Integration-Test is triggered by upstream FlexRIC
push events, it takes develop
- Triggered by RAN takes commit SHA where origin/SHA does not work
Below are issues seen after this week's merge to develop:
https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-Ubuntu-ARM-Image-Builder/4103/pipeline-overview/?selected-node=44
08:43:07 + git reset --hard origin/9777d23173a740de7cf982659fae13ad6627d3aa
08:43:07 fatal: ambiguous argument 'origin/9777d23173a740de7cf982659fae13ad6627d3aa': unknown revision or path not in the working tree.
When triggered through upstream FlexRIC (as a PUSH Event), it is taking
the branch as shown in the logs:
https://jenkins-oai.eurecom.fr/job/OAI-FLEXRIC-RAN-Integration-Test/3832/pipeline-overview/?selected-node=47
13:45:27 + git reset --hard origin/develop
13:45:27 HEAD is now at 9777d23173 Merge branch 'integration_2026_w06' into 'develop'
Cleanup Cmake: remove some double compilation
Harmonize some cmake code to avoid double compilation, notably around
polar and smallblock. In develop, we just add their sources to other
targets, whereas now we define STATIC libraries (further changed to
shared library in !3856) to avoid double compilation.
With this command line:
cmake .. -GNinja -DENABLE_TESTS=ON && ninja
shows that before we compile 12631 files, where after it is 12583
there is additional supporting cleanup (move code, remove headers,
types, ...).
there is more harmonization to do, I limited myself to some easy wins.
For instance, we do the same with PDCP/SDAP, and this should be
refactored into STATIC libraries as well.
Fix SRS power computation
The SRS symbols have been remapped recently in
srs_estimated_channel_freq, and therefore the calculation of the SRS
power has to retrieve the symbols from different positions.
CI: Rename RAN-SA-2x2-Module-CN5G pipeline
RAN-SA-2x2-Module-CN5G performs tests not only with 2x2 but also with a
4x4 MIMO configuration. The pipeline name has been generalized to
RAN-SA-Multi-Antenna-CN5G to cover multiple antenna configurations.
RRC: Multi-cell handling architecture
This MR implements a foundational multi-cell handling architecture for
RRC by separating DU management from cell management and establishing a
hierarchical cell organization within each DU container. The changes
enable proper multi-cell support where each DU can serve multiple cells,
addressing the previous limitation where DU and cell management were
tightly coupled with the assumption of one cell per DU.
Key Changes:
- Data Structure Separation: Separated for DU containers (DU-specific
info) from cell containers (cell-specific data)
- Global DU and Cell Trees: Cells are now stored in global RB trees in
RRC, similarly to DUs
- Du-specific cell seq_arr: within each DU container (du->cells) is
stored a seq_arr of cells belonging to the DU
- UE Cell Association Framework: Introduced serving_cells array to track
PCell and SCells for each UE with servCellIndex indexing
- Cell Management Library: Extracted cell management functions into
rrc_cell_management.c/h for better testability and maintainability
Other relevant changes:
- F1AP Refactoring: cell list definitions, heap allocation to prevent
stack overflow
- 5G-S-TMSI Helpers: Common helper functions for 3GPP TS 23.003
compliant construction
- Integration Tests: Comprehensive test suite for DU lookup, cell
lookup, and UE cell association
- Cell Duplication Checks: Validation in F1 DU configuration update to
prevent duplicate cells
- Documentation: Updated RRC developer documentation with multi-cell
architecture details
Validated with RFsim in re-establishment and handover scenarios.
openair2/COMMON/rrc_messages_types.h has mostly 4G types. The only 5G
(gNB) RRC type is gNB_RrcConfigurationReq, which we can move to a header
in the corresponding directory (where it is used).
This allows to separate 5G gNB RRC module from the 4G types in
rrc_messages_types.h in the next commit.
reversing bits is not NR specific. Think of it like this: LTE code might
use reverse_bits*() as well, but in the old location, it would pull in a
bunch of NR dependencies that are superfluous.
Remove VCD signal dumper from NR code
We don't test VCD in 5G NR code (and haven't tested it in 4G for years).
Remove the VCD traces in 5G code to avoid any ambiguity. 4G code remains
in place, as well as the tools to analyze existing traces.
Move the module cmake code to its subdirectory for better organization,
and remove superfluous include_directories() that are not recommended
to be used (as it populates all other targets with those directories,
most of which don't need it anyway).
Slightly clean up the module by removing headers to unused dependencies.
The GTP module has a dependency to 4G and 5G RLC, which should not exist
(the RLC modules have a dependency on GTP, not the other way around),
but in this commit, make as little modifications as possible.
Compile all targets in Ubuntu build to avoid breakage of software.
Remove ldd in build dockerfile, as we don't need that (can also be
inspected manually).
- Add more sampling rates to support, e.g., 40MHz in 5G
- Allocate memory only at end to avoid memory leaks in case of failure
- Group recurring configuration functionality in configure_channel() to
reduced code duplication and uniform output
- Read maximum TX gain to set maximum automatically, and analogous to
USRP radio lib
- Check if BladeRF config (buffer size, num transfers, ...) fulfills
requirements as specified in documentation [1]
- Set BladeRF logging early to see BladeRF output
[1] https://www.nuand.com/bladeRF-doc/libbladeRF/v2.6.0/group___f_n___s_t_r_e_a_m_i_n_g___a_s_y_n_c.html#ga72752f2a047b95544e7686596a409abd
Co-authored-by: Brice Robert <robert@eurecom.fr>
Closes: #845
Don't enable radios twice, and only do it on device startup. Simplify
that function by using a new BLADERF_CHECK macro that checks return
codes and that will be reused in the following commits.
There is no reason to not allow
./build_oai -I -w USRP -w BLADERF
To install USRP and BladeRF together (which will be used in the CI in a
later commit). Fix this.
In this case, there are a number of linker errors:
/usr/bin/ld: libL2_NR.a(rrc_gNB.c.o): in function `nr_rrc_transfer_protected_rrc_message':
/home/richie/oai/openair2/RRC/NR/rrc_gNB.c:330:(.text+0x6f6): undefined reference to `signal_rrc_msg'
However, nr_srssim does not need RRC, while it is being linked in. Thus,
link without nr_rrc and L2. For the remaining two linker problems:
- provide a definition of NR_IF_Module_init() as in most other
simulators
- move rrc_get_max_nr_csrs() to nr_common.c. It is already declared in
the corresponding header, and itself does not have anything to do with
RRC radio configuration, therefore it does not belong to
nr_radio_config.c
Fix for split 7.2 DU configurations including DU & RU ethernet addresses
Fix parsing of DU configurations that include both RU and DU ethernet
addresses in the fhi_72 section. The extraneous DU addresses are used in
MPlane to configure the RU.
RRC QoS refactor: PDU Session Modify support, SDAP fixes, and code improvements
The goal of this MR is to prepare the RRC/NGAP layer for the multi-QoS
support. The MR:
- enables PDU Session Resource Modify support in RRC/NGAP/E1AP
- fixes SDAP header mapping
- enables SDAP by default
- refactors QoS flow handling in RRC/NGAP
- improves error handling, and code maintainability in RRC/NGAP
Changes:
- NGAP PDU Session Modify:
* add NGAP PDU Session Resource Modify Request/Response handling with
proper error reporting for unrecognized sessions and AMF UE NGAP ID
validation
- E1AP Bearer Context Modification:
* add DRB To Remove List IE to support DRB release during modify
* rename numQosFlow2Setup to numQosFlowsMod in DRB To Modify List
- RRC QoS flow handling:
* enable multi-QoS flow support per DRB
* add utilities to map NGAP QoS parameters to E1AP
* filter QoS flows by DRB ID
- SDAP configuration:
* Fix SDAP header UL/DL mapping between internal representation and
ASN.1 enum (invert mapping)
* change SDAP header fields from long to bool for clarity
- F1 DRB setup refactoring:
* Extract shared helpers for F1 DRB setup list filling
* reduce duplication between E1 response and direct DRB setup paths
- AMBR management:
* Store AMBR in UE context
* validate AMBR is set before bearer setup
- Configuration:
* remove unused drbs configuration parameter
* enable SDAP by default (change default from false to true)
RAN-SA-2x2-Module-CN5G performs tests not only with 2x2 but also with a 4x4 MIMO
configuration. The pipeline name has been generalized to RAN-SA-Multi-Antenna-CN5G
to cover multiple antenna configurations.
Integrate GPU-Accelerated Channel Simulation + CI Test Pipeline
This MR builds on top of MR !3588 (feat: GPU Accelerated Channel
Simulation Pipeline).
The main portion of the changes is directly taken from MR !3588, and
focuses on integrating the GPU-accelerated channel simulation. On top of
that, this MR adds CI-related configurations to introduce a new channel
simulation testing pipeline into the CI --> RAN-Channel-Simulation
This MR introduces a CUDA-based pipeline to offload the
multipath_channel and add_noise channel simulation functions to the GPU.
This enables large-scale, real-time physical layer simulations not
possible on the CPU.
For full documentation, please see the file at openair1/SIMULATION/TOOLS/DOC/gpu_acceleration.md.
System & Compiler Requirements: An NVIDIA GPU with a compatible driver
and the CUDA Toolkit installed.
This feature was developed and tested on the GH200 server using the GCC
12 toolchain. To ensure reproducibility, building with GCC 12 is highly
recommended. Build Instructions
The primary flag to enable this feature is -DCUDA_ENABLE=ON. The
following command shows a sample configuration used during development
on the GH200 server:
./build_oai --phy_simulators --cmake-opt "\
-DCUDA_ENABLE=ON \
-DUSE_UNIFIED_MEMORY=ON \
-DUSE_ATS_MEMORY=OFF \
-DCMAKE_C_COMPILER=/usr/bin/gcc-12 \
-DCMAKE_CXX_COMPILER=/usr/bin/g++-12 \
-DENABLE_TESTS=ON"
Memory Model Configuration
The pipeline supports multiple CUDA memory management modes, which can
be configured at compile time. ATS Memory (-DUSE_ATS_MEMORY=ON) is
enabled by default. To use another memory model, you must first disable
ATS.
For a detailed explanation of these models, please refer to Section 3 of
the gpu_acceleration.md report.
vrtsim: add CIR DB playback with CLI flags
VRTSIM: CIR DB playback via CLI
This change adds an optional in-process CIR DB path to VRTSIM. When
enabled with --vrtsim.cirdb and optional --vrtsim.cirdb-path, VRTSIM
reads precomputed taps from cir_db.bin. Default behavior is unchanged
when the flag is not set.
Build
cmake ../../ -GNinja -DOAI_VRTSIM_CIRDB=ON -DOAI_VRTSIM_TAPS_CLIENT=OFF
cmake --build . --target vrtsim
How to run
gNB
sudo ./nr-softmodem \
-O ./targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf \
--device.name vrtsim \
--vrtsim.role server \
--gNBs.[0].min_rxtxtime 3 \
--vrtsim.cirdb 1 \
--vrtsim.cirdb-path /home/merkeb/oai-cir-emitter/cir_db.bin
UE
sudo ./nr-uesoftmodem \
-C 3619200000 -r 106 --numerology 1 --ssb 516 --band 78 \
--device.name vrtsim
Expected logs
- VRTSIM prints that channel modelling is active and uses DB backed taps
- CIRDB ready: model=..., shape=Tx x Rx, L=..., S=..., fs=..., dt=...,
speed=...
CLI behavior and fallbacks
- TAPS client and chanmod paths are unchanged
- If --vrtsim.cirdb is not set or equals 0, VRTSIM uses the existing
channel model path
Add fallbacks for ARMv8a to make it compile
The current code, on ARM, uses ARMv8.1-A RDM instructions. Add a
fallback for processors that do not have this instruction set.
Add some specific compile options for this platform.
Add debian 12 to the list of architectures.
- Change gNB RRC enable_sdap default to true
- Update RRC and RUNMODEM docs to reflect new default behavior
- Clean up CI gNB configs by removing redundant enable_sdap=1
- Keep explicit SDAP disable config for NFAPI gNB VNF
According to TS 38.413:
* AMBR is conditional to PDU Session Resource to setup in the Initial UE
Context Setup procedure
* The UE Aggregate Maximum Bit Rate IE should be sent to the NG-RAN node
if the AMF has not sent it previously. If it is included in the PDU
SESSION RESOURCE SETUP REQUEST message, the NG-RAN node shall store
it in the UE context
* Range is INTEGER [0..4,000,000,000,000]
To this purpose, changes in the commit:
* Init AMBR to out of range value when creating UE context
* Store AMBR in UE context whenever is received
* Assert if not set at the time of Bearer Setup (should be known at that stage)
Compute ssPBCH_BlockPower from RU max TX power and bandwidth
ssPBCH_BlockPower = P_TX(dBm) − 10 x log10(N_RB x 12)
Assume P_TX = 24 dBm for indoor RUs and 35 dBm for outdoor RUs.
Fix parsing of DU configurations that include both RU and DU ethernet
addresses in the fhi_72 section. The extraneous DU addresses are used
in MPlane to configure the RU.
For now, test in the following configuration:
- 16 parallel channels
- channel length of 32 and 128
- with 61440 and 122880 samples
- 12 trials per each test (due to CUDA kernel loading delay in first iterations)
- multiple MIMO configurations: 2TX - 2/4/8/32 RX, 2/4/8/32 TX - 2RX
Add undocumented Aerial ERROR.indication vendor specific error codes
This MR adds the remaining vendor-specific ERROR.indication error codes
that are undocumented in the Aerial online documentation, but are
present in the cuPHY-CP/scfl2adapter/lib/scf_5g_fapi/scf_5g_fapi.h
header file.
This change stems from the appearance of an undocumented error code
during testing (SCF_ERROR_CODE_L1_MISSING_UL_IQ = 0x44) It aims to ease
the comprehension of the errors thrown by Aerial L1.
Extract common code from `fill_drb_to_be_setup_from_e1_resp` and
`rrc_fill_f1_drb_to_setup` into reusable helper functions to reduce
duplication and improve maintainability. This refactoring enables
multi-QoS flow handling per DRB and prepares helpers for upcoming
PDU Session Modify changes.
Impact:
- Enables multi-QoS flow support: `rrc_fill_f1_drb_to_setup` now
collects all QFIs mapped to a DRB instead of only the first one
- Reduces code duplication between E1 response and direct DRB setup
code paths
- Improves maintainability by centralizing F1 DRB setup logic
Major changes:
- Add `fill_f1_drb_info_nr`: fills DRB information IE including QoS
flows from QFI list
- Add `fill_f1_drb_to_be_setup`: creates F1 DRB to setup structure
from RRC DRB, PDU session, and QFI list
- Add `fill_f1_drbs_from_e1`: processes DRBs from E1 response and
extracts QFIs from drb_config->qosFlows
- Refactor `fill_drb_to_be_setup_from_e1_resp` to use
`fill_f1_drbs_from_e1`
- Refactor `rrc_fill_f1_drb_to_setup` to collect all QFIs mapped to
each DRB and use `fill_f1_drb_to_be_setup`
TS 38.413 8.2.3 PDU Session Modify:
> For each PDU session which failed to be modified, the PDU Session Resource Modify
> Unsuccessful Transfer IE shall be included containing the failure cause
> If the NG-RAN node receives a PDU SESSION RESOURCE MODIFY REQUEST message containing
> some PDU Session ID IEs (in the PDU Session Resource Modify Request List IE) that the
> NG-RAN node does not recognize, the NG-RAN node shall report the corresponding invalid
> PDU sessions as failed in the PDU SESSION RESOURCE MODIFY RESPONSE message
> with an appropriate cause value
Changes in the commit:
* add rrc_gNB_ngap_pdusession_mod_failure helper function to handle
abnormal conditions and send NGAP response with (all) failed PDU sessions
* improve error handling: send NGAP response instead of silently returning -1
when UE context lookup fails (unknown RAN UE NGAP ID)
* add AMF UE NGAP ID validation: check stored AMF UE NGAP ID matches request
and send failure response if mismatch (per 3GPP TS 38.413)
* handle unrecognized PDU Session IDs per 3GPP TS 38.413 8.2.3.4: add to
failed list to be sent in the reponse message
* simplify failure path: reuse rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP
instead of manually constructing response message
* remove failed PDU sessions from RRC list in rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP
* remove redundant code and improve code organization
* add bounds checking
* improve function signature
This commit refactors the rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP function
to improve code clarity, fix bugs, and ensure compliance with 3GPP TS 38.413
section 9.2.1.6.
The main improvement is ensuring the PDU Session Resource Modify Response message
is always sent with mandatory IEs, even when there are no PDU sessions to report
in the optional lists.
Key changes:
- Initialize message structure parameters to 0 by leveraging structure
initialization, ensuring clean state
- Replace local counter variables (pdu_sessions_done, pdu_sessions_failed)
with direct access to resp->nb_of_pdusessions and resp->nb_of_pdusessions_failed,
eliminating redundant state tracking and improving code clarity
- Remove conditional message sending: always send the response message
(per 3GPP TS 38.413 9.2.1.6, PDUSessionResourceModifyResponse must always
be sent with mandatory IEs: AMF-UE-NGAP-ID and RAN-UE-NGAP-ID, even when
optional lists are empty)
- Fix duplicate assignment: remove redundant p->pdusession_id assignment
(was assigned twice in the PDU_SESSION_STATUS_DONE case)
- Improve failed PDU session handling: use direct structure assignment
(failed->cause = session->cause) instead of field-by-field copying,
making the code more maintainable
- Remove failed PDU session upon response
- Enhance logging: improve log messages for better debugging and clarity
- Add function documentation comment
Introduce fill_e1_qos_flow_to_setup to translate pdusession_level_qos_parameter_t (NGAP)
into qos_flow_to_setup_t (E1), including ARP and QoS characteristics (dynamic/non-dynamic).
Refactor fill_e1_drb_to_setup to use the new helper for building QoS flows.
* Only include QoS flows whose drb_id matches the target DRB.
* Add DevAssert(drb_ngran.numQosFlow2Setup > 0) to ensure at least one QoS flow is added.
This change centralizes and simplifies QoS mapping logic between NGAP inputs
and E1 DRB configuration. It ensures correctness by associating QoS flows
to the appropriate DRB.
Major changes:
- Extract QoS flow mapping logic into fill_e1_qos_flow_to_setup helper function
- Filter QoS flows by matching drb_id before adding to DRB setup list
- Replace inline mapping code with helper function call
- Add assertion to verify at least one QoS flow is added per DRB
This commit fixes two related issues:
1. SDAP Header Mapping Bug (cucp_cuup_handler.c):
The original code incorrectly mapped SDAP header configuration from
internal E1AP representation to ASN.1 enum values. The internal
representation (`bearer_context_sdap_config_t`) uses true=present/false=absent,
while ASN.1 enum (`E1AP_SDAP_Configuration_t`) uses
0=present/1=absent. The fix correctly inverts the mapping:
- Internal true (1) → ASN.1 0 (present)
- Internal false (0) → ASN.1 1 (absent)
The commit also clarifies internal representation in the stack.
2. Test Overhead Adjustment (nr-cuup-load-test.c):
The change in (1) led to a failure in nr_cuup_functional_test
with assertion: "size % 4 == 0" in recv_ng()
- Changed UL packet overhead from 3 bytes to 2 bytes in sender_thread()
- Before the SDAP fix, the test incorrectly accounted for 3 bytes:
* 2 bytes PDCP header (correct)
* 1 byte SDAP header (incorrectly included)
- After the SDAP fix, SDAP headers are correctly set to absent, so
only 2 bytes (PDCP header) are needed
This ensures the test sends packets with the correct header size,
matching what CU-UP expects after the SDAP configuration fix.
The load test does not enable SDAP headers, therefore the original 3-byte
overhead was possibly a workaround for the SDAP header bug.
With the bug fixed, the test correctly uses 2-byte overhead (PDCP header).
This commit refactors the PDU Session Resource Modify Response message
structures to improve naming, documentation, and compliance with 3GPP TS 38.413 9.2.1.6.
Changes in NGAP:
- Rename qos_flow_tobe_modified_t to qos_flow_addmod_response_item_t to better
reflect its purpose as a QoS Flow Add or Modify Response Item IE (as per specs)
- Add mandatory AMF UE NGAP ID field to ngap_pdusession_modify_resp_t structure
- Optimize field types: change nb_of_pdusessions and nb_of_pdusessions_failed
from uint16_t to uint8_t (NGAP_MAX_PDU_SESSION limit) (ref 3GPP TS 38.413, 9.2.1.6)
- Update PDU Session Modify Response encoder to use amf_ue_ngap_id from the
message structure (pdusession_modify_resp_p->amf_ue_ngap_id) instead of
retrieving it from UE context (ue_context_p->amf_ue_ngap_id)
- Add comprehensive comments with 3GPP TS 38.413 section references throughout
Changes in RRC/NGAP:
- Populate amf_ue_ngap_id field in PDU Session Modify Response message from
UE context
- Update type reference to qos_flow_addmod_response_item_t
A DRB To Modify Item contains a Flow Mapping Information,
which overrides previous mapping information. For consistency,
rename the count member to reflect a QoS Flow modification,
since it is not limited to setup only.
- Rename DRB flow mapping counters to `numQosFlowsMod`
for a DRB To Modify List
- Adjust encode/decode/equality + E1AP tests
Add DRB To Remove List IE to PDU Session To Modify list, which is sent
in the Bearer Context Modification request. This allows the CUCP to
inform the CUUP about DRBs to be released in a specific PDU session
during a MODIFY procedure.
Changes:
* Add struct definition
* Add enc/dec/eq/cp func
* Add test
- Delete drbs field from gNB_RrcConfigurationReq and its use in RCconfig_NRRRC()
- Remove GNB_CONFIG_STRING_DRBS, help text, index, and GNBPARAMS_CHECK entry from gnb_paramdef.h
- Drop DU-side verification and DRB count logging in gnb_config.c
This commit introduces a new, configurable benchmark,
`test_channel_scalability`, designed to measure the performance and
scalability of the CUDA channel simulation pipeline under various
conditions.
This benchmark provides several key features:
- It supports multiple GPU execution models, including a high-throughput
"batch" mode, an asynchronous "stream" mode, and a "serial" mode for
baseline measurements.
- It includes an optional interference simulation mode, activated by the
`--sum-outputs` flag, which sums the outputs of multiple parallel
channels.
- Simulation parameters (MIMO configuration, signal length,
channel length, and batch size) are configurable via command-line
arguments.
- It runs the full simulation pipeline on both the CPU and the GPU,
reporting the average execution time for each and calculating the
overall speedup.
This commit extends the CUDA API with new functions designed for
high-throughput scalability testing and advanced concurrency.
Key additions include:
- Batched versions of the kernels (`..._batched`) that use the
`blockIdx.z` grid dimension to process many independent channel
simulations in parallel.
- A C-callable wrapper, `run_channel_pipeline_cuda_batched`, to
orchestrate the execution of these new kernels.
- A "streamed" version of the pipeline,
`run_channel_pipeline_cuda_streamed`, which accepts a
`cudaStream_t` as an argument. This allows the calling
application to manage the execution stream, enabling overlap
with other GPU or CPU tasks.
This commit adds a performance benchmark for the end-to-end channel simulation pipeline, named `test_channel_simulation`. Its methodology is as follows:
- It systematically iterates through a matrix of test cases, varying
MIMO configuration (Tx/Rx antennas), signal length, and channel
length.
- For each case, it runs both the full CPU pipeline (`multipath_channel_float`
followed by `add_noise_float`) and the single `run_channel_pipeline_cuda`
function.
- It measures the average execution time for both implementations over
many trials and calculates the resulting speedup.
This provides a performance characterization of the GPU pipeline across different workloads and directly compares it to the CPU baseline.
This commit introduces the main C-callable pipeline function,
`run_channel_pipeline_cuda`, located in a new `channel_pipeline.cu`
file.
This function serves as the primary entry point for the GPU channel
simulation. It orchestrates the entire sequence of operations:
- Manages Host-to-Device data transfers for the input signal and
channel coefficients.
- Launches the `multipath_channel_kernel` and the
`add_noise_and_phase_noise_kernel` in the correct order.
- Manages the Device-to-Host data transfer for the final output signal.
- Synchronizes to ensure completion before returning.
This commit adds a new standalone benchmark, `test_noise`, to measure
and compare the performance of the CPU and CUDA implementations of noise
generation.
The benchmark's methodology is as follows:
- It iterates through various configurations, including different
numbers of receive antennas and signal lengths.
- For each configuration, it runs both the CPU (`add_noise_float`)
and CUDA (`add_noise_cuda`) functions multiple times to get a stable
average execution time.
- It prints a formatted table comparing the CPU and GPU latencies and
calculates the resulting speedup.
This commit adds the CUDA implementation for adding Additive White
Gaussian Noise (AWGN) and phase noise to the signal. The code is
located in phase_noise.cu.
- The `add_noise_and_phase_noise_kernel` uses the NVIDIA cuRAND
library for efficient parallel random number generation.
- Helper functions are included to create, initialize, and destroy
the cuRAND states required by the kernel.
- Placeholder for a C-callable wrapper, `add_noise_cuda`, is also
provided.
This commit adds a new standalone unit test, `test_multipath`, to
validate the CUDA implementation of the multipath channel.
The test performs the following steps:
- Generates a random input signal and channel model.
- Runs the CPU version (`multipath_channel_float`) to get a baseline result.
- Runs the CUDA version (`multipath_channel_cuda`) with the same inputs.
- Compares the two outputs by calculating the Mean Squared Error (MSE)
and ensures it is below a small tolerance.
This commit introduces the CUDA implementation of the multipath channel
model in `multipath_channel.cu`.
- Implements `multipath_channel_kernel` using shared memory for
efficient, high-performance convolution.
- Provides a C-callable wrapper, `multipath_channel_cuda`, to
orchestrate the full pipeline of data transfers and kernel
launches.
- The wrapper includes support for multiple memory models (Explicit
Copy, Unified Memory, ATS) via preprocessor directives to adapt to
different build configurations.
- Adds a `interleave_channel_output_cuda` utility to convert signal
data from the CPU's planar format to the GPU's interleaved format.
This commit refactors the CPU-based channel model for improved reusability and extends it with single-precision floating-point support.
This serves as a performance and correctness baseline for the new CUDA implementation.
Key changes include:
- The original double-based multipath_channel function is refactored to remove hardcoded antenna dimensions from its signature. It now accepts dynamically sized arrays, making it more flexible for use in simulators like dlsim and ulsim.
- A new multipath_channel_float function is introduced to operate on float data types, matching the GPU's native format.
- A corresponding add_noise_float function is also added to complete the floating-point CPU pipeline.
- The new float-based functions are designed to work with an interleaved IQ sample format ([I, Q, I, Q]), which is more suitable for vectorized (SSE) and GPU processing.
This commit adds the initial infrastructure for building accelerated simulation components.
- Adds the CUDA_ENABLE option and logic to find the CUDA toolkit.
- Adds the CHANNEL_SSE option to enable SSE-specific code paths.
- Sets required properties on the SIMU target to allow linking with CUDA-compiled objects.
- Creates the initial oai_cuda.h header for the public API.
- By default, eNB_CommitID is set as 'develop' in the config
- When OAI-FLEXRIC-RAN-Integration-Test is triggered by upstream FlexRIC push events, it takes `develop`
- Triggered by RAN takes commit SHA where `origin/SHA` does not work
Integration `2026.w06`
* !3690 [FHI72] Support large DU delay profiles in the xran F, and include ProtO-RU emulator designed to run 7.2 with an USRP
* !3887 Update RHEL UBI image source to `registry.redhat.io`
* !3882 Change Aerial to pack directly in nvIPC message buffer
* !3895 CI: Ensure OAI-FLEXRIC-RAN-Integration-Test pipeline always uses latest commit for non-MR builds
* !3873 Ensure noise power is non-zero
* !3889 Enable imscope for split7.2
* !3801 Resolve "7.2 split ru_thread slot miss
* !3898 Fix config_libconfig_get for string
* !3876 Removing the duplicate loop in ULSCH power computation
Closes#972
See merge request oai/openairinterface5g!3888
Removing the duplicate loop in ULSCH power computation
- Removing the duplicate loop in ULSCH power computation.
- The logs obtained are as follows:
[NR_MAC] UE dc65: 134.11 Generating RA-Msg2 DCI, RA RNTI 0x113, state 1, preamble_index(RAPID) 42, timing_offset = 5 (estimated distance 195.3 [m])
[PHY] PUSCH not detected in 134.17 (307,302,50)
[PHY] PUSCH not detected in 134.17 (311,309,50)
[NR_MAC] 135 4: RA RNTI 41c5 CC_id 0 Scheduling retransmission of Msg3 in (135,8)
[NR_MAC] 135 4: RA RNTI a3cc CC_id 0 Scheduling retransmission of Msg3 in (135,8)
[PHY] PUSCH not detected in 134.18 (310,312,50)
[NR_MAC] 135 5: RA RNTI dc65 CC_id 0 Scheduling retransmission of Msg3 in (135,9)
[PHY] PUSCH not detected in 135.8 (309,309,50)
[PHY] PUSCH not detected in 135.8 (313,308,50)
[NR_MAC] 13515: RA RNTI 41c5 CC_id 0 Scheduling retransmission of Msg3 in (135,19)
[NR_MAC] 13515: RA RNTI a3cc CC_id 0 Scheduling retransmission of Msg3 in (135,19)
[PHY] PUSCH not detected in 135.9 (308,300,50)
[NR_MAC] 136 4: RA RNTI dc65 CC_id 0 Scheduling retransmission of Msg3 in (136,8)
[NR_PHY] [RAPROC] 135.19 Initiating RA procedure with preamble 6, energy 19.1 dB (I0 63, thres 120), delay 4 start symbol 0 freq index 0
[PHY] PUSCH not detected in 135.19 (310,310,50)
[PHY] PUSCH not detected in 135.19 (312,310,50)
[NR_MAC] 135.19 UE RA-RNTI 010b TC-RNTI 0888: initiating RA procedure
[NR_MAC] UE 0888: Sync beam index 0
[NR_MAC] UE 0888: Msg3 scheduled at 136.17 (136.10 TDA 2) start 0 RBs 8
[NR_MAC] UE 0888: 136.10 Generating RA-Msg2 DCI, RA RNTI 0x10b, state 1, preamble_index(RAPID) 6, timing_offset = 4 (estimated distance 156.3 [m])
- For the same scenario, develop branch gives exactly the same result. When
there is no PUSCH, the power measured for ULSCH and noise are practically
the same. Furthermore, the value in develop branch is also approximately
310 for the same noise level.
Expand RRC developer and usage documentation to match the current
multi-cell design with separate DU and cell management.
- rrc-dev.md: Document DU and cell data structures and key functions
(get_du_by_assoc_id, get_cell_by_cell_id, rrc_add_cell_to_du, etc.);
add DU and cell lifecycle (F1 Setup, config update, disconnection)
and UE cell association (serving cells, PCell/SCells) with sequence
diagrams; add handover and cell association update flow; update UE
context description.
- rrc-usage.md: Update DU/cell list output format and description
(e.g. integrated DU-CU) and multi-cell per DU wording.
This commit adds documentation comments and logging to improve
code readability and debugging capabilities for the multi-cell
architecture.
Changes:
- gnb_config.c: Add logging when configuring DU with cell ID and PCI
- rrc_gNB_du.c: Add documentation comment for ssb_arfcn_mtc()
- rrc_gNB_du.c: Add documentation comment for dump_du_info()
After introduction of new cell management design, these helper functions
are now only used internally within their respective modules and do not
need to be part of the public API. They are made static and their
declarations are removed from public headers.
Changes:
- f1ap_interface_management.c: Make free_f1ap_cell() and
copy_f1ap_served_cell_info() static
- f1ap_interface_management.h: Remove declarations for the above functions
- rrc_gNB_du.c: Make get_dl_band() and get_ssb_scs() static
- rrc_gNB_du.h: Remove declarations for get_dl_band() and get_ssb_scs()
Remove the single-cell limit in F1 Setup Request processing and
refactor to loop-based cell handling. Move cell validation (PLMN
check, neighbor configuration validation, system info extraction),
cell creation, SIB encoding, and neighbor labeling inside a loop
over all available cells.
Update F1 Setup Response to include all cells instead of hardcoding to 1.
Add warning log when more than one cell is received. Add proper
cleanup with free_f1ap_setup_response() on error paths.
Impact:
- F1 Setup now accepts and processes multiple cells from a single
DU, enabling multi-cell deployments
- All cells are validated, created, and included in the setup
response
Add xran_queue_length atomic variable to count the number of messages in
oran_sync_fifo (as notifiedFIFO_t does not do this). Use this to
tolerate some double messages (e.g. excessive processing delay), but
start to skip if messages accumulate.
Prior to this change, "Detected double sync message" was printed each
time there was more than one message, which reflected the previous
behavior when using polling, but the gNB might catch up if it is only
once. The new logic ensure that we don't skip individual slots but do so
once messages start to accumulate.
Finalize the migration from single-cell-per-DU to the multi-cell
architecture: remove legacy DU/cell fields and refactor RRC procedures
to use cell containers and UE serving cells instead of DU-based lookups.
Data structure changes:
- Remove nr_cellid from gNB_RRC_UE_t; cell identity comes from the UE's
serving_cells (PCell entry via ue_get_pcell_entry(ue)). UE_LOG_ARGS
and LOG_UE_* macros take a PCell entry pointer for null-safe cell_id
in logs; all call sites pass ue_get_pcell_entry(ue).
- Remove setup_req, mib, sib1, mtc from nr_rrc_du_container_t (held in
cell containers); remove nr_cellid from gNB_RRC_INST and its
assignment in gnb_config.c.
Function and signature updates:
- get_ssb_arfcn(): take cell container instead of DU.
- label_intra_frequency_neighbours(): drop du parameter, use cell only.
- Handover: Handover context (source and target) now stores cell
pointers (source->cell, target->cell) instead of DU pointers. When
the context is created (N2: on Handover Request; F1: in
nr_rrc_trigger_f1_ho), the target cell is set in ho_context->target->cell
and, for F1, the source cell in ho_context->source->cell.
nr_initiate_handover() takes only source_cell and reads the target
from ho_ctx->target->cell, so it no longer takes a target parameter.
The target is known at handover creation time, while the UE’s
serving_cells are only updated after F1 UE Context Setup Response.
- nr_rrc_trigger_f1_ho() and the N2 handover path pass cell pointers
and set ho_context->target->cell (and for F1, source->cell) when
the handover is triggered.
Procedure refactoring:
- Lookups: replace get_du_by_cell_id() with get_cell_by_cell_id()/
get_cell_by_pci(); remove get_du_by_cell_id() and
get_cell_information_by_phycellId().
Rationale: cell-specific data (MIB, SIB1, mtc, info) now lives in
cell containers, and a DU can host multiple cells. Callers need the
cell (to use cell->info, cell->mtc, etc.), not the DU. Looking up
by cell_id therefore returns the cell container
(get_cell_by_cell_id()); when the DU is needed, use
cell->assoc_id and get_du_by_assoc_id(). Looking up by PCI is
scoped (e.g. get_cell_by_pci_for_du() for a given DU, or via the
UE’s serving cells) because PCI is not globally unique.
- Setup/Reestablishment: resolve cell, register as PCell via
rrc_add_ue_serving_cell(); reestablishment resolves cell by PCI
(rrc_get_cell_by_pci_for_du), then rrc_remove_ue_scells_from_du +
rrc_add_ue_serving_cell; validate_ue_cell_association() after update.
- Measurement config: use cell->info (SCS/band) and cell->mtc.
- Handover: use cell containers end-to-end; after UE context
modification response call nr_rrc_update_cell_assoc_after_ho().
- NGAP: cell_id and TAC from UE PCell via rrc_get_pcell_for_ue();
Handover Notify: get cell for message content, use get_du_for_ue() for
DU existence check; paging resolves UE by 5G-S-TMSI-Part1 and uses that
UE's PCell (rrc_get_pcell_for_ue) for F1AP_PAGING_IND nr_cellid.
Performance and robustness:
- Use rrc_get_pcell_for_ue() when cell data is needed; use
get_du_for_ue() when only the DU is needed (F1/N2 HO trigger,
Handover Notify DU check) for efficiency.
- Reestablishment: remove old PCell before adding new; error handling
for PCell add and validation.
Code cleanup:
- F1 setup: stop copying/storing setup request in DU container; F1
disconnect only frees cell containers via rrc_free_cell_container().
- dump_du_info(): iterate du->cells and show all cells per DU.
- telnetsrv_ci.c: use du->gNB_DU_id directly and fix format (%ld).
- UeContextSetupRequest servCellIndex set to RRC_PCELL_INDEX; remove
servCellIndex from F1AP UE context modification request.
In rrc_gNB_NGAP.c, rrc_gNB_process_Handover_Request() is updated to
resolve the target by cell instead of by DU, then resolve the DU from
the cell's assoc_id. This aligns Handover Request with the new
cell-centric model and cell management APIs.
- Resolve target with get_cell_by_cell_id(&rrc->cells, msg->nr_cell_id)
instead of get_du_by_cell_id(); on failure, log "no cell found" and
send NGAP handover failure.
- Resolve DU with get_du_by_assoc_id(rrc, cell->assoc_id); add a
failure path (log, NGAP handover failure, return -1) when no DU
exists for the cell's assoc_id.
- Use cell->info (nr_rrc_cell_info_t) for logging and for key
derivation (nr_derive_key_ng_ran_star); use du->assoc_id
for UE context creation instead of du->setup_req->cell[0].info.
get_ssb_arfcn(du) is unchanged and still takes the DU; other DU-based
lookups are kept where still required.
Migrate F1 DU configuration update procedures in openair2/RRC/NR/rrc_gNB_du.c
to use the cell management API instead of accessing cell data through
setup_req, completing the transition to the new multi-cell architecture.
1. update_cell_info:
- Refactored to use cell management API: takes RRC instance, old cell_id,
and new cell info; finds cell via get_cell_by_cell_id() internally.
- Returns cell container pointer (or NULL on failure) instead of void.
- When cell_id changes: removes cell from RB tree (old key), updates via
cp_f1_served_cell_info_to_cell(), re-inserts (new key); validates no
duplicate cell_id/PCI before allowing change.
- Frees old MTC when new measurement timing config is present.
- Encapsulates cell lookup and update logic.
2. rrc_gNB_process_f1_du_configuration_update:
- Uses update_cell_info() for cell modify; validates cell belongs to DU
(assoc_id) after update.
- Duplicate checking via get_cell_by_cell_id() and
rrc_get_cell_by_pci_for_du()
- For cells to add: validates duplicate cell_id globally and duplicate
PCI within DU; rejects with logging.
- MIB/SIB1 updated in cell container (cell->mib, cell->sib1); uses
du->gNB_DU_id; passes cell to label_intra_frequency_neighbours();
removes direct setup_req->cell[0] access.
Backward compatibility: setup_req remains until migration is completed;
cell-specific data is managed in the cell container and accessed via
the cell management API. Improves separation of concerns and enables
proper multi-cell support.
Refactor F1 setup processing to create and manage cell containers during DU
initialization, establishing the foundation for multi-cell architecture where
cells are managed independently from DUs.
Why: Cell information is currently tied to F1AP structures (f1ap_served_cell_info_t),
which complicates multi-cell support. Introducing cell containers at F1 setup
decouples RRC cell management from F1AP and allows cells to be managed
independently while keeping existing code paths working.
Key changes:
1. Cell container creation (cp_f1_served_cell_info_to_cell):
New helper copying F1AP served cell info into nr_rrc_cell_container_t (cell_id,
pci, plmn, tac, TDD/FDD frequency info). Extracts and stores MTC in the cell.
2. Function signature updates:
get_cell_neighbour_list() and label_intra_frequency_neighbours() now take
nr_rrc_cell_container_t* and use cell->info; improved logging (cell_id, PCI,
SSB ARFCN).
3. valid_du_in_neighbour_configs:
Removed ssb_arfcn parameter; MTC is extracted and freed inside the function.
4. F1 Setup (rrc_gNB_process_f1_setup_req):
Initialize DU cell tree (RB_INIT(&du->cells)). Populate DU-only fields
(gNB_DU_id, gNB_DU_name, rrc_ver).
Flow:
- create cell with cp_f1_served_cell_info_to_cell
- add to global tree via rrc_add_cell()
- add DU via rrc_add_du()
- attach cell to DU with rrc_add_cell_to_du().
Store MIB/SIB1/MTC in cell.
Use cell container for neighbour labeling and SIB encoding.
5. Duplicate cell detection:
Use rrc_add_cell() for global cell tree insert; collision return indicates
duplicate cell_id. Clearer error messages for Cell ID vs PCI conflicts.
Use F1AP_CauseRadioNetwork_cell_not_available for cell conflicts.
6. DU configuration update:
Use get_cell_by_cell_id() to find cell, check assoc_id, pass cell container
to label_intra_frequency_neighbours().
7. DU disconnection:
Use rrc_cleanup_du() to remove cells from global tree and free resources;
logging uses DU fields (gNB_DU_id, gNB_DU_name).
8. Global cell tree:
Initialize rrc->cells in openair_rrc_gNB_configuration().
Backward compatibility: setup_req still built via cp_f1ap_setup_request();
du->mib, du->sib1, du->mtc remain set (shared with cell container).
Add integration tests for RRC cell and DU management and UE serving-cell
logic so that multi-cell behaviour and regressions can be validated
without running the full stack.
* test_du_lookup() – DU container lookup by assoc_id:
- Multiple DU creation and insertion into RRC DU tree
- Lookup of existing DUs by assoc_id
- Non-existing and invalid assoc_ids
- Cleanup of DU containers and cells
* test_cell_lookup() – Cell management and UE association:
- Cell lookup by cell_id and PCI (global and per-DU)
- DU-specific lookup: rrc_get_cell_for_du(), rrc_get_cell_by_pci_for_du()
- Duplicate cell and PCI collision handling (including PCI reuse across
DUs and rejection of duplicate PCI within same DU)
- Cell–DU association (add/remove cells from DU containers)
- UE serving cell: add PCell/SCells, get by ID, get PCell, max serving
cells limit, single PCell enforcement
- validate_ue_cell_association(), rrc_remove_ue_scells_from_du()
- Edge cases and error handling
Add openair2/RRC/NR/tests/rrc_cell_management_test.c and extend
openair2/RRC/NR/tests/CMakeLists.txt to build and register the test.
Add functions to manage UE serving cells so the RRC can track which cells
a UE is using (PCell and SCells) for multi-cell UE context and future
SCell management.
- rrc_cell_management.c / rrc_cell_management.h:
* rrc_get_ue_serving_cell_by_id(): return serving cell by servCellIndex
(O(k) linear search, k ≤ 32).
* rrc_add_ue_serving_cell(ue, cell, serving_cell_id): add entry to UE
serving_cells with validation: reject duplicate servCellIndex with
different nci, enforce max 32 serving cells (TS 38.331), keep PCell
at index 0 for O(1) access; return existing entry if same
servCellIndex and nci.
* rrc_remove_ue_scells_from_du(ue, assoc_id): remove all serving cells
for the given DU (handover/DU disconnect); use stored assoc_id for
O(k) comparison.
* ue_get_pcell_entry(): return PCell entry (first element, O(1)).
* rrc_get_pcell_for_ue(): return PCell container from cell tree using
UE's PCell entry.
* Header: RRC_PCELL_INDEX (0), RRC_MAX_NUM_SERVING_CELLS (32), and
declarations for the above.
- UE context lifecycle:
* rrc_gNB_create_ue_context(): seq_arr_init(serving_cells).
* rrc_delete_ue_data(): seq_arr_free(serving_cells).
Move DU tree management from rrc_gNB_du.c into rrc_cell_management so that
DU and cell lookup logic live in one place, improving maintainability and
testability (there is no DU lib).
- rrc_cell_management: add du_compare(), RB_GENERATE(rrc_du_tree),
get_du_by_assoc_id(), rrc_add_du(), rrc_rm_du(), rrc_cleanup_du(),
rrc_free_du_container(); declare them in rrc_cell_management.h.
- rrc_gNB_du: move du_compare(), RB_GENERATE, get_du_by_assoc_id()
to rrc_cell_management
This commit introduces a new library module (rrc_cell_management.c/h)
to centralise functions that provides cell lookup, DU-specific cell
management, and cell lifecycle managements.
The design uses a dual-tree architecture:
- Global cell tree: RB-tree at RRC level (rrc->cells) keyed by cell_id,
used for O(log N_CELL) lookups and for maintaining num_cells.
- DU-specific storage: seq_arr_t per DU (du->cells) for iteration and
management of cells belonging to each DU.
API added:
- Global tree: get_cell_by_cell_id()(finds cell using global RB-tree
lookup (O(log N_CELL) complexity); rrc_add_cell(); rrc_rm_cell()
(rrc_rm_cell removes from tree, decrements num_cells, and frees the
cell via rrc_free_cell_container).
- DU-local seq_arr: rrc_get_cell_for_du(), rrc_get_cell_by_pci_for_du(),
rrc_add_cell_to_du() (with duplicate cell_id/PCI checks).
- Cleanup: rrc_free_cell_container() (frees ASN.1 MIB/SIB1/MTC and
container
Build: add rrc_cell_management static library in openair2/RRC/NR;
link it into nr_rrc from top-level CMakeLists.txt.
Add foundational data structures in nr_rrc_defs.h for multi-cell handling
in RRC, separating DU management from cell management.
Design uses a global cell tree for O(log N) lookups while keeping cell
ownership in DUs for locality and maintenance.
The implementation maintains backward compatibility and follows the same
patterns as existing DU and CUUP management in the codebase, i.e. RB-trees
with logarithmic complexity for scalable multi-cell deployments.
- Cell container structures:
* nr_rrc_cell_container_t: cell-specific data (cell_id, pci, plmn, tac,
frequency info, mib, sib1, mtc)
* nr_rrc_cell_info_t: TDD/FDD modes; frequency structs nr_rrc_freq_info_t,
nr_rrc_tdd_info_t, nr_rrc_fdd_info_t
- UE serving cell tracking:
* ue_serving_cell_t: nci, serving_cell_id (ServCellIndex TS 38.331,
0=PCell, 1-31=SCell), assoc_id for fast DU lookup
* gNB_RRC_UE_t: seq_arr_t serving_cells, with PCell always being the
first in the sequence
- DU container refactoring:
* nr_rrc_du_container_t: DU-only fields (gNB_DU_id, gNB_DU_name, rrc_ver);
seq_arr_t cells for per-DU iteration; setup_req/mib/sib1/mtc kept for
backward compatibility
- Global cell tree:
* gNB_RRC_INST_s: RB_HEAD(rrc_cell_tree, nr_rrc_cell_container_t) cells,
num_cells (data only; lookup helpers get_cell_by_cell_id/get_cell_by_pci
to be added separately)
Neighbour lists are built per serving cell in fill_neighbour_cell_configuration.
Each neighbour in a list is identified by PCI; having two entries with the same
PCI in one cell's list would be ambiguous and indicate a configuration error.
This commit adds validation so that duplicate PCIs within a cell's neighbour
list are detected at configuration load time and cause a fatal assertion with
a clear error message.
Changes:
- Add eq_neighbour_pci() and get_neighbour_by_pci() using
common/utils/alg/find.h to look up a neighbour by PCI in a seq_arr.
- In fill_neighbour_cell_configuration(), before appending each
cell's neighbour list, iterate over neighbours and assert that no PCI
appears more than once
Replace generic UE event log with explicit INFO log including UE ID and RNTI
when removing a UE context and centralize access to UE fields via a local
pointer.
rrc_delete_ue_data removes the all the list in the UE context, including the
serving cells, and therefore the cell id should not be logged in the function
responsible for the removal of the UE context, which at this point is already
emptied and while the cells themselves are still there (in the DU/global cell
structures), the lists in the UE context are empty.
Ensure noise power is non-zero
Prior to this commit, noise power estimation could be zero because of a
call to clearArray() in gNB_I0_measurements(). This is problematic, as
this can lead to a noise power of 0 if all symbols in a RB are used,
which in turn leads to a spike in SNR.
To avoid this, use an intermediate array to store noise power, and only
update n0_subband_power if not all RBs are used (i.e., we can detect
noise power). Further, use an exponential moving average to smoothen
noise estimation.
Fixes: fb4235fd ("changes in PUCCH0 SNR measurement, testing for
PUCCH power control")
Prior to this commit, noise power estimation could be zero because of a
call to clearArray() in gNB_I0_measurements(). This is problematic, as
this can lead to a noise power of 0 if all symbols in a RB are used,
which in turn leads to a spike in SNR.
To avoid this, use an intermediate array to store noise power, and only
update n0_subband_power if not all RBs are used (i.e., we can detect
noise power). Further, use an exponential moving average to smoothen
noise estimation.
Fixes: fb4235fd50 ("changes in PUCCH0 SNR measurement, testing for
PUCCH power control")
CI: Ensure OAI-FLEXRIC-RAN-Integration-Test pipeline always uses latest commit for non-MR builds
Related MR -> mosaic5g/flexric!77
For push events, we have:
sh "git fetch"
sh "git checkout -f ${commitID}"
We need to do a reset hard so that the run is executed on synchronized
develop branch.
In the pipeline, we see:
17:38:34 + git checkout -f develop
17:38:34 Previous HEAD position was 9cb79027e4 Merge branch 'integration_2026_w05' into 'develop'
17:38:34 Switched to branch 'develop'
17:38:34 Your branch is behind 'origin/develop' by 526 commits, and can be fast-forwarded.
17:38:34 (use "git pull" to update your local branch)
After implementing the fix:
Below are the runs for pipeline triggered by a merge request event:
https://jenkins-oai.eurecom.fr/job/OAI-FLEXRIC/229/https://jenkins-oai.eurecom.fr/job/OAI-FLEXRIC-RAN-Integration-Test/3788/
In the OAI-FLEXRIC-RAN-Integration-Test pipeline, which is executed by
Build with Parameters from OAI-FLEXRIC
We see the pipeline took the latest develop:
11:26:02 + git reset --hard origin/develop
11:26:02 HEAD is now at 9cb79027e4 Merge branch 'integration_2026_w05' into 'develop'
Change Aerial to pack directly in nvIPC message buffer
This MR changes the Aerial pack/send procedures to pack the messages
directly into the nvIPC message buffers.
This saves the use of some memcopy calls, as well as clean up the code.
The P7 message packing/send is now only handled in the file
`fapi_nv_p7.c`
Add 3 functions in fapi_nvIPC.c to allow message allocation, release and
send from fapi_vnf_p7.c
Add 2 functions to access the memory pool sizes allocated from nvIPC, as
we can't use sizeof to report the buffer size to the packing functions
Remove now unused aerial_send_P5_msg , aerial_send_P7_msg and
aerial_send_P7_msg_with_data functions
Now Aerial only has one function to handle sending P5 and another to
send P7 messages
Remove fapi_phy_api_msg from fapi_nvIPC.h as it is duplicated in
nr_fapi.h
Update RHEL UBI image source to registry.redhat.io
This merge request updates the RHEL UBI base image source to registry.redhat.io,
aligning with Red Hat’s supported container registry and avoiding potential
access or availability issues with registry.access.redhat.com.
[FHI72] Support large DU delay profiles in the xran F, and include ProtO-RU
emulator designed to run 7.2 with an USRP
This MR does the following:
- we patch xRAN to support large DU delay profiles (i.e., T1a/Ta4 values larger
than a TTI)
- we update the FHI72 docs to introduce ProtO-RU, a software implementation of a
Split-7.2 O-RU with large delay profile
- we provide an example configuration for ProtO-RU
Details on the xRAN patch:
In xRAN, it appears that T1a/Ta4 values are assumed to be within a TTI. When
T1a/Ta4 values larger than a TTI are used, this causes two issues:
(1) C-plane packets to be generated later than expected, and
(2) oai_xran_fh_rx_callback() receives the wrong timing information, resulting
in potentially empty/stale PUSCH/PRACH data to be read.
In the xRAN patch, we modify xRAN to make it handle large T1a/Ta4 values properly.
The changes include:
(1) three additional variables in offset_num_slots_* (xran_dev.h),
(2) modify "xran_timing_create_cbs" and "xran_timer_arm_for_deadline"
(xran_cb_proc.c), and
(3) revise "tx_cp_dl_cb" and "tx_cp_ul_cb" (xran_main.c).
Additionally, we add additional guard conditions to prevent xran_tx_proc.c from
sending U-plane packets when it is not a downlink slot.
* Commit applies to Setup Request, CU/DU Configuration Update
* Set standard compliant max number of cells per DU
* Allocate large lists on the heap to prevent stack overflow
due to the large size
* Update relevant free functions
* Also, fix bug in eq_f1ap_cu_configuration_update
Also, improve comments in struct definition.
* 5G-S-TMSI construction is defined in 3GPP TS 23.003 and
relevant at both gNB and UE side
* Add helper functions to be later used in NG Paging
* Adopt in NAS UE
In xRAN, it appears that T1a/Ta4 values are assumed to be within a TTI.
When T1a/Ta4 values with larger than a TTI are used, this causes two issues: (1) C-plane packets to be generated later than expected and (2) oai_xran_fh_rx_callback() receives the wrong timing information resulting in potentially empty/stale PUSCH/PRACH data to be read.
In this patch, we modify xRAN to make it handle large T1a/Ta4 values properly.
The changes include: (1) three additional variables in offset_num_slots_* (xran_dev.h), (2) modify "xran_timing_create_cbs" and "xran_timer_arm_for_deadline" (xran_cb_proc.c), and (3) revise "tx_cp_dl_cb" and "tx_cp_ul_cb" (xran_main.c).
Additionally, we add additional guard conditions to prevent xran_tx_proc.c from sending U-plane packets when it is not a downlink slot.
Integration `2026.w05`
* !3850 Update vrtsim timing job thread
* !3853 Clear memory in shm_td_iq_channel after RX
* !3823 Fix RSRP overflow
* !3766 UE support to send CSI report on PUSCH
* !3848 Initial implementation of O-RU for 7.2 emulator
* !3860 NGAP: improve error handling in RRCReconfiguration from Handover Command decoding
* !3507 Create Debian and Redhat packages with CPack
* !3875 Fix FFT size for xran_fh_tx_send_slot_BySymbol() and xran_fh_rx_read_slot_BySymbol()
* !3593 NR UE: add support for multiple RF frontends
* !3769 Add Ethernet PDU session support and make PDU session request configurable
* !3831 semi-manual remove of not used #define commands
* Update RFsim4G UE configs for RFsim changes after !3593
* !3821 [FHI72] [xran F] Handle fragmented (un)compressed packets
* !3732 Implement TS 38.473 transparency for CellGroupConfig forwarding and handle re-establishment on a different DU
* !3880 Prevent the PNF from sending P7 messages after sending a STOP.indication
* !3868 CI: Upgrade Aerial pipeline to 25-3
* Revert one CI XML change after !3732Closes#1045, #837, and #1043
See merge request oai/openairinterface5g!3877
The CI test proved not as stable as expected (because the UE triggers A3
events which we don't want), so revert this functionality while we work
on a new pipeline.
This reverts commit bc62e8abca.
Prevent the PNF from sending P7 messages after sending a STOP.indication
Upon stopping the PNF, when sending the STOP.indication to the VNF, set
pnf_p7->terminate to 1.
Add a check on the PNF P7 send functions to not send a message after
pnf_p7->terminate is set.
This prevents the PNF from sending SLOT.indications after stopping,
which sometimes was causing the VNF to process a SLOT.indication after
it had received the indication to STOP.
Also, this MR adds a sanity check on the VNF P7 message handler to
ignore any P7 messages it receives after having it's own terminate flag
set to 1
This MR closes issue #1045
[FHI72] [xran F] Handle fragmented (un)compressed packets
In both E and F, the radio-transport fragmentation is not supported, and
all the "fragmented" (not seen as fragments in the xran, only as
sections) packets contain "E-bit" equal to 1. Per spec, the value 1 for
"E-bit" signifies the last fragment of one symbol. For more info, please
see "ecpriSeqid" section in the spec.
In E:
- nRBStart and nRBSize is updated according to the sent/received packet;
- max sections = 1;
- when a packet is fragmented, the xran uses memcpy(pos, iq_data_start,
size) function, and nothing is stored in start_prbu , num_prbu ,...
In F:
- nRBStart and nRBSize is only used for C-plane messages;
- nPrbElm represents the number of sections for DL only;
- based on the nPrbElm, each section contains UP_nRBStart and UP_nRBSize
parameters which represent the start and number of PRBs in one section
or one fragment;
- when a packet is fragmented, the xran uses nSecDesc and sec_desc to
extract the packet section content, and the data is stored in
start_prbu , num_prbu ,...
Previous work on the fragmentation in F:
- #884
- !3394 - only increases the XRAN_MAX_FRAGMENT from 4 to 6, since it was
only tested with BFP 8, but not end-to-end unfortunately. But this MR
fixes all the issues.
Tested with VVDN RU, 2x2, 16 bits, 100MHz, 30kHz, MTU <= 9216 B, and
Quectel UE RM520N-GL Revision: RM520NGLAAR03A03M4G.
Implement TS 38.473 transparency for CellGroupConfig forwarding and handle re-establishment on a different DU
This MR implements the following fixes that are relevant in RRC
procedures (e.g. re-establishment, reconfiguration):
1. Transparent CellGroupConfig forwarding
This MR implements TS 38.473 transparency requirements by ensuring that
the CellGroupConfig IE is transparently forwarded from the gNB-DU to the
UE without any re-encoding at the gNB-CU. The CU stores and forwards the
encoded bytes transparently, while the DU is responsible for all
encoding and modifications (e.g., reestablishRLC flags). Motivation
Motivation: The 3GPP TS 38.473 specification mandates that the
CellGroupConfig IE shall be transparently signaled to the UE.
Previously, the CU was re-encoding CellGroupConfig depending on the
scenario, instead of retrieving it from the DU, violating the
transparency requirement. CU may decode for internal use but must not
re-encode for forwarding. Solution
Solution: Core Principle: The CU stores the encoded CellGroupConfig
bytes received from the DU and forwards them directly to the UE without
any re-encoding. The DU handles all encoding and modifications.
Key Changes:
1. Transparent Forwarding in RRC Reconfiguration
- Modified build_RRCReconfiguration_IEs() to use pre-encoded bytes
directly
- Changed parameter from cell_group_config to cgc (encoded byte
array with buffer and size)
2. Encoded Bytes Storage
- Added byte_array_t mcg field to RRC UE structure to store encoded
CellGroupConfig
- Added store_cgc() helper function to save encoded cell group in
the RRC UE Context at gNB (from F1AP messages)
3. DU Encoding Responsibilities
- Add gNB-DU Configuration Query IE support to trigger cgc encoding
to request CellGroupConfig from DU
- DU encodes CellGroupConfig with proper reestablishRLC flags
during re-establishment
- DU removes SRB1 from rlc-BearerToAddModList during
re-establishment (SRB1 re-establishment is done before
RRCReconfiguration)
4. New functions
- Add rrc_detect_reestablishment() function to detect
re-establishment during UE Context Modification
- Extracted rrc_gNB_first_reconfiguration_after_reestablishment()
function to handle first reconfiguration after re-establishment
- Added dump_cgc() and dump_mcg() utility functions for debugging
purposes
5. Re-establishment Flow
- rrc_gNB_process_RRCReestablishmentComplete() requests
CellGroupConfig from DU via gNB_DU_Configuration_Query in UE
Context Modification Request
- DU detects re-establishment and add reestablishRLC IEs
- CU stores encoded CGC from the UE Context Modification Response
and forwards it transparently in subsequent RRC Reconfiguration
Testing
Manual Testing:
- RRC re-establishment procedure completes successfully
- RRC Reconfiguration after re-establishment includes all DU-provided information
Issues fixed
Closes issue #837
2. Trigger UE Context Setup fallback upon reestablishment on DU
different from the original one
As per 38.401 §8.7: if the UE accesses a DU different from the original
one during re-establishment, the CU must trigger UE Context Setup toward
the new DU. This refers to steps 9-10 and steps 9’-10’. Either one or
the other can be executed during re-establishment.
e.g. if this happens during handover, it shall trigger a UE Context
Setup fallback on the CU.
This MR implements the required behavior by:
- Adding a new helper function rrc_handle_f1_ho_reestab_on_target() to
handle F1 handover reestablishment on target DU. The function triggers
UE Context Setup procedure when the UE reestablishes on the target DU
during an ongoing F1 handover.
- Calling this function when detecting that the UE is reestablishing on
the target DU during handover, i.e.: (1) from
handle_rrcReestablishmentComplete(), as per 38.401 §8.7, NOTE on steps
9-10: CU gets UL RRC MESSAGE TRANSFER from a DU different than the
original (2) from rrc_CU_process_ue_modification_required, as per
38.401 §8.7, NOTE on steps 9'-10': CU gets a UE CONTEXT MODIFICATION
REQUIRED from a DU different from the original one.
Also:
- add helper rrc_fill_f1_ue_context_setup and adopt it in handover
- move DRB list filler fill_drb_to_be_setup into rrc_gNB.c and rename it
rrc_fill_f1_drb_to_setup for consistency
See also TS 38.401 Figure 8.7-1 "RRC connection reestablishment
procedure" for reference
3. DU: Handle missing old UE context in DL RRC Message Transfer
During F1 handover reestablishment, the CU may forward a DL RRC Message
Transfer to the target DU with old_gNB_DU_ue_id included, even though
the target DU does not have the old UE context yet.
The code previously used AssertFatal when the old UE context was not
found, causing a crash: "CU claims we should know UE %04x, but we don't"
According to TS 38.473, the gNB-DU shall release the old gNB-DU UE F1AP ID only:
> if the gNB-DU identifies the UE-associated logical F1-connection If
> there is no matching connection, there is nothing to release.
Fix:
- Check if old UE context exists before accessing it
- If old UE does not exist, log error, clean up any stale F1 UE data,
and return early (do not deliver RRC message since reestablishment
can't be completed)
The goal is to address a recurrent issue in the F1 pipeline, see
jenkins-oai.eurecom.fr/job/RAN-SA-Handover-CN5G/514:
Assertion (oldUE) failed!
In dl_rrc_message_transfer() /oai-ran/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c:956
CU claims we should know UE 35ce, but we don't
The sufficient number of fragments needed for MTU 1500 and 8b compression is 6.
However, XRAN_MAX_FRAGMENT must be incremented by one (6+1 = 7).
In the MR https://gitlab.eurecom.fr/oai/openairinterface5g/-/merge_requests/3394, XRAN_MAX_FRAGMENT was increased to 6,
but the Tx data was actually copied 5 times, and unfortunately I haven't tested end-to-end back then.
This commit was successfully tested with Liteon FR1.
Even though the jumbo frame has 9600 bytes by the spec, the max MTU is limited to the MTU of a switch, if any used.
However, the value can be < max MTU of a switch.
This is very important for fragmentation purposes. If not properly set, the PDSCH packets will be missing.
- increase requirements for Event A3 trigger to avoid unwanted handovers
and allow testing reestablishment on different DUs
- increase ping_packetloss_threshold from 5 to 30 because we are forcing
a reestablishment, thus, packet loss will inevitably happen
- further adjustments to avoid A3 Events
During F1 handover reestablishment, the CU may forward a DL RRC
Message Transfer to the target DU with old_gNB_DU_ue_id included,
even though the target DU does not have the old UE context yet.
The code previously used AssertFatal when the old UE context was
not found, causing a crash: CU claims we should know UE %04x, but we don't
According to TS 38.473, the gNB-DU shall release the old gNB-DU UE
F1AP ID only "if the gNB-DU identifies the UE-associated logical
F1-connection". If there is no matching connection, there is nothing
to release.
However, the primary purpose of DL RRC MESSAGE TRANSFER is to deliver
the RRC message to the UE. The RRC message delivery is independent of
whether the old UE context can be retrieved. Per TS 38.473, the RRC
message must be delivered to the new UE regardless of old context
retrieval status.
Additionally, per TS 38.331 5.3.7.2 and 5.3.7.4, during reestablishment:
- The UE releases spCellConfig, which must be removed from CellGroupConfig
- SRB1 RLC must be reconfigured with specific parameters
These operations are required for the new UE during reestablishment and
are independent of whether the old UE context can be retrieved.
Fixes:
- Check if old UE context exists before accessing it
- If old UE does not exist, log error and clean up any stale F1 UE data,
but continue to deliver the RRC message
- Restructure code so context transfer only happens when oldUE exists
- Keep GTP-U update and RLC context transfer inside oldUE check (they
require old UE context to exist)
- Move spCellConfig handling and reestablish_rlc flag to execute
regardless during re-establishemnt (per TS 38.331 5.3.7.2)
- Move SRB1 RLC reconfiguration outside the oldUE check so it executes
regardless during re-establishment (per TS 38.331 5.3.7.4)
- Add function documentation and improve spec references in comments
This commit fixes the timing of SRB and DRB PDCP re-establishment
during RRC connection re-establishment to align with 3GPP TS 38.331
specifications.
Key Changes:
1. SRB1 activation and re-establishment (TS 38.331 5.3.7.4):
- Move SRB1 activation to rrc_gNB_generate_RRCReestablishment()
- Use SRB1 constant instead of magic number 1 for clarity
- Remove redundant security configuration loop (handled by
nr_pdcp_reestablishment internally)
2. SRB2 re-establishment (TS 38.331 5.3.5.6.3 SRB addition/modification):
- Move SRB2 PDCP re-establishment from rrc_gNB_process_RRCReestablishmentComplete()
to rrc_gNB_generate_dedicatedRRCReconfiguration(): per spec: SRB2
should be re-established in the first RRCReconfiguration after
re-establishment (with reestablishPDCP=true flag)
3. DRB re-establishment (TS 38.331 5.3.5.6.5 DRB addition/modification):
- Move cuup_notify_reestablishment() from rrc_gNB_process_RRCReestablishmentComplete()
to rrc_gNB_generate_dedicatedRRCReconfiguration(). e.g at the first
reconfiguration after reestablishment
- Ensures CU-UP is notified at the correct time
As per TS 38.401 §8.7: if the UE accesses a DU different from the original
one during re-establishment, the CU must trigger UE Context Setup toward
the new DU. This refers to steps 9-10 and steps 9'-10'. Either one or the
other can be executed during re-establishment.
e.g. if this happens during F1 handover, it shall trigger a
UE Context Setup fallback on the CU.
This commit implements the required behavior:
1. Detection mechanism:
- Add `old_du_assoc_id` field to `f1_ue_data_t` to store the original
DU association ID
- At RRCReestablishmentRequest: Store original `du_assoc_id` in
`old_du_assoc_id` and update `du_assoc_id` to the new DU
- At RRCReestablishmentComplete: Compare `old_du_assoc_id` with the
`assoc_id` from the Complete message to detect different DU
2. UE Context Setup trigger:
- In `rrc_gNB_process_RRCReestablishmentComplete()`: When different DU
is detected, call `rrc_f1_ue_context_setup_for_target_du()` to trigger
UE Context Setup procedure (per TS 38.401 §8.7, NOTE on steps 9-10)
upon reception of UL RRC MESSAGE TRANSFER
- In `rrc_CU_process_ue_modification_required()`: Refuse UE Context
Modification Required when `old_du_assoc_id != 0` to avoid conflicts
with the ongoing UE Context Setup procedure (per TS 38.401 §8.7, NOTE
on steps 9'-10')
3. UE Context Setup:
- Replace `clone_CellGroupConfig()` with `get_cellgroup_config()` in
UE Context Setup handler
- Call `update_cellgroup_for_reestablishment()` during UE Context Setup
when `reestablish_rlc` flag is set to prepare CellGroupConfig with
reestablishRLC flags
- Clean up `old_du_assoc_id` in `rrc_CU_process_ue_context_setup_response()`
- Add `free_ue_context_mod_req()` call after UE Context Modification request
4. Function signature updates:
- Update `handle_rrcReestablishmentComplete()` to accept `gNB_DU_ue_id`
and `assoc_id` parameters, change return type from `int` to `void`
- Update `rrc_gNB_process_RRCReestablishmentComplete()` to accept
`assoc_id` parameter
- Update `rrc_gNB_decode_dcch()` to accept and forward `assoc_id` parameter
Re-establishment on different DU flow (TS 38.401 §8.7, steps 9-10):
1. UE sends RRCReestablishmentRequest to new DU
2. DU forwards to CU via UL RRC MESSAGE TRANSFER
3. CU detects different DU (`assoc_id != ue_data.du_assoc_id`):
- Stores `old_du_assoc_id = ue_data.du_assoc_id` (original DU)
- Updates `ue_data.du_assoc_id = assoc_id` (new DU)
4. CU sends RRCReestablishment to UE
5. UE sends RRCReestablishmentComplete to new DU
6. DU forwards to CU via UL RRC MESSAGE TRANSFER
7. CU detects different DU scenario (with old_du_assoc_id):
- Triggers UE Context Setup Request to new DU via `rrc_f1_ue_context_setup_for_target_du()`
8. DU receives UE Context Setup Request:
- Detects re-establishment (`UE->reestablish_rlc` flag)
- Calls `update_cellgroup_for_reestablishment()` to set reestablishRLC flags
- Encodes CellGroupConfig with reestablishRLC flags and sends to CU
9. CU receives UE Context Setup Response:
- Stores encoded CellGroupConfig
- Clears `old_du_assoc_id = 0`
10. CU sends RRC Reconfiguration with transparent CellGroupConfig to UE
This commit implements transparent forwarding of CellGroupConfig
as required by TS 38.473, eliminating CU-side decode/re-encode
cycles that violate transparency requirements.
Main Design Change:
- Before: CU decoded CellGroupConfig from DU, stored in the UE
context then re-encoded when sending to UE. CU constructed
new CellGroupConfig after RRCReestablishmentComplete.
- After: CU requests CellGroupConfig from DU via UE Context Modification
Request with `gNB_DU_Configuration_Query=true`, DU sends CellGroupConfig
which CU stores as encoded `byte_array_t` and forwards transparently
via reconfiguration without decode/re-encode cycles
To this purpose, all decode operations of CellGroupConfig were removed
from DU and all encode operations were removed from the CU.
Key Changes:
CU:
- Replace NR_CellGroupConfig_t* masterCellGroup with byte_array_t mcg in
gNB_RRC_UE_t for storing encoded CellGroupConfig
- Rename cell_group_config to cgc in nr_rrc_reconfig_param_t for brevity
- Implement transparent forwarding in build_RRCReconfiguration_IEs()
- Add helper functions:
- `store_cgc()` to store encoded bytes
- `get_meas_gap_config()`: Decode MeasGapConfig from DU to CU response
- `rrc_detect_reestablishment()` to detect re-establishment by decoding
temporarily (only for detection)
- Remove legacy decode/re-encode paths in RRC message generation
- Update all CellGroupConfig storage to use encoded bytes
- Update reconfiguration generation to accept is_reestablishment parameter
DU:
- Add `get_cellgroup_config()` to select source (CellGroup vs reconfigCellGroup)
based on re-establishment state
- Add re-establishment detection logic in `ue_context_modification_request()`
- Add `update_cellgroup_for_reestablishment()` to set reestablishRLC flags and
remove SRB1 from bearer list
- When `gNB_DU_Configuration_Query` is present and re-establishment detected:
- Clones from reconfigCellGroup (which contains spCellConfig) instead of
CellGroup (where spCellConfig was removed)
- Sets `reestablishRLC` flags for all bearers except SRB1
- Removes SRB1 from bearer list (already re-established)
Data Structure Changes:
- gNB_RRC_UE_t: Add byte_array_t mcg field
- nr_rrc_reconfig_param_t: Change cell_group_config to cgc (byte_array_t*)
- Remove masterCellGroup field usage in favor of encoded mcg
New re-establishment flow:
1. UE sends RRCReestablishmentRequest
2. CU processes -> sends RRCReestablishment
3. CU sends RRCReestablishmentComplete
4. CU sends UE Context Modification Request to DU with `gNB_DU_Configuration_Query=true`
5. DU detects re-establishment (`UE->reestablish_rlc && UE->reconfigCellGroup != NULL`):
- Clones `UE->reconfigCellGroup` -> `new_CellGroup` (contains spCellConfig)
- Sets `reestablishRLC` flags for all bearers except SRB1
- Removes SRB1 from bearer list (already re-established)
- Encodes `new_CellGroup` and sends to CU
6. CU receives encoded CellGroupConfig -> stores in `UE->mcg` via `store_cgc()`
7. CU detects re-establishment via `rrc_detect_reestablishment()`
8. CU calls `rrc_gNB_generate_dedicatedRRCReconfiguration()` with `is_reestablishment=true`:
- Creates SRB/DRB lists with re-establishment flags
- Generates RRC Reconfiguration with transparent CellGroupConfig
- Sends to UE
Why spCellConfig must be added in the DU in case of re-establishment:
With transparent forwarding, CU requests CellGroupConfig from DU instead
of constructing it. During re-establishment, DU's runtime CellGroup has
spCellConfig = NULL (removed per TS 38.331 §5.3.7.2). However, for the
gNB_DU_Configuration_Query response, DU must provide a complete CellGroupConfig
including spCellConfig. Therefore, DU restores spCellConfig by encoding
reconfigCellGroup (with the original spCellConfig) in CellGroupConfig.
In the old design CU constructed CellGroupConfig itself in
`rrc_gNB_process_RRCReestablishmentComplete()` and used `spCellConfig`
from its stored `masterCellGroup`.
Closes#837
Apply CGC encoding through GNB-DU Configuration Query. This applies to the
pdu session release path (rrc_gNB_send_f1_drb_release_request) and E1 bearer
mod / DRB add+release path (rrc_gNB_generate_UeContextModificationRequest).
This is necessary to implement 3GPP TS 38.473 requirement for
gNB-DU Configuration Query IE in UE Context Modification Request:
"If the GNB-DU Configuration Query IE is contained in the UE CONTEXT
MODIFICATION REQUEST message, gNB-DU shall include the CellGroupConfig
IE in the DU To CU RRC Information IE in the UE CONTEXT MODIFICATION
RESPONSE message."
i.e.: The DU sends the CGC only when this IE is enabled in the REQ
message from the CU. The only other scenario according to the same
specs is when the Full Configuration IE is present. Outside of these
two cases, CGC shall not be sent.
This field will be adopted to trigger cgc encoding at DU,
according to the specs (see subsequent commit for details).
Changes:
- Add gNB_DU_Configuration_Query field to f1ap_ue_context_mod_req_t
- Implement encoding/decoding
- Add to cp, eq, and free functions for the new field
- Update tests to include the new field
Issue: sometimes it happens that an ul failure occurs in the handover
pipeline, UE reconnects with different UE ID and fetch_du_by_ue_id fails.
- Modified fetch_du_by_ue_id in telnetsrv_ci.c to automatically find
the connected UE when no UE ID is provided, similar to other
telnet commands like rrc_gNB_trigger_f1_ho
- Updated test cases in container_sa_f1_ho_b210_quectel.xml to use
the improved command without hardcoded UE ID parameter
- This makes the command more robust and easier to use in CI tests
Add debugging utilities dump_cgc() and dump_mcg() to decode and
print CellGroupConfig in XER format when DEBUG_ASN1 flag is enabled.
This helps debug RRC Reconfiguration messages containing masterCellGroup.
Add intermediate fallback to rrc_gNB_get_ue_context_by_rnti_any_du() in
re-establishment request handling to better handle cases where UE
re-establishes on a different DU.
RNTI is NOT globally unique - different DUs can assign the same RNTI to
different UEs. The assoc_id check in rrc_gNB_get_ue_context_by_rnti()
disambiguates RNTI across DUs and prevents returning the wrong UE.
However, during re-establishment on a different DU, du_assoc_id hasn't
been updated yet (message comes from new DU, but ue_data.du_assoc_id
still points to old DU), causing the primary lookup to fail even though
the UE exists.
The lookup now uses a three-tier fallback:
1. Primary: rrc_gNB_get_ue_context_by_rnti() with assoc_id check
(normal case: same DU)
2. Fallback 1: rrc_gNB_get_ue_context_by_rnti_any_du() by RNTI only
(re-establishment on different DU)
3. Fallback 2: rrc_gNB_get_ue_context_source_cell() using physCellId
(handover scenarios)
- Remove unused masterCellGroup_from_DU parameter from rrc_gNB_generate_RRCReestablishment() as it is not used in the RRC
re-establishment generation, RRCReestablishment message does not contain CellGroupConfig which is obtained later via UE Context Modification Request/Response
- Update function documentation
- Initialize security_parameters struct to zero for safety
- Add check on ciphering and integrity algorithm ranges
When a UE re-establishes on a different DU, the physCellId in the
re-establishment request (from the old cell) will differ from the
new DU's physCellId. The previous check incorrectly treated this as
a "too fast movement" scenario and triggered fallback to RRC setup.
This fix distinguishes between two scenarios:
1. Different DU scenario: physCellId differs because UE is on a
different DU - this is legitimate and should be allowed. UE
Context Setup will be triggered at RRCReestablishmentComplete.
2. Same DU but different physCellId: "too fast movement" scenario
- fallback to RRC setup as before.
The fix checks if assoc_id != ue_data.du_assoc_id to detect a
different DU scenario and allows re-establishment in that case.
This addresses the issue where re-establishment on a different DU
was incorrectly rejected, preventing proper UE Context Setup per
TS 38.401 Section 8.7.
Handle target DU UE context setup when handover preparation info
is unavailable (i.e. re-establishment scenario) by retrieving
secondary UE ID from F1 UE data.
rrc_f1_ue_context_setup_for_target_du is either applying to
handover or re-establishment. In the latter scenario, populate
DU UE ID, which should be known.
semi-manual remove of not used #define commands
As i was upset to see all these #define with no code under, i made a
global pass to remove the obvious cases semi-manual remove of not used
bodies
manual script, then a lot of manual review
grep -IRs "#define" ../openair* ../common/* ../executables/ ../nfapi/ ../radio/ | \
fgrep -v '(' | fgrep -v '//' |awk '{print $2}' | egrep -v "#define *$n"| \
while read n ; do
grep -IRs $n ../openair* ../common/* ../executables/ ../nfapi/ ../radio/ | grep -v "#define *$n" | grep -q $n || echo $n;
done
will give a decent list of #define never used. Then, I think we should
keep lists of # define when it comes from standards, even if the code
doesn't use it right now
Add Ethernet PDU session support and make PDU session request configurable
This MR adds support for Ethernet PDU sessions, and makes PDU sessions
configurable: per-PDU session ID, type (IPv4/IPv4v6/IPv6/Ethernet [1]),
DNN, NSSAI.
Concretely, it adds a new configuration file section pdu_sessions below
uicc0 that looks like this if everything is specified (default values
are shown):
uicc0:
[...]
pdu_sessions:
- id: 1
type: "IPv4"
nssai_sst: 1
nssai_sd: 0xffffff
dnn: "oai"
It is possible to list multiple PDU sessions (add new line - id: 2 to
request a second PDU session). It is backwards-compatible to the current
PDU session configuration (uicc0.dnn/nssai_sst/etc), the idea being that
either legacy or new configuration could be used, but (1) if
pdu_sessions exist, it will overwrite the legacy configuration, and (2)
multiple PDU sessions, and type, can only be configured using the new
config. The old parameters --extra-pdu-id and --default-pdu-id are not
accepted anymore. Documentation has been added to the UE tutorial.
It is possible to test an Ethernet PDU session [1]. It is possible to
test the PDU session inside the UE by verifying it has an TAP interface
oaitap_ue1, and ARPing the data network (arping has been added to
oai-nr-ue container for that purpose):
ip addr add 192.168.72.140/26 dev oaitap_ue1 # same subnet as data network!
ip link set dev oaitap_ue1 up
arping -c 20 -I oaitap_ue1 192.168.72.135 # will send ARP request in Ethernet frame to get IP address of data network
[1] See description MR !3769 for more information. On the UE side, only
the type has to be changed to "Ethernet".
NR UE: add support for multiple RF frontends
This MR adds basic support for multiple RF-frontends at the UE.
There are multiple reasons why we might want this:
1. There might be different antennas needed for different bands (e.g. NTN or
TN antennas). These antennas might be connected to different RF-frontends.
In case of Handover, the UE needs to dynamically switch between these
RF-frontends.
2. Each rf-simulator connection carries baseband I/Q samples. To be able to
perform a handover between two cells at different frequencies, there must
be two rf-simulator connections, as the baseband channels should not
interfere and thus cannot simply be added.
3. When we want to support multiple UE simulation within one instance of
nr-uesoftmodem, and allow multiple cells and probably even handover between
these cells, we need either:
1. dedicated RF-frontends for each simulated UE, or
2. dedicated RF-frontends for each connected cell and dynamically assign
simulated UEs accordingly.
This MR implements what is needed for 1., 2. and 3.1.
Fix FFT size for xran_fh_tx_send_slot_BySymbol() and xran_fh_rx_read_slot_BySymbol()
This MR handles
- Fix FFT size for xran_fh_tx_send_slot_BySymbol() and
xran_fh_rx_read_slot_BySymbol() (!3809)
- Fix E release build
Create Debian and Redhat packages with CPack
Use CPack in CMakelists in order to create packages, creation command is
available in build_oai script and options description is available in
packages.md
Upon stopping the PNF, when sending the STOP.indication to the VNF, set pnf_p7->terminate to 1.
Add a check on the PNF P7 send functions to not send a message after pnf_p7->terminate is set
Even after this commit, we still have duplicated UL C-plane packets due to xran F release internal architecture.
Note: in E, all PRBs were in one section of one C-plane DL and UL. It is working even though the U-plane has "fragmented" packets.
Co-authored-by: Mario Joa-Ng <mario.joa-ng@openairinterface.com>
Previously, in F, only the following (subframe, slot, symbol) combinations were sent every frame:
(0, 0, 0)
(2, 1, 0)
(5, 0, 0)
(7, 1, 0)
Now, all the DL symbols are sent.
Notes:
In both E and F, the radio-transport fragmentation is not supported, and
all the "fragmented" (not seen as fragments in the xran, only as sections)
packets contain "E-bit" equal to 1.
Per spec, the value 1 for "E-bit" signifies the last fragment of one symbol.
For more info, please see "ecpriSeqid" section in the spec.
In E:
- nRBStart and nRBSize is updated according to the sent/received packet;
- max sections = 1.
In F:
- nRBStart and nRBSize is only used for C-plane messages;
- nPrbElm represents the number of sections for DL only;
- based on the nPrbElm, each section contains UP_nRBStart and UP_nRBSize parameters
which represent the start and number of PRBs in one section or one fragment.
Co-authored-by: Mario Joa-Ng <mario.joa-ng@openairinterface.com>
Packages must have a name, a version, a section, an architecture, a maintainer, a description (long and summary), dependencies
Shared libraries must be stripped, have soversion, version (debug symbols are found in separate packages), since MODULE is used instead of SHARED it works as a plugin library which is opened using dlopen-like functionality, see: https://cmake.org/cmake/help/latest/command/add_library.html
Packages must have postin and postun scripts
Since it is not recommended to modify CMAKE_EXE_LINKER_FLAGS, cmake's path variables are used : https://discourse.cmake.org/t/how-do-i-replace-the-compiler-options-for-one-target/7815/5
NGAP: improve error handling in RRCReconfiguration from Handover Command decoding
This MR refactors doRRCReconfiguration_from_HandoverCommand for consistency and
safety, and enables NGAP Handover Cancel encoding/decoding.
- Refactored doRRCReconfiguration_from_HandoverCommand function:
- Changed signature to return byte_array_t instead of taking a buffer parameter
- Prevents buffer overflow by auto-sizing memory with uper_encode_to_new_buffer
- Input validation
- HandoverCommand structure validation
- Error handling and cleanup for encode/decode failures
- ASN.1 structure cleanup on all error paths
- Updated caller in rrc_gNB_NGAP.c: use new byte_array_t return signature,
added buffer cleanup with free_byte_array(), sends Handover Cancel to AMF on
decoding failure (source gNB)
- Improved error logging
- NGAP Handover Cancel encoding/decoding support
- Added missing Handover Cancel ack case handler for
NGAP_ProcedureCode_id_HandoverCancel in ngap_gNB_decode_initiating_message()
to decode and log incoming Handover Cancel Ack message
- Added NGAP_ProcedureCode_id_HandoverCancel to the list of supported
initiating message procedure codes in ngap_gNB_encode_initiating() allowing
the gNB to encode and send Handover Cancel messages
Note: The Handover Cancel procedure is already implemented elsewhere in the NGAP
stack; these changes complete support by ensuring the procedure code is
recognized in both encoder and decoder.
Closes#1043
The CN team would like to test the ethernet PDU session capabilities of
the UPF. Install arping in the UE by default for ubuntu to help them
test the PDU session by pinging over ARP.
Look up the index of a PDU session in the list of PDU sessions upon
accept to determine if the PDU session is the default (first PDU
session) or not. If it is the default, it will not append a suffix to
the interface name (oaitun_ueY), otherwise append the PDU session ID
(e.g., for 5: oaitun_ueYp5).
Use the new PDU session configuration functionality of the parent
commit. It is now possible to request multiple PDU sessions, and to
request specific PDU session types. While the new uicc0.pdu_sessions is
preferred, it is still possible to use the "legacy"
uicc0.dnn/nssai_sst/nssai_sd.
The old parameters --default-pdu-id and --extra-pdu-id are not allowed
anymore, as it is possible to manually define this in the UE
configuration. Correspondingly, fix the use of those options, where
applicable.
Note: since the default_pdu_id is changed to -1, all interface names
will have pX to interface names appended (oaitun_ue1pX). The next commit
will correct this.
When writing dummy data or reading to trash, we don't need to allocate data buffers for each antenna.
We can allocate just for one antenna and use this buffer for each antenna.
This feature shall allow in future to simulate an arbitratry number of UEs connected to an other arbitrary number of cells.
Therefore each RF-frontend (also called RU) needs to be configured for one specific cell.
In case of handover of a UE from one cell to another cell, it needs to switch RUs accordingly (TODO).
There has to be a 1-to-1 mapping between RUs and cells.
Each UE will be assigned to one of the defined cells.
Initially all UEs are assigned to cell 0.
UE support to send CSI report on PUSCH
Earlier work on UCI on PUSCH implemented only ACK/NACK. This MR extends that
to send CSI report too.
This branch is verified with MATLAB implementation for multiplexing CSI part 1
and part 2 on PUSCH. It is also verified with srsRAN gNB which successfully
decodes CSI part 1 on PUSCH.
Fix RSRP overflow
If UE L1 measure an RSRP = 0 it would report to L2 and RSRP value of -INT_MAX
dBm causing overflow in the qsort to determine the best RSRPs
The global variable rx_gain_off was always 0.0, as it was not even modified by the NR UE command line parameter --ue-rxgain-off.
That command line parameter modified only a parameter in the struct nrUE_params_t, which was not used at all and is removed in this commit, too.
Also, the global variable rx_gain_off was just added to rx_total_gain_dB and subtracted from it again in nr_rf_card_config_gain().
So we simplify that function slightly, too.
Clear memory in shm_td_iq_channel after RX
Clear memory in shm_td_iq_channel after RX. This prevents the IQ
from being read twice. This can happen if the application crashes
and will keep the other side reading historical IQ samples.
Update vrtsim timing job thread
List of changes:
- avoid calculating accumulated rounding error by calculating absolute
sample index based on CLOCK_REALTIME every time.
- use threadCreate instead of plain pthread_create which assigns a unique
thread name and simplifies debugging
Use nr_get_csi_measurements() function to get CSI report for PUCCH and
UCI on PUSCH.
Harmonize filling csi report for UCI on PUSCH for periodic and aperiodic
CSI reports.
Extract the common RRC container handling logic from
ue_context_setup_request() and ue_context_modification_request() into
a new static function handle_ue_context_rrc_container().
This refactoring:
- Eliminates code duplication between the two functions
- Centralizes RRC container forwarding logic
- Improves code maintainability and consistency
Extract common CellGroupConfig encoding logic from
ue_context_setup_request() and ue_context_modification_request() into
encode_cellgroup_config().
Replace uper_encode_to_buffer() with uper_encode_to_new_buffer() to:
- Remove 1024-byte buffer size limit
- Automatically allocate correct buffer size
- Simplify code (no manual bit-to-byte conversion)
- Align with other protocol encoders
- Add function documentation blocks for `rrc_fill_f1_ue_context_setup`,
`rrc_f1_ue_context_setup_for_target_du`, and `rrc_f1_ue_context_setup_from_e1_response`
explaining their purpose, parameters, and usage scenarios
- Add inline comments throughout these functions
Improve maintainability by centralizing common F1AP UE context setup
logic into reusable helper functions, enabling consistent handling
and clear serving/target DU entry points for different scenarios.
Code duplication prevention is a beneficial side effect, since at
least one helper function is adopted in subsequent commits.
Major changes:
- Move DRB list filler from external file into rrc_gNB.c and rename
fill_drb_to_be_setup to rrc_fill_f1_drb_to_setup for naming
consistency
- Add static helper rrc_fill_f1_ue_context_setup to populate common
fields shared between serving DU and target DU scenarios:
- Rename rrc_gNB_generate_UeContextSetupRequest to
rrc_f1_ue_context_setup_from_e1_response to clarify it prepares
F1AP context setup from E1AP bearer setup response for serving DU
- Add rrc_f1_ue_context_setup_for_target_du (for target DU in
handover/reestablishment scenarios)
- Adopt helper rrc_fill_f1_ue_context_setup in both functions
When processing UL RRC messages from PDCP, the DU association ID (assoc_id)
was not being propagated to RRC, resulting in assoc_id being 0 in
rrc_gNB_decode_dcch.
Fix by setting originInstance in the ITTI message header to the stored
du_assoc_id from ue_data when PDCP creates the F1AP_UL_RRC_MESSAGE.
Integration `2026.w04`
* !3787 CI: disable aerial x86 build pipeline
* !3820 Integrate F1AP messages required for NRPPa
* !3789 fix A3 event configuration
* !3861 add a csv T tracer
* !3669 NR UE: add neighboring cell measurements and measurement report of event A3
* !3866 nr-softmodem: ensure RU is ready before L1 init in NFAPI PNF mode
* !3402 Test FDM PRACH in CI
* !3852 Cleanup nr_slot_fep_ul
* !3782 Improvements to support CSET0 multiplexing pattern 3 for FR2
* !3862 Check for PDSCH overlapping CORESET during RA
* !3430 NR gNB handling TCI state indication for beam switching
* !3872 Fix compilation issues with vrtsim taps client
* !3687 Standardize Documentation Formatting and Navigation for MkDocs
Closes#705
See merge request oai/openairinterface5g!3867
Standardize Documentation Formatting and Navigation for MkDocs
This merge request improves and organizes the documentation to align with MkDocs
requirements. The following guidelines have been applied:
Guidelines Followed
Fix Broken Links and Paths
- Updated all links with proper paths to ensure correct rendering in MkDocs.
Correct Headings
- Removed multiple H1 headings (#).
- Subheadings use H2–H6 (## to ######) for consistent structure.
Proper URL Formatting
- All URLs now follow standard Markdown syntax,
e.g., [Example](https://www.example.com).
Proper Syntax
- Tables, lists, and code blocks use standard Markdown formatting to ensure
correct rendering.
Remove HTML Formatting
- Removed unnecessary inline HTML styling from documents, retaining only the
content.
Notes and Warnings
- Converted notes and warnings into blockquote syntax (>).
This ensures the documentation is properly structured, consistent, and
MkDocs-friendly.
- Include functions/file_names in backticks for readability
- Include the images directly inside the document (rather than plain image file name)
- Give relevant spacing if required
- Remove multiple single top-level (# H1) headings per file
- Use (# H2 and ###### H6) sub-headings for consistency
- Remove any trailing # in the headings
- This ensures proper table of contents rendering in MkDocs.
- Also removed RUN_NR_multiple_BWPs.md as it is moved to MAC usage
- bold current status for clarity and add spacing for better readability
- Wrap processes in the test setup block inside code blocks as they were rendered as GitLab issues
- Remove extra spacing in the test setup block
- Give a line in between bullet points to reflect bullet points correctly
- Split long statement into bullet points for readability
- Format the document for proper rendering
- Fix table formatting
- Use standard TOC syntax in 5GNAS
- The parser was incorrectly interpreting `</` as the start of an HTML closing tag, leading to a crash in mkdocs
- Replace with HTML entity to ensure it is treated as a plain text.
NR gNB handling TCI state indication for beam switching
This MR implements the procedure to send in DLSCH MAC-CE for TCI state
indication to UE
- if new beam is reported via SSB RSRP, gNB allocates MAC-CE with TCI
indication
- DLSCH is scheduled to be transmitted with priority
- a timer is started when receiving ACK according to the delay mandated
by standard (8.10.3 of 38.133)
- at timer expiry the gNB switches beam
Check for PDSCH overlapping CORESET during RA
CORESET 0 is configured in the configuration file by
'initialDLBWPcontrolResourceSetZero' and PDSCH TDA list is configured based on
the current BWP size.
It may happen that the user configures a 2 symbol CORESET 0 for a BWP >= 48 PRBs
(which is a valid 3GPP configuration) but in function 'nr_rrc_config_dl_tda'
this scenario is not taken in account causing an overlap between PDSCH and PDCCH
symbols during RA.
This leads to very unreliable Msg2 and Msg4 decoding at the UE, but from time to
time it succeeds, which becomes hard to identify this issue.
closes#705
Fix two issues regarding vrtsims taps client implementation:
- Incorrect #define used to enable taps socket handling
- flatbuffers package name changing between ubuntu versions
Cleanup nr_slot_fep_ul
Rename nr_slot_fep_ul to nr_symbol_fep_ul to relfect its function
Simplify logic so that the function does not require RU context and
the implementation is not dependent on the implementation of RU buffer
management.
This makes the function easier to understand and moves the responsibility
to set the correct buffer offset on the caller.
nr-softmodem: ensure RU is ready before L1 init in NFAPI PNF mode
PROBLEM: In PNF mode, L1 is started from nfapi_pnf.c without verifying RU
readiness. The only gate is config_sync_var, but nr_softmodem.c sets this before
the RU (e.g., FHI-72) is actually started. As a result, START_REQUEST can
trigger L1 init while the RU is not yet ready -- this is an issue when using
FHI72 with DPDK BBDEV, where a pre-mature L1 init will crash the entire program
as DPDK BBDEV depends on xRAN's DPDK EAL. Note that this issue is more like a
"race" condition, so it may not always manifest, and happens at random.
FIX: Perform RU readiness checks before setting config_sync_var in NFAPI PNF mode.
This aligns PNF behavior with other modes and prevents L1 from starting before the
RU is operational.
SSB position in burst is set to 2 so only SSB index 1 is transmitted.
prach_msg1_FDM is set to 1 so there are two occasions per time slot.
All the UE connecting to gNB will receive SSB index 1 and trigger PRACH
in the second FDM prach occasion.
FHI 7.2 does not have a field for the number of RACH Occasions.
It seems this needs to be manually configured, and M plane has field
num-prach-re to set the number of frequency domain PRACH occasions.
Rename nr_slot_fep_ul to nr_symbol_fep_ul to relfect its function
Simplify logic so that the function does not require RU context and
the implementation is not dependent on the implementation of RU buffer management.
This makes the function easier to understand and moves the responsibility
to set the correct buffer offset on the caller.
Modify all functions to also handle TAP (where applicable). The actual
TAP interface code is not used in this commit, it will be used later.
To make the interface creation stand out, make "Interface XXX
successfully configured" a LOG_A.
Simplify interface handling by storing the name: this allows to simplify
to remove_ip_if(), which does not need to recreate a valid name, and
will simplify handling of ethernet PDU sessions with a possibly
different name.
Defacto, the PDU session ID for noS1 modes is already hardcoded, as
starting the nr-softmodem with --noS1 --default-pdu-id 1 leads to
Assertion (entity != ((void *)0)) failed!
In start_sdap_tun_gnb_first_ue_default_pdu_session() openair2/SDAP/nr_sdap/nr_sdap.c:163
Further, the --default-pdu-id parameter will be deactivated in a later
commit, and we cannot rely on it. Therefore:
- hardcode noS1 PDU ID (also used in --do-ra/--phy-test modes) to 10 and
use in gNB&UE
- pass the PDU session ID used in SDAP entity initialization down to
start_sdap_tun_gnb_first_ue_default_pdu_session() to always use the
correct one
For configuring a TAP interface, we need to set different options, which
is not easily feasible with the current change_interface_state() API (or
would make it more complex). To simplify while allowing to set flags
more flexibly, separate into two functions get/set_if_flags().
PROBLEM: In PNF mode, L1 is started from nfapi_pnf.c without verifying RU
readiness. The only gate is config_sync_var, but nr_softmodem.c sets this before
the RU (e.g., FHI-72) is actually started. As a result, START_REQUEST can
trigger L1 init while the RU is not yet ready -- this is an issue when using
FHI72 with DPDK BBDEV, where a pre-mature L1 init will crash the entire program
as DPDK BBDEV depends on xRAN's DPDK EAL.
FIX: Perform RU readiness checks before setting config_sync_var in NFAPI PNF mode.
This aligns PNF behavior with other modes and prevents L1 from starting before the
RU is operational.
NR UE: add neighboring cell measurements and measurement report of event A3
This is a rework of MR !2385 (closed), the goal is to add neighboring cell
measurements and measurement report of event A3 for NR UE.
This MR was tested with:
- 3rd-party gNB
- 2 OAI-gNB-DUs
The neighboring cell measurements and measurement report of event A3 for OAI-UE
are working as expected.
fix A3 event configuration
See commit message for more information.
As a reference, for comparison purpose, PCAPs and TXT files for various tests
done in develop and in this MR are available in the MR description.
Integrate F1AP messages required for NRPPa
This MR is one of the several MRs that will follow in the integration of NRPPa
protocol (!2437) required for positioning in 5G NR. We specifically introduce
encoding and decoding of several F1AP messages including unit tests for
verification in this MR.
The details of the F1AP messages introduced here can be seen below:
- POSITIONING INFORMATION REQUEST
- POSITIONING INFORMATION RESPONSE
- Supported optional field: SRS Configuration
- POSITIONING INFORMATION FAILURE
- POSITIONING INFORMATION UPDATE
- Supported optional field: SRS Configuration
- POSITIONING ACTIVATION REQUEST
- POSITIONING ACTIVATION RESPONSE
- POSITIONING ACTIVATION FAILURE
- POSITIONING DEACTIVATION
- TRP INFORMATION REQUEST
- TRP INFORMATION RESPONSE
- Supported : NR PCI, NG-RAN CGI, NR ARFCN, Geogarphical Coordinates
- TRP INFORMATION FAILURE
- POSITIONING MEASUREMENT REQUEST
- Supported optional field: SRS Configuration
- POSITIONING MEASUREMENT RESPONSE
- POSITIONING MEASUREMENT FAILURE
- POSITIONING MEASUREMENT REPORT
- POSITIONING MEASUREMENT ABORT
- POSITIONING MEASUREMENT FAILURE INDICATION
- POSITIONING MEASUREMENT UPDATE
- Supported optional field: SRS Configuration
The reference to these messages can be found in 3GPP 38.473 v16.21.0
CI: disable aerial x86 build pipeline
We use Aerial exclusively on ARM/gracehopper, so no need to build it on
x86. On this occasion, rename the "kind" (ID which images to build) to
x86 for clarity and align with the other "kinds" (build_cross_arm,
native_armv9, ...).
While testing the gNB with two hypotetical neighbors, some issues were found
with A3 event configuration.
The configuration of neighbors is:
neighbour_list = (
{
nr_cellid = 12345679L;
neighbour_cell_configuration = (
{
gNB_ID = 0xba0;
nr_cellid = 720898;
physical_cellId = 1;
absoluteFrequencySSB= 621312;
subcarrierSpacing = 1;
band = 78;
plmn = { mcc = 505; mnc = 01; mnc_length = 2 };
tracking_area_code = 1;
},
{
gNB_ID = 0xea0;
nr_cellid = 1345678L;
physical_cellId = 2;
absoluteFrequencySSB= 640000;
subcarrierSpacing = 1;
band = 78;
plmn = { mcc = 505; mnc = 01; mnc_length = 2 };
tracking_area_code = 1;
}
);
}
);
There were two problems.
The first problem is:
- when only default A3 event is configured, it is duplicated in the
RRC Reconfiguration Report Config To AddMod list with IDs 4 and 5
To test this case, the event configuration is:
nr_measurement_configuration = {
Periodical = {
enable = 1;
includeBeamMeasurements = 1;
maxNrofRS_IndexesToReport = 4;
};
A2 = {
enable = 1;
threshold = 60;
time_to_trigger = 1;
};
A3 = (
{
physCellId = -1;
offset = 15;
hysteresis = 2;
time_to_trigger = 3
}
);
};
The second problem is:
- when configuring an A3 event with an unknown physCellId, the gNB
does not include any A3 event in the RRC Reconfiguration Report
Config To AddMod list (which is correct), but configures some
meas ID with nonexistant Report Config IDs
To test this case, the event configuration is:
nr_measurement_configuration = {
Periodical = {
enable = 1;
includeBeamMeasurements = 1;
maxNrofRS_IndexesToReport = 4;
};
A2 = {
enable = 1;
threshold = 60;
time_to_trigger = 1;
};
A3 = (
{
physCellId = 10;
offset = 15;
hysteresis = 2;
time_to_trigger = 3
}
);
};
Reworking A3 event configuration as done in this commit solves both
issues.
CORESET 0 is configured in the configuration file by 'initialDLBWPcontrolResourceSetZero' and PDSCH TDA list is configured based on the current BWP size.
It may happen that the user configures a 2 symbol CORESET 0 for a BWP >= 48 PRBs (which is a valid 3GPP configuration) but in function 'nr_rrc_config_dl_tda' this scenario is not taken in account causing an overlap between PDSCH and PDCCH symbols.
This leads to very unreliable Msg2 and Msg4 decoding at the UE, but from time to time it succeeds, which becomes hard to identify this issue.
Correct how the slot for SIB1 is computed in case of MUX pattern 2 and 3.
Renamed n_0 to slot for clarity. n_c was never used outside of the function, so
remove it where it is not used.
We use Aerial exclusively on ARM/gracehopper, so no need to build it on
x86. On this occasion, rename the "kind" (ID which images to build) to
x86 for clarity and align with the other "kinds" (build_cross_arm,
native_armv9, ...).
Reference: 3GPP 38.473 v16.21.0
Mandatory fields:
Transaction ID (supported)
LMF Measurement ID (supported)
RAN Measurement ID (supported)
Add F1AP positioning measurement failure indication message enc/dec + test
Reference: 3GPP 38.473 v16.21.0
Mandatory fields:
Transaction ID (supported)
LMF Measurement ID (supported)
RAN Measurement ID (supported)
Cause (supported)
Reference: 3GPP 38.473 v16.21.0
Mandatory fields:
Transaction ID (supported)
LMF Measurement ID (supported)
RAN Measurement ID (supported)
Positioning Measurement Result List (range: 1)
> Positioning Measurement Result List Item (range: 1..64)
>> Positioning Measurement Result (supported)
>> TRP ID (supported)
Reference: 3GPP 38.473 v16.21.0
Mandatory fields:
Transaction ID (supported)
LMF Measurement ID (supported)
RAN Measurement ID (supported)
Cause (supported)
Optional fields:
Criticality Diagnostics (not supported)
Reference: 3GPP 38.473 v16.21.0
Mandatory fields:
Transcation ID (supported)
LMF Measurement ID (supported)
RAN Measurement ID (supported)
Positioning Measurement Result List (range: 0..1)
> Positioning Measurement Result List Item (range: 1..64)
>> Positioning Measurement Result (supported)
>> TRP ID (supported)
Optional fields:
Criticality Diagnostics (not supported)
Reference: 3GPP 38.473 v16.21.0
Mandatory fields:
Transcation ID (supported)
TRP Information List (range : 1)
> TRP Information Item (range : 1..65535)
>> TRP Information (supported)
Further details of TRP Information:
TRP ID
TRP Information Type Response List (range : 1)
> TRP Information Type Response Item (range : 1..64)
>> CHOICE TRP Information Type Response Item
>>> NR PCI (madatory : supported)
>>> NG-RAN CGI (madatory : supported)
>>> NR ARFCN (madatory : supported)
>>> PRS Configuration (madatory : not supported)
>>> SSB Information (madatory : not supported)
>>> SFN Initialisation Time (madatory : not supported)
>>> Spatial Direction Information (madatory : not supported)
>>> Geographical Coordinates (madatory : supported)
For now, we only use Geographical Coordinates.
Optional fields:
Criticality Diagnostics (not supported)
Reference: 3GPP 38.473 v16.21.0
Mandatory fields:
Transcation ID (supported)
TRP list (range : 0..1)
> TRP list Item (range : 1..65535)
>> TRP ID (supported)
TRP Information Type List (range : 1)
> TRP Information Type Item (range : 1..64)
>> TRP Information Type Item (supported)
While implementing NRPPA-related F1AP messages, we remarked that
extension field "UL-AoA-ExtIEs" needs to be OPTIONAL (e.g., in NRPPA it
is optional in the OAI-compiled version), but it was not marked as such.
This later version 16.21.0 fixes this.
- Refactor function to return byte_array_t instead of taking buffer
parameter for consistency with other encoding functions
(do_RRCReconfiguration, do_HO_RRCReconfiguration) and to prevent buffer
overflow issues since the memory size is determined automatically
- Add comprehensive error checking:
* Input validation
* Check return of each decode (HandoverCommand
and RRCReconfiguration)
* Validate HandoverCommand structure before access
* Validate OCTET_STRING before decoding RRCReconfiguration
* Error handling and cleanup for enc/dec failures
- Update caller in rrc_gNB_NGAP.c
* use new signature
* free buffer
* send HO Cancel on decoding failure (source gNB)
Closes#1043
This commit adds support for the Handover Cancel initiating message
procedure code (NGAP_ProcedureCode_id_HandoverCancel).
Changes:
- ngap_gNB_decoder.c: Added case handler for Handover Cancel in
ngap_gNB_decode_initiating_message() to properly decode and log
incoming Handover Cancel messages from the AMF.
- ngap_gNB_encoder.c: Added Handover Cancel to the list of supported
initiating message procedure codes in ngap_gNB_encode_initiating(),
allowing the gNB to encode and send Handover Cancel messages.
The Handover Cancel procedure is already implemented in other parts of
the NGAP stack, these changes were missing to complete the support
by ensuring the procedure code is properly recognized in both the encoder
and decoder switch statements, following the same pattern as other
procedure codes.
Clear memory in shm_td_iq_channel after RX. This prevents the IQ
from being read twice. This can happen if the application crashes
and will keep the other side reading historical IQ samples.
List of changes:
- avoid calculating accumulated rounding error by calculating absolute
sample index based on CLOCK_REALTIME every time.
- use threadCreate instead of plain pthread_create which assigns a unique
thread name and simplifies debugging
self.htmlFile.write(' <div class="well well-lg">End of Test Report -- Copyright <span class="glyphicon glyphicon-copyright-mark"></span> 2025 <a href="http://www.openairinterface.org/">OpenAirInterface</a>. All Rights Reserved.</div>\n')
self.htmlFile.write(' <div class="well well-lg">End of Test Report -- Copyright <span class="glyphicon glyphicon-copyright-mark"></span> 2026 <a href="http://www.openairinterface.org/">OpenAirInterface</a>. All Rights Reserved.</div>\n')
These scripts are used by a Jenkins [job](../Jenkinsfile-colosseum) to trigger automated testing of OpenAirInterface (OAI) gNB and softUE on the [Colosseum](https://www.northeastern.edu/colosseum/) Open RAN digital twin.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.