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.
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.
Integration: `2026.w03`
* !3818 Update threadCreate
* !3845 Update physim timing thresholds in gNB-N300-Timing-Phytest-LDPC
* !3849 Make gpd config utility global
* !3812 Fix reestablishment after handover
* !3826 Define speed of light
* !3799 Fix for threadpool abort function
* !3791 fix array lenght errors, k variable wrapping threshold. Make the code smaller and more efficient
* !3718 Introduce SRS physical simulator and improvements
* !3857 Fix bug "no AMF for UE"
* !3858 remove function decode_cellGroupConfig
* !3668 Support beam index for LiteON FR2 RU that needs per symbol section in CP packets
* !3844 CI: Remove testcase ids from XML files
* !3620 update multi-RU 7.2 documentation for DAS scenario
* !3788 Fix handover documentation and configuration files for event configuration
See merge request oai/openairinterface5g!3854
- 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.
Support beam index for LiteON FR2 RU that needs per symbol section in CP packets
This branch supports beam index for LiteOn FR2 RU and others. It adds
the support of beam index for LiteOn RU that uses per-symbol CP packet
and is a sequel of MR !3605 (merged) that supports beam index for RU
that uses per-slot CP packets.
A. To support LiteOn FR2 RU, the following are needed.
a. Per symbol beamforming. Need separate section for each symbol on CP packet.
b. Handle these two bugs:
- section ID on UP packet is set wrongly to 13 for all sections
- prach eAxC offset starts from 0 instead of from last antenna port
number used by other channels.
B. Implementation
a. set fh_config->RunSlotPrbMapBySymbolEnable based on the setting in the configuration file
- if disable, the existing per-slot scheme is run on xran.
- if enable, RunSlotPrbMapBySymbolEnable mode is on in xran so that xran
will generate PrbElm per symbol (aka total of 14)and perform
per-symbol processing on the corresponding PrbElm.
b. set fh_config->LiteOnIgnoreUPSectionIdEnable based on the setting in
the configuration file if enable, handle 2 "features" of Liteon:
- To handle the section_id = 13 issue on Liteon where section ID is set
wrongly to 13 for all sections
- To handle the prach eAxC offset issue on Liteon where it starts from 0
instead of from the end of last antenna port number
c. if fh_config->RunSlotPrbMapBySymbolEnable, OAI FHI
- invoke xran_fh_rx_read_slot_BySymbol() instead of xran_fh_rx_read_slot()
- invoke xran_fh_tx_send_slot_BySymbol() instead of xran_fh_tx_send_slot()
C. Testing
a. Command to test benetel RU
sudo LD_LIBRARY_PATH=.:$DPDK_INST/lib/x86_64-linux-gnu/ ./nr-softmodem -O /etc/ran_development/CONFs/gnb.sa.band77.273prb.fhi72.4x4-benetel550_c0.conf --thread-pool 21,22,23,24,25,26,27,28
Results:
iperf UDP uplink
[ 5] 0.00-10.22 sec 87.3 MBytes 71.6 Mbits/sec 0.100 ms 370/63081 (0.59%) receiver
iperf UDP downlink
[ 5] 0.00-10.00 sec 796 MBytes 668 Mbits/sec 0.017 ms 1824/586404 (0.31%) receiver
b. Command to test LiteOn FR2 RU
sudo LD_LIBRARY_PATH=.:$DPDK_INST/lib/x86_64-linux-gnu/ ./nr-softmodem -O /etc/ran_development/CONFs/gnb.sa.band78.66prb.fhi72.2x2-liteon-F-Release.conf--thread-pool 21,22,23,24,25,26,27,28
Result:
iperf UDP uplink
[ 5] 0.00-10.20 sec 89.9 MBytes 73.9 Mbits/sec 0.156 ms 212/64848 (0.33%) receiver
iperf UDP downlink
[ 5] 0.00-10.00 sec 361 MBytes 303 Mbits/sec 0.077 ms 277662/542891 (51%) receiver
D. Difference between LiteOn FR2 E release configuration file and that for F release is
diff gnb.sa.band78.66prb.fhi72.2x2-liteon-KB.conf gnb.sa.band78.66prb.fhi72.2x2-liteon-F-Release.conf 39d38
< beam_weights = [1, 1];
225a225
> beam_weights = [1];
312c312,313
< mtu = 1500; # check if xran uses this properly
---
> #mtu = 1500; # check if xran uses this properly
> mtu = 9000; # check if xran uses this properly
313a315,316
> RunSlotPrbMapBySymbol = 1;
> LiteOnIgnoreUPSectionId = 1;
Add the F patch that work on both Benetel and LiteOn RU. support
fh_config parameters RunSlotPrbMapBySymbol and LiteOnIgnoreUPSectionId.
Change version number.
Fix bug "no AMF for UE"
It might happen that the RRC does not know the AMF UE NGAP ID, yet. Even
in that case, we should forward the release request to the NGAP module,
which can either forward a message to the AMF, or reply back to release
the UE. This avoids an error where the CU claims there was no AMF, when
there actually is.
One possible problematic behavior is if a UE disconnects before the gNB
receives an NGAP Initial Context Setup. In this case, the AMF UE NGAP ID
was not forwarded to the RRC (although it was known at NGAP), thus
blocking the release of the UE.
This is the main fix, the rest are minor fixes:
- store AMF UE NGAP ID as early as possible
- warn in MAC if UE unknown for UE context release command
- show TEIDs with correct endianness in GTP
- avoid NG Setup Failure+Setup log.
Introduce SRS physical simulator and improvements
This MR consists of two parts:
- Introduces SRS physical simulator to test different configurations of
SRS
- Improvements in the SRS channel estimation (Addressing the comments
from old, unfinished MR !2875)
- rewrite nr_srs_channel_estimation() to loop over rx antennas and
antenna ports to be able to parallelize
- Improvements in timing_advance_offset and timing_advance_offset_nsec
computation
- Introduce SRS multi-symbol channel estimation
- The channel impulse response is estimated from the averaged
channel frequency response over multiple symbols
- The channel frequency estimates are left as they are to be able to
estimate doppler in the future
- Simplify SRS channel estimation to handle memory alignment in the
case of different SRS configurations (eg: comboffset)
To use multiple symbols when running gNB, the following parameters needs
to be edited in the function get_srs_resource()
- srs_res->resourceMapping.startPosition with a range from {0,1,..,5}
corresponds to the start symbol {13, 12, .. 8} with in a slot
- srs_res->resourceMapping.nrofSymbols indicates the number of symbols
{n1, n2, and n4}
Make sure the that start symbol + number of symbols is < 14
The timing results for SRS in develop and srs_phy_simulator are as follows:
Command used: sudo ./nr_ulsim -n1000 -s50 -S50 -R273 -W2 -y2 -z2 -E 1 -P
develop
|__ RX SRS time 124.94 us (1000 trials) (124.94 total [ms])
|__ Generate SRS sequence time 0.05 us (1000 trials) ( 0.05 total [ms])
|__ Get SRS signal time 19.41 us (1000 trials) ( 19.41 total [ms])
|__ SRS channel estimation time 89.11 us (1000 trials) ( 89.11 total [ms])
|__ SRS timing advance estimation time 13.10 us (1000 trials) ( 13.10 total [ms])
|__ SRS report TLV build time 2.80 us (1000 trials) ( 2.80 total [ms])
|__ SRS beam report build time 0.00 us ( 0 trials)
|__ SRS IQ matrix build time 2.73 us (1000 trials)
srs_phy_simulator
|__ RX SRS time 211.93 us (1000 trials) (211.93 total [ms])
|__ Generate SRS sequence time 0.04 us (1000 trials) ( 0.04 total [ms])
|__ Get SRS signal time 19.55 us (1000 trials) ( 19.55 total [ms])
|__ SRS channel estimation time 152.05 us (1000 trials) (152.05 total [ms])
|__ SRS timing advance estimation time 36.67 us (1000 trials) ( 36.67 total [ms])
|__ SRS report TLV build time 2.96 us (1000 trials) ( 2.96 total [ms])
|__ SRS beam report build time 0.00 us ( 0 trials)
|__ SRS IQ matrix build time 2.88 us (1000 trials)
Note that in srs_phy_simulator, to compute timing offset ns, an
oversampling factor of 2 is performed. Also, for peak detection, we
average the channel estimates for every port.
fix array lenght errors, k variable wrapping threshold. Make the code smaller and more efficient
generate_nr_prach() has several errors coming from replace int16_t by
c16_t, and also older error in k wrapping at the end of the symbol
the code is also ridiculously complex, wasting memory and cpu time in
intermediate useless buffers and headache usage of memmove()
On NGSetupFailure, before moving, we might have
[NGAP] Received NG setup failure for AMF... please check your parameters
[NGAP] Received NGSetupResponse from AMF
In the Initial Context Setup message, the NGAP forwards the AMF UE ID,
but not in the DL NAS Message, although 38.413 says, in $8.3.1.2 either
> The NG-RAN node shall use the AMF UE NGAP ID IE and RAN UE NGAP ID IE
> received in the INITIAL CONTEXT SETUP REQUEST message as identification
> of the logical connection
or in $8.6.2.2
> The NG-RAN node shall use the AMF UE NGAP ID IE and RAN UE NGAP ID IE
> received in the DOWNLINK NAS TRANSPORT message as identification of the
> logical connection
So forward in both cases for harmonization.
It might happen that the RRC does not know the AMF UE NGAP ID, yet. Even
in that case, we should forward the release request to the NGAP module,
which can either forward a message to the AMF, or reply back to release
the UE.
Reported-By: Jegor Zelenjak <jzelenjak@proton.me>
Make gpd config utility global
Make gpd a global utility macro for reading config/command line
parameters. Add a corresponding function with full name for clarity,
keep the short name for the macro for backward compatibility and ease of
use.
The main benefit of gpd/config_get_paramdef_from_name macro/function is
that it does not require maintaining a separate parameter index list.
Update physim timing thresholds in gNB-N300-Timing-Phytest-LDPC
The lower bound for the tests are too tight and any slight improvement
in the timing can result in a test failure. For example, these tests
were failing due to the improvements from the MR !3718
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.
The lower bound for the tests are too tight and any slight improvement in the timing can result in a test failure.
For example, these tests were failing due to the improvements from the MR 3718
- We use the same function at gNB and UE.
- We always use nb_antennas_tx to check the max possible number of ports (which is wrong).
- At gNB, we should use nb_antennas_rx and at the UE, we should use nb_antennas_tx.
The memory alignment is required to use c16multaddVectRealComplex
in SRS channel interpolation. With a change in SRS comb_offset, the
existing algorithm was giving segmentation fault.
The existing srs channel estimation required memory alignment at two
stages. 1. When k = 0 (the first srs subcarrier), 2. When subcarrier <
K_TC (wrapped around after ofdm_symbol_size). Thus two memory alignments
are required leading to complications.
The srs channel estimation is now simplified to do it linearly instead of
wrapping around. This simplified the memory alignment required only when
k = 0.
- Introduce signal energy and noise variance functions
- Combine rotation and OFDM modulation RX as a function
- Harmonize the use of number of antennas across the code
- Rename nr_ue_pusch_common_procedures() to nr_tx_rotation_and_ofdm_mod() to decribe the functionality better
Integration: `2026.w02`
* !3828 L2 UE files code cleanup for static functions
* !3839 Couple rfsim fixes
* !3835 Correctly include cblas include directories for RHEL
* !3840 Fix missing return statements in SIB1 TDA validation
* !3836 move NTN UE L1 functions to a new file
* !3793 CI: Remove redundant Jenkinsfiles
* !3770 RRC UE: Implement proper NH chain synchronization for RRC Reestablishment
* !3843 fix(documentation): issue 1042
* !3842 Remove unused cmake_targets files
* !3832 Remove global iq_txshift and iq_rxrescale
* !3847 Minor CI and nr_ulsim reporting adjustments
* !3838 NR NGAP (N2HO) : Fix Time UE Stayed in Cell IE type and calculation
* !3677 Support prach with start symbol of PRACH not at symbol 0
Closes#1042 and #857
See merge request oai/openairinterface5g!3841
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
Make gpd a global utility macro for reading config/command line parameters.
Add a corresponding function with full name for clarity, keep the short name
for the macro for backward compatibility and ease of use.
The main benefit of gpd/config_get_paramdef_from_name macro/function is that
it does not require maintaining a separate parameter index list.
Support prach with start symbol of PRACH not at symbol 0
The following PRACH indice have been tested.
index / format (nf mod x = y) / Subframe/ start_symbol /no_of_slot / occ / duration
152 B4 2 1 4,9 0 2 1 12
151 B4 2 1 4,9 2 1 1 12
157 B4 1 0 4 0 1 1 12
159 B4 1 0 9 0 1 1 12
NR NGAP (N2HO) : Fix Time UE Stayed in Cell IE type and calculation
According to 3GPP TS 38.413, the 'Time UE Stayed in Cell' IE is an
integer ranging from 0 to 4095. This patch updates the data structure
to reflect the correct bit width and implements the dynamic calculation
based on the UE's residence time.
- Change time_in_cell from long to uint16_t in ngap_messages_types.h.
- Replace dummy value with real-time calculation in rrc_gNB_NGAP.c.
- Implement a ceiling of 4095 to comply with the 12-bit protocol limit.
Ref: 3GPP TS 38.413 Section 9.3.1.97
Refactor key derivation logic to properly handle Next Hop (NH) chain
synchronization according to 3GPP TS 33.501 specifications for both RRC
Reestablishment and Master Key Update procedures.
Changes in rrc_gNB.c:
- Clarify key derivation in rrc_gNB_generate_RRCReestablishment by explicitly
selecting base key (NH or KgNB) based on nh_ncc value
- Add comment explaining vertical vs horizontal derivation logic
Changes in rrc_UE.c:
Refactored the NH chain synchronization and key derivation code to match
TS 33.501 terminology:
- nr_sync_nh_chain(): Common helper to synchronize NH parameter chain per
TS 33.501 Annex A.10, supporting both Master Key Update and RRC Reestablishment
procedures
- nr_derive_kgnb_horizontal(): Derive KNG-RAN* from current KgNB when NCC values
match (horizontal derivation per TS 33.501 A.11/A.12)
- nr_derive_kgnb_vertical(): Derive KNG-RAN* from synchronized NH after NH chain
sync (vertical derivation per TS 33.501 A.11/A.12)
- nr_update_kgnb_from_ncc(): Unified function implementing TS 33.501 6.9.2.3.4
logic for updating KgNB based on received nextHopChainingCount
- Refactor as_security_key_update(): Use new nr_update_kgnb_from_ncc() helper
function for cleaner, more maintainable code
- Fix nr_rrc_ue_process_rrcReestablishment(): Properly handle received
nextHopChainingCount and update KgNB using unified helper function
- Replaced the previous nr_rrc_nh_update() helper with these functions to
improve clarity and alignment with the specification.
- Add debug logging for key derivation process
Key NAS deriver utils:
- update derive_kgnb documentation and protect input keys with const attribute
Closes#857
These files are not used anywhere. The only remaining cmake find files
are:
- findarmral and findxran: used by FHI7.2 driver
- findsctp: used by top-level CMakeLists.txt
- findgnutls: NOT actually used but GnuTLS is a dependency of websrv, so
I leave it for the moment (should be removed if the webserver is
removed)
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
There is no HSS/MME in this repository, which is the majority of this
file. Remove it, since it is outdated.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Setup routes was added by the author of FlexRAN. The UEs always set up
routes automatically, and this file is therefore not needed.
See-also: 287c182925 ("Remove FlexRAN")
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
According to 3GPP TS 38.413, the 'Time UE Stayed in Cell' IE is an
integer ranging from 0 to 4095. This patch updates the data structure
to reflect the correct bit width and implements the dynamic calculation
based on the UE's residence time.
- Change time_in_cell from long to uint16_t in ngap_messages_types.h.
- Replace dummy value with real-time calculation in rrc_gNB_NGAP.c.
- Implement a ceiling of 4095 to comply with the 12-bit protocol limit.
Ref: 3GPP TS 38.413 Section 9.3.1.97
RHEL uses a dedicated cblas include directory. Correctly include this
for the one target PHY_UE that relies on this.
Co-authored-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Per TS 33.501 6.9.2.3.4 and Fig 6.9.2.1.1-1, when sending
RRCReestablishment with nextHopChainingCount, the gNB is staying at
the same NCC level (not advancing). Therefore, horizontal derivation
from the currently active KgNB must be used, not vertical derivation
from NH.
Vertical derivation (from NH) is only used when advancing to a new
NCC level, which happens during handover or masterKeyUpdate procedures.
The previous implementation incorrectly used vertical derivation from
NH whenever nh_ncc > 0, which caused key mismatch between gNB and UE
during reestablishment after handover, leading to integrity check
failures.
This fix ensures both gNB and UE use horizontal derivation when
nextHopChainingCount matches the current NCC level, aligning with the
specification's "virtual NH at NCC=0" model where:
- Horizontal derivation = derive KNG-RAN* from currently active KgNB
- Vertical derivation = derive KNG-RAN* from NH (only when advancing NCC)
During N2 handover, the UE receives reconfigurationWithSync which correctly
sets the target cell frequency in mac->phy_config.config_req.carrier_config
via config_common_ue() call.
However, when SIB1 is decoded after reconfiguration,
nr_rrc_mac_config_req_sib1() calls config_common_ue_sa() which unconditionally
overwrites the frequency with the command-line parameter (downlink_frequency),
which corresponds to the source cell frequency.
This causes a critical issue during RRC re-establishment:
- The UE uses the wrong frequency (source cell) for key derivation (kgnb*)
- The gNB uses the correct frequency (target cell) for key derivation
- This mismatch results in different kgnb* keys on UE and gNB
- Integrity check fails: "Integrity of RRCReestablishment failed, going to IDLE"
Root cause:
config_common_ue_sa() is used for SIB1 processing (initial cell selection) and
uses ServingCellConfigCommonSIB which doesn't contain absoluteFrequencyPointA.
It must derive frequency from command-line parameters. However, after handover,
the frequency has already been correctly set by config_common_ue() (used for
reconfigurationWithSync) which uses ServingCellConfigCommon with absolute
frequency information.
Solution:
Modify config_common_ue_sa() to preserve the existing frequency if it's already
initialized (non-zero). Only set frequency from command-line parameters during
initial cell selection when dl_frequency is 0. This ensures:
- Initial cell selection: frequency derived from command-line parameter, just once
- After handover: frequency preserved from reconfigurationWithSync
- MAC maintains its own frequency state independently
The fix applies to both DL and UL frequencies to maintain consistency.
There is probably room for more refactoring to the resync flow, since
the functionalities in config_common_ue and config_common_ue_sa are
partially overlapping and upon reconfigurationWithSync some other
configurations might be applied twice.
These logs are very helpful to identify cell configuration
changes in MAC/PHY, for monitoring purposes, and to rapidly
signal integrity failures during re-establishment.
The RNTI from the target context was not updated after HO acknowledge
this led to a failure in the first re-establishment after HO.
This commit is introducing the function nr_rrc_apply_target_context
in nr_rrc_n2_ho_acknowledge() and also updates the cell ID for
consistency.
Refactor handover target context application logic into a reusable
function nr_rrc_apply_target_context() that updates both F1AP
associations (secondary UE and DU association) and RNTI from the
target handover context.
And apply to rrc_CU_process_ue_context_modification_response()
Integration: `2025.w52`
* !3809 [FHI72] Fix the PRACH FFT size
* !3829 Hotfix for handling the case where the number of physical antennas is larger than the number of logical antennas
* !3663 NR UE: calculate DL and UL Doppler based on SIB19 information in NTN mode, fixing LEO reestablishment
* !3819 CORESET start multiple of 6 fix
* !3641 automatic selection of SIB1 TDA
* !3804 gNB: apply new NR_CellGroupConfig when RRCReconfiguration is acknowledged
* !3833 Add missing CMakeLists entries for test_nr_frame_params
* !3656 Rfsimulator beam reception/transmission
Closes#1037 and #1002
See merge request oai/openairinterface5g!3830
Rfsimulator beam reception/transmission
A simplified beam switching simulation for rfsimulator. This works
mainly in 1 gNB - N UEs scenarios. This is not a real beamformer with
antenna, channel and propagation model. The way it works is that the
peers inform each other about the beams they transmit in, and on
reception before channel modelling, the beam data is combined based on
preconfigured rx_beam/tx_beam gain matrix.
Usage:
- Add --rfsimulator.enable_beams to enable beam simulation
- Add --rfsimulator.beam_gains .
Example list: 0,-5,-10
Resulting matrix:
[[0, -5, -10] [-5, 0, -5]] [-10, -5, 0]]
- Add --telnetsrv if you want to control the beams manually. The command
in telnet is "rfsimu setbeam <beam_map>", where beam_map is a uint64_t
controling the reception beam and transmission beam. If the
application is switching the beams automatically the beams will be
overwritten as soon as the application chooses to switch beams.
Supports up to 64 concurrent TX and RX beams.
gNB: apply new NR_CellGroupConfig when RRCReconfiguration is acknowledged
Currently part of the NR_CellGroupConfig is already applied when the
RRCReconfiguration message is created. This is not correct and this MR
fixes this by applying it when the RRCReconfiguration message is
acknowledged.
With this fixed, we also move disabling the feedback (in case
disable_harq is used) from the RRCSetup message to the
RRCReconfiguration message.
Closes: #1002
Add CLI parameter rfsimulator.beam_ids which uses a list of beam ids instead of a
beam map. The beam map API is still present and can be used interchangably.
Add telnet command setbeamids which has similar semantics
Allow arbitrary order of beam ids in set_beams2 function. This
allows the application to select any arbitrary order of beam ids.
The underlying transport mechanism still uses beam_map so the beam_ids
are ordered before sending.
Also replaced tx_beam_map/rx_beam_map into beam_map.
Also fixed an issue where --rfsimulator.enable_beams required an argument.
- Added first beam optimization to combine_tx_buffers.
- Added first beam & first peer optimization to rfsimulator_read_internal
This results in significant speed up for the first rx beam, first tx
beam and first peer which is the base case with beam simulation disabled.
In rfsim, received packets are dynamically allocated and freed when no longer
needed, which is dependent on the channel model, packet timestamp and packet
size (number of samples carried).
This commit fixes the packet age check for channels with nonzero channel offset
(most notalby NTN channels).
Also present:
- extract the NTN satellite position update code to a separate function and
call it once per trx_read call instead of once per rx beam.
Add a set of macros with designated initializers to simplify using
paramdef_t arrays in C++ source code. Fix clang error with
RFSIMULATOR_PARAMS_DESC using mixed designated and non-designated
initializers.
- Received packets are dynamically allocated and kept in a
queue for as long as they are needed.
- The layout of the packets was changed from interleaved antennas
to non-interleaved antennas.
- Generate a contiguous buffer from saved packets as needed.
There is extra work caused by this change due to recv() call no
longer saving data directly into the circular buffer, however further
processing is easier due to contiguous nature of the tx antenna buffers
prepared. The impact on performance was not measured.
A simplified beam switching simulation for rfsimulator. This works
mainly in 1 gNB - N UEs scenarios. This is not a real beamformer with
antenna, channel and propagation model. The way it works is that the
peers inform each other about the beams they transmit in, and on
reception before channel modelling, the beam data is combined based on
preconfigured rx_beam/tx_beam gain matrix.
Usage:
- Add --rfsimulator.enable_beams to enable beam simulation
- Add --rfsimulator.beam_gains <comma separated Toepliz form matrix of gains in dB>.
Example list: 0,-5,-10
Resulting matrix:
[[0, -5, -10]
[-5, 0, -5]]
[-10, -5, 0]]
- Add --telnetsrv if you want to control the beams manually. The command in telnet
is "rfsimu setbeam <beam_map>", where beam_map is a uint64_t controling the
reception beam and transmission beam. If the application is switching the beams
automatically the beams will be overwritten as soon as the application chooses to
switch beams.
Co-authored-by: Laurent Thomas <laurent.thomas@open-cells.com>
CORESET start multiple of 6 fix
According to the standard any CORESET (except CSET0) would always start
from the first common resource block index which is multiple of 6 in the
BWP. This was not taken into account in the code. The BWP switch CI test
is modified to test a BWP start not multiple of 6.
An exception is the case where rb-Offset-r16 parameter is set, but can't
be used at gNB for FAPI compatibility.
Closes: #1037
[FHI72] Fix the PRACH FFT size
ru_config->fftSize is used for the C-plane Section Type 3 which is
dedicated for PRACH and mixed numerology. Previously, we assumed that
PRACH FFT size is equivalent to PxSCH FFT size, but should be based on
the PRACH format.
Tests with the following RUs:
- [x] Benetel v1.2.2 & v1.4.1
- [x] VVDN Gen 3
- [x] Liteon 02.00.10
- [x] Metanoia v2.2.8 (Jura)
Integration `2025.w51`
* !3816 Add two missing include guards
* !3715 Pass beam ID as per FAPI v222.10
* !3777 UE NTN : Fix in case SIB19 periodicity is greater than 2 secs
* !3813 Reset outdated PUCCHs to avoid Assertion caused by non-processed and active PUCCHs
* !3815 Remove phy_extern_nr_ue file
* !3824 CI: adjust UE attach timeout handling
* !3735 vrtsim: Optimize channel modelling
See merge request oai/openairinterface5g!3817
Per TS 33.501 6.9.2.3.4 and Fig 6.9.2.1.1-1, when sending
RRCReestablishment with nextHopChainingCount, the gNB is staying at
the same NCC level (not advancing). Therefore, horizontal derivation
from the currently active KgNB must be used, not vertical derivation
from NH.
Vertical derivation (from NH) is only used when advancing to a new
NCC level, which happens during handover or masterKeyUpdate procedures.
The previous implementation incorrectly used vertical derivation from
NH whenever nh_ncc > 0, which caused key mismatch between gNB and UE
during reestablishment after handover, leading to integrity check
failures.
This fix ensures both gNB and UE use horizontal derivation when
nextHopChainingCount matches the current NCC level, aligning with the
specification's "virtual NH at NCC=0" model where:
- Horizontal derivation = derive KNG-RAN* from currently active KgNB
- Vertical derivation = derive KNG-RAN* from NH (only when advancing NCC)
Refactor key derivation logic to properly handle Next Hop (NH) chain
synchronization according to 3GPP TS 33.501 specifications for both
RRC Reestablishment and Master Key Update procedures.
Changes in rrc_gNB.c:
- Clarify key derivation in rrc_gNB_generate_RRCReestablishment by
explicitly selecting base key (NH or KgNB) based on nh_ncc value
- Add comment explaining vertical vs horizontal derivation logic
Changes in rrc_UE.c:
- Add nr_sync_nh_chain(): Common helper to synchronize NH parameter
chain per TS 33.501 Annex A.10, supporting both Master Key Update
and RRC Reestablishment procedures
- Add nr_derive_kgnb_horizontal(): Derive KNG-RAN* from current KgNB
when NCC values match (horizontal derivation per TS 33.501 A.11/A.12)
- Add nr_derive_kgnb_vertical(): Derive KNG-RAN* from synchronized NH
after NH chain sync (vertical derivation per TS 33.501 A.11/A.12)
- Add nr_update_kgnb_from_ncc(): Unified function implementing TS 33.501
6.9.2.3.4 logic for updating KgNB based on received nextHopChainingCount
- Refactor as_security_key_update(): Use new nr_update_kgnb_from_ncc()
helper function for cleaner, more maintainable code
- Fix nr_rrc_ue_process_rrcReestablishment(): Properly handle received
nextHopChainingCount and update KgNB using unified helper function
- Add debug logging for key derivation process
Key NAS deriver utils:
- update derive_kgnb documentation and protect input keys with const attribute
Make sure to apply Doppler and TA not directly when receiving the target cell ntn_config,
but apply Doppler just before the initial sync, and the TA after the initial sync when
we have tha actuel cell frame and slot numbers.
We need the ntn_config when reconfiguring the PHY layer for a new initial sync,
e.g. for calculating the DL Doppler frequency.
As a dedicated scheduled_response dl_config PDU it reaches the PHY layer too late,
as part of the phy_config.config_req it reaches the PHY layer in time with the
other configuration values.
vrtsim: Optimize channel modelling
Optimization pass for channel modelling on transmission in vrtsim. This
comes from a requirement of O-RU to perform channel modelling with minimum
latency. The latency measured in O-RU 4TX 2RX on the UE is lowered from
~400 uS to ~100uS.
- Reduced MAX_CHANNEL_LENGTH to 200 and introduced SAVED_SAMPLES_LEN
- Refactored channel modelling actor allocation to parallelize work better
- Improved batching and task creation for channel modelling
- Replaced static global saved_samples with local static buffer in vrtsim_write_with_chanmod
Create a new CI pipeline for testing with vrtsim on Gracehopper:
https://jenkins-oai.eurecom.fr/job/RAN-VRT-Sim-Test-5G/
CI: adjust UE attach timeout handling
This modification addresses an issue in the RFSim-5G 2x2 test where the UE
often fails to attach within the initial 20s window. The timeout may cause
the UE to restart, which leads to two UEs appearing in the gNB log. By
increasing the initial timeout to 40s, we avoid unnecessary restarts.
- Set default attach_timeout to 40s
- Increase timeout only after failed attach attempts
This modification addresses an issue in the RFSim-5G 2x2 test where the UE
often fails to attach within the initial 20s window. The timeout may cause
the UE to restart, which leads to two UEs appearing in the gNB log. By
increasing the initial timeout to 40s, we avoid unnecessary restarts.
This function is to be called by the application to switch beams
on reception and transmission. When receiving new samples using
trx_read/trx_write the application is expected to be able to
determine which beam the samples belong to.
Reset outdated PUCCHs to avoid Assertion caused by non-processed and
active PUCCHs
When there is real-time issues in L1 it may happen that the scheduler
misses/skips some slots, thus, L2 not processing and not freeing some
structures like PUCCH. This commit avoids the Assertion by resetting
any Active outdated PUCCH
UE NTN : Fix in case SIB19 periodicity is greater than 2 secs
This was observed when testing OAI NTN UE against a third party gNB (UXM).
LEO SIB19 periodicity of > 2000 ms was used, in which case T430 timer expires
before SIB19 is re-read. This fix handles the case where SIB19 periodicity >
2secs, such that SIB19 is re-read in time and T430 timer does not expire.
Pass beam ID as per FAPI v222.10
This MR
1. Sets MSB of beam ID when passing beam ID to 7.2 radio
2. Modifies phytest scheduler to allocate SSBs on different beams
3. Introduce new MAC config parameter for beam mode to specify HiPHY or LoPHY
beamforming
In perfrom_channel_modelling, do convolution in batches which allows
vrtsim to write the channel samples as they are being produced instead
of waiting for the last sample in the slot to be ready.
Limit sample history to 256 samples and copy it into each channel modelling
task instead of relying on globally available buffer. This simplifies the code
and addressing into the saved samples buffer as well as enabling further
optimizations without sacrificing thread safety.
We assumed that PRACH FFT size is equivalent to PxSCH FFT size.
However, the parameter ru_config->fftSize is used for the C-plane Section Type 3
which is dedicated for PRACH and mixed numerology.
Based on the PRACH format, short or long, the PRACH values 256 or 1024
shall be filled.
Co-authored-by: knopp <raymond.knopp@eurecom.fr>
When doing analogue beamforming, the beam ID for a pre-defined beam
table is passed directly to RU and there is no need to store the beam
table in PHY.
When there is real-time issues in L1 it may happen that the scheduler misses/skips some slots, thus, L2 not processing and not freeing some structures like PUCCH.
This commit avoids the Assertion by resetting any Active outdated PUCCH
Integration `2025.w50`
* !3638 NR UE: calculate TA based on SIB19 information in NTN mode, if autonomous TA is not enabled
* !3624 NR UE: improve handling of Handover procedures
* !3807 doc: Update doc for IF setup
* !3741 Update documenation for handover
* !3798 Fix for computation of PRACH occasions and association period
* !3808 Add symbol timing functions for NR_DL_FRAME_PARMS + optimization for slot timing counterparts
Closes#981
See merge request oai/openairinterface5g!3806
Add symbol timing functions for NR_DL_FRAME_PARMS + optimization for slot timing
counterparts
Add two new functions for calculation symbol timestamp and symbol duration for
NR_DL_FRAME_PARMS. Also includes an optimization focused on removing
inefficiencies related slot-related counterparts.
1. Removed function pointers for functions get_samples_per_slot(),
get_samples_slot_timestamp() and get_slot_from_timestamp() as it does
not offer any advantage. The functions are now called directly from
everywhere.
2. Optimized these functions by removing loops where ever possible.
Update documenation for handover
Update documentation for handover to include the changes that were made after
upgrading the CI handover setup (attenuator, USRPs synchronization)
NR UE: calculate TA based on SIB19 information in NTN mode, if autonomous TA is not enabled
To achieve the goal, the hyper frame number (HFN) is introduced at the NR UE
PHY, MAC and RRC layers.
Besides this, we also implemented an orbit propagation to improve the accuracy
of N_UE_TA_adj, and a fix to keep the N_TA from RAR and MAC CE.
Fixes#981
Add two new functions for calculation symbol timestamp and symbol
duration for NR_DL_FRAME_PARMS. These functions are not using
the existing indirection mechanism via function pointers as this
prevents the compiler from properly optimizing the code.
Fixed an issue where if threadpool was aborted when some threads were in a running
state the threadpool would never exit. This was due to the fact that the thread
terminate task (func == NULL && args == NULL) could have been pushed to queues which
were inactive. This change adds a uint64_t mask of threads that have already exited
so whenever the terminate task is sent to another queue, it is ensured that the queue
used will wake up at least one tpool worker.
Also added pushTpool_mask which allows to specify a subset of threads to push the task
to but its only used internally.
Also added in this commit: A way to allocate thread-safe storage for thread pool
workers via get_tpool_worker_index. This index is unique to the thread pool worker
within one threadpool and can be used to access arrays in a thread-safe manner.
An example of such use was added in a testcase that was added which compares delay
between actors and threadpool workers.
Fix FAPI WLS timing, UL counter, doc
- Fix FAPI WLS timing
- Fix periodical PNF UL throughput logs
- Update documentation to better explain how to run WLS with radio (USRP
B210)
Fixes for BWP switching
This MR fixes some issues when performing BWP switching via
reconfiguration. It also adds a CI test for BWP switching. # Please
enter a commit message to explain why this merge is necessary,
In all cases (CFRA in SA for HO, or CFRA in NSA/do-ra for access), the
UE has the full configuration already. We can therefore directly switch
to a dedicated search space, as it is already known to the UE.
... so if we want to have 1 BWP configured at any given time we need to
reconfigure BWP 1 every time. This means that since the gNB has more
than 1 BWPs (for use for different UEs), that there is a "gNB BWP ID"
(as used by the gNB), which can be any BWP ID X, and one "UE BWP ID",
which is always 1. This commit implements this distinction.
Return from triggering reconfiguration with BWP switch if BWP is the
same as before the switch, and add check to verify if BWP triggered by
switch command exists
Current FAPI slot_ahead value for WLS is too low for UL, as we see these
errors:
[NR_MAC] Unexpected ULSCH HARQ PID 14 (have 3) for RNTI 0xa68e
[NR_MAC] UE a68e expected HARQ pid 3 feedback at 586. 7, but is at 587.17 instead (HARQ feedback is in the past)
Similarly to nFAPI, scale it by mu (for mu=1 => slot_ahead=2) to give
additional time, which removes these warnings at the VNF.
E2SM-RC RRC message forwarding (e.g., to signal a new UE, measurement
reports, ...) was broken since commit d6c29b2d2c, as we accidentally
removed the E2_AGENT compilation definition from RRC layer.
Although this commit fixes the mentioned issue, it also causes undefined
references to functions defined in ran_func_rc.c file. Therefore, we
add a hack that provides the definition, and abort if we ever hit these
functions, which in theory should not happen.
Future cleanup should avoid linking in RRC and other layers into
simulators.
Fixes: d6c29b2d2c ("Fix E2_AGENT linking w.r.t. simulators ")
Testing has revealed that if PDCP drops some packets, the scheduler
falls behind with handling Slot.indication. It could be that we don't
have enough cores, which was reduced previously (from total 8 -> 2).
Reincrease to four cores to have a bit more headroom.
See-also: a18a4888ec ("Change number of cores used for OAI gNB from 8 to 2")
The PDUSessionResourceReleaseResponse message was missing the mandatory
pDUSessionResourceReleaseResponseTransfer IE in each released PDU session item. This caused Open5GS to send an error indication.
Changes:
- Add encode_ngap_pdusession_release_response_transfer() function to
properly encode the transfer structure (empty since Secondary RAT Usage
Information is optional and not used, per 9.3.4.21)
- Always include the mandatory PDUSessionResourceReleasedListRelRes IE
- Always encode the pDUSessionResourceReleaseResponseTransfer for each
PDU session item
- Fix Release Command handler to decode and log Cause from command transfer:
instead of incorrectly copying command data to response: the 2 transfer
IEs in the Command and the Response messages are different and should
not be mixed
- Split Command/Response struct type definitions
- Add missing includes
1) Remove UE Context Release Response code: there is no
such thing in the specs, it is either UE Context Release Request
(NG-RAN node initiated) or UE Context Release (AMF initiated)
(3GPP TS 38.413). The former message has only the request, no
response is defined by the specs. The code in the stack had no
purpose at all and was removed.
2) The UE Context Release Request message only contains a PDU
Session Resource List (optional) of PDU Session IDs, therefore
the use of pdusession_release_t was wrong and was refactored
Add yq to edit yaml files and add yaml-dev library in containers missing it
- nr-cu-up and some containers were missing the yaml-config support
libraries
- yq tool is required to manipulate YAML files from within the container
for Helm charts
Consistently use OAI_RNGSEED env variable for RNG
use OAI_RNGSEED env variable everywhere. Hide normal table
initialization of Ziggurat generator from outside. Fix atoi() to use
stroul()
atoi() used previously does not capture all of unsigned long (so we
could not reproduce a high seed), and its use is discouraged as it does
not detect errors. Use strtoul() instead, which allows to also use other
bases (so we can e.g., write OAI_RNGSEED=0x1234)
Hide normal table initialization of Ziggurat generator from outside to
force the usage of randominit() for RNG initialization. In this step,
remove the randominit() seed parameter and only rely on OAI_RNGSEED for
a consistent RNG initialization, as this parameter was used differently
("0" as fixed number or to force a random seed).
Now, only use OAI_RNGSEED env variable to force the usage of a fixed
seed.
Integration `2025.w48`
* !3778 CI: Update IP addresses in Aerial gNB config files
* !3659 UE NTN - Epoch time handling for Target cell
* !3772 CI: Ensure EPC is always terminated in NSA-B200 pipeline
* !3773 Fix doc for UTC timestamp
* !3759 NR UE: fix bug for SRS generation when freqDomainShift (n_shift) is not 0
* !3774 Use UL functions for Qm/R determination
* !3767 Fix DRB integrity failures during handover and re-establishment
* !3764 Avoid measGap configuration on handover in intra-freq scenarios
* !3768 Fix MIB encoding in F1SetupRequest: use encode_MIB_NR_setup instead of encode_MIB_NR
* !3771 CI build analysis: print log file errors
* !3703 Taking into account UE capabilities for TBS_lbrm layers
* !3561 Implementation of STOP exchange
* !3776 Fix reestablishment after handover
* !3763 CI: Reduce the tries to attach the UE in CI runs
* !3761 fix(FHI 7.2): PRACH frame test
* !3616 [FHI72 M-plane] Update the M-plane support to v16.01
* !3790 Correctly copy nFAPI messages
* !3779 CFRA: mark RA complete when sending Msg2 - check CI
Closes#563 and #1034
See merge request oai/openairinterface5g!3775
CFRA: mark RA complete when sending Msg2
The current contention-free random access forces a "Msg3" (which does
not exist in CFRA) to be received by a UE. Sometimes, this "Msg3" is not
received (for whatever reason), and the MAC declare that RA failed.
This is problematic, as the spec says that RA is complete once Msg2 is
received by the UE. Since the gNB cannot know when this is, simply mark
it as complete once we sent Msg2.
We still send Msg3 in CFRA, which is explained further in the commits.
Also, improve logging and stabilize an RFsim test by reducing sl_ahead.
Correctly copy nFAPI messages
All nFAPI message have copy helpers, so use that for "loading" nFAPI
messages into the L1. This also fixes a bug/error message
2. 0 no corresponding tx_data.request for dl_tti.request index 11, dropping
because the loop over DL_tti.request assumed that all messages are PDSCH
PDUs, when we can have others such as PDCCH, etc. In other words, when
looking up indices ("11" in the example above), we were checking also
inside other messages for SSB, PDCCH, etc, which is of course wrong.
That loop was an attempt to validate matching PDSCH PDUs with
TX_data.requests. This check is already done inside
phy_procedures_gNB_TX() through an assert, but this commit replaces with
the equivalent check previously inside nr_pnf_p7_get_msgs(). This is ok,
as the L1 cannot trust the scheduler (in monolithic) to provide the
correct information, either.
Fixes: eefb9da6 ("Reimplement nFAPI message exchange after msgDataTx removal")
[FHI72 M-plane] Update the M-plane support to v16.01
- retrieve the additional hardware states (oper-state, admin-state,
availability-state) and update according to the received notifications
- properly configure MIMO mode if a RU supports
- update the yang models to v16.01
- tested with Benetel v1.4.1, and added an example run in the M-plane doc
Note: backwards compatible with M-plane v05.00
Also, memory leakages fixed cause by ru_session_list_t, and xml functions
xmlReadMemory() and xmlNodeGetContent().
fix(FHI 7.2): PRACH frame test
A test was missing in the PRACH RX function of the FHI 7.2 in order to know if
the frame had a PRACH occasion. This was leading to continuous warning messages
as PRACH RX was triggered on frames in which PRACH was not expected by the
scheduler.
CI: Reduce the tries to attach the UE in CI runs
The goal of this MR is to save time in CI runs by reducing the UE attach tries
to 3 instead of 4 and UE timeout to 20 seconds, which will be incremented after
each fail, instead of 60 seconds.
Since the parent commit, CFRA is inconditionally marked complete on Msg3
reception (successful or not). This works because the current
implementation still sends a UL grant (see parent commit for details).
In this commit, handle Msg3 if received in CFRA (notably for TA and
power). Note that since we declare RA complete, UE->ra does not exist
anymore, and so an intermediate variable is introduced to capture the
CFRA flag. The code should be such that if we are in CFRA, we never
access any UE->ra variable.
All nFAPI message have copy helpers, so use that for "loading" nFAPI
messages into the L1. This also fixes a bug/error message
2. 0 no corresponding tx_data.request for dl_tti.request index 11, dropping
because the loop over DL_tti.request assumed that all messages are PDSCH
PDUs, when we can have others such as PDCCH, etc. In other words, when
looking up indices ("11" in the example above), we were checking also
inside other messages for SSB, PDCCH, etc, which is of course wrong.
That loop was an attempt to validate matching PDSCH PDUs with
TX_data.requests. This check is already done inside
phy_procedures_gNB_TX() through an assert, but this commit replaces with
the equivalent check previously inside nr_pnf_p7_get_msgs(). This is ok,
as the L1 cannot trust the scheduler (in monolithic) to provide the
correct information, either.
Fixes: eefb9da69a ("Reimplement nFAPI message exchange after msgDataTx removal")
A test was missing in the PRACH RX function of the FHI 7.2 in order to
know if the frame had a PRACH occasion.
This was leading to continuous warning messages as PRACH RX was
triggered on frames in which PRACH was not expected by the scheduler.
The current contention-free random access forces a "Msg3" (which does
not exist in CFRA) to be received by a UE. Sometimes, this "Msg3" is not
received (for whatever reason), and the MAC declare that RA failed.
This is problematic, as the spec says that RA is complete once Msg2 is
received by the UE. To avoid this, inconditionally mark RA as complete
as soon as we receive an indication of Msg3 (DTX or not).
Note that after this change, we still send a UL grant in Msg2. This is
because 38.321 §5.1.4 is not clear to me whether we should send UL grant
(it does not explicitly exclude it), and it says
> 3> if the Random Access Response includes a MAC subPDU with RAPID only:
> [...]
> 4> indicate the reception of an acknowledgement for SI request to
> upper layers.
which is NOT the case (but then I don't know/think we can have CFRA for
SI request?). Since it also works with COTS UE, I leave Msg3 for the
moment.
The reason to not directly mark RA as complete when sending Msg2 is
because of possible retransmissions in do-ra mode. In fact, in do-ra,
there might already be data awaiting. In that case, the DLSCH scheduler
schedules data _in the same slot as Msg2_, which the UE does not decode,
leading to retransmissions.
Implementation of STOP exchange
This implements the STOP.request/indication for all 3 transport mechanisms, the
VNF will send the STOP.request to the PNF, indicating it will disconnect, and
await a STOP.indication from the PNF
The WLS VNF is reworked to be able to start before the PNF, by calling call
rte_eal_init and rte_dev_probe to determine if dpdk has been initialized
properly, before calling rte_eal_init in the intended process when it is
appropriate to do so
Fix reestablishment after handover
- fix reestablishment by not re-creating LCIDs with priority set to 0 (see first
commit for more details)
- cleanup code
CI build analysis: print log file errors
The generated HTML from CI builds so far only shows the number of errors, but
not the errors themselves. This is inconvenient, as this means that developers
have to go to the logs.
This commit modifies AnalyzeBuildLogs(), which already iterates the entire file,
to store the lines containing "error:" (as it would be emitted by a compiler).
The callers of AnalyzeBuildLogs() now also print the analysis outcome in a more
concise manner.
Also, change the return parameter of AnalyzeBuildLogs() to a tuple to make the
variable handling easier, and remove the unused warnings list.
The idea is to reestablish all RLC entities (it's a new UE, and we set
reestablishRLC on all bearerrs), so we should reestablish all RLC
entities on gNB side as well, without any additional loop.
Co-authored-by: Roberto Magueta <rmagueta@allbesmart.pt>
Move the file process_addmod_bearers_cellGroupConfig() to the file where
it is used. Correctly set priorities as requested in RLC bearer
configuration.
In all cases (NSA, HO), we create LCIDs before the UE triggers random
access. Hence, process_addmod_bearers_cellGroupConfig() is not
necessary, as it just tries to recreate an LCID.
Furthermore, it includes a bug, as this function does set a wrong
priority (0), so the sorting of LCIDs is not correct. This in turn
creates problems with reestablishment, as LCID 1/SRB1 is not in the
first position, making reestablishment fail (where we assume LCID 1 be
in first position).
The actual bug of setting priorities is fixed in the next commit.
Fix MIB encoding in F1SetupRequest: use encode_MIB_NR_setup instead of encode_MIB_NR
- The DU was using encode_MIB_NR() while constructing the GNB-DU System
Information for the F1SetupRequest.
- encode_MIB_NR() encodes a full NR_BCCH_BCH_Message_t, causing the MIB to be
wrapped in a BCH container.
- This results in incorrect MIB values in the F1SetupRequest PCAP (e.g., wrong
systemFrameNumber, SCS, DMRS position, cellBarred).
- According to 3GPP TS 38.473, the MIB carried in F1AP must be encoded as a raw
NR_MIB_t.
- The correct function encode_MIB_NR_setup() encodes MIB in the required format
but was not used.
- This patch replaces encode_MIB_NR() with encode_MIB_NR_setup() to ensure correct
and standards-compliant MIB encoding in the F1SetupRequest.
Closes issue #1034.
Fix DRB integrity failures during handover and re-establishment
This MR fixes DRB integrity protection failures that occur during N2 handover
and connection re-establishment scenarios. The issues were caused by incorrect
security key handling and ciphering configuration during these procedures with
DRB integity enabled.
See merge request !3767 for more details.
Avoid measGap configuration on handover in intra-freq scenarios
During the handover, we are incorrectly configuring the measGap, even though
neighboring cells are on the same frequency. Since gNB is not expecting this
measGap, the SRS scheduling is performed. Therefore, we are periodically
receiving these logs after the handover:
[NR_MAC] Invalid timing advance offset for RNTI 58e2
[NR_MAC] Invalid timing advance offset for RNTI 58e2
[NR_MAC] Invalid timing advance offset for RNTI 58e2
[NR_MAC] Invalid timing advance offset for RNTI 58e2
[NR_MAC] Invalid timing advance offset for RNTI 58e2
[NR_MAC] Invalid timing advance offset for RNTI 58e2
These logs occur at a time when UE is performing a MeasGap operation and not
sending the SRS, while gNB thinks it will receive the SRS, but will not receive
any SRS.
This MR resolves this issue, and after the handover, these logs no longer
appear.
CI: Update IP addresses in Aerial gNB config files
This MR updates the NG-AMF and NG-U IP addresses in both Aerial configuration
files (standard and UL-heavy) following the IP address change on GH1.
Use UL functions for Qm/R determination
During refactoring, the wrong functions and correspondingly tables have
been used to calculate UL TB size. Fix through correct functions.
This should fix these error messages:
3624774.778195 [MAC] E (nr_get_Qm_dl:2034) Invalid MCS table index 3 (expected in range [0,2])
3624774.778207 [MAC] E (nr_get_code_rate_dl:2066) Invalid MCS table index 3 (expected in range [0,2])
3624774.778211 [NR_MAC] E (nr_compute_tbs:63) Error in compute TBS with a NULL input, returning NULL TBS
Fixes: 9449f777 ("Remove TBS table and recompute on demand")
NR UE: fix bug for SRS generation when freqDomainShift (n_shift) is not 0
According to TS 38.211 section 6.4.1.4.3, the frequency domain shift value
n_shift is from higher-layer parameter freqDomainShift. The quantity n_RRC
is given by higher-layer parameter freqDomainPosition. Also corrected
k_0_overbar_p calculation formula to align with standard.
Fix doc for UTC timestamp
After merging !3751 (merged), the UTC timestamp now prints only the time.
Update the documentation to reflect this simplified format.
UE NTN - Epoch time handling for Target cell
In case of Handover, NTNconfig sent in RRCreconfiguration triggering handover
contains epoch time wrt timing of Target cell. NTNconfig in RRC needs to be
processed only after timing is acquired on the target cell.
In case of Target cell, epoch time is the sfn nearest to the frame timing of the
target cell.
During refactoring, the wrong functions and correspondingly tables have
been used to calculate UL TB size. Fix through correct functions.
This should fix these error messages:
3624774.778195 [MAC] E (nr_get_Qm_dl:2034) Invalid MCS table index 3 (expected in range [0,2])
3624774.778207 [MAC] E (nr_get_code_rate_dl:2066) Invalid MCS table index 3 (expected in range [0,2])
3624774.778211 [NR_MAC] E (nr_compute_tbs:63) Error in compute TBS with a NULL input, returning NULL TBS
Fixes: 9449f777cc ("Remove TBS table and recompute on demand")
This change updates the NSA-B200 CI pipeline to guarantee that the EPC is
properly terminated regardless of pipeline success or failure. This avoids
leaving EPC processes running after failed test.
The generated HTML from CI builds so far only shows the number of
errors, but not the errors themselves. This is inconvenient, as this
means that developers have to go to the logs.
This commit modifies AnalyzeBuildLogs(), which already iterates the
entire file, to store the lines containing "error:" (as it would be
emitted by a compiler). The callers of AnalyzeBuildLogs() now also print
the analysis outcome in a more concise manner.
Also, change the return parameter of AnalyzeBuildLogs() to a tuple to make
the variable handling easier, and remove the unused warnings list.
- The DU was using encode_MIB_NR() while constructing the GNB-DU System Information for the F1SetupRequest.
- encode_MIB_NR() encodes a full NR_BCCH_BCH_Message_t, causing the MIB to be wrapped in a BCH container.
- This results in incorrect MIB values in the F1SetupRequest PCAP (e.g., wrong systemFrameNumber, SCS, DMRS position, cellBarred).
- According to 3GPP TS 38.473, the MIB carried in F1AP must be encoded as a raw NR_MIB_t.
- The correct function encode_MIB_NR_setup() encodes MIB in the required format but was not used.
- This patch replaces encode_MIB_NR() with encode_MIB_NR_setup() to ensure correct and standards-compliant MIB encoding in the F1SetupRequest.
Closes issue #1034.
Problem:
During N2 handover with integrity protection (NIA1/NIA2), the target gNB
was disabling ciphering when configuring SRB1 security, while the UE
continued using the old security context from the source gNB until it
received and processed the RRC Reconfiguration with masterKeyUpdate. The
first PDUs sent after CFRA were still ciphered with the old keys, but the
target gNB had ciphering disabled, causing it to skip deciphering and
attempt integrity verification on ciphered data, leading to MAC-I
mismatches and integrity failures.
Specification Reference:
According to TS 33.501 section 6.11, "the UE shall keep the K gNB used in
the source cell until the handover or a connection re-establishment has been
completed successfully". This means the UE continues using the old security
context (old KRRCint, KRRCenc) until it receives and processes the RRC
Reconfiguration with masterKeyUpdate. The target gNB must therefore enable
ciphering during handover setup to correctly decipher and verify integrity
of PDUs sent with the old security context before the UE switches to the new
keys.
Root Cause:
The code was calling nr_rrc_pdcp_config_security(UE, false) during
handover setup, which disabled ciphering. This was incorrect because:
1. The UE already has security active from the source gNB
2. The UE continues using old ciphered keys until masterKeyUpdate
3. The UE sends ciphered PDUs immediately after CFRA succeeds
4. The target gNB must be able to decipher these PDUs to verify integrity
Why it only manifested when drb_integrity = "yes":
The bug was always present, but only caused visible failures when
integrity verification was enabled. When drb_integrity = "no", the config
typically also sets integrity_algorithms to only NIA0, resulting in
UE->integrity_algorithm = 0, which causes has_integrity = 0 for SRB1,
skipping integrity verification and hiding the underlying ciphering bug.
When drb_integrity = "yes", integrity_algorithms typically includes
NIA1/NIA2, resulting in has_integrity = 1 for SRB1, causing integrity
checks to run on ciphered data and fail.
Fix:
Change nr_rrc_pdcp_config_security(UE, false) to
nr_rrc_pdcp_config_security(UE, true) during handover setup to enable
ciphering immediately, allowing the target gNB to correctly decipher and
verify integrity of PDUs sent with the old security context.
Note: This fix is specific to handover. During initial context setup,
ciphering should remain disabled until SecurityModeComplete is received,
as the UE hasn't activated ciphering yet at that point.
During re-establishment, new KgNB* is derived, requiring new UP keys (KUPint,
KUPenc) to be sent to CU-UP. When do_drb_integrity = true, CU-UP needs the
updated integrity keys to verify DRB PDUs. Without this update, CU-UP uses
old keys while the UE uses new keys, causing integrity failures.
The fix ensures security info is always sent during re-establishment,
which is critical for DRB integrity.
Instead of using the projected velocity and acceleration vectors,
calculate vel_sat_gnb and acc_sat_gnb so the delay is correct for
epoch_time, epoch_time + 5 seconds and epoch_time + 10 seconds.
Separate timing_advance (N_TA) from timing_advance_ntn (N_common_TA_adj + N_UE_TA_adj)
to keep N_TA when updating N_common_TA_adj + N_UE_TA_adj.
Fixes#981
Instead of trying to estimate N_UE_TA_adj with a second degree polynomial,
we introduce orbit propagation to calculate N_UE_TA_adj with higher accuracy.
When we receive the satellite ephemeris data consisting of the satellite position vector
and the satellite velocity vector, we calculate parameters for orbit propagation, assuming
a circular orbit in the plane created by the satellite position vector and the satellite
velocity vector. This is done in the function prepare_ue_sat_ta().
Every millisecond, we use these parameters together with the time since epoch to calculate
the satellite position on that orbit and from this the reound-trip-time between UE and the
satellite, what corresponds to N_UE_TA_adj. This is done in the function apply_ntn_timing_advance().
In case of Handover, NTNconfig sent in RRCreconfiguration triggering handover contains epoch time wrt
timing of Target cell. NTNconfig in RRC needs to be processed only after timing is acquired on the target cell
In case of Target cell, epoch time is the sfn nearest to the frame timing of the target cell.
Integration `2025.w46`
* !3754 NR UE: correctly provide measured SSB SINR value from PHY to MAC
* !3666 NTN: Fixing variable ULDLduplex issue for NTN bands
* !3747 SDAP: guard RX header parsing with enable_sdap and init per-entity
* !3729 DCI 00 alt size fix
* !3753 gNB: fix MAC TA command scheduling if measurement gaps are configured
* !3722 [NGAP] Fix incorrect AMF Set ID type (uint8 → uint16) causing AMF lookup failure
* !3745 Collection of small fixes
* !3755 CI: Increase tested UL throughput on Aerial pipeline using 2L UL
* !3752 [MAC] Add UL total/used aggregated MAC stats; [E2 agent] Properly calculate used UE PRBs in KPM
* !3707 Cleanup phy_procedures_gNB_uespec_RX
* !3750 Handling newly opened UE issues
* !3751 Update log header format to align log output
* !3757 Remove schedule response and update L1 threading documentation
* !3748 Refactor imscope
* !3760 gNB: modify RLC configuration applied for SRB1 during RRCReestablishment
* !3684 PDU Session Release
Closes#867, #960, #1025, #1024, #1026, #1031, #1030, and #1012
See merge request oai/openairinterface5g!3756
PDU Session Release
This MR implements end-to-end PDU Session Release functionality
according to 3GPP TS 38.413 and TS 38.331 specifications.
Reason for Change Previous implementation had incomplete and wrongly
places tunnel cleanup during PDU session release. UP cleanup shall be
done at CUUP, RRCReconfiguration shall be sent after retrieval of
updated CellGroupConfig from the DU. This implies F1 and E1 exchanges
during PDU session release procedure.
Major Changes:
1. RRC PDU Session Release: DRBs and PDU session teardown in NGAP PDU
Session Release Response callback
- Helper Functions: Introduced rm_pduSession,
find_drb_by_pdusession_id and rm_drbs() helpers to locate and clean
up DRBs linked to a specific PDU session
- Targeted Cleanup: RRC PDU Session and per-session DRB removal in
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE()
- Status Cleanup: Removed unused PDU_SESSION_STATUS_RELEASED status
2. RRC PDU Session Release: Refactor
rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND
- Any PDU session in the pdusession_release_params list that is
present in the RRC list can be set to release, regardless of its
status
- Function Signature Update: Updated function signature and other
minor changes
- Response Handling: rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE is
sent upon completion of RRCReconfiguration
3. RRC PDU Session Release: add missing procedures E1AP Integration:
- Populates E1AP Bearer Modification for each to be released session
- PDCP Enhancement: Added nr_pdcp_release_drbs() to remove all DRBs
linked to a given PDU session in CUUP
- GTP-U Cleanup: GTP tunnel teardown handled in CUUP
e1_bearer_context_modif() using correct F1 or N3 GTP instance
4. NR PDCP/GTP:
- Enhanced Tunnel Deletion Logic: Separate handling for N3 tunnels (1
per PDU session) and F1-U tunnels (1 per DRB)
- New PDCP API Function: Added nr_pdcp_get_drb_ids_for_pdusession()
function to retrieve all DRB IDs associated with a specific PDU
session
5. RRC PDU Session Release: F1AP-based UE Context Modification:
- Replaced direct RRC message transfer with F1AP UE Context
Modification Request for proper retrieval from DU
- Cell Group Configuration: handling of updated CellGroupConfig from
DU ensures DRB release at CU
6. Docs and testing:
- Added PDU session add/remove test cases to 25 PRB RFSIM pipeline
- Documentation: Added PDU Session Release sequence diagram
- Telnet Commands: Added ci command to trigger NGAP PDU Session
Release and ciUE command to trigger establishment of a new PDU
Session
7. Additional fixes:
- UE RLC Management: ensure release of RLC entities
- Unify NG delay control before calling the RRC NGAP handler, for both
Setup and Release
8. Code Cleanup: Cleaned up unused GTP teardown functions.
Closes#867
- Add delayed_action_state_t in the UE context for ongoing delayed action
- Move delay check and timer re-enqueue to rrc thread in rrc_gNB.c (rrc_delay_transaction)
- Call delay before NGAP setup/release handlers; remove local delay logic from rrc_gNB_NGAP.c
- Clear on RRCReconfigurationComplete (reset_delayed_action)
Closes#960
- Enable telnet server on VNF (gNB) and UE in docker-compose.yaml
- Add new test cases for PDU session management:
* Add PDU session via UE telnet
* Release PDU session via telnet
* Verify connectivity after PDU session release
- Integrate telnet commands into existing container_5g_rfsim_u0_25prb.xml pipeline
- Test cases added before undeploy step in proper execution order
This commit introduces a new telnet server command `pdu_session_release` to
manually trigger the NGAP PDU Session Release Command message from the telnet ci shell.
This is useful for integration testing of PDU session teardown behavior.
Details:
- Added `trigger_ngap_pdu_session_release()` to send NGAP_PDUSESSION_RELEASE_COMMAND
to the RRC task, targeting the specified `gNB_ue_ngap_id`.
- The command currently releases PDU session ID 10 (hardcoded).
- Hooked into telnet shell with command: `pdu_session_release [gNB_ue_ngap_id]`
Usage example:
telnet > pdu_session_release 1
We need to keep PDU sessions and DRBs in list until the NGAP PDU Session Release Response is sent.
* Introduced find_drb() and remove_drbs_by_pdu_session() helpers to locate
and clean up DRBs linked to a specific PDU session
* Targeted per-session DRB removal in rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE()
* Ensures DRBs for unaffected PDU sessions remain intact
* Remove unused PDU_SESSION_STATUS_RELEASED status: keeping this status is no longer relevant
since the PDU sessions are effectively removed from the RRC lists
Closes#867
Also, refactor rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND
3GPP TS 38.413 8.2.2 PDU Session Resource Release says:
> upon reception the NG-RAN node shall execute the release of the requested PDU sessions.
> For each PDU session to be released the NG-RAN node shall release the corresponding
> resources over Uu and over NG, if any.
Therefore, any PDU session in the pdusession_release_params list that is
also present in the RRC list can be set to release, regardless of its status.
The function signature was also updated along with other minor changes.
The partial-tunnel deletion API was buggy and redundant:
* e.g. It erased entries from globGtp.te2ue_mapping but never erases
the corresponding entries from inst->ue2te_mapping[ue].bearers
All current use cases are already covered by:
* newGtpuDeleteOneTunnel() for targeted deletion
* newGtpuDeleteAllTunnels() for full cleanup
Call sites should explicitly loop over newGtpuDeleteOneTunnel()
if multiple tunnels need removal.
This commit implements proper PDU Session Release handling across
RRC, PDCP, F1AP, E1AP to ensure clean resource cleanup when
a PDU session is terminated.
Key changes:
NGAP:
In `rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND()`:
* Populates E1AP Bearer Modification for each released session
* If a CU-UP is connected, triggers `bearer_context_mod()` for PDU teardown
PDCP:
* Added `nr_pdcp_release_drbs()` to remove all DRBs linked to a given PDU session
* Called from `e1_bearer_context_modif()` for correct clean-up during session release
F1AP UE Context Modification:
Replace direct RRC message transfer with F1AP UE Context Modification Request
to properly handle PDU session release according to 3GPP TS 38.331.
3GPP TS 38.331 `5.3.5.6.4 DRB release` says: whether or not the RLC and MAC entities associated
with a PDCP entity are reset or released is determined by the CellGroupConfig. Thus,
updated CellGroupConfig needs to be received by the UE. This has to be retrieved by CUCP
from the DU. Therefore:
After receiving an NGAP_PDUSESSION_RELEASE_COMMAND, the CUCP shall:
1) forward (store for later) the NAS PDU to the UE, if present as per 3GPP TS 38.413, and
2) send a UE Context Modification to the DU with the list of DRBs to release
and the RRC container (RRCReconfiguration with NAS PDU)
After reception of UE Context Modification Response, the list of drbs to release
is prepared based on PDU session status PDU_SESSION_STATUS_TORELEASE
in rrc_gNB_generate_dedicatedRRCReconfiguration and then encoded
in drb_ToReleaseList for a new RRCReconfiguration with the new cellGroupConfig.
Key changes:
* rrc_gNB_generate_dedicatedRRCReconfiguration_release() now uses F1AP UE Context
Modification Request instead of direct RRC transfer
* Only DRBs to be released are now added to the list.
* The ASN.1 memory allocation is entirely done in build_RRCReconfiguration_IEs
* No longer needed to store ASN1 struct in UE context
GTP-U:
* Previous implementation had incomplete tunnel cleanup during PDU session release
- Missing distinction between N3 (PDU session level) and F1-U (DRB level) tunnels
- Lack of proper DRB identification for F1-U tunnel deletion
Major Changes:
* GTP tunnel teardown now handled in `e1_bearer_context_modif()` using the correct
F1 or N3 GTP instance (`newGtpuDeleteOneTunnel()`)
* Enhanced Tunnel Deletion Logic (cucp_cuup_handler.c):
- Separate handling for N3 tunnels (1 per PDU session) and F1-U tunnels (1 per DRB)
- Added proper DRB identification for F1-U tunnel cleanup
- Improved error handling with detailed logging for each tunnel deletion
- Enhanced logging to distinguish between N3 and F1-U tunnel operations
* New PDCP API Function (nr_pdcp_oai_api.c/h):
- Added nr_pdcp_get_drb_ids_for_pdusession() function
- Enables retrieval of all DRB IDs associated with a specific PDU session
- Supports proper F1-U tunnel cleanup by providing DRB identifiers in CUUP
* Enhanced GTP Interface (gtp_itf.cpp/h):
- Modified newGtpuDeleteOneTunnel() to accept tunnel_type parameter
- Improved logging to distinguish between PDU session and DRB tunnel types
- Better error messages for tunnel deletion failures
- Enhanced debugging information for remaining tunnels
Clean-up:
* Ensured xid tracking works consistently between PDU Session Establishment (with NAS PDU)
and dedicated RRCReconfiguration
* Add function to release GTP-U tunnel in Bearer Context Modification Request handler
* Do not send rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE when no PDU session are to
be released: it is sent upon completion of the RRCReconfiguration and needs to contain
released PDU Sessions (mandatory IE), therefore it is no necessary to send it in case
there is no PDU session to release.
Related to #867
Co-authored-by: rmagueta <rmagueta@allbesmart.pt>
gNB: modify RLC configuration applied for SRB1 during RRCReestablishment
TS 38.331 clause 5.3.7.4 specifies to apply the configuration defined in
9.2.1 for SRB1 at UE side. This implies that the gNB also has to apply
sn_field_length = 12, but there are no implications on the other RLC
parameters.
As wrong timer values break SRB1 e.g. for long RTT NTN scenarios, this
commit switches to using the RLC timer values provided in the
configuration file. Currently we still set poll_pdu, poll_byte and
max_retx_threshold to the values defined in 9.2.1, but this can be
changed.
Refactor imscope
This MR refactors imscope by introducing changes to the default layout
in the config file imgui.ini. The global settings are moved to a new
menu item. This modified layout is intended as a suggestion subject to
change based on feedback. This MR also adds PDCCH LLR and IQ plots to
the UE scope and set axes to AutoFit by default.
The MR has a screenshot of the new layout.
Remove schedule response and update L1 threading documentation
This merge requests removes the somewhat superfluous "schedule response"
mechanism. "schedule response" was run after running the scheduler
itself and copied various FAPI messages into a global msgDataTx
structure from which the various TX/RX jobs were triggered. It is not
necessary, though, given that the scheduler is run inside the tx_func()
(running the TX jobs of the L1), and so the scheduler output FAPI
messages can directly be read into a variable of the existing
NR_Sched_Rsp_t type. This allows to delete a couple of hundred lines of
code (while retaining functionality), and simplifies the msgDataTx type
(which is still there to trigger TX job (including the scheduler) from
the ru thread).
In short, prior, there was this call chain:
- tx_func() calls run_scheduler_monolithic() (through fptr
NR_slot_indication())
- get some memory through allocate_sched_response() which has enough
space for NR_Sched_Rsp_t type variable
- call the scheduler and fill the variable
- call nr_schedule_response() (through fptr NR_schedule_response())
which copies into L1: to msgDataTx for TX, to separate structures
for RX
this is changed to
- tx_func() runs one message at a time, hence we can use memory in the
data segment for NR_Sched_Rsp_t. It calls run_scheduler_monolithic()
through the fptr
- pointers into NR_Sched_Rsp_t are passed to the scheduler, which
fills as before
- we return, memory is in its right place and does not need an extra
copy.
Additionally, this merge request updates documentation on threading and
cleans up some unused code along the way.
Update log header format to align log output
The new format:
- left-aligns the log header name and enforces a minimum width of 6 characters,
padding shorter names with spaces while allowing longer names to be printed in
full
- shortens UTC timestamp
- align function names to 32 characters
Example output:
[19:51:34.647930] [NGAP] I (ngap_gNB_decode_initiat:100) Handover Resource Allocation initiating message
[19:51:34.648539] [NGAP] D (decode_ng_handover_requ:267) AllowedNSSAI.list.count 2
[19:51:34.648586] [NGAP] I (ngap_gNB_handle_handove:728) Received NG Handover Request from AMF OAI-AMF (ID=1)
[19:51:34.648627] [NR_RRC] I (rrc_gNB_process_Handove:1199) Received Handover Request (on NR Cell ID=11111111, PCI=1)
[19:51:34.648647] [NR_RRC] A (rrc_gNB_create_ue_conte:230) [--] (cellID 0, UE ID 1 RNTI ffff) Create UE context: CU UE ID 1 DU UE ID 4294967295 (rnti: ffff, random ue id ffffffffffffffff)
[19:51:34.648659] [NR_RRC] A (set_UE_security_algos:692) [--] (cellID 0, UE ID 1 RNTI ffff) Selected security algorithms: ciphering 0, integrity 2
Reimplement nFAPI message exchange between L1 and L2 following the
changes in parent commit removing msgDataTx.
Avoid direct calls and use NR_IF_module fptrs to avoid linking problems.
allowing to remove some function definitions that are not needed.
Note: after this commit, monolithic works but nFAPI operation is broken
and fixed in the next commit, to keep the changes small(er). All
simulators work.
This commit removes the use of msgDataTx's intermediate buffers for FAPI
messages and the call of the "Schedule response". The latter incurs an
additional copy of FAPI messages for the TX chain (for the RX chain, it
is and will remain there) which we can avoid.
Instead, it uses an NR_Sched_Rsp_t-typed variable sched_response to
store the results of the scheduler when called from tx_func(). Thus, the
scheduler remains unchanged (it gets a pointer to where to put FAPI
messages), but we don't call nr_schedule_response() to then copy FAPI
messages into the L1, but have them in a local variable sched_response.
sched_response on on the data segment, as it is big and would overflow
the stack; at the same time, this is ok because only one tx_func() runs
at a time.
Since we don't use allocate_sched_response() anymore, we don't need
deref_sched_response().
clear_slot_beamid() is moved to tx_func(), as it was called in
nr_schedule_response().
Since the "intermediate" NR_gNB_DLSCH_t structure groups both the
DL_tti_pdsch and TX_data.req structures, a pointer has been created to
point to pdsch_pdu. This affects a number of simulators, as they have to
put some messages on the stack:
- nr_dlschsim: put the corresponding variable on the stack
- nr_pbchsim: a new array for the SSB PDUs has been introduced
Further, these changes are now necessary:
- nr_dlsim: there were variables "rel15" and "pdsch_pdu_rel15" that
point to the same PDSCH PDU. At least "rel15" would not exist, as the
corresponding pointer is now populated in phy_procedures_gNB_TX(), and
we therefore refer to the single PDSCH PDU variable with
"pdsch_pdu_rel15", but at the place where "rel15" used to be
initialized.
- nr_ulsim: use nr_save_ul_tti_req() to load PDUs into the RX chain
instead of nr_schedule_response(), which does not exist anymore.
The next commit will remove msgDataTx. We can therefore not use
msgDataTx to retain the PDSCH/DLSCH variables, and move them to the gNB.
Note that the only reason for NR_gNB_DLSCH_t after this commit is to
hold various large buffers (c, b, f). Future work could be done to
remove this, in which case the array inside PHY_VARS_gNB could be
deleted.
On this occasion, clean up the use of init_DLSCH_struct() and
reset_DLSCH_struct() (renamed destroy_DLSCH_struct()) and centralize
their call in phy_init_nr_gNB()/phy_free_nr_gNB(), and correct
simulators accordingly.
TS 38.331 clause 5.3.7.4 specifies to apply the configuration defined in 9.2.1 for SRB1 at UE side.
This implies that the gNB also has to apply sn_field_length = 12, but there are no implications on the other RLC parameters.
As wrong timer values break SRB1 e.g. for long RTT NTN scenarios, this commit switches to using the RLC timer values provided in the configuration file.
Currently we still set poll_pdu, poll_byte and max_retx_threshold to the values defined in 9.2.1, but this can be changed.
Cleanup phy_procedures_gNB_uespec_RX
phy_procedures_gNB_uespec_RX is too long function with too long lines of code,
this commit only shorten lines and improve a bit the readability
[MAC] Add UL total/used aggregated MAC stats; [E2 agent] Properly calculate
used UE PRBs in KPM; [CI] Simplify and improve the Undeploy_Object() and
implement Stop_Object()
- Create common dlul_mac_stats_t struct for both DL and UL total/used aggregated
PRBs
- Use correct unit [%] for RRU.PrbTotDl and RRU.PrbTotUl , instead of [PRBs]
- Use correct unit [Mb] for DRB.PdcpSduVolumeDL and DRB.PdcpSduVolumeUL [kb]
- Implement Stop_Object() (docker compose stop = SIGTERM)
- Simplify the Undeploy_Object() function
- Improve the logging for Deploy/Undeploy_Object() functions
- OAI-FlexRIC CI: properly stop all the containers (one by one or a subgroup of
running containers), and rename oai-flexric to nearRT-RIC container
CI: Increase tested UL throughput on Aerial pipeline using 2L UL
The goal of this MR is to activate the use of 2-layer uplink by enabling SRS
and to increase the tested UL throughput in CI.
The new format left-aligns the component name and enforces a minimum width
of 7 (log component) characters, padding shorter names with spaces after
the closing "]".
Example output:
[14:05:43.395376] [E1AP] I releasing UE 1
[14:05:43.395400] [GTPU] I [91] UE ID 1: Delete all tunnels (1 tunnels)
[14:05:43.395414] [NR_RRC] A [DL] (cellID bc614e, UE ID 1 RNTI 8e27) Send RRC Release
[14:05:43.395431] [RRC] I UE 1: received bearer release complete
[14:05:43.424551] [RLC] W Remove UE 36391
[14:05:43.424597] [NR_RRC] I removed UE CU UE ID 1/RNTI 8e27
[14:05:43.424773] [NR_RRC] A [--] (cellID bc614e, UE ID 1 RNTI 8e27) Remove UE context
[14:05:43.425205] [NR_MAC] I Remove NR rnti 0x8e27
[14:05:43.582158] [HW] W Lost socket
^C
** Caught SIGTERM, shutting down
Returned from ITTI signal handler
[14:05:43.948721] [GNB_APP] I stopping nr-softmodem
[14:05:43.948746] [PHY] I Killing gNB 0 processing threads
[14:05:44.574818] [PHY] I Stopping RU 0 processing threads
[14:05:44.575000] [PHY] I RU 0 RF device stopped
[14:05:44.575006] [GNB_APP] I turned off RU rfdevice
Prior to this change, when no "level" option is given to the logging
module, we see
[PHY] RU 0 RF started cpu_meas_enabled 0
[HW] No connected device, generating void samples...
with three spaces, which is too much. This change reduces the amount of
spaces to 1 without log level.
Co-authored-by: Robert Schmidt <robert.schmidt@openairinterface.org>
We probably almost never care about the date, but it takes a lot of
space. Remove it; if somebody needs the full time stamp including the
date, we could still add it with a new option.
1. Rename oai-flexric to nearRT-RIC. FlexRIC is a project combining nearRT-RIC, xApps, and E2 agent emulators.
2. Instead of undeploying all the containers at the same time, and not checking the logs for xApps and nearRT-RIC, do the following:
- Stop containers (docker compose stop) - one or subgroup of running containers in the following order:
a) xapp-kpm-moni
b) xapp-kpm-rc
c) xapp-gtp-mac-rlc-pdcp-moni
d) oai-nr-ue oai-nr-ue2
e) oai-gnb
f) nearRT-RIC
- Undeploy containers (docker compose down), collect and analyze all the logs.
For some test cases, we might want to stop a service earlier. This
functionality is done by StopObject().
Test log collection is still done by UndeployObject(), which will
collect the logs of all services (at that point, stopped or not).
GetRunningServices() was returning all services, running or stopped.
Hence, rename to reflect what this function does, and rewrite slightly
to better capture what is actually happening. Also, don't return the
container ID, as we don't use it.
Call stop on all services, as we will down the deployment right after.
The list of services is still used to retrieve logs.
Remove a stray "return False", which would sometimes prevent us from
seeing all error messages.
Collection of small fixes
A few fixes needed while testing FHI libraries
- set subcarrier spacing in PUSCH PDU in NRUE
- a set of two LOG_Ds that prints out the PUSCH allocation on gNB & UE
[NGAP] Fix incorrect AMF Set ID type (uint8 → uint16) causing AMF lookup failure
This PR fixes issue #1012 , a data type issue related to the AMF Set ID used
during UE RRC reestablishment. The AMF Set ID was mistakenly declared as uint8_t
instead of uint16_t, even though it is a 10-bit field as specified in 3GPP TS
23.003 section 2.10.1. As a result, AMF Set IDs greater than 255 were truncated,
leading to failed AMF lookups and the following warning: No matching AMF found
for PLMN (MCC=%03d MNC=%0*d) and AMF SetID=%u.
Verified reestablishment succeeds with AMF Set IDs >255.
DLSCH encoding is not concerned with HARQ processes directly. Instead,
it gets the redundancy version and encodes a specific redundancy version
for a given TB. The rest is up to the MAC, the L1 is stateless in that
regard. Hence, remove the HARQ type and put it into DLSCH, which also
simplifies the code elsewhere.
Similarly to the parent commit, simplify the array type to the FAPI PDU
towards further refactoring, and encapsulate the code in a function for
easier reuse in a later refactoring step.
Note on ZP-CSI: after this commit, we continue treating CSI PDUs. The
prior code was returning, which I think is wrong (as this information is
only for the currently treated CSI-RS PDU).
There is no point in tracking the "active" state: the SSB PDU will be
sent from MAC to L1, encoded, and then "discarded" (by marking the
number of SSB PDUs as 0). Hence, remove this intermediate type.
According to TS 38.211 section 6.4.1.4.3, the frequency domain shift value n_shift
is from higher-layer parameter freqDomainShift.
The quantity n_RRC is given by higher-layer parameter freqDomainPosition.
Also corrected k_0_overbar_p calculation formula to align with standard.
Problem:
- GTP-U logs showed negative TEID values (e.g., -1943516315) due to signed/unsigned
conversion. Due to wrong conversion from uint32_t to int and overflow caused negative values.
- TEID values were inconsistently formatted across different log statements, due to
mixed use of %d, %u, %x formats for TEID logging. Made debugging and troubleshooting difficult
Changes:
1. Fixed signed/unsigned conversion bug: use teid_t. Prevents overflow when TEID values exceed int range.
2. Standardized TEID logging format: all TEID values now use '0x%x' hexadecimal format.
Consistent 'TEID' capitalization throughout
According to TS 38.463 - clause 9.2.2.4 and 9.3.3.12.
Also, fix response message by encoding choice IE only
with presence of modified PDU sessions.
Co-authored-by: rmagueta <rmagueta@allbesmart.pt>
Both (DL) PDCCH and UL PDCCH PDU types are fundamentally of the same
type, so correct the array's type to facilitate refactoring later (a
later commit will reuse a single "generate DCI" function for both
cases).
gNB: fix MAC TA command scheduling if measurement gaps are configured
In the current implementation, if UE transmission is interrupted via
nr_mac_interrupt_ue_transmission(), UE_sched_ctrl.ta_frame is modified to be
the previous frame avoiding TA scheduling in the measurement gap. So the next
scheduled TA is shifted to be in 99 frames. As there are other measurement gaps
before that, the scheduled TA is always shifted, but actually never reached,
effectively disabling the MAC TA commands.
To fix this, UE_sched_ctrl.ta_frame is changed to not indicate the last TA
command transmission, but the next one. This allows to check in
nr_mac_interrupt_ue_transmission() if the next TA command transmission is within
the measurement gap and if so shift it to just after that gap.
DCI 00 alt size fix
DCI size for format 00 and 10 should be equal so we need to compute the size of
the alternative format when computing the size of DCIX0. There was a bug where
the alt_size input (0 in that case) was taken into account also when computing
that alternative size, resulting in an alt_size of 0. Possibly easier to
understand by looking at the code then reading this description.
For now, only DL/UL MAC stats.
This commit fixes the "RRU.PrbTotDl" and "RRU.PrbTotUl" measurement calculation
to align with the TS 28.552 specifications.
DL stats (aggregated total and used PRBs) previosuly used only for O1 interface,
now finds the purpose for E2 interface as well.
New UL stats (aggregated total and used PRBs) serve for E2 interface only.
Co-authored-by: Teodora Vladić <teodora.vladic@openairinterface.org>
SDAP: guard RX header parsing with enable_sdap and init per-entity
!3519 (merged) refactored the SDAP to use the QFI from the header rather than
pass it to the rx function and got rid of the initialization of QFI to -1.
However, entity roles are stored into the drb2qfi table, and the indexing
implies that the QFI is known.
While in TX it is not an issue since packets are forwarded based on the QFI,
in RX the QFI can only be parsed from the header, therefore if headers are
disabled (--enable_sdap) the QFI is not there and it is wrong to access the
header (buf[0]) and looking for it.
This commit adds enable_sdap to nr_sdap_entity_t and initialize it in
nr_sdap_add_entity() from sdap->role (disabled when NO_SDAP_HEADER).
In nr_sdap_rx_entity(), only parse buf[0] for QFI and derive sdap_ul_rx/
sdap_dl_rx when enable_sdap is true; otherwise, keep offset=0 and forward
payload unchanged.
NTN: Fixing variable ULDLduplex issue for NTN bands
- Duplex is assumed to be static but for NTN bands (and also for some non NTN
bands), it is not static.
- Tx-RX Duplex is defined in section 5.4.4 of 38.101-5 (for NTN) specs v1809
- For example: In NTN-OTA testing, the GEO satellite operator configured in
band 256 the DL, UL frequencies with duplex of 185Mhz.
Using nFAPI introduces additional delays. At the same time, RFsim does
not run in real-time, and we can allow a low sl_ahead, as RFsim will
"wait" for the gNB.
Therefore, reduce sl_ahead to ensure that the response window does not
run out during handling of RA in nFAPI.
In the current implementation, if UE transmission is interrupted via nr_mac_interrupt_ue_transmission(),
UE_sched_ctrl.ta_frame is modified to be the previous frame avoiding TA scheduling in the measurement gap.
So the next scheduled TA is shifted to be in 99 frames. As there are other measurement gaps before that,
the scheduled TA is always shifted, but actually never reached, effectively disabling the MAC TA commands.
To fix this, UE_sched_ctrl.ta_frame is changed to not indicate the last TA command transmission, but the
next one. This allows to check in nr_mac_interrupt_ue_transmission() if the next TA command transmission
is within the measurement gap and if so shift it to just after that gap.
!3519 refactored the SDAP to use the QFI from the header rather
than pass it to the rx function and got rid of the initialization
of QFI to -1.
However, entity roles are stored into the drb2qfi table, and the
indexing implies that the QFI is known. While in TX it is not an
issue since packets are forwarded based on the QFI, in RX the QFI
can only be parsed from the heaedr, therefore if headers are
disabled (--enable_sdap) the QFI is not there and it is wrong to
access the header (`buf[0]`) and looking for it.
This commit adds `enable_sdap` to `nr_sdap_entity_t` and initialize
it in `nr_sdap_add_entity()` from `sdap->role`
(disabled when `NO_SDAP_HEADER`). In `nr_sdap_rx_entity()`, only
parse `buf[0]` for QFI and derive `sdap_ul_rx`/`sdap_dl_rx` when
`enable_sdap` is true; otherwise, keep `offset=0` and forward
payload unchanged.
Integration `2025.w45`
* !3736 fix bugs in scope for pdcch, and optimize cpu cost of pdcch decoding
* !3743 NR UE: fix PDCCH LLR indexing for different search space RB sizes
* !3739 Bugfix: save old tunnel info to remain the user plane connection while rolling back to source DU due to handover failure
* !3742 Simplify node management in CI, handle SIGINT
* !3670 PRS bug fix and CI Integration
* !3746 Fix unsigned to signed decoding parameters to allow for 'no affinity'/'no pin' threads to CPUs
* !3738 CI: Add new Jenkinsfiles
Closes#984 and #1021
See merge request oai/openairinterface5g!3744
CI: Add unified Jenkinsfile for all test pipelines
This MR introduces a single Jenkinsfile to cover all current CI test pipelines
Improvements:
- correct reporting of the start timestamp in the HTML report
- harmonize log collection - always collect as test_logs_${env.BUILD_ID}.zip
Fix unsigned to signed decoding parameters to allow for 'no affinity'/'no pin'
threads to CPUs
By default, 'L1_rx_thread_core', 'L1_tx_thread_core', 'ru_thread_core' are set
to '-1' but the values were decoded from config file as unsigned instead of
signed types, thus, it was not allowing to set them with '-1' from config file.
PRS bug fix and CI Integration
- Fix the bug in PRS channel estimation while copying memory to compute the
impulse response
- Integrate PRS testing to CI
Simplify node management in CI, handle SIGINT
- Make a single <node> XML step entry common to all XML steps to harmonize code
- Handle SIGINT to make it possible to more easily stop the CI script.
Bugfix: save old tunnel info to remain the user plane connection while rolling
back to source DU due to handover failure
This MR closes issue #984 that UE lost the data plane connection while rolling
back to the source DU due to handover failure.
NR UE: fix PDCCH LLR indexing for different search space RB sizes
After !3603 (merged), when multiple search spaces have different CORESET
configurations (different number of RBs), the LLR buffer stride must be
calculated based on the maximum RB size across all search spaces, not the
current search space's RB size.
The LLR buffer is allocated with size based on get_pdcch_max_rbs(), but the
demapping function was using coreset_nbr_rb (current search space) for symbol
stride calculation, causing incorrect LLR extraction when search spaces have
different RB configurations.
This MR tries to fix it.
Closes#1021
Set the subcarrier_spacing field in nfapi_nr_ue_pusch_pdu_t from MAC
to PHY. This has no consequence for the NR UE Softmodem operation as this
field is never read, but prevents a potential future bug in case L1 was
modified to read it.
By default, 'L1_rx_thread_core', 'L1_tx_thread_core', 'ru_thread_core' are set to '-1' but the values were decoded from config file as unsigned instead of signed types, thus, it was not allowing to set them with '-1' from config file
This commit inputs several distances at once and obtain the summary of
successful and failed tests. We look for the number of successful tests
that are geater than 0. We do that here since we sometimes dont receive
a response for a telnet command from the rfsim although the command
is applied. This is related to the queing telnet commands in the rfsim.
The script for the distances 50, 100 and 150 are called as follows,
./set-and-verify-distance-prs.sh 50 100 150
The summary can be viewed as follows,
==================== SUMMARY ====================
Total tests run : 3
Successful tests: 3
Failed tests : 0
=================================================
Set RFsim (DL) distance and use PRS to estimate the new distance. This
is verified by comparing the distance set in RFsim with the distance
reported through ToA estimation at the UE.
Note that since RFsim telnet output is asynchronous (it uses a queue
internally), we use grep --max-count 1 to wait for the matching line,
together with ncat --idle 0.3 to keep ncat open for some time. The
--max-count option will terminate grep after the first occurrence. For
this to work reliably, we need to use grep <(echo | ncat) as opposod to
simply echo | ncat | grep, as the latter does not seem to reliably
make grep exit after the occurrence.
Co-authored-by: Robert Schmidt <robert.schmidt@openairinterface.org>
fix bugs in scope for pdcch, and optimize cpu cost of pdcch decoding
fix bugs in scope for pdcch, and optimize cpu cost of pdcch decoding by not
processing useless samples in one symbol
When multiple search spaces have different CORESET configurations
(different number of RBs), the LLR buffer stride must be calculated
based on the maximum RB size across all search spaces, not the
current search space's RB size.
The LLR buffer is allocated with size based on get_pdcch_max_rbs(),
but the demapping function was using coreset_nbr_rb (current search
space) for symbol stride calculation, causing incorrect LLR extraction
when search spaces have different RB configurations.
Handle SIGINT and mark any subsequent steps as failed. Receiving SIGINT
a second time will abort the script immediately (as is the case before
this commit).
Note that Python seems to relay the signal to the "controlled" process
(e.g., Ping), which would return immediately with an error. So some
steps like Ping will abort immediately, others (e.g., IdleSleep) will
finish their step, and then the present logic will mark subsequent steps
as failed.
Some CI tasks/commands like Iperf(), Ping() get multiple nodes (via XML
parameter "nodes") to potentially run UEs on different nodes (hosts) at
the same time. However, I argue that this is not good:
- we don't actually use this -- where we specify multiple UEs, it's
always "localhost localhost..."
- it is inconsistent, as we typically have a single "node", not nodes,
and there is a possibility to harmonize (see also next commit)
- if we needed it, there would be better ways to achieve the same.
First, for hardware-based UEs, the ci_infra.yaml can specify different
UEs. For simulated UEs, it would be feasible to have multiple XML
steps run in parallel, e.g., in the XML <parallel> tag, which would
clarify that multiple UEs on different hosts run in parallel
- it reduces code.
Hence, make a single <node> for these XML steps.
Created Jenkinsfiles:
- Jenkinsfile: for stadard test pipelines
- Jenkinsfile-oc: for deployments with OC
These 2 Jenkinsfiles covers all current test pipelines.
Previously, we were using int16_t for the variable ch_tmp which was later harmonized to use c16_t while leaving <<1. This introduced the bug while accessing the address of the element at first_half of the ch_tmp variable.
Integration `2025.w44`
* !3721 improvements in formatting and LOGs in DMRS common functions at MAC
* !3725 Handle GTP receiver errors, fix memory leaks, add CU-UP test
* !3726 fix for CSI payload sizes in PUCCH structure at UE
* CI: Adjust attenutation for HO setup
* !3728 Fix for scenario with no CSI report configured for CSI-RS
* !3731 CI: ensure clean iperf3 server startup
* !3592 Refactor PRACH handling at the gNB
* !3682 Refactor DLSCH scheduler
* !3733 Clarify whitespace
* !3706 Change registry name env var content
Closes#1015 and #1014
See merge request oai/openairinterface5g!3727
Change registry name env var content
Currently setting REGISTRY="" in a .env file results in docker failing to find
/image-name:tag. This corrects that, so it looks for local images named
image-name:tag.
Following the change to use:
image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop}
the REGISTRY variable must now include the trailing slash.
Refactor DLSCH scheduler
Refactor the DLSCH post processor similarly to what has been done in
!3521 with the goal of saving an additional iteration through all UEs,
hopefully making the DLSCH scheduler faster.
It further includes changes to make working with and debugging multi-UE
operation easier:
- add some measurements in L1 (for total TX/RX time)
- a new option MACRLCs.[0].stats_max_ue to limit the number of UEs in
the periodic output (default: 8, 0=disable)
- avoid stack overflow in the MAC
- fix the writing of stats to nrMAC_stats.log and nrL1_stats.log when
the written output reduces by truncating the files
- avoid to schedule retransmission with 0 RBs.
This slightly speeds up the scheduler (it e.g., does not need to check
for UEs that have retransmissions), and harmonizes with pf_ul(), which
evaluates (UL) BSR at a similar place within the scheduler.
Check and return, if necessary, that we have enough resources to make
retransmissions. Without, we can asserts in L1, such as
Assertion (NPRB>0 && (NPRB + RBstart <= BWPsize)) failed!
In PRBalloc_to_locationandbandwidth0() openairinterface5g/common/utils/nr/nr_common.c:506
Illegal NPRB/RBstart Configuration (0,51) for BWPsize 51
which indicates that the scheduler requested a transmission with 0 PRBs,
which does not make sense.
Refactor PRACH handling at the gNB
- Remove race conditions by correctly setting mutexes
- Fix a bug when having multiple RACH occasions
- Reduce memory footprint by removing global memory, which should also
fix potential memory data races in FHI 7.2
- Additional fixes, see commit messages
a bit difficult to understand: sl_ahead=6 => we systematically miss the
rach detection in the scheduler because the scheduler runs more than 6
slots ahead the rx slot processing (here > 11 slots because 6 (DL and UL
slots) + 4 (RU_RX_SLOT_DEPTH, so UL only))
so, reducing sl_ahead works better than large sl_ahead because the idea
behind is: the scheduler of slot+sl_ahead will never create work to do
in a UL slot before slot+sl_ahead+X (as minimum k2 is X, in the 24PRB CI
test: 6)
saves about 600MB of memory allocation
Move the definition of PRACH items and the PRACH list to the
defs_nr_commons.h file.
Do not re-write the entire structure in nr_schedule_rx_prach(), as it is
quite large now.
Call the post-processor when the allocation is "fixed" (i.e., nothing
changes anymore), instead of having a final loop across all UEs that
might potentially be costly.
In order to calculate the PF metric, note that the statistics "reset" is
moved into pf_dl() instead of the post-processing loop, as it has to be
done on each slot.
See also: dd98030202 ("Refactor to call post-processor in place")
Similarly to parent commit(s), assign sched_pdsch in a single place
instead of relying on sched_ctrl. In a follow-up commit, the
post-processor will be called in a single place.
Similarly to parent commit(s), refactor the use of NR_sched_pdsch.
Instead of using nr_mac->sched_ctrlCommon, put the NR_sched_pdsch_t on
the stack.
This also refactors update_rb_mcs_tbs() to update the existing
NR_sched_pdsch instead of updating individual fields.
This also reduces the extend to which sched_ctrlCommon is used.
Assign NR_sched_pdsch to sched_ctrl->sched_pdsch in one place, where the
post-processing functionality will be called in a follow-up commit. This
should result in no functional change.
It seems to be assumed that curInfo actually has the currently active
number of layers/PMI. However, I am not sure this would always be true
(e.g., UE might not have been scheduled for some slots, but number of
layers decreased as reported by CSI). Instead, recalculate the info
from scratch when necessary.
PF uses MCS and average throughput to decide which UE to schedule. Thus,
the first loop decides on MCS, whereas the second does the "main UE
allocation" after sorting by the PF metric.
A follow-up commit will remove sched_pusch from NR_UE_sched_ctrl_t.
Thus, we cannot rely on sched_ctrl to store the MCS in the first loop,
and look it up from there in the second. Instead, store it as part of
the UE iterator data, and take it from there.
See also: f3068caa37 ("Store selected MCS in UE iterator", for UL)
Introduce a struct with information on FAPI structures to save resource
and data allocation into. It's in nr_mac_gNB.h because the next commits
will reuse this for all preprocessors.
Especially in pf_dl()/pf_ul(), we use a first loop using
UE_iterator(), then iterate over a subset of UEs. It has happened a
couple of times that I was using variable "UE" (from the iterator), when
it should only be used in the first UE_iterator() loop.
Rewrite UE_iterator() to effectively limit the scope of the iterator
variables to the body of the UE_iterator. This should also make it
possible to reuse multiple UE_iterator()s with the same variables in
sequence.
CI: ensure clean iperf3 server startup
- Resolves issue with iperf3 test failure in RFSim5G multiue test
- Minor fix of iperf3 test descriptions in RFSim5G pipeline
Fix for scenario with no CSI report configured for CSI-RS
After changes in !3714 (merged), if we select to measure RSRP on SSB and not
CSI-RS (default option) and there is a single antenna port (so no MIMO report
either) we won't schedule any CSI-RS measurements for the UE. In that case
ideally we shouldn't set do_CSIRS = 1 in configuration file but still the
option is possible. So the fix is to not perform any measurements at UE on
that CSI-RS but not asserting.
Closes#1015
1. Create a free_ru_session_list() function to free the memory allocated for the connected RUs
before closing the nr-softmodem.
2. xmlReadMemory() and xmlNodeGetContent() were causing serious memory leakages,
and now all is properly freed using xmlFreeDoc() and xmlFree().
This struct is used in multiple source files.
Previously, when stopping the nr-softmodem, the ru_session_list "disappears"
and the M-plane wasn't terminated properly (num_rus = 0 even though DU connected to at least one RU).
MIMO mode is defined by setting separate carriers to different antenna ports.
Benetel v1.2.2 does not support MIMO mode to be set via M-plane, and therefore
we only created one Tx and one Rx carrier.
Benetel v1.4.1 supports MIMO mode setting via M-plane.
Therefore, this commit introduces the adaptation based on the number of supported carriers by a DUT RU.
These 3 states: "oper-state", "admin-state", "availability-state" are optional,
but shall be checked in order to activate the carriers. If an O-RU doesn't support it,
we assume the expected values:
- "oper-state" = "enabled"
- "admin-state" = "unlocked"
- "availability-state" = "NORMAL"
Implement retrieval of the hardware states if O-RU supports, i.e. Benetel release v1.4.1.
Duplex is assumed to be static but for NTN bands, it is not static.
TxRX Duplex is defined in section 5.4.4 of 38.101-5 (for NTN) specs v1809
n256 190 MHz, 165 to 215 MHz
n255 -101.5 MHz, -72.5 to -130.5 MHz
n254 862 - 885 MHz
The function rx_nr_prach become autonomous, it doesn't read anymore global variables
So, it can become (later) a threadpool work, that will send a message when it finishes
rx_nr_prach_ru() still use some global variables, but it is executed in sequence, inside the ru main loop, that limits the probability of race conditions
Before starting a new iperf3 server instance in CI tests, explicitly kill any existing
iperf3 processes bound to the same port. This prevents conflicts or failures caused by
leftover iperf3 servers from previous runs that did not terminate properly or on time.
The cleanup is performed using `pkill` before launching the new server.
Handle GTP receiver errors, fix memory leaks, add CU-UP test
- Fix use-after-free bugs in GTP by properly stopping the receive thread(s)
- Fix a bug from !3519 (merged): QFI 0 is a valid QFI
- Fix multiple memory leaks in CU-UP, E1, CU-UP load tester, SCTP
- Add a (conservative) functional CU-UP test that verifies that the load tester
and CU-UP work. Test only a low throughput, as it will run in parallel with
other tests.
Use the CU-UP load tester to test the functionality of the CU-UP and
its loader tester. The requirements on this load test are intentionally
low, as it will be run with other unit tests in parallel, and should
still pass.
It uses an existing configuration file for the CU-UP. The test script
runs the CU-UP, runs the load tester, stops the CU-UP, and returns the
load tester return value as test result (which will be 0=success if all
packets have been received).
Note that this strdup has been intentioally created for debugging
purposes in core files.
See also: 1ab3b8dd8e ("add version signature in core files...")
Direct leak of 8 byte(s) in 1 object(s) allocated from:
#0 0x7f7bc7ee68a3 in calloc (/lib64/libasan.so.8+0xe68a3) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
#1 0x0000004abfa6 in calloc_or_fail /home/richie/oai/common/utils/utils.h:74
#2 0x0000004abfa6 in decode_e1ap_cuup_setup_request /home/richie/oai/openair2/E1AP/lib/e1ap_interface_management.c:219
#3 0x00000046a9f5 in e1apCUCP_handle_SETUP_REQUEST /home/richie/oai/openair2/E1AP/e1ap.c:187
#4 0x000000470b35 in e1ap_handle_message /home/richie/oai/openair2/E1AP/e1ap.c:109
#5 0x000000470b35 in e1_task_handle_sctp_data_ind /home/richie/oai/openair2/E1AP/e1ap.c:120
#6 0x00000047717b in E1AP_CUCP_task /home/richie/oai/openair2/E1AP/e1ap.c:832
#7 0x7f7bc7e28ee5 in asan_thread_start(void*) (/lib64/libasan.so.8+0x28ee5) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
Direct leak of 8 byte(s) in 1 object(s) allocated from:
#0 0x7f7bc7ee68a3 in calloc (/lib64/libasan.so.8+0xe68a3) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
#1 0x0000004ac30c in calloc_or_fail /home/richie/oai/common/utils/utils.h:74
#2 0x0000004ac30c in decode_e1ap_cuup_setup_request /home/richie/oai/openair2/E1AP/lib/e1ap_interface_management.c:194
#3 0x00000046a9f5 in e1apCUCP_handle_SETUP_REQUEST /home/richie/oai/openair2/E1AP/e1ap.c:187
#4 0x000000470b35 in e1ap_handle_message /home/richie/oai/openair2/E1AP/e1ap.c:109
#5 0x000000470b35 in e1_task_handle_sctp_data_ind /home/richie/oai/openair2/E1AP/e1ap.c:120
#6 0x00000047717b in E1AP_CUCP_task /home/richie/oai/openair2/E1AP/e1ap.c:832
#7 0x7f7bc7e28ee5 in asan_thread_start(void*) (/lib64/libasan.so.8+0x28ee5) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
Direct leak of 100 byte(s) in 1 object(s) allocated from:
#0 0x7f6585ee6f2b in malloc (/lib64/libasan.so.8+0xe6f2b) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
#1 0x000000414a0d in malloc_or_fail /home/richie/oai/common/utils/utils.h:86
#2 0x0000004061c9 in main /home/richie/oai/tests/nr-cuup/nr-cuup-load-test.c:544
#3 0x7f6585211574 in __libc_start_call_main (/lib64/libc.so.6+0x3574) (BuildId: 48c4b9b1efb1df15da8e787f489128bf31893317)
#4 0x7f6585211627 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3627) (BuildId: 48c4b9b1efb1df15da8e787f489128bf31893317)
#5 0x000000413034 in _start (/home/richie/oai/build/tests/nr-cuup/nr-cuup-load-test+0x413034) (BuildId: 8af0132792b03fa12ba95b5623865c9a8a5625a3)
Direct leak of 100 byte(s) in 1 object(s) allocated from:
#0 0x7f6585ee6f2b in malloc (/lib64/libasan.so.8+0xe6f2b) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
#1 0x000000414a0d in malloc_or_fail /home/richie/oai/common/utils/utils.h:86
#2 0x0000004061ff in main /home/richie/oai/tests/nr-cuup/nr-cuup-load-test.c:546
#3 0x7f6585211574 in __libc_start_call_main (/lib64/libc.so.6+0x3574) (BuildId: 48c4b9b1efb1df15da8e787f489128bf31893317)
#4 0x7f6585211627 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3627) (BuildId: 48c4b9b1efb1df15da8e787f489128bf31893317)
#5 0x000000413034 in _start (/home/richie/oai/build/tests/nr-cuup/nr-cuup-load-test+0x413034) (BuildId: 8af0132792b03fa12ba95b5623865c9a8a5625a3)
Free memory including the "base pointer". Fix two places in which it was
on the stack to harmonize. The only stack variable is in reception of
new E1 messages (e1ap_handle_message()), which uses
ASN_STRUCT_FREE_CONTENTS_ONLY().
This fixes bugs similar to these logs:
Direct leak of 40 byte(s) in 1 object(s) allocated from:
#0 0x7f418f4e68a3 in calloc (/lib64/libasan.so.8+0xe68a3) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
#1 0x00000049e367 in calloc_or_fail /home/richie/oai/common/utils/utils.h:74
#2 0x00000049e367 in encode_e1_bearer_context_release_command /home/richie/oai/openair2/E1AP/lib/e1ap_bearer_context_management.c:1235
#3 0x000000482951 in e1apCUCP_send_BEARER_CONTEXT_RELEASE_COMMAND /home/richie/oai/openair2/E1AP/e1ap.c:546
#4 0x000000482951 in E1AP_CUCP_task /home/richie/oai/openair2/E1AP/e1ap.c:856
#5 0x7f418f428ee5 in asan_thread_start(void*) (/lib64/libasan.so.8+0x28ee5) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
Direct leak of 40 byte(s) in 1 object(s) allocated from:
#0 0x7f418f4e68a3 in calloc (/lib64/libasan.so.8+0xe68a3) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
#1 0x00000049380a in calloc_or_fail /home/richie/oai/common/utils/utils.h:74
#2 0x00000049380a in encode_E1_bearer_context_setup_request /home/richie/oai/openair2/E1AP/lib/e1ap_bearer_context_management.c:578
#3 0x00000047f6a2 in e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST /home/richie/oai/openair2/E1AP/e1ap.c:378
#4 0x0000004829f8 in E1AP_CUCP_task /home/richie/oai/openair2/E1AP/e1ap.c:846
#5 0x7f418f428ee5 in asan_thread_start(void*) (/lib64/libasan.so.8+0x28ee5) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
Direct leak of 40 byte(s) in 1 object(s) allocated from:
#0 0x7f418f4e68a3 in calloc (/lib64/libasan.so.8+0xe68a3) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
#1 0x00000046ede7 in calloc_or_fail /home/richie/oai/common/utils/utils.h:74
#2 0x00000046ede7 in encode_e1ap_cuup_setup_response /home/richie/oai/openair2/E1AP/lib/e1ap_interface_management.c:305
#3 0x00000047e412 in e1ap_send_SETUP_RESPONSE /home/richie/oai/openair2/E1AP/e1ap.c:167
#4 0x000000482a68 in E1AP_CUCP_task /home/richie/oai/openair2/E1AP/e1ap.c:836
#5 0x7f418f428ee5 in asan_thread_start(void*) (/lib64/libasan.so.8+0x28ee5) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
QFI 0 is a valid QFI: don't check for qfi <= 0, as uint8 cannot be
negative. Also, correctly use SDAP_MAP_RULE_EMPTY for a DRB ID (which
need to be larger than 0).
The gNB will stop the periodical logging of UEs in MAC Info level after
a configurable number of UEs have been printed, by default 8.
Set it to 17 in some CI tests to ensure we still get all UEs for the
time being, as the CI might depend on this.
improvements in formatting and LOGs in DMRS common functions at MAC
DMRS LOGs at MAC were misleading. This MR tried to improve them (and also
adds some formatting fix).
The call to snprintf() as was used is wrong: we use the return value to
advance output, but the man page says
> The functions snprintf() and vsnprintf() do not write more than size
> bytes (including the terminating null byte ('\0')). If the output was
> truncated due to this limit, then the return value is the number of
> characters (excluding the terminating null byte) which would have been
> written to the final string if enough space had been available.
> Thus, a return value of size or more means that the output was
> truncated.
Thus, output could go beyond end, and we get a stack overflow. Instead,
encapsulate the call to snprintf() checking this condition, and only
advancing output as intended, limiting to 0 if we are at the end of the
buffer. This avoids this error:
==964825==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7be799f51988 at pc 0x7fe7d66b0d39 bp 0x7be79b825ef0 sp 0x7be79b8256c0
WRITE of size 3 at 0x7be799f51988 thread T24
#0 0x7fe7d66b0d38 in vsnprintf (/lib64/libasan.so.8+0xb0d38) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
#1 0x7fe7d66b2d44 in snprintf (/lib64/libasan.so.8+0xb2d44) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
#2 0x0000008fe7c6 in dump_mac_stats /home/richie/w/refactor-dlsch/openair2/LAYER2/NR_MAC_gNB/main.c:183
#3 0x00000092071a in gNB_dlsch_ulsch_scheduler /home/richie/w/refactor-dlsch/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c:200
#4 0x0000008f8f78 in run_scheduler_monolithic /home/richie/w/refactor-dlsch/openair2/NR_PHY_INTERFACE/NR_IF_Module.c:399
There is the (global) sched_lock that prevents concurrent access. A
dedicated UE lock does not make sense in that case. Worse, this lock
does not prevent all concurrent UE accesses (e.g., there are many loops
over UEs that are not protected), so it's also wrong.
truncate resets the file size to 0. Without this, e.g., when
disconnecting a UE, the old UE remains at the end and is not
overwritten, which is confusing.
- Corrected AMF Set ID data type in ngap_gNB_nnsf_select_amf_by_amf_setid() from uint8_t to uint16_t.
- AMF Set ID is a 10-bit field as per 3GPP TS 38.413 §9.3.3.12.
- The incorrect data type caused truncation for AMF Set IDs >255, leading to lookup failures during RRC reestablishment.
- Verified successful reestablishment with large AMF Set IDs after the fix.
Reason for fix: AMF lookup using AMF Set ID was failing because the 10-bit AMF Set ID was truncated to 8 bits.
Closes#1012
Stop the receive thread before closing the socket, which avoids an error
message when stopping the GTP softmodem:
[GTPU] [91] Recvfrom failed (Bad file descriptor)
[GTPU] exiting thread
On error, exit the GTP thread after printing a diagnostic message. This
avoids also an error flagged by address sanitizer for use-after-free.
[GTPU] [91] Recvfrom failed (Bad file descriptor)
=================================================================
==285377==ERROR: AddressSanitizer: heap-use-after-free on address 0x7cd7b7fe5590 at pc 0x0000006a9e18 bp 0x7b97ad4e1d50 sp 0x7b97ad4e1d48
READ of size 4 at 0x7cd7b7fe5590 thread T8
=================================================================
==285377==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 160 byte(s) in 1 object(s) allocated from:
#0 0x0000006a9e17 in gtpv1uReceiver /home/richie/oai/openair3/ocp-gtpu/gtp_itf.cpp:1346
#1 0x7f97b9a28ee5 in asan_thread_start(void*) (/lib64/libasan.so.8+0x28ee5) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
#2 0x7f97b8e7ff53 in start_thread (/lib64/libc.so.6+0x71f53) (BuildId: 48c4b9b1efb1df15da8e787f489128bf31893317)
#3 0x7f97b8f0332b in __clone3 (/lib64/libc.so.6+0xf532b) (BuildId: 48c4b9b1efb1df15da8e787f489128bf31893317)
#0 0x7f97b9ae60cb in memalign (/lib64/libasan.so.8+0xe60cb) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
#1 0x000000471039 in newNotifiedFIFO_elt /home/richie/oai/common/utils/threadPool/notified_fifo.h:75
#2 0x000000471039 in tx_func /home/richie/oai/executables/nr-gnb.c:107
#3 0x000000471039 in L1_tx_thread /home/richie/oai/executables/nr-gnb.c:167
#4 0x7f97b9a28ee5 in asan_thread_start(void*) (/lib64/libasan.so.8+0x28ee5) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f)
0x7cd7b7fe5590 is located 336 bytes inside of 400-byte region [0x7cd7b7fe5440,0x7cd7b7fe55d0)
freed by thread T0 here:
SUMMARY: AddressSanitizer: 160 byte(s) leaked in 1 allocation(s).
Integration: `2025.w43`
* !3605 Support beam index in OAI 7.2 Fronthaul Interface
* !3709 Fixes for T-Tracer to work with NR-UE
* !3712 Restore UE Capability IE after RRCReestablishment
* !3716 Remove unused ULSCH measurements at gNB
* !3603 UE symbol based PDCCH receiver
* !3708 Add monolithic N2 handover test pipeline with B210 and Quectel
* !3719 Remove Benetel-specific radio drivers
* !3710 [CI] Update the Push to DockerHub Stage
* !3711 CI: Multiple adjustments
* !3717 Initialize NCC=0 on NGAP Initial Context Setup (3GPP TS 33.501 §6.9.2.1.1)
* !3720 fix direct bugs of not used RU_RX_SLOT_DEPTH defined constant
* !3714 Improve handling of selection of RSRP/SINR report via configuration file
* !3519 Refactor SDAP adaptation work for QoS
* !3698 Other CSI measurement fixes
* !3699 Updates for Feature Set
Closes#1008
See merge request oai/openairinterface5g!3713
Other CSI measurement fixes
Errors fixed in this MR:
- UE currently sends empty CSI measurement report resulting in invalid
cqi_idx 0, default to MCS 9 at gNB because mismanagement of new L1
measurement structure at MAC UE
- nrofReportedRS not updated after UE capability reception at gNB
- multiple RSRP reports multiplexed / de-multiplexed in wrong order
Refactor SDAP adaptation work for QoS
This MR is an adaptation of the code introduced in !2703.
The goal is a cleanup and functional refactor of the SDAP/PDCP
integration, that is:
- centralize SDAP configuration logic
- simplify entity creation
- improve robustness of role-based SDAP handling
- prepare the codebase for clean support of DRB reconfiguration and
teardown flows
More concretely:
1. New sdap_config_t and get_sdap_Config()
- Introduced an internal struct sdap_config_t to abstract SDAP config
input
- Centralized SDAP config parsing into new get_sdap_Config() function
that translates ASN.1 NR_SDAP_Config into this internal
representation. This is called during RRC triggered
(re)configuration procedures.
- Enable mapping of number of QoS flows > 1
2. Unified role handling with bitmasks
- Added a bitmask-based entity_role field to track SDAP directions:
SDAP_UL_RX, SDAP_UL_TX, SDAP_DL_RX, SDAP_DL_TX: header presence was
determined by simple direction (UE vs gNB) and individual
is_sdap_rx/tx() checks, however nr_sdap_rx_entity behaves
differently depending on the direction of the RX entity (DL/UL),
therefore this change can help enable a more accurate SDAP header
handling across directions and node types.
- Replaces old helpers is_sdap_rx() / is_sdap_tx() with internal
checks against the role bitfield
- QFI-to-DRB mapping is now annotated with direction for both data and
control PDUs
3. Simplified DRB and SDAP setup
- add_drb() in PDCP API now delegates SDAP config processing cleanly
- new_nr_sdap_entity() is used consistently to register a fresh SDAP
context for the UE and PDU session.
- Also, re-use and reconfigure existing SDAP entity if already
exists.
- logging has been added to trace mapped QFIs from RRC and resulting
table entries
4. Improved QFI-to-DRB management
- Refactored nr_sdap_qfi2drb_map_update() to register QFIs based on
parsed config
- Ensures control PDUs are correctly routed even after reconfiguration
- Extended nr_sdap_ue_qfi2drb_config: perform UL QoS flow to DRB
mapping configuration for a SDAP entity has already been established
according to TS 37.324, 5.3 QoS flow to DRB Mapping, 5.3.1
Configuration Procedures. Handle both UL QoS Flows mapping rules to
add and to remove. QFIs will now be properly unmapped if specified
via mappedQoS_FlowsToRelease, this might prevent stale QFI mappings
from being used incorrectly.
- nr_sdap_qfi2drb() and sdap_map_ctrl_pdu() now strictly fallback to
default_drb only if a QFI mapping is missing. Missing default DRB
now triggers LOG_E() (previously silent or misrouted to DRB 0).
5. Other cleanup
- Remove dependencies from legacy rb_id_t
Improve handling of selection of RSRP/SINR report via configuration file
In current develop, the selection of SSB or CRI RSRP depends on the
do_CSIRS flag being activated. That's not wanted. CRI report for now it
is never handled, while we need SSB RSRP report for beam switching
regardless of CSI-RS configuration.
This commit refactors the SDAP entity QoS flow to DRB mapping functionality
to improve code organization and enhance maintainability.
Key changes:
- Split nr_sdap_qfi2drb_map_update into focused functions:
* nr_sdap_add_qos_flows_to_drb: handles QFI addition to DRB
* nr_sdap_rm_qos_flows_from_drb: handles QFI removal from DRB
* nr_sdap_ue_control_pdu_config: handles UE control PDU generation
- Consolidate add/modify logic into reusable nr_sdap_addmod_entity function
- Remove entity existence checking and updating from new_nr_sdap_entity:
this function should only add SDAP entities
- Improve function separation of concerns: do SDAP entity add or update
separately and improve modularity by splitting operations in self
contained functions
- At SDAP creation, do only add of QFI to DRB mapping
- rename new_nr_sdap_entity to nr_sdap_add_entity for function naming consinstency
- Remove rb_id parameter from nr_sdap_tx_entity() function signature
- Update tx_entity function pointer
- Remove rb_id parameter from sdap_data_req() function signature
- Remove unused rb_id variable from sdap_tun_read_thread
The rb_id parameter was redundant since SDAP determines DRB ID
from QFI mapping via entity->qfi2drb_map(entity, qfi). This
simplifies the interface.
Each QFI should always be mapped to a DRB. If that is not the case, we
have an undefined behavior. This should not occur. This commit prints
an error in tx_entity and returns.
The TX/RX entity should have different behavior according to
5.2.1, 5.2.2, 3GPP TS 37.324, depending on whether it is UL and DL.
The gNB can play a role both as UL RX entity and DL TX entity, while
the UE can play a role both as UL TX entity and DL RX entity.
The goal of this commit is to extend the information stored in the
SDAP entity as the current code is just marking the entity as TX/RX.
The commit introduces a bitmap to store the role of the
entity, which can be DL RX, DL TX, UL RX and UL TX. Based on this
the TX SDAP entity knows whether a DL/UL PDU should be build, and
the RX SDAP entity knows whether a DL/UL PDU should be processed.
See also Figure 4.2.2-1.
SDAP headers are present only if enable_sdap option is used.
nr_sdap_qfi2drb_map_update function pointer should
process QFIs to add and release from the entity mapping, therefore
a new function pointer for QFIs to add was introduced and
the function pointer to release the QFIs was called in the same function.
Now the nr_sdap_qfi2drb_map_update is:
(1) looping through the QFIs to add/update and store in the qfi2drb_table
(2) looping through the QFIs to release and delete from qfi2drb_table
Also:
* Update the function signature to use sdap_config_t and nr_sdap_entity_t
* log error when the update fails
* limit the scope of the function
* clang-formatted
* removed limit on table entries set by AVLBL_DRB, replaced with MAX_DRBS_PER_UE
The function nr_sdap_ue_qfi2drb_config should do UL QoS flow to DRB mapping configuration
for a SDAP entity has already been established according to TS 37.324, 5.3 QoS flow to
DRB Mapping, 5.3.1 Configuration Procedures. It should handle both mapping rules to add and to remove.
To this purpose:
* Simplify function signature by passing the sdap config.
* Improve readability of the function.
* Move handling of sdap.mappedQFIs2ReleaseCount (in nr_reconfigure_sdap_entity)
inside the function.
* Simplify end-marker control PDU mapping function by removing unused
DRB ID input parameter (the function is fetching the DRB ID based on the input
map type)
* use int instead of legacy rb_id_t
* limit scope of functions whenever necessary
The goal of this function is to return the DRB ID mapped to the input QFI, for both DL and UL.
The function looks up the DRB that is mapped to the QFI, if no mapping rule exists
returns the default DRB. Returns 0 If no mapping and no default DRB exists for that QFI
The function should not update the stored mapping rules, that is done when receiving
a new SDAP configuration. In this function it was removed.
See TS 37.324, 5.2.1 Uplink
> If there is no stored QoS flow to DRB mapping rule for the QoS flow as specified in the subclause 5.3,
> map the SDAP SDU to the default DRB else, map the SDAP SDU to the DRB according to the stored QoS flow to DRB mapping rule.
* change function signature: pass the sdap_config_t
* update qfi2drb mapping when receiving a configuration for an already existing SDAP entity
* always update mapping rules, not only for default DRB
* use get_sdap_Config to process sdap_Config
* move SDAP config logic to the scope where it is relevant
* add SDAP entity direcly in RRC, not from PDCP
* replaced nr_pdcp_add_drbs with single add_drb call: it was no longer
efficient to keep it in the new logic. The addMod list can be looped directly in RRC.
* add specific function to add bearers from addMod list in E1, NSA, and UE
fix direct bugs of not used RU_RX_SLOT_DEPTH defined constant
with this commit, the gNB can work if we change RU_RX_SLOT_DEPTH to
another value than 4 but it remain not well designed
Initialize NCC=0 on NGAP Initial Context Setup (3GPP TS 33.501 §6.9.2.1.1)
The nhcc should be initialized to 0 upon Initial Context Setup.
Also, remove unused kgnb_ncc: nh_ncc is already there.
Closes#1008
[CI] Update the Push to DockerHub Stage
This MR addresses two cases:
1. Error Handling: Ensures subsequent Image Test Processes stages
continue to run even if the preceding Push to DockerHub stage fails
(applies when the condition is PUSH event and doBuild is true).
2. Introduces conditional logic to correctly handle multi-architecture
images: Images built for both AMD64 and Jetson ARMv8 (oai-gnb,
oai-nr-ue, oai-nr-cuup) use docker buildx imagetools for push to
DockerHub.
All other AMD64 images are pushed using standard Docker commands.
Related MR !3691
Add monolithic N2 handover test pipeline with B210 and Quectel
The goal of this MR is to provide an automated end-to-end N2 HO
validation with real RF (B210) and Quectel UE.
During the testing phase a post-HO assertion failure due to
uninitialized selected_plmn_identity was found: this was also fixed.
CI: Add monolithic N2 handover test pipeline (B210 + Quectel)
- New XML pipeline for N2 HO testing
- Docker Compose for two monolithic gNBs (gNB1/gNB2)
- Handover sequence: gNB1 → gNB2 → gNB1 with 5s controlled attenuation
(RC4DAT).
- Channel mapping: ch1-2 gNB1, ch3-4 gNB2
- Telnet server enabled for CI commands
- Clean-up/reset of attenuator state included
NGAP
- fix PLMN/cell location for Initial UE and Uplink NAS
- Prevents assertion in ngap_gNB_nas_uplink() due to uninitialized
selected_plmn_identity
- Initial UE Message: pass UE-selected PLMN and NR cell ID from RRC to
NGAP
- Uplink NAS Transport: use PLMN, TAC, and cell ID from the message
- Build NR CGI as gNB ID + cell ID
- Store UE-selected PLMN only in RRC UE context (for later NAS); stop
storing PLMN in NGAP UE context.
- PLMN validation when processing handover requests from the source gNB:
when PLMN validation fails, the target gNB now properly sends
NGAP_HANDOVER_FAILURE
- Store serving PLMN for later use in UE context
UE symbol based PDCCH receiver
This is a partial rebase/rewrite of !2895
The goal of this MR is to check how we can merge this.
The eventual result is stated in !2895. The way forward is to modify UE
RX procedures to work symbol by symbol by extracting the symbol loop out
of RX procedures. After all channels are modified this way, the main
thread can be modified to work symbol by symbol.
At this point only PDCCH was modified.
This change is needed due to the previous addition of the function nfapi_stop_l1() in gnb_config.c which in turn calls 2 functions that do not exist in the simulators, since they're not linked against the nfapi libraries
This implements the STOP.request/indication for all 3 transport mechanisms, the VNF will send the STOP.request to the PNF, indicating it will disconnect, and await a STOP.indication from the PNF
The WLS VNF is reworked to be able to start before the PNF, by calling call rte_eal_init and rte_dev_probe to determine if dpdk has been initialized properly, before calling rte_eal_init in the intended process when it is appropriate to do so
The WLS VNF is reworked to be able to start before the PNF, by calling call rte_eal_init and rte_dev_probe to determine if dpdk has been initialized properly, before calling rte_eal_init in the intended process when it is appropriate to do so
- Push both AMD64 & ARMv8 Jetson images together for images built on both using `docker buildx imagetools`
- Use standard 'docker pull and push' for images built only on AMD64.
This allows access to the VNF configuration in the various transport mechanisms straight from config, without this, the transport specific thread would cause a segmentation fault when trying to access the pack/unpack function pointers.
Add 2 functions to access the P5 and P7 VNF structures, to avoid having to always cast user_data and p7_vnfs
Prevent assertion in ngap_gNB_nas_uplink() due to uninitialized selected_plmn_identity:
the selected_plmn_identity field was not being set during N2 handover,
causing the assertion ((plmn->mnc_digit_length == 3) || (plmn->mnc_digit_length == 2))
to fail when processing subsequent NAS messages. The issue is that the Serving PLMN
is not stored by RRC. During N2 mobility, RRC can get this info from GUAMI.
When receiving the Handover Request the target gNB knows from GUAMI
which serving PLMN is the AMF belonging to. In current design, allowed PLMNs
are stored in rrc.configuration. The incoming PLMN needs to be validate
against the PLMNs in the list, then stored in the UE context as Serving PLMN.
This change adds PLMN validation when processing handover requests from the source gNB.
The validation is needed because:
- Target gNB must verify that the PLMN from the GUAMI in the handover request
is allowed by its configuration before accepting the handover to prevent handover
to unsupported PLMNs.
- When PLMN validation fails, the target gNB now properly sends NGAP_HANDOVER_FAILURE
- UE Context must store serving PLMN for later use
This commit is removing the storage of selected PLMN in NGAP UE context.
We store the Serving PLMN in the RRC UE context instead.
The Selected PLMN is the PLMN that the UE chose (or was directed to) for registration
and it is sent in the RRCSetupComplete. This is different from the selected
PLMN mentioned in the NG INITIAL UE MESSAGE for network sharing.
Selected PLMN: determines which core network and AMF the UE is registered with
GUAMI = Identifies the serving AMF and includes the PLMN of that AMF
Serving PLMN: the PLMN that is currently serving the UE (e.g. contained in GUAMI)
The AMF’s PLMN may match the selected PLMN, or not (especially in network sharing or roaming).
Regardless, the UE always have a Serving PLMN.
Initial UE message does not have a TAI IE per se, but TAI is a mandatory
member of the mandatory UserLocationInformation CHOICE.
NR CGI is also mandatory and carried inside UserLocationInformation:
in network sharing, the PLMN ID in TAI takes on additional
significance: RAN is shared but CN are different, so in this case PLMN in TAI is
needed for the AMF route the message to the correct operator’s core.
If network sharing applies (e.g., shared RAN between PLMN-A and PLMN-B):
the UE or network may select PLMN-B instead, and that PLMN identity
is included in the Initial UE Message’s TAI IE.
Conclusion:
1) UE always sends the selected PLMN during the registration,
regardless of whether it is shared or not.
2) Selected PLMN Identity is an actual IE sent in the RRCSetupComplete
while in NGAP there's no Selected PLMN Identity IE, only PLMN Identity
IEs in both TAI and NR CGI. It is a subtle difference.
3) The serving PLMN of the UE needs to be stored in RRC UE Context for
later use in NAS procedures. e.g. at initial registration it matches
the Selected PLMN
4) No need to store PLMN in NGAP UE Context, params are passed by RRC
5) TAI and NR CGI, which contain the PLMN identity, are mandatory in
UserLocationInformation IE CHOICE, and should reflect current status
Changes
- Initial UE Message: pass UE-selected PLMN and NR cell id from RRC to NGAP
- Uplink NAS Transport: use PLMN, TAC, and cell id provided by the message;
- Build NR CGI from gNB ID + cell id
- Store UE-selected PLMN only in RRC UE context at NAS_FIRST_REQ for later
Uplink NAS, stop storing PLMN in NGAP UE context
- Add XML pipeline for N2 handover testing
- Add Docker compose for two monolithic gNBs
- Features:
* Two monolithic gNBs (gNB1, gNB2) with proper CU+DU parameters
* Gradual attenuation control using RC4DAT attenuator (5s duration)
* N2 handover sequence: gNB1 → gNB2 → gNB1
* Proper channel mapping: ch1-2 for gNB1, ch3-4 for gNB2
* Telnet server configuration for CI commands
* Handover-specific neighbor configuration
* Clean test state management with attenuator reset
Update based on !3645
Note: For some test configurations we still need to provide
ra_ResponseWindow, for more details, check commit message of
41d14b571c
1. Refactor PDCCH PHY functions to take rxdataF of one OFDM symbol and
produce LLR for each search space. The modified functions take
rxdataF in a different format than that produced by nr_slot_fep(). So
for now a memcpy is used to change the array structure. Once
nr_slot_fep() is modified, this memcpy will no longer be needed and
will be removed.
2. Modify DCI functions to decode DCI in the last PDCCH symbol and
inidcate to MAC once.
3. Fix PDCCH monitoring for start symbol > 0.
4. Fix multiple PDCCH monitoring within slot.
Co-authored-by: Sakthivel Velumani <mail@sakthi.me>
1.Create new funtion nr_symbol_fep() to do OFDM demod of one symbol on
all antennas. This is called by nr_slot_fep() for now. In the
upcoming MR, this function will be called directly after reading
each OFDM symbol from the radio.
2.Removed redundant memory alignment. DFT function performs memory
alignment if the input memory is not aligned.
Fixes for T-Tracer to work with NR-UE
Fixes to align NR UE events with their definitions in T_messages.txt and
match the expected format in the tracer GUI parser.
Also fixes DL SNR to work in tracer GUI.
Support beam index in OAI 7.2 Fronthaul Interface
This branch supports beam index in OAI 7.2 Fronthaul Interface.
- For CP DL (PDSCH), nBeamIndex of the corresponding prbMapElm is set
when sending IQ data in oran_fh_if4p5_south_out. nBeamIndex of the
corresponding prbMapElm is set when sending IQ data in
oran_fh_if4p5_south_out.
- For CP UL (PUSCH and PRACH), nBeamIndex of the corresponding prbMapElm
is set in oran_fh_if4p5_south_out.
In addition, it fixes a couple of issues
- XRAN hardcodes nBeamIndex of PRACH to zero. Modify XRAN to support
setting of nBeamIndex of PRACH and update xran F release patch.
- Fix the bug in calculating fh_config->neAxc where num_beams_period is
multiplified twice
Testing methodology: Use Benetel O_RU for testing even though it does
not support beamforming. With successful registration and data transfer,
one could check the pcap on the fronthaul interface to see if CP packets
are with the right beam index.
Results:
1. Verified that CP-packets for SSB, DCI, PDSCH, PRACH, PDSCH, PUSCH,
CSI-RS and SRS are with the right beam index
2. Verified that there is no side-effect on Benetel O_RU. UE could
register properly.
3. Verified 4 SSB with ssb_PositionsInBurst_Bitmap = 85. Could see SSB
and PRACH with 4 different indices.
Handle CP UL packet at xran_fx_tx_send_slot() instead of
xran_fh_rx_read_slot(), as the latter would set this information too
late (on reception on samples, but it needs to be filled in the CP
packet prior to reception).
Initialize ru_info structure with beam information, and set beams on TX
direction. Initialize the number of antennas for both RX/TX in both
cases for completeness.
By configuring the Jenkins pythonExecutor to match the test machine, we can use
localhost as the node for running individual test cases. This change makes it
easy to move tests across machines, as the only adjustment needed is updating
the pythonExecutor in Jenkins.
By configuring the Jenkins pythonExecutor to match the test machine, we can use
localhost as the node for running individual test cases. This change makes it
easy to move tests across machines, as the only adjustment needed is updating
the pythonExecutor in Jenkins.
By configuring the Jenkins pythonExecutor to match the test machine, we can use
localhost as the node for running individual test cases. This change makes it
easy to move tests across machines, as the only adjustment needed is updating
the pythonExecutor in Jenkins.
1. Fix UE_PHY_PDSCH_IQ event
2. Fix UE_PHY_PDCCH_ENERGY event
3. Fix UE_PHY_PDSCH_ENERGY event
4. Fix UE_PHY_MEAS event
All fixes align NR UE events with their definitions in T_messages.txt and match the expected format in the tracer GUI parser.
Integration `2025.w42`
* !3623 Optimization of PDSCH precoding operation
* !3691 \[CI\] Ensure multi-arch DockerHub Push after successful image build
* !3696 asn1c doesn't follow c99 variables alias rules, it needs to be compiled this...
* !3685 Assign antenna ports correctly for 1 and 2 layers for aerial.
* !3495 Type0 PDSCH frequency allocation at L1 UE
* !3686 Remove NR L2 simulator code from UE
* !3693 Remove B200-specific clock-rate setting
* !3701 OAI UE: add shared RSRP Table 10.1.6.1-1 mapping function to helpers and adopt it RRC UE
* !3662 RRC UE file cleanup
* update doc/README.md
* !3608 use common scale channel functions for DLSCH and ULSCH
* !3694 fix non initialized DMRS port value in case of DCI00 at UE
* !3702 Extend F1 rfsim CI test
* !3704 remove unused global queues, dead code
* !3673 CI: Aerial: Add an UL-heavy pipeline test
* !3651 CI: Upgrade HO setup to use an attenuator
* !3695 CI: Upgrade Aerial setup to 25-2.1
Closes#940
See merge request oai/openairinterface5g!3700
CI: Upgrade Aerial setup to 25-2.1
The purpose of this MR is to upgrade the cuBB image in the Aerial setup to
release 25-2.1 and update the doc/Aerial_FAPI_Split_Tutorial.md accordingly.
CI: Upgrade HO setup to use an attenuator
The goal of this MR is to upgrade HO CI setup to include a digital attenuator
that will allow us to trigger handover by attenuating the signals on the DUs.
Doing this before using set_master_clock_rate() on the B200 seems to
invalidate synchronization setting.
[HW] USRP clock set to 1759836386.000000 sec
[...]
[HW] current pps at 3.286750, starting streaming at 4.286750
In other words, the current time setting was reset. With this change
now, we see
[HW] USRP clock set to 1759929873.000000 sec
[...]
[HW] current pps at 1759929873.000000, starting streaming at 1759929874.000000
This is because changing clock sources (I assume setting the master
clock rate impacts the clock) can result in changing the time. From the
documentation of [1]:
> Note: When changing clock sources, a previously set time will most
> likely be lost. It is recommended to set the time after changing the
> clock source. Otherwise, an unexpected time may line up with future PPS
> edges.
[1] https://files.ettus.com/manual/classuhd_1_1usrp_1_1multi__usrp.html#a99254abfa5259b70a020e667eee619b9
- main.py: replace %%workspace%% with CONTAINERS.eNBSourceCodePath in Custom_Command and Custom_Script
Co-authored-by: Guido Casati <hello@guidocasati.com>
- Add band mismatch check in valid_du_in_neighbour_configs function
- Ensures neighbor cell band matches serving cell band
- Prevents invalid neighbor configurations for handover
The code only checked that Msg3 would be scheduled during UL, but in
some combinations, e.g., with DSUUU, the current slot can very well be
UL as well => we would schedule DCI in UL slot.
Update cuBB image to cubb-build:25-2.1_srs-ul-heavy (release 25-2.1 with
changes in the L1 config to test heavy ul)
Co-authored-by: Reem Bahsoun <reem.bahsoun@openairinterface.org>
fix non initialized DMRS port value in case of DCI00 at UE
When transmitted PUSCH is neither scheduled by DCI format 0_1 with CRC
scrambled by C-RNTI, CS-RNTI, SP-CSI-RNTI or MCS-C-RNTI, nor
corresponding to a configured grant, the UE shall use [...] DM-RS port
0.
In UE code it was not set in case of DCI00 and that was leading to ULSCH
failures in some scenarios.
- Trigger handover
- IdleSleep 2s
- Ping ext-dn from NR-UE
- Verify UE(1) connected to DU-PCI1
Validate absence of heap-use-after-free ASAN error found in !3600.
Closes#940
OAI UE: add shared RSRP Table 10.1.6.1-1 mapping function to helpers and adopt
it RRC UE
- Add to common/utils/nr/nr_common remove from NR_MAC_UE/nr_ue_procedures.c
- Adopt in asn1_msg.c for MeasurementReport: this solves the following possible
assert:
Assertion (enc_rval.encoded > 0) failed!
In do_nrMeasurementReport_SA() /oai-ran/openair2/RRC/NR/MESSAGES/asn1_msg.c:898
ASN1 message encoding failed (MeasResultServMOList, 18446744073709551615)!
Motivation: unify RSRP-to-index mapping across layers and fix NR RRC
MeasurementReport encoding failures due to out-of-range values by reusing the
validated mapping.
Note: NR_RSRP-Range.c constraint: /* (0..127) */
Also refactored MeasurementReport to improve the code.
Remove B200-specific clock-rate setting
Avoid this clock-rate setting, as we already do it around usrp_lib.cpp:1121, so
it is superfluous. For instance, we also do not set a master clock rate for N3xx
either. This also enables us to synchronize B200 for handover settings,
e.g., for !3651.
See the commit message for more information about synchronization.
- Simplify do_nrMeasurementReport_SA API (encoder allocates local report)
- Adopt asn1cCalloc consistently
- Minor init cleanup for UL_DCCH message struct
- Add to common/utils/nr/nr_common remove from NR_MAC_UE/nr_ue_procedures.c
- Adopt in asn1_msg.c for MeasurementReport: this solves the following assert:
Assertion (enc_rval.encoded > 0) failed!
In do_nrMeasurementReport_SA() /oai-ran/openair2/RRC/NR/MESSAGES/asn1_msg.c:898
ASN1 message encoding failed (MeasResultServMOList, 18446744073709551615)!
Motivation: unify RSRP-to-index mapping across layers and fix NR RRC MeasurementReport
encoding failures due to out-of-range values by reusing the validated mapping.
Note NR_RSRP-Range.c constraint:
{ APC_CONSTRAINED, 7, 7, 0, 127 } /* (0..127) */
Remove NR L2 simulator code from UE
This MR removes NR (SA and NSA) L2 simulator from the codebase. The code, at
least at the UE side, was done at a time where there was no clear L2/L1 split
leading to a complex implementation that never worked as expected. The L2
simulator has been broken and removed from testing for long time and, once it
needs to be revived, it would require a complete new implementation.
Assign antenna ports correctly for 1 and 2 layers for aerial.
With this change aerial successfully decodes PUSCH with 2 UL layers.
The code should use sched_pusch->dmrs.num_dmrs_cdm_grps_no_data == 1 rather
than NFAPI_MODE != NFAPI_MODE_AERIAL, but that will make the changes a bit
more extensive.
Prior to this change, sending antenna_ports.val = 2 with rank 2 would tell
the UE to transmit on DMRS ports 2,3 rather than 0,1 causing it to not decode.
[CI] Ensure multi-arch DockerHub Push after successful image build
This merge request improves the CI script to ensure that the DockerHub-Push
stage executes whenever:
- All Image Build stages succeed &
- doBuild is true &
- The event is a PUSH
This behavior ensures that Docker images are published whenever the image build
stages succeed, regardless of any failures in the Image Test stages.
Jetson ARM64/V8 and AMD64 images will now be published on DockerHub under the
same tag (develop or WEEK_TAG) to provide multi-architecture images.
Optimization of PDSCH precoding operation
x86/aarch64 optimizations for precoding, more complete timing reporting in
nr_dlsim. Timing report in nr_dlsim now shows the total PDSCH generation time
and is broken down into Layer mapping, resource mapping and precoding.
The optimizations for x86 are basically reorganizing loops (for AVX512,AVX2,
NEON but not SSE2) to minimize repetitive instructions when formatting of the
precoder weights, and creation of inline functions for complex multiply-add.
AVX512 optimization was added. requiring AVX512BW. Detection of up to 4 PRBs
with common PMI for efficiency with AVX512 (was 2 in develop for AVX2).
For aarch64, native coding of the precoder to avoid inefficient SIMDe
translations for this operation.
nr_dlsim now uses default precoding indices depending on the scenario instead
of 0 which doesn't do precoding at all.
See merge request description for nr_dlsim test results.
- On PUSH events, if image build stages succeed, trigger DockerHub push stage
- Build the images, then trigger the Push to DockerHub stage
- Publish Jetson (ARM64/v8) and AMD64 images under the same tag on DockerHub
Doing this before using set_master_clock_rate() on the B200 seems to
invalidate clock settings:
[HW] USRP clock set to 1759836386.000000 sec
[...]
[HW] current pps at 3.286750, starting streaming at 4.286750
In other words, the current time setting was reset. With this change
now, we see
[HW] USRP clock set to 1759929873.000000 sec
[...]
[HW] current pps at 1759929873.000000, starting streaming at 1759929874.000000
This is because changing clock sources (I assume setting the master
clock rate impacts the clock) can result in changing the time. From the
documentation of set_time_next_pps() [1]:
> Note: When changing clock sources, a previously set time will most
> likely be lost. It is recommended to set the time after changing the
> clock source. Otherwise, an unexpected time may line up with future PPS
> edges.
[1] https://files.ettus.com/manual/classuhd_1_1usrp_1_1multi__usrp.html#a75b1c5375549e6a446d686ee7d9b4e14
The next commit introduces an "UL-heavy" configuration to be tested with
Aerial. To avoid waiting for the CN, start&stop it once at the beginning
of the CI run.
Reduce throughput requirement, as this fails once two DUs are connected
to a UE, which creates more load on the machine and frequently fails
with low throughput.
CI: Enable Physim threshold check for tests on Caracal and GH
This MR adds support for configurable timing threshold files in PhySim
tests.
- Introduces a new CMake cache variable PHYSIM_CHECK_FILES to specify
one or more timing threshold files (semicolon-separated).
- Enables optional enforcement of timing thresholds check in PhySim
tests without changing existing test definitions.
- Defines timing thresholds for LDPC encoding/decoding in nr_ulsim,
nr_dlsim and ldpctest on Caracal and GH machines.
SRS noise power
This MR implements the calculation of the noise power based on SRS in a
different way, and check whether SNR is more accurate or not. This MR is
built on top of the MR: !3460
A graph was added in T_Tracer to observe UL-SNR calculated using SRS.
See merge request description for measurement results.
Replace the previous add_timed_physim_test() macro with add_physim_test()
to use a single, unified function for defining physim tests. This simplifies
the test configuration and removes redundant macro definitions while keeping
all existing functionality.
This change follows up on the earlier addition of support for including
custom timing threshold files (PHYSIM_CHECK_FILES).
Update existing tests accordingly.
Add missing timinig analysis scripts to RHEL9 physim docker image. These files
are now copied from the build stage to /oai-ran/openair1/SIMULATION/tests/,
where they are expected by ctest.
Resolves following issue when running ctest in docker container:
CMake Error: Error processing file: /oai-ran/openair1/SIMULATION/tests/RunTimedTest.cmake
For some physical simulators, we have multiple SNR iterations.
The previous version of the script correctly retained only the last
measurement, but if a previous measurement condition set RC=1, the
script would fail although the final "good" run might fulfil the
measurement condition (IOW, it would show SUCCESS, but still fail on the
check).
Instead, check if all measurement lines finish on SUCCESS, which handles
the above case.
The awk script in analyze-timing.sh used syntax that works with gawk but fails
on systems where mawk is the default implementation, producing errors such as:
awk: /dev/fd/3: line 6: syntax error at or near ,
-- test command finished with SIGPIPE
Concretely, the match(text, pattern, variable) function does not exist
in mawk, as it cannot capture matches in variables. Work around by
substituing strings, and force a numeric comparison.
Fixes to prevent assertion due to 0 PRB allocation
Assertion (NPRB>0 && (NPRB + RBstart <= BWPsize)) failed!
In PRBalloc_to_locationandbandwidth0() /home/user/openairinterface5g/common/utils/nr/nr_common.c:506
Illegal NPRB/RBstart Configuration (0,51) for BWPsize 51
Probably caused by missing safeguards to prevent computing TBS with 0 PRB
as input.
Fix OAI UE memory leaks
Fix 1: Replaced asn1cFreeStruc with ASN_STRUCT_FREE in MAC layer to properly
free nested ASN.1 structures in cell group configuration.
Fix 2: Removed premature nullification of dedicatedNAS_Message->buf in
dlInformationTransfer processing to allow proper ASN.1 cleanup.
Fix 3: Fixed memory ownership in nr_rrc_process_dedicatedNAS_MessageList by
copying OCTET_STRING data instead of transferring ownership, preventing
ASN.1 cleanup from losing track of allocated memory
Closes#828
fix RSRP computation at UE
Conflicts between !3595 (merged) and !3596 (merged) leading to double conversion
of RSRP into index in L1 and L2. With this fix it is only converted in L2.
Replace int16 min when obvious
INT16_MIN doesn't have a opposite value on 16 bits, so SIMD abs (absolute()), or
simple C operations doesn't make the expected result.
example:
(gdb) p (short)-(short)-32768
$4 = -32768
(gdb)
This MR replaces constants INT16_MIN by -INT16_MAX (so -32767) in places where
it used for mathematical operations. This is not perfect, nevertheless reduces
overflow probability.
We saw in some places a dirty case: code do first calls to _mm_adds_epi16
(or subs), so because of the saturated operations, the probability to reach
32767 and -32768 is higher than the other numbers but, _mm_abs_epi16(), or
negate operations (conjugate) can follow, that is making strong error as
abs(-32768)=-32768
Also, don't use "set -x" debugging for oc login command:
ci-scripts/cls_cmd.py:242 sets BASH_XTRACEFD=1, which makes that all
"set -x" output is in stdout, leading to a redirect to the file into
which we redirect. This would lead to the following error with
unsuccessfull oc login:
error: You are not a member of project "****-core-for-ci-ran".
Error from server (Forbidden): imagestreams.image.openshift.io "oai-physim"
is forbidden: User "system:anonymous" cannot get resource "imagestreams" in
API group "image.openshift.io" in the namespace "****-ran"
This fixes basically two problems. First, remove "set -e", which leads
to the script exiting on error. For instance, there was the sleep which
should account for the time of the pod being in "ContainerCreating", but
might not be enough. In that case, the script would exit, leaving the
pod deployed.
Second, a fixed time is not good, as it can be too short and unduly
prolong waiting time. Replace with a loop.
- Remove unnecessary NULL assignment for dedicatedNAS_Message->buf
- The original buffer is copied and transfered to NAS, so it can be properly freed by ASN.1 structure cleanup
Root cause: Code was nullifying dedicatedNAS_Message->buf pointer before ASN.1 cleanup could free the original allocation, causing the leak from OCTET_STRING_decode_uper.
AddressSanitizer leak trace (FIXED):
Direct leak of 119 byte(s) in 3 object(s) allocated from:
/#0 0x7ec2a42b4c38 in __interceptor_realloc
/#1 0x555fade852e0 in OCTET_STRING_decode_uper
/#9 0x555fadb48b11 in nr_rrc_ue_decode_dcch.
The leak was caused by improper memory ownership handling in the
dedicatedNAS_MessageList processing. The function was transferring
buffer ownership to NAS messages and then preventing ASN.1 cleanup
from freeing the original allocations by setting
list.count = 0, causing a memory leak.
Leak trace:
Direct leak of 40 byte(s) in 1 object(s) allocated from:
/#0 0x7f2ce3ab4a57 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
/#1 0x567907083f0f in OCTET_STRING_decode_uper /cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/OCTET_STRING_uper.c:89
/#2 0x5679070ed5e6 in SET_OF_decode_uper /cmake_targets/ran_build/build/openair2/RRC/NR/MESSAGES/constr_SET_OF_uper.c:70
/#3 0x56790707b6dc in SEQUENCE_decode_uper /cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/constr_SEQUENCE_uper.c:118
/#4 0x56790707b6dc in SEQUENCE_decode_uper /cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/constr_SEQUENCE_uper.c:118
/#5 0x56790709a403 in CHOICE_decode_uper /cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/constr_CHOICE_uper.c:84
/#6 0x56790707b6dc in SEQUENCE_decode_uper /cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/constr_SEQUENCE_uper.c:118
/#7 0x56790709a403 in CHOICE_decode_uper /cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/constr_CHOICE_uper.c:84
/#8 0x56790709a403 in CHOICE_decode_uper /cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/constr_CHOICE_uper.c:84
/#9 0x56790707b6dc in SEQUENCE_decode_uper /cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/constr_SEQUENCE_uper.c:118
/#10 0x56790708b5f1 in uper_decode /cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/uper_decoder.c:83
/#11 0x567906d44b4b in nr_rrc_ue_decode_dcch /openair2/RRC/NR_UE/rrc_UE.c:2212
/#12 0x567906d520a3 in rrc_nrue /openair2/RRC/NR_UE/rrc_UE.c:2615
/#13 0x567906d5f77e in rrc_nrue_task /openair2/RRC/NR_UE/rrc_UE.c:2501
/#14 0x7f2ce2494ac2 in start_thread nptl/pthread_create.c:442
Fix:
- Copy OCTET_STRING data instead of transferring ownership
- Allow ASN.1 cleanup to properly free original allocations
This fixes the leak that occurred during rrcReconfiguration
message processing when dedicatedNAS_MessageList was present.
Closes#828
- Replace asn1cFreeStruc with ASN_STRUCT_FREE in MAC layer cleanup
- Fixes improper memory management of NR_CellGroupConfig structures
Root cause: asn1cFreeStruc only calls ASN_STRUCT_RESET + free(), which doesn't properly free nested ASN.1 allocations. ASN_STRUCT_FREE frees all nested structures completely.
AddressSanitizer leak trace:
Direct leak of 288 byte(s) in 1 object(s) allocated from:
/#0 0x7fb72bab4a57 in __interceptor_calloc
/#1 0x593752b28d0d in SEQUENCE_decode_uper
/#2 0x593752b9a546 in SET_OF_decode_uper
/#3 0x593752b2863c in SEQUENCE_decode_uper
/#4 0x593752b47363 in CHOICE_decode_uper
/#5 0x593752b2863c in SEQUENCE_decode_uper
/#6 0x593752b2863c in SEQUENCE_decode_uper
/#7 0x593752b2863c in SEQUENCE_decode_uper
/#8 0x593752b2863c in SEQUENCE_decode_uper
/#9 0x593752b2863c in SEQUENCE_decode_uper
/#10 0x593752b38551 in uper_decode
/#11 0x5937527d859f in nr_rrc_ue_process_masterCellGroup
/#12 0x5937527d9408 in nr_rrc_process_reconfiguration_v1530
/#13 0x5937527dd5bb in nr_rrc_ue_process_rrcReconfiguration
/#14 0x5937527f5e6b in nr_rrc_ue_decode_dcch
/#15 0x5937527ff003 in rrc_nrue
/#16 0x59375280c6de in rrc_nrue_task
Integration: `2025.w40`
* !3672 \[ci\] Fix MissingPropertyException - COTS-UE by binding OAI_Registry globally
* !3609 BWP with no PRACH occasions
* !3657 do not assert for mismatched TBS in phy-test mode
* !3667 CI: Updates for HO and AW2S pipeline
* !3674 NR UE: remove function get_nr_RSRP() and get_nr_rx_total_gain_dB() for cleanup
* !3478 NR UE: add UCI (HARQ-ACK/NACK) on PUSCH support at PHY
* !3664 modulation LUTs size was wrong, and remove inconsistent test of SSE2 enable
* !3665 Make all targets compile
* !3554 Handle failures in RRCReconfiguration encoding gracefully
* !3655 Improvements to N2 handover
* !3678 Add OAIUE longrun pipeline
* !3628 Update documentation
Closes#979, #726, #959, #967, and #930
See merge request oai/openairinterface5g!3676
Add OAIUE longrun pipeline
Add a new XML file for OAIUE longrun.
- Test description:
* 40 MHz BW, n78
* gNB with USRP N310, UE with USRP N310
* CN deployed on OC
- Test duration: 1 hour
- Test scenario: 3x DL 10 min test (20 Mbps) + 3x UL 10 min test (5
Mbps)
pods deployed through helm occasionally take more time, leading to
errors such as
Error from server (BadRequest): container "physim" in pod "oai-physims-4g-sczvl" is waiting to start: ContainerCreating
Give a bit more time before checking the logs. We cannot wait too much,
as the container will just end on FINISHED in running state, so the logs
will always be there.
Make all targets compile
This MR enables us to compile all targets, and does that in one CI test. This
closes#726. Now, this should work:
cd ~/openairinterface5g
mkdir build && cd build
cmake .. -GNinja && ninja
To achieve this, I did the following:
- some targets have been fixed (warnings, errors)
- some targets have been removed when they did not seem to serve a good purpose
(e.g., an almost empty test)
- some targets have been commented (e.g., LTE simulators, some unitary tests)
which we maybe want to revive in the future
- some targets built when just building with ninja, but not all. For instance,
telnetsrv_enb would typically build, but it was missing a dependency. Doing
cmake .. -GNinja && ninja telnetsrv_enb would show this (in develop)
To help with the last bullet point, there is a script compile_targets.sh that
can compile targets independently (and in parallel, to not wait for ages) to
show that targets compile properly compile-targets.patch.
In almost all cases, the problem is that a specific module uses the logging
module, which depends on T, which needs to dynamically create headers. The way
to do this is to have a dependency, and many targets use generate_T or {T_LIB}
({} intentional: T might be absent, so then it evaluates to nothing). However,
not all do this, and those that depend on T actually don't depend on T, but on
the logging module, which in turn depends on T. So in many places, a simple
dependency onto log_headers fixes this problem, and generate_T or {T_LIB}
simplifies the dependency (but not always). The commits should have more info.
Note that at least the targets in FlexRIC do not all compile, at least in the
configuration that we use in docker/Dockerfile.build.ubuntu. So for the latter,
we cannot build with a simple ninja, but FlexRIC seems to be the only one that
does not compile. Since FlexRIC is a separate repository, that needs to be
addressed in the corresponding repository.
Previously, the script attempted to directly merge ${merge}, which could f
ail if the branch was not already available locally. This update explicitly
fetches the branch from origin and then merges FETCH_HEAD with --ff, ensuring
the merge works even when the branch is missing locally.
- Move 'What is a gNB neighbor?' explanation from rrc-usage.md to handover-tutorial.md where it belongs
- Replace generic parameter names with actual configuration parameter names and specific descriptions (e.g. gNB_ID, nr_cellid)
- Add example configuration structure showing proper syntax
- Add missing 'band' parameter that was not listed before
- Provide concrete examples and exact constraints for each parameter
- Cross-reference between documents for better organization
This addresses documentation issues where generic parameter descriptions were
not useful for developers configuring neighbor cells.
- Remove extensive traffic testing before HO (iperf tests 030001, 030002)
- Do 1 ping test after attachment
- Reduce ping packet count from 100 to 50 packets for remaining connectivity test
Time savings: ~2-3 minutes by removing traffic validation overhead
Split monolithic e1_send_bearer_updates into three focused functions:
- e1_send_bearer_updates(): DRB setup from F1 UE Context Modification Response
- e1_request_pdcp_status(): Request PDCP status during inter-CU handover
- e1_notify_pdcp_status(): Notify CU-UP with PDCP status during handover
Extract common helpers:
- append_e1_drb_mod_req(): Common DRB-to-mod for bearer request logic
- e1_send_bearer_modification_request(): Common sending step
Bug fixes:
- Fix loop bounds (i < n instead of i == n)
- Fix array access bounds checking
- Fix DRB ID consistency
Memory management:
- Add missing free_e1ap_context_mod_request calls
- Improve error handling with early returns
In the process:
- Simplify cuup_notify_reestablishment with FOR_EACH_SEQ_ARR loop
- Adopted all callers to use new consolidated functions
Improves maintainability and eliminates complex conditional logic.
Replace field-by-field assignment with struct copy for plmn_identity.
Both source and destination use identical plmn_id_t type, making
this change safe and more maintainable.
- Reduces lines of code
- More readable and less error-prone
- Single memory copy operation instead of multiple field assignments
- ngap_gNB_handover_notify: Fix misleading error message from 'Failed to encode'
to 'Failed to find UE context' for better clarity
- ngap_gNB_handle_ul_ran_status_transfer: Standardize error message format
from 'Could not find' to 'Failed to find' for consistency across functions
This ensures consistent and accurate error reporting across all NGAP handover functions.
- Update encoder functions in ngap_gNB_mobility_management.c to use calloc_or_fail
- Provides zero-initialized memory and consistent error handling
- Prevents uninitialized fields and improves memory safety
Also:
- Update NG Setup Request to use calloc_or_fail
- Replace inefficient 'allocate, extract, free' pattern with direct value extraction
- Remove unused functions get_gap_config_from_smtc() and get_gap_config()
- Add extract_gap_config_from_smtc() that extracts values directly without allocation
- Eliminates use-after-free risk and improves performance
- No allocation overhead, no memory leaks
- Add missing ASN_STRUCT_FREE for NR_MeasGapConfig in create_measgap_config
- Fix 48-byte measurement gap config leak in get_gap_config_from_smtc
AddressSanitizer backtrace:
Direct leak of 48 byte(s) in 1 object(s) allocated from:
/#0 0x7d32adab4a57 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
/#1 0x5751f99cbb79 in calloc_or_fail /home/guido/repo/openairinterface5g/develop/common/utils/utils.h:74
/#2 0x5751f99cbb79 in get_gap_config_from_smtc /home/guido/repo/openairinterface5g/develop/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c:4164
/#3 0x5751f99cbb79 in create_measgap_config /home/guido/repo/openairinterface5g/develop/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c:4310
/#4 0x5751f9964abe in ue_context_setup_request /home/guido/repo/openairinterface5g/develop/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c:709
/#5 0x5751f979e568 in nr_initiate_handover /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB_mobility.c:218
/#6 0x5751f97a637f in nr_rrc_trigger_n2_ho_target /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB_mobility.c:526
/#7 0x5751f9703608 in rrc_gNB_process_e1_bearer_context_setup_resp /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB.c:2641
/#8 0x5751f9706b7b in rrc_gnb_task /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB.c:3020
/#9 0x7d32ac494ac2 in start_thread nptl/pthread_create.c:442
Root cause: create_measgap_config allocated NR_MeasGapConfig via get_gap_config_from_smtc()
but never freed it after extracting the needed values to populate the measgap_config_t
return structure.
- Add missing handover context cleanup in rrc_CU_process_ue_context_release_complete
- Fix 16-byte handover context leak in N2 handover source gNB trigger path
AddressSanitizer backtrace:
Direct leak of 16 byte(s) in 1 object(s) allocated from:
/#0 0x7fee67cb4a57 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
/#1 0x58059e33454b in calloc_or_fail /home/guido/repo/openairinterface5g/develop/common/utils/utils.h:74
/#2 0x58059e33454b in alloc_ho_ctx /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB_mobility.c:47
/#3 0x58059e339e4d in nr_rrc_trigger_n2_ho /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB_mobility.c:556
/#4 0x58059e33ae93 in nr_HO_N2_trigger_telnet /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB_mobility.c:611
Root cause: Handover context allocated in N2 handover source gNB trigger path (nr_rrc_trigger_n2_ho)
for any successful N2 handover but not properly freed in all handover completion scenarios.
The UE context release complete handler was missing cleanup for handover context.
Solution: refactor handover context cleanup
- Move nr_rrc_finalize_ho() call to rrc_delete_ue_data() for centralized cleanup
- Remove redundant nr_rrc_finalize_ho() calls from handover failure paths:
* rrc_CU_process_ue_context_release_request() - UE not deleted yet
* invalidate_du_connections() - UE will be deleted later
- Keep nr_rrc_finalize_ho() calls in handover success paths where UE continues operating
- Ensures handover context is cleaned up exactly once when UE is actually deleted
- Prevents potential double-free and use-after-free issues in handover cleanup
This centralizes all UE data cleanup in rrc_delete_ue_data() and ensures
handover context is properly managed throughout the UE lifecycle and cleaned up
when UE delete happens.
NR UE: add UCI (HARQ-ACK/NACK) on PUSCH support at PHY
Add UCI (HARQ-ACK/NACK) on PUSCH support at nrUE PHY, the multiplexing procedure
can be found in TS 38.212 section 6.2.7.
Verified with 3rd-pary gNB for cases when HARQ payload bits length is 1, 2 or 3.
Closes#959 and #967 .
- Add missing ASN_STRUCT_FREE for NR_MeasurementTimingConfiguration in ue_context_setup_request
- Fix 64-byte MTC sequence leak in get_nr_mtc → SEQUENCE_decode_uper
AddressSanitizer backtrace:
Direct leak of 64 byte(s) in 1 object(s) allocated from:
/#0 0x7dcfcb8b4a57 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
/#1 0x591fcc59b67d in SEQUENCE_decode_uper /home/guido/repo/openairinterface5g/develop/cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/constr_SEQUENCE_uper.c:37
/#2 0x591fcc57eaa1 in uper_decode /home/guido/repo/openairinterface5g/develop/openair2/RRC/LTE/MESSAGES/uper_decoder.c:83
/#3 0x591fcbdbedeb in get_nr_mtc /home/guido/repo/openairinterface5g/develop/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c:4216
/#4 0x591fcbd58188 in ue_context_setup_request /home/guido/repo/openairinterface5g/develop/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c:635
/#5 0x591fcbb92568 in nr_initiate_handover /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB_mobility.c:218
/#6 0x591fcbb9a37f in nr_rrc_trigger_n2_ho_target /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB_mobility.c:526
/#7 0x591fcbaf7608 in rrc_gNB_process_e1_bearer_context_setup_resp /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB.c:2640
/#8 0x591fcbafab7b in rrc_gnb_task /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB.c:3019
/#9 0x7dcfca294ac2 in start_thread nptl/pthread_create.c:442
Root cause: ue_context_setup_request allocated NR_MeasurementTimingConfiguration via
get_nr_mtc() but never freed it after creating the measurement gap configuration.
The create_measgap_config function only reads from the structure and doesn't take
ownership, so the caller must free it.
- Replace heap allocation with stack allocation for seq_arr_t structures
- Use proper seq_arr_free() with free functions for ASN.1 structures
- Remove unnecessary malloc/free calls for sequence containers
- Improve memory safety and performance with automatic cleanup
Fixes 128-byte memory leak:
Direct leak of 128 byte(s) in 2 object(s) allocated from:
/#0 0x7e7f39ab4a57 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
/#1 0x56df8b07312d in SEQUENCE_decode_uper /home/guido/repo/openairinterface5g/develop/cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/constr_SEQUENCE_uper.c:37
/#2 0x56df8b056551 in uper_decode /home/guido/repo/openairinterface5g/develop/cmake_targets/ran_build/build/openair2/RRC/LTE/MESSAGES/uper_decoder.c:83
/#3 0x56df8a896b1b in get_nr_mtc /home/guido/repo/openairinterface5g/develop/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c:4216
/#4 0x56df8a82feb8 in ue_context_setup_request /home/guido/repo/openairinterface5g/develop/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c:635
/#5 0x56df8a66a298 in nr_initiate_handover /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB_mobility.c:218
/#6 0x56df8a6720af in nr_rrc_trigger_n2_ho_target /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB_mobility.c:526
/#7 0x56df8a5cf338 in rrc_gNB_process_e1_bearer_context_setup_resp /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB.c:2633
/#8 0x56df8a5d28ab in rrc_gnb_task /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB.c:3012
/#9 0x7e7f38494ac2 in start_thread nptl/pthread_create.c:442
- Add early check for existing UE context by AMF UE NGAP ID at beginning of rrc_gNB_process_Handover_Request
- Add dedicated function to get UE context by AMF UE NGAP ID: rrc_gNB_get_ue_context_by_amf_ue_ngap_id()
- Send handover failure with appropriate cause if UE context already exists
- Remove redundant ho_context NULL check that could never be true for newly created UE contexts
- Prevents duplicate handover processing and resource leaks
Move UE context creation and storage to after successful PDU encoding
to prevent memory leaks if encoding fails. Also add proper PDU cleanup
when AMF fetch fails and use consistent NULL check style.
This ensures UE context is only stored when the operation is guaranteed
to succeed, improving error handling and memory management.
In the current memory management the caller wasn't responsible for freeing
memory they allocate. The ngap_gNB_encode_pdu function was taking ownership
of PDU contents by calling ASN_STRUCT_FREE_CONTENTS_ONLY, while callers
also expected to manage the same memory. This created unclear ownership semantics and
potential double-free bugs.
- Remove ASN_STRUCT_FREE_CONTENTS_ONLY from ngap_gNB_encode_pdu to prevent double-free
- Remove unnecessary ASN_STRUCT_FREE when encode function returns NULL
- Add proper ASN_STRUCT_FREE cleanup for heap-allocated PDUs in ngap_gNB.c functions
- Add ASN_STRUCT_FREE_CONTENTS_ONLY cleanup for stack-allocated PDUs in NAS and context management functions
- Ensure consistent memory cleanup patterns across all NGAP encoder callers
- Fix potential memory leaks in all ngap_gNB_encode_pdu call sites
This prevents double-free bugs and ensures proper cleanup of ASN.1 structures
in both heap and stack allocation scenarios.
Add check for cu_exists_f1_ue_data() before calling cu_get_f1_ue_data()
to prevent assertion failure when telnet command 'ci fetch_du_by_ue_id'
is used for UEs that have been handed over via N2 (and no longer have
F1 UE data).
This fixes the crash:
Assertion (ret == HASH_TABLE_OK && data != ((void *)0)) failed!
In get_hashtable_data() /oai-ran/openair2/F1AP/f1ap_ids.c:36
element for ue_id 1 not found
The function now returns NULL gracefully when F1 UE data is not available.
Co-authored-by: Guido Casati <hello@guidocasati.com>
- Add proper cleanup of allocated ASN.1 structures in all return paths
- Fix early returns that were leaking NR_HandoverPreparationInformation
- Fix early returns that were leaking NR_RRCReconfiguration
- Add cleanup at end of successful function execution
This prevents memory leaks when processing handover preparation information
during N2 handover procedures.
- Add UE context cleanup before sending handover failure message
- Prevents memory/resource leak when PDU session establishment fails during handover
- UE context was created but never cleaned up on failure path
This fixes a bug where UE contexts would accumulate over time
when handovers failed after context creation.
Since there is no UCI on PUSCH implementation in gNB, it is good to test
UE's implementation with matlab.
This commit allows to test with matlab in two ways:
1. generate OFDM waveform from ulsim and decode it in matlab using
uci_on_pusch_decode.m
2. generate codeword in matlab using uci_on_pusch_encode.m read it in
ulsim and compare the bits. ulsim option -o is used
When the codeword has UCI multiplexed with data, we need to handle UCI scrambling according to 38.211 section 6.3.1.1.
Especially when O_ACK <= 2 there are x and y placeholder bits for UCI.
Get beta offset, alpha scaling and other parameters to calculate rate matching information for UCI on PUSCH,
then use the rate matching info to encode UCI and re-encode PUSCH, call nr_uci_on_pusch to get final multiplexed codeword for scrambling.
NR UE: remove function get_nr_RSRP() and get_nr_rx_total_gain_dB() for cleanup
The function get_nr_RSRP() and get_nr_rx_total_gain_dB() are not used anywhere
in the code, removing for cleanup.
CI: Updates for HO and AW2S pipeline
This MR introduces several CI updates:
- Change center frequency from 3439 MHz (n78) to 4185 MHz (n77) in HO setup to
prevent interference with other lab setups.
- Enable attaching multiple AmariUEs simultaneously in the AW2S pipeline - save
~25s.
- Update RX gain configuration on AmariUE - improve DL throughput.
BWP with no PRACH occasions
This MR includes fixes at gNB and UE in case the current BWP has no PRACH
occasions, i.e. we need to switch to initial BWP.
`def` creates a variable local to the script object, not automatically visible inside helper functions.
This fixes the following exception in Jenkins:
Found unhandled groovy.lang.MissingPropertyException exception:
No such property: OAI_Registry for class: groovy.lang.Binding
These libraries depend on the logging module, so add the right
dependency log_headers. Indirectly, this will fulfill the condition of
T. I consider the prior usage of generate_T or {T_LIB} incorrect,
because basically none of these libraries actually, actively use T, but
rather only the logging module, which pulls in T. The dependency of
log_headers will also take care of generating and including T headers,
which is a dependency of the logging module.
For conf2uedata and related, fulfill the dependency
through conf2uedata_lib (on which the rest depends).
These libraries have no dependencies on UTIL, so it's better to omit it.
However, then the test is missing symbols for the config (which likely,
indirectly came through UTIL -> LOG -> CONFIG_LIB, so add it now onto
the test.
These libraries have an (indirect) dependency on T, either by using the
logging module (which in turn depends on T), or through other includes.
The easiest is to depend on the logging module, which will fulfil also
the T dependency.
It would equally be feasible to use the utils target (which in turn
depends on log_headers), but this would necessitate to compile, and does
not seem to be necessary.
Since E2 agent uses the config library, include it directly. This also
makes the dependency on T obsolete, because
- it is the logging headers that are needed, and
- the T dependency is fulfilled through the log_headers.
It seems that many compilation units include T.h through the config
module (as evidenced when taking out T.h from
config_load_configmodule.h). This is strange, because T.h is only used
in the logging headers. Hence, move it to there, where it is used.
coding_defs.h included defs_common.h, which pulls in many dependencies,
e.g., the logging module, which pulls in T. However, it does not use
anything of this. So remove, and include stdbool.h instead (because bool
is used in coding_defs.h.
nr_polar_defs.h relied on some includes done in coding_defs. Use
includes for pthreads and SIMD to define types that are used in
nr_polar_defs.h.
We don't use JER. This avoids compilation problems, such as:
/usr/bin/ld: openair3/NRPPA/MESSAGES/libasn1_nrppa.a(INTEGER_jer.c.o): in function `INTEGER_decode_jer':
tmp.MtrwVDhQqY/openair3/NRPPA/MESSAGES/INTEGER_jer.c:186:(.text+0x5b8): undefined reference to `jer_decode_primitive
XNAP is asn1c compiled with -no-gen-BER. Correspondingly, no
ber_decoder.h file is created. However, when running cmake followed by
ninja, it notices the absence of this file:
ninja explain: output openair2/XNAP/MESSAGES/ber_decoder.h doesn't exist
which triggers a complete rebuild of XNAP ASN.1. Without this file, the
targets are not marked as dirty.
This constant seems to be an analogon to NUMBER_OF_UE_MAX; replace with
the latter, as it does the same. (NBIoT does not work, anyway)
Fix dependencies of the NB_IoT target so it compiles.
Remove, because
1) it does not compile (the asn1c generated code should be prepend with
LTE_ etc, nobody did that)
2) a shared module makes no sense
3) the configuration is trivial to recreate
Link E2_AGENT libraries directly into nr-softmodem/lte-softmodem instead
of L2/L2_NR/F1AP. Doing that ensures that simulators, e.g.,
nr_dlsim/nr_ulsim do still compile. It also simplifies the code.
Prior to this, compiling nr_ulsim with E2_AGENT, for instance, resulted
in the following errors, fixed in this commit:
FAILED: nr_ulsim
/usr/bin/ld: openair2/E2AP/RAN_FUNCTION/libe2_ran_func_du_cucp_cuup.a(ran_func_rc.c.o): in function `send_aper_ric_ind':
/home/oai/robert/cleanup-t-dependency-cmake/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc.c:643: (.text+0xee6): undefined reference to `async_event_agent_api'
/usr/bin/ld: /home/oai/robert/cleanup-t-dependency-cmake/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc.c:643:(.text+0x11ca): undefined reference to `async_event_agent_api'
/usr/bin/ld: /home/oai/robert/cleanup-t-dependency-cmake/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc.c:643:(.text+0x1485): undefined reference to `async_event_agent_api'
/usr/bin/ld: /home/oai/robert/cleanup-t-dependency-cmake/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc.c:643:(.text+0x159c): undefined reference to `async_event_agent_api'
/usr/bin/ld: /home/oai/robert/cleanup-t-dependency-cmake/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc.c:643:(.text+0x16b1): undefined reference to `async_event_agent_api'
[...]
warning: ‘genericPowerPerAntena’ defined but not used [-Wunused-function]
warning: ‘graph.text’ is used uninitialized [-Wuninitialized]
warning: ignoring return value of ‘read’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
Lower the RX gain used by the Amarisoft UE in CI tests to prevent DL signal
saturation. This resolves an issue with low DL throughput observed in CI.
RX/TX signal levels on the Amarisoft UE can be checked with "t spl" command
in lteue; MAX values should not approach 0.
Data and control multiplexing procedure is defined in 38.212 section 6.2.7.
Step 3 (CSI1 and CSI2 mapping) is not implemented, only HARQ-ACK.
PUSCH frequency hopping is not supported.
Use betaOffset and alpha scaling etc. to get rate matching information of UCI on PUSCH (e.g. max bit capacity of encoded UCI and encoded ULSCH)
according to TS 38.212 section 6.3.2.4 and 6.2.7.
38.212 section 5.3.3.1 and 5.3.3.2 describe how to encode 1-bit and 2-bit information.
This is needed when typically HARQ-ACK will be transmitted on PUSCH.
38.212 section 5.4.3 also describes how to do rate matching for channel coding of small block lengths.
- Replace error handling for impossible ID mismatches with DevAssert statements
- If ngap_get_ue_context() succeeds, returned context must have matching NGAP gNB UE IDs by definition
- This catches potential bugs in the lookup function immediately
- Affects: handover_required, handover_notify, handover_cancel, ul_ran_status_transfer
These checks were logically impossible since we looked up the context using
the same IDs we were then checking for mismatch.
- Fixed incorrect log messages that said 'PCI=%lu' when printing nr_cell_id
- Now prints both NR Cell ID and PCI when DU is found
- Provides better debugging information for handover requests
- Add _E1_EQ_CHECK_OPTIONAL_PTR checks for pdcp_config, sdap_config, UP_TL_information, and securityIndication
- Fix bug in eq_pdu_session_to_mod_item where a->UP_TL_information was compared with itself instead of b->UP_TL_information
- Fix eq_security_ind call to properly handle return value with early return pattern
- Improve consistency with existing macro usage patterns in the codebase
- Provide better error reporting for optional pointer field mismatches
Replace result &= pattern with consistent early return pattern:
- Fix mixing of logical (&&) and binary (&) operators
- Use consistent 'if (!eq_()) return false;' pattern throughout
- Fix bug in eq_bearer_context_mod_response where drbModA was compared with itself
- Remove unused 'bool result = true;' variables
- Always return true at the end of equality functions
This makes the code more consistent with the rest of the codebase
and provides better error reporting through the existing _E1_EQ_CHECK macros.
Integration `2025.w39`
* !3582 replace bad DCI by specific message for each case and add checks for bad...
* !3595 Implementing the option to have more than 1 RSRP in CSI report
* !3640 Code cleanup (SRS, config files and more)
* !3654 Extend t300 in multi_ue rfsim testcase
* !3650 NR UE improvements for scheduling ACK/NACK for MSG4
* !3652 In ReconfigurationWithSync, make sure epochTime_r17 present if there is a ntn_Config_r17
* !3653 NR UE: in nr_ue_scheduler.c set LCID_buffer_remain to 0 if RLC indicates not more bytes in buffer
* !3549 Switch to new (internal) registry
* !3513 Improvements to RRC PDU session and DRB handling logic
Closes#995 and #997
See merge request oai/openairinterface5g!3658
Improvements to RRC PDU session and DRB handling logic
This merge request introduces a major simplification and cleanup of the gNB RRC
PDU Sessions and DRBs handling logic. The core goals of this work are to:
- Replace fixed-size PDU Session, DRBs and QoS arrays with dynamic containers
- Simplify and modularize helper functions for session/DRB management
- Prepare for further refactoring of the PDU Session state machine
- Improve code safety and maintainability through better bounds checking
common/utils/threadPool/measurement_display.c:55:14 warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 3 has type ‘long long unsigned int’ [-Wformat=]
- Replace simple counter-based DRB ID assignment with actual DRB ID lookup
- Add nested loop to iterate through DRBs for each PDU session to be release
- Improve logic flow with early continue for non-matching PDU sessions
This ensures DRB release list contains correct DRB IDs that correspond to actual DRB entities
* There is no IE corresponding to PDU sessions failed to release
in the PDU SESSION RESOURCE RELEASE RESPONSE message. This was removed
and the corresponding code was refactored and cleaned up.
* In the Release Command handler, only established PDU Session are set to be
released. The Response message is filled accordingly.
Motivation:
The previous architecture had several issues:
- Duplicate DRB generation logic in generateDRB() and generateDRB_ASN1()
- Embedded SDAP/PDCP configs in drb_t created tight coupling
- No clear separation between RRC internal state and ASN.1 encoding
- Maintenance burden due to duplicated configuration logic
New Architecture:
- drb_t now only stores DRB-specific data (ID, PDU session ID, PDCP config)
- SDAP configuration moved to PDU session level (following PDCP design pattern)
- ASN.1 encoding helpers (nr_rrc_build_*_config_ie()) handle conversion
- Single source of truth for DRB creation in RRC via nr_rrc_add_drb()
Key changes:
- Store nr_sdap_configuration_t per PDU session
- Simplified drb_t structure: removed embedded SDAP/PDCP configs, added pdusession_id
- New helper: nr_rrc_build_sdap_config_ie()
- Updated createDRBlist() to use new helper functions and proper DRB ID lookup
- Refactored trigger_bearer_setup() to use nr_rrc_add_drb() and fill_e1_drb_to_setup()
- Removed generateDRB() and generateDRB_ASN1() functions
- Updated set_bearer_context_pdcp_config() to return config by value
- Added SDAP configuration header file for type definitions
This eliminates code duplication, improves maintainability, and creates
a cleaner separation between RRC state management and ASN.1 encoding.
- Move QoS-related enums and structures from ngap_messages_types.h to 5g_platform_types.h
- Replace ngap_* QoS types with generic qos_* types for better reusability
- Update field names from allocation_retention_priority to arp for consistency
- Update all references across RRC and NGAP modules to use new type names
- Remove duplicate QoS type definitions from NGAP-specific header
This improves code organization by centralizing QoS parameter definitions
in a common platform types header and eliminates NGAP-specific naming
in favor of more generic, reusable type definitions.
The maximum number of QoS flows is 64.
- Replace QOSFLOW_MAX_VALUE with MAX_QOS_FLOWS constant
- Move MAX_QOS_FLOWS definition to common/platform_constants.h
- Remove duplicate QOSFLOW_MAX_VALUE definition from ngap_messages_types.h
This improves maintainability by centralizing the QoS flow limit constant
and eliminates duplicate definitions across different header files.
- Limit scope of get_default_rbconfig function: from asn1_msg.c/.h to rrc_gNB_nsa.c where it's used
- Create new rrc_gNB_asn1.c/h files for ASN.1 utility functions: they can be used in other RRC files
- Add nr_rrc_build_pdcp_config_ie function for building PDCP configuration IEs
- Update get_default_rbconfig to use the new PDCP config builder
- Add rrc_gNB_asn1.c to CMakeLists.txt build configuration
The previous DRB management relied on a fixed-size array (established_drbs[MAX_DRBS_PER_UE])
and manual status tracking using DRB_ACTIVE/INACTIVE flags. This approach was inefficient,
and made assumptions about DRB ID allocation that do not generalize well
to dynamic procedures like bearer modification or removal.
* Replace fixed-size array established_drbs[] with dynamic
seq_arr_t *drbs in gNB_RRC_UE_t
* Refactor get_drb() and added nr_rrc_add_drb() with clean abstractions
using find and seq_arr lib
* Updated all DRB-related logic (e.g., generateDRB,
F1AP/E1AP tunnel config, reestablishment, mobility) to use seq_arr.
* Removed status field and DRB_ACTIVE/INACTIVE logic: list presence implies active
* DRB ID allocation now tracked via seq_arr size : simplifies DRB management and
avoids DRB ID–indexed assumptions: code assumed DRB IDs mapped directly to
array indices: established_drbs[drb_id - 1]. This could break when:
DRB IDs are not sequential, DRBs are removed and re-added, or there are gaps in IDs
The RRC PDU Session struct is converted from a fixed-size array
to a dynamically sized seq_arr. This improves flexibility and
simplifies session management by eliminating arbitrary size limits
and enabling dynamic addition/removal of PDU sessions.
Helper functions and loops have been adapted to use the seq_arr API.
This change is a step toward more robust and maintainable handling
of PDU sessions in the gNB RRC layer.
The "status" state machine remains untouched in this commit and
is refactored in a later commit.
Also:
* add macro to push to seq_arr and return the new element
* move initialization of xid (RRC PDU Session struct) to
find_pduSession (temporary, will be finalized in a later
commit) since with the new seq_arr design the initialization
is no longer possible in the UE context generation (also
does not belong to it, initialize when adding a new PDU Session)
The function was printing a "not found" error message even in the case
the return value was set to "true". Return directly true/false.
This is relevant in PDU Session Release procedures.
- Process all PDU sessions in handover request instead of only the first one
- Add DevAssert for bounds checking on nb_of_pdusessions
- Fix logic error where multiple PDU sessions were ignored in handover scenarios
Previously, the RRC layer was incorrectly allocating stack memory for the ho_required_transfer field and passing it to NGAP, however it was not used. The IE is mandatory but contains only 1 optional IE, therefore is encoded in the NG message with empty content.
Changes:
- Remove unnecessary ho_required_transfer field from pdusession_resource_t definition, the IE is encoded anyway with empty content. If Direct Forwarding Path Availability is needed at any stage in the future it can be added to pdusession_resource_t and filled in RRC.
- Add clarifying comment about empty HandoverRequiredTransfer structure
NR UE: in nr_ue_scheduler.c set LCID_buffer_remain to 0 if RLC indicates not
more bytes in buffer
If the RLC indicates that there is no more data in the buffer, also the
scheduler's LCID_buffer_remain should be set to 0. Else the UE sends BSR
indicating it has data to be transmitted. The gNB would then unnecessarily
schedule UL for this UE, which would not be used, as there is no actual data
to be transmitted.
Extend t300 in multi_ue rfsim testcase
Extend t300 to 1000 to increase the time the gNB has to handle MSG3. Hopefully
this prevents the UEs from timing out after MSG3. Add UE id to timer timeout
LOGs so the UE behavior can be traced through the stack.
Code cleanup (SRS, config files and more)
- Remove deprecated elements from some configuration files (also closes#997)
- Improve SRS code with a better separation between common code and gNB/UE code
- Other minor compilation improvements
Implementing the option to have more than 1 RSRP in CSI report
In collaboration with NI/Emerson.
The standard allows up to 4 RSRP measurements in CSI report (1 full and the other
differential). In current OAI, we just configure 1 RSRP report for the strongest
SSB. This MR allows to configure at gNB more than 1 RSRP report (depending on
config file, number of SSBs and UE capabilities) and makes changes at the UE to
send this report.
replace bad DCI by specific message for each case and add checks for bad...
Replace bad DCI by specific message for each case and add checks for bad
pointers, or sanitize detected warnings. Then fix several issues in DCI
decoding. With this MR, LTE UE has less bad DCI, and each bad DCI has a
reason better diagnosis.
If the RLC indicates that there is no more data in the buffer, also the scheduler's
LCID_buffer_remain should be set to 0. Else the UE sends BSR indicating it has data
to be transmitted. The gNB would then unnecessarily schedule UL for this UE, which
would not be used, as there is no actual data to be transmitted.
Correctly handle unpacking of the first RSRP report and its resource ID before processing additional reports.
Use the initial RSRP value as the reference for differential RSRP calculations in subsequent reports.
N2 handover
This MR introduces full support for N2 handover, covering handover
decision, preparation, execution, and notification between source and
target NG-RAN nodes.
Key features:
1. Handover Decision & Preparation:
- Implement N2 handover decision based on UE measurement reports.
- Generate the Handover Preparation Information message, including
RRCReconfiguration.
- Send Handover Required message from the source NG-RAN to the AMF.
2. Handover Execution:
- Decode and handle the Handover Request on the target NG-RAN.
- Process the Handover Command on the source gNB, triggering
RRCReconfiguration.
- Initiate Handover Notify after successful completion.
3 NGAP & RRC Enhancements:
- Implement NGAP encoding/decoding functions for Handover Required,
Handover Request, Handover Command, Handover Failure, and Handover
Notify (3GPP TS 38.413).
- Adds NG-RAN Status Transfer support (UL/DL) for PDCP COUNT
preservation during mobility:
- support for NGAP Uplink and Downlink RAN Status Transfer messages
(TS 38.413 §9.2.3.13-14) to enable proper PDCP COUNT value
transfer during handover or recovery: NGAP encoding/decoding for
RAN Status Transfer, PDCP helpers to extract and apply COUNT (HFN
+ SN) per DRB. This aligns with TS 38.300 §9.2.3.2.1 and TS 23.502
§4.9.1.3.3, ensuring PDCP status preservation in AM.
4. Testing:
- Introduce a Telnet command to manually trigger N2 handover using UE
ID and neighbor PCI.
- Add configuration file for testing N2 handover with a target gNB.
CI: build images on Jetson (armv8)
Add a new build pipeline for NVIDIA Jetson (armv8). Images have tag
prefix armv8_ to distinguish from gracehopper-built images prefixed arm_
(should have maybe been better with armv9_?)
This commit completes the NGAP Mobility Management procedure for N2 handover.
Upon failure on source gNB the Handover Cancel message is sent to the AMF which
in return responds with an ack.
Upon reception of NG RAN Status at the target CU-CP, send PDCP Status
via E1 Bearer Context Modification to the target CU-UP and update PDCP Count
upon reception of the message.
For the sake of simplicity, re-used and extended legacy e1_send_bearer_updates.
Further refactoring is not addressed in this commit.
Once fetched the PDCP Status from the PDCP entity over E1, the CU-CP triggers
the NG RAN Status Transfer procedure to transfer the PDCP Status to the target
CU.
This commit is also introducing the RRC callback.
* Check presence of PDCP Status Requested in Bearer Context Modification Request
* Fetch PDCP Status from PDCP entity and fill in the Bearer Context Modification Response
The E1 Bearer Context Modification Request shall send a PDCP Status Request IE
during handover, e.g. the HO context is set to source, and it is not target, i.e.
only in N2 not in F1.
The current function "e1_send_bearer_updates" used to fill the E1 Request has been
refactored only for the sake of this commit and to avoid duplicated and redundant code.
The function itself deeper analysis and eventually a refactoring that will not be addressed
in this commit.
* Introduced nr_pdcp_count_update() to apply COUNT values to the PDCP entity:
- Computes tx_next, rx_next, and rx_deliv from HFN+SN
- Handles both 12-bit and 18-bit SN modes with dynamic bitmask
* Introduced nr_pdcp_get_drb_count_values() to extract PDCP COUNT values from entity:
- Used for building UL RAN Status Transfer on source CU side
According to 4.9.1.3.3 of 3GPP TS 23.502:
> 2a. - 2c. The S-RAN sends the Uplink RAN Status Transfer message to the S-AMF,
> as specified in TS 36.300 [46] and TS 38.300 [9]. The S-RAN may omit sending
> this message if none of the radio bearers of the UE shall be treated with PDCP status preservation.
TS 38.300 says:
> For DRBs not configured with DAPS, the source gNB sends the SN STATUS TRANSFER message to the target
> gNB to convey the uplink PDCP SN receiver status and the downlink PDCP SN transmitter status of DRBs for
> which PDCP status preservation applies (i.e. for RLC AM). The uplink PDCP SN receiver status includes at
> least the PDCP SN of the first missing UL PDCP SDU and may include a bit map of the receive status of the out
> of sequence UL PDCP SDUs that the UE needs to retransmit in the target cell, if any. The downlink PDCP SN
> transmitter status indicates the next PDCP SN that the target gNB shall assign to new PDCP SDUs, not having a
> PDCP SN yet.
i.e., for DRBs for which PDCP status preservation applies (i.e. for RLC AM), which is is our case.
This commit introduces full support for NG-RAN Status Transfer message handling
(TS 38.413 §9.2.3.13-14) in CU. It enables correct state transfer of PDCP COUNT
values (SN + HFN) during mobility or recovery scenarios.
Summary of changes - NGAP:
* Added encoding/decoding support for UL/DL RAN Status Transfer message
* Defined structures for: ngap_drb_count_value_t, ngap_drb_status_t,
ngap_ran_status_container_t, ngap_ran_status_transfer_t
The pipeline is using the already existing conf files
for the source/target gNB CUs/DUs.
For the sake of simplicity, neighbour-config.conf has
been rewritten and simplified in this commit, then
adopted in this pipeline. The file was not used before.
* the command gets in input the neighbour PCI and the UE ID
* the telnet ci function to retrieve the UE context was extended in the process
* add function to trigger handover on the same gNB for testing purposes
Co-authored-by: batuhan duyuler <batuhan.duyuler@firecell.io>
* trigger upon reception of MasterKeyUpdate
* derive NH, store NH NCC and valid NH key in RRC
* masterKeyUpdate: derive enc/int keys after master key update
and set PDCP security for SRB1
* call nr_rrc_process_reconfiguration_v1530 before nr_rrc_ue_process_RadioBearerConfig
and move dedicatedNAS_MessageList processing at the end of the flow. The sequence
shall be (1) keys/security update (2) radioBearerConfig processing, with PDCP entity
creation, PDCP reestablishment, SDAP entity creation (3) NAS PDUs processing, which
triggers PDU Session Establishment Accept, which sets up the TUN interface.
SDAP entity is a pre-requisite, therefore the radioBearerConfig has to be processed
(in nr_rrc_ue_process_RadioBearerConfig, add_drb) early enough, or it may cause a
race condition in SDAP.
* add trigger function to (1) add the callbacks and (2) initiate
handover on the target NG-RAN
* add handover failure callback on target NG-RAN: the Handover
Failure is a procedure that belongs to the target NG-RAN and
it is different from the Handover Cancel procedure
Co-authored-by: batuhan duyuler <batuhan.duyuler@firecell.io>
This commit introduces the NG Mobility Management Procedure known as
Handover Notification. The outbound message is sent by the target NG-RAN
and is known as Handover Notify. The procedure is used to indicate to
the AMF that the UE has arrived to the target cell and the NG-based
handover has been successfully completed
* after RRCReconfiguration complete, in the N2 callback for HO success
* add NGAP encoder for the message
* RRC callback to trigger Handover Notify message
Co-authored-by: batuhan duyuler <batuhan.duyuler@firecell.io>
* add NG Handover Command message decoder
* process in RRC: encode RRCReconfiguration message
from the received HandoverCommandMessage
* trigger RRCReconfiguration for handover
Co-authored-by: batuhan duyuler <batuhan.duyuler@firecell.io>
* generate Handover Command for the source NG-RAN
to be added to the target to source transparent
container of the Handover Acknowledge message
* add Handover Acknowledge callback for N2
* send NG Handover Acknowledge to AMF
Co-authored-by: batuhan duyuler <batuhan.duyuler@firecell.io>
This commit completes the NG Mobility Management Procedure known as
Handover Resource Allocation. The outbound message is sent by the
target NG-RAN and is known as Handover Request Acknowledge.
Major changes:
* add RRC callback to trigger the generation of NG Handover
Request Acknowledge on the target NG-RAN
* add NG Handover Request Acknowledge encoder
Co-authored-by: batuhan duyuler <batuhan.duyuler@firecell.io>
This commit introduces the NG Mobility Management Procedure known as
Handover Resource Allocation. The inbound message is sent by the AMF
and is known as Handover Request.
Major changes:
(0) Add Handover Resource Allocation initiating message decoding
* add case for NGAP initiating message and unsuccessful message decoding
(1) handle Handover Request on the target NG-RAN
(2) decode NG Handover Request message
(3) process payload, e.g. create UE context,
store IDs, set UP security and trigger bearer setup
Co-authored-by: batuhan duyuler <batuhan.duyuler@firecell.io>
This message is sent from the Target NG-RAN to the AMF.
The commit introduces:
* NGAP encoding function
* N2 callback for the target gNB
* handle the failure in RRC, inform NGAP
* send NGAP message to AMF via SCTP
Note: UE context in NGAP is fetched from the amf_ue_ngap_id
Co-authored-by: batuhan duyuler <batuhan.duyuler@firecell.io>
(1) add N2 ho decision based on measurements
(2) add trigger for N2 HO on source CU
(3) generate NG Handover Preparation Information message,
including RRCReconfiguration, to be passed to the
NG Handover Required message
(4) call RRC callback for Handover Required message
Co-authored-by: batuhan duyuler <batuhan.duyuler@firecell.io>
This commit introduces the NG Mobility Management Procedure known as
Handover Preparation. The outbound message is sent by the source NG-RAN
and is known as Handover Required.
* introduce NGAP library for Mobility Management
* introduce NGAP IEs encoder functions for Handover Required and relevant common IEs
* handle RRC trigger in NGAP and Send NGAP Handover Required to the AMF
Co-authored-by: batuhan duyuler <batuhan.duyuler@firecell.io>
During the N2 HO review has been found that the HO context
was not allocated at trigger time but later in the flow. This
might lead to issues in some scenarios (e.g. in N2 HO)
and it was fixed in this commit.
Introduce a new timer for the use case where a UE should not be
scheduled anymore after a certain time. This is the case, for instance,
during handover, where the "source DU" forwards the RRCReconfiguration
and should stop scheduling this UE after some time.
Originally, transm_interrupt was introduced in 5c6d90aaff ("Use
NR_timer_t for UE transmission interrupt, e.g., RRC processing") to stop
scheduling a UE.
Commit 004403c84d ("Implement F1 UE Ctxt Modif Transmission Action
Indicator") reused this timer in an attempt to save code with an
"interrupt follow action".
In commit 89ebbb4192 ("Do not trigger ul failure in measgap scheduling
and standardize the verification if MAC is active in other scheduling
functions"), the transm_interrupt timer is used to not schedule a UE
through function nr_mac_ue_is_active(). This led to the UE not being
forwarded the RRCReconfiguration, effectively breaking handover, as the
message never reaches the UE. By using a new timer, the intended
functionality is restored.
Fixes: 89ebbb4192 ("Do not trigger ul failure in measgap scheduling
and standardize the verification if MAC is active in other
scheduling functions")
Remove this flag, as it is not used as of this commit, and introduces
confusion (see next commit: we reused the trans_interrupt timer for
the transmission action indicator stop action, where the UE should stay
active, while it is *not* when transm_interrupt is active).
For clarity, rename to native_armv9 for clarity. The check inside Python
checked for native_arm, and if we introduce native_armv8 (for jetson),
it would also match that.
Add nr-cuup to run_locally.sh
E1 deploy wasn't enable in the run_locally.sh script to run the CI on a local
machine. This MR is adding it. It was validated locally.
Fix UE DCI monitoring after RRC setup
After the UE is configured with pdcch-Config, it continues to monitor
fallback search spaces in pdcch-ConfigCommon for DCI with C-RNTI.
The rational is that after sending RRC Setup the network won't know if
the UE has received and successfully applied it. Hence the network would
still continue to use the fallback DCI till it receives RRC setup
complete.
Closes#954
Fix memory allocation issue in KPM RAN function sd parameter handling
This fixes a segmentation fault in the gNB when a KPM xApp sends the sd
parameter in the subscription message.
The segmentation fault seems to occur because *sd is uninitialized when
malloc(**sd) is called. This causes a double dereference of an uninitialized
pointer - **sd reads a random memory value which becomes the size parameter
for malloc(), leading to unpredictable memory allocation and segfaults.
This fix allocates the size using malloc(sizeof(uint32_t)) instead of
dereferencing the uninitialized pointer.
After the UE is configured with pdcch-Config, it continues to monitor
fallback search spaces in pdcch-ConfigCommon for DCI with C-RNTI.
The rational is that after sending RRC Setup the network won't know if
the UE has received and successfully applied it. Hence the network would
still continue to use the fallback DCI till it receives RRC setup
complete.
Fix an issue in which the unpacking is erroneously deemed unsuccessful even though it succeed in pulling all the bytes, this was due to not properly handling the return value of pull16 which is either 0 or 2, not 0 or 1.
Check the results of push and pull operation with correct boolean operator.
During the review of the N2 HO MR it has been found that the wrong type
plmn_identity_t (S1AP) was used in RRC. Now updated to the platform type plmn_id_t.
The malloced struct is initialized to garbage and when
the IE is absent, the output "PDCP reestablishment"
member (allocated in the stack) is set to a random value.
Integration: `2025.w37`
* !3514 NR UE: add support for PDSCH rate matching with NZP CSI-RS
* !3630 feat(ldpc_aal): Do not try EAL init if FHI 7.2 is enabled
* !3634 reset MSG3 C-RNTI flag in case of failure
* !3566 fix 600 cppcheck notifications
* !3633 Fix PLMN print in select_amf
* !3631 Revert "Removed TRP-scheme byte from UL BF PDU to Interop with Aerial 25-1 (FAPI 10.02)"
* !3622 Populate sampled_ue_antennas
* !3601 gNB: adaptive DL/UL MCS based on reported SSB-SINR and measured PUSCH SNR
* !3637 fix bug in computing number of LCG IDs with data at UE
* !3635 Fixes and updates for UL scheduling, notably DSUUU
* !3607 Reworking BWP configuration
* !3531 Refactor measConfig
* !3612 CI: Creation of F1 Handover pipeline
* !3611 CI: Generalize PhySim tests, run PhySims on Gracehopper
Closes#985 and #975
See merge request oai/openairinterface5g!3636
CI: Generalize PhySim tests, run PhySims on Gracehopper
This changeset generalizes/harmonizes the CI infrastructure for physim
testing, and adds a new pipeline for physim tests on Gracehopper
machines.
Specifically:
- Refactor the existing CI code for running and analyzing physical
simulators. The existing code assumed those tests are deployed using
OpenShift. Instead, OpenShift/Helm-specificities (e.g., running a
"release") have been removed, and instead of hardcoding the deployment
of the physical simulators using a script for Helm, the function takes
any script that can deploy using Helm/docker/from source. The overall
appearance is the same.
- Add a new pipeline RAN-PhySim-GraceHopper-5G that executes physical
simulators on gracehopper. Reporting is done in the same way as for
existing physical simulators (e.g., like in the RAN-PhySim-Cluster-5G
pipeline), but deployed in docker instead of helm.
-> some tests don't work reliably on ARM yet and are skipped
- the RAN-gNB-N300-Timing-Phytest-LDPC pipeline has been reworked to use
the same code for testing T2 offload, with ctest, and the same
reporting.
- the CUDA LDPC test XML has been removed, as these tests don't work
reliably.
- add a new macro add_timed_physim_test() that allows to define
thresholds to be checked, so that ctest will check for them. see the
documentation for more information
CI: Creation of F1 Handover pipeline
In this MR we are modifying/adding all the required files (.xml, .conf,
.yml) in order to create a pipeline on Jenkins that allows us to test
OTA F1 handover.
Remove the runtime, which is not interesting, and add instead
- test name and if the test failed
- the threshold checks, if any, and
- possible additional information about test failures.
Prior to this change, each test would have, as label, it's description.
This leads to many labels, which are normally reserved for grouping
tests. Move the description into a custom property instead.
Since we rely on the JSON output for the generation of HTML reports, we
need to also extract the description from the generated JSON. However,
custom properties are only logged starting from cmake 3.30. For
back-wards compatibility, write an additional, separate environment
variable TEST_DESCRIPTION from which the description can be read as a
fallback.
For the add_timed_physim_test(), this has been already done in a parent
commit.
The unit tests have been imported with this command:
xmlstarlet sel -t
-m '//testCaseList/testCase[class="Run_Physim"]' \
-v "concat('add_timed_physim_test(physim.5g-offload.',physim_test,'.testX.Y \"',desc,'\" ',physim_test,' ',physim_run_args,')')" \
-n t2_offload_enc_nr_dlsim.xml t2_offload_dec_nr_ulsim.xml >> ../../openair1/SIMULATION/tests/CMakeLists.txt
The next commit will further cleanup this output. I commit it like this
for verification purposes.
Add two new macros that allow to register physim tests for ctest,
including timing thresholds that should be fulfilled.
First, add_timed_physim_test() registers a new test using a helper
script RunTimedTest.cmake. This is because after test execution, we need
to analyze logs, and the recommended way to do multiple steps in one
test is via a helper cmake script:
https://cmake.org/pipermail/cmake-developers/2016-February/027816.html
Second, check_physim_threshold() adds new thresholds. It takes a text to
be parsed, and a condition (e.g., "< 20") to check for the number
following the threshold (which is assumed to be present right after the
threshold). It uses a test property to count the total number of checks
(limiting them to 10), and sets environment variables for the script. I
initially planned to use a test property for checks, but those are only
valid in the same directory, and RunTimedTest.cmake seems to be assumed
by cmake to be "elsewhere", hence I needed to resort to environment
variables.
RunTimedTest.cmake is called through cmake with the test parameters and
checks. It re-constructs a list of checks [1], runs the test, and pipes
the log into a separate script that is passed all checks (see below).
Afterwards, it verifies that both the test and script passed.
A script analyze-timing.sh builds an awk script from the checks passed.
The script analyzes each line of the test output for the threshold, and
compares against the threshold. analyze-timing.sh returns success if all
checks passed.
[1] I did not manage to pass a "list" of checks in a single environment
variable through the check_physim_threshold(), which would be simpler.
Change signature of the macro to take the full test name, a separate
description (previously called a label?), and the executable and test
invocation. The overall signature becomes easier.
The rational for the full test name is that a later commit will
introduce the possibility to define physim tests that are checked for
specific times, in which case we need to reuse the test name. Thus,
using the full name from the beginning leads to more clarity, even
though they are a bit longer.
Add an additional safety check that the given simulator is actually a
target defined within the project (in other words, it actually exists).
Update the documentation correspondingly.
Most (but not all) physical simulators are defined under
openair1/SIMULATION/. Defining physical simulators below there seems to
be the more "obvious" directory anyway, as the physical simulators are
openair1/SIMULATION/tests
Phy(L1) Sim tests => PhySim (tests)
Refactor measConfig
- Refactor and minor improvements in get_MeasConfig function;
- Add support for band in neighbourConfiguration (It is currently
possible to handover cells with different frequencies, as long as they
are in the same band, but this MR allows the handover to also be done
between cells in different bands).
Reworking BWP configuration
This MR reworks the configuration via fail of additional BWPs. Moreover, it
allows for a single BWP to be configured for a given UE at a given time (BWP
switch possible only via reconfiguration). It also reworks PTRS configuration
for consistency with the BWP one.
Fixes and updates for UL scheduling, notably DSUUU
Fix a number of problems that stem from !3521, notably regarding Msg3
scheduling, retransmissions in "UL-heavy" TDD scenarios, and BSR
handling. Modify a CI test to run a UL-heavy TDD scenario, and add
documentation for UL-heavy TDD scenarios.
The parameter is either set to 10 (the default, so not necessary), or to
0 forcing the gNB to schedule the UE all the time, which is only
necessary in specific scenario, and here simply wrong.
In high throughput UL scenarios, at least with our configuration, the UE
only sends Short BSR. The maximum is 300000 bytes, which is completely
"scheduled away" after a couple of UL grants. Increase the periodic BSR
to 5ms to get more BSR, which results in higher UL throughput.
On BSR reception, reset sched_ul_bytes. This change means that we assume
that no data is "in flight" for this UE at time of BSR reception, or,
put differently, that we overestimate the buffer size at UE (in the
worst case).
To illustrate this, consider the following traces before/after this
change.
Before this change: Upon BSR reception, the estimated BSR of the UE is
reset, but the gNB still accounts for data "in flight". It is visible
that the calculated buffer size (estimated - scheduled) quickly goes to
zero, and we don't use all resources, despite the buffer still being
full. The maximum application throughput in this run was ~220Mbps.
[NR_MAC] SHORT BSR at 773.19, est buf 300000
[NR_MAC] ULSCH/PUSCH: 774. 6 RNTI af8e UL sched 774. 9 PRB start 0:162 TDA 2 TBS 32797 est 300000 sched 152704 est BSR 147296 TPC 1
[NR_MAC] ULSCH/PUSCH: 774. 6 RNTI af8e UL sched 774.11 PRB start 0:162 TDA 4 TBS 7172 est 300000 sched 159876 est BSR 140124 TPC 1
[NR_MAC] ULSCH/PUSCH: 774.10 RNTI af8e UL sched 774.12 PRB start 0:162 TDA 0 TBS 32797 est 292845 sched 185501 est BSR 107344 TPC 1
[NR_MAC] ULSCH/PUSCH: 774.10 RNTI af8e UL sched 774.13 PRB start 0:162 TDA 2 TBS 32797 est 292845 sched 218298 est BSR 74547 TPC 1
[NR_MAC] ULSCH/PUSCH: 774.11 RNTI af8e UL sched 774.14 PRB start 0:162 TDA 2 TBS 32797 est 260117 sched 218298 est BSR 41819 TPC 1
[NR_MAC] ULSCH/PUSCH: 774.11 RNTI af8e UL sched 774.16 PRB start 0:162 TDA 4 TBS 7172 est 260117 sched 225470 est BSR 34647 TPC 1
[NR_MAC] ULSCH/PUSCH: 774.15 RNTI af8e UL sched 774.17 PRB start 0: 35 TDA 0 TBS 7172 est 220236 sched 185501 est BSR 34735 TPC 1
[NR_MAC] ULSCH/PUSCH: 774.15 RNTI af8e UL sched 774.18 PRB start 0:162 TDA 2 TBS 32797 est 220236 sched 218298 est BSR 1938 TPC 1
[NR_MAC] ULSCH/PUSCH: 774.16 RNTI af8e UL sched 774.19 PRB start 0: 10 TDA 2 TBS 2017 est 187508 sched 187518 est BSR -10 TPC 1
[NR_MAC] SHORT BSR at 774. 9, est buf 300000
[NR_MAC] ULSCH/PUSCH: 775. 0 RNTI af8e UL sched 775. 2 PRB start 0:162 TDA 0 TBS 32797 est 260117 sched 147549 est BSR 112568 TPC 1
[NR_MAC] ULSCH/PUSCH: 775. 0 RNTI af8e UL sched 775. 3 PRB start 0:162 TDA 2 TBS 32797 est 260117 sched 180346 est BSR 79771 TPC 1
[NR_MAC] ULSCH/PUSCH: 775. 1 RNTI af8e UL sched 775. 4 PRB start 0:162 TDA 2 TBS 32797 est 227389 sched 180346 est BSR 47043 TPC 1
[NR_MAC] ULSCH/PUSCH: 775. 1 RNTI af8e UL sched 775. 6 PRB start 0:162 TDA 4 TBS 7172 est 227389 sched 187518 est BSR 39871 TPC 1
[NR_MAC] ULSCH/PUSCH: 775. 5 RNTI af8e UL sched 775. 7 PRB start 0:162 TDA 0 TBS 32797 est 180353 sched 173174 est BSR 7179 TPC 1
[NR_MAC] ULSCH/PUSCH: 775. 5 RNTI af8e UL sched 775. 8 PRB start 0: 36 TDA 2 TBS 7298 est 180353 sched 180472 est BSR -119 TPC 1
After this change: The gNB resets the number of bytes "in flight"
(sched). Thus, the calculated buffer is larger, and does not "run out"
before a new BSR arrives (which still indicates the maximum). The UE is
thus allocated all resources, but we might overestimate some resources.
The maximum application throughput in this run was ~300Mbps, limited by
MCS and not by estimated buffer size as in the previous case.
[NR_MAC] SHORT BSR at 43. 3, est buf 300000
[NR_MAC] ULSCH/PUSCH: 43.15 RNTI d3ea UL sched 43.17 PRB start 0:162 TDA 0 TBS 36897 est 263180 sched 36897 est BSR 226283 TPC 1
[NR_MAC] ULSCH/PUSCH: 43.15 RNTI d3ea UL sched 43.18 PRB start 0:162 TDA 2 TBS 36897 est 263180 sched 73794 est BSR 189386 TPC 1
[NR_MAC] ULSCH/PUSCH: 43.16 RNTI d3ea UL sched 43.19 PRB start 12:150 TDA 2 TBS 33822 est 263180 sched 107616 est BSR 155564 TPC 1
[NR_MAC] ULSCH/PUSCH: 43.16 RNTI d3ea UL sched 44. 1 PRB start 0:162 TDA 4 TBS 7941 est 263180 sched 115557 est BSR 147623 TPC 1
[NR_MAC] ULSCH/PUSCH: 44. 1 RNTI d3ea UL sched 44. 3 PRB start 0:162 TDA 0 TBS 36897 est 173698 sched 25881 est BSR 147817 TPC 1
[NR_MAC] ULSCH/PUSCH: 44. 1 RNTI d3ea UL sched 44. 4 PRB start 0:162 TDA 2 TBS 36897 est 173698 sched 62778 est BSR 110920 TPC 1
[NR_MAC] ULSCH/PUSCH: 44. 1 RNTI d3ea UL sched 44. 6 PRB start 0:162 TDA 4 TBS 7941 est 173698 sched 70719 est BSR 102979 TPC 1
[NR_MAC] SHORT BSR at 43.13, est buf 300000
[NR_MAC] ULSCH/PUSCH: 44. 5 RNTI d3ea UL sched 44. 7 PRB start 0:162 TDA 0 TBS 36897 est 292079 sched 36897 est BSR 255182 TPC 1
[NR_MAC] ULSCH/PUSCH: 44. 5 RNTI d3ea UL sched 44. 8 PRB start 0:162 TDA 2 TBS 36897 est 292079 sched 73794 est BSR 218285 TPC 1
[NR_MAC] ULSCH/PUSCH: 44. 6 RNTI d3ea UL sched 44. 9 PRB start 0:162 TDA 2 TBS 36897 est 292079 sched 110691 est BSR 181388 TPC 1
[NR_MAC] ULSCH/PUSCH: 44. 6 RNTI d3ea UL sched 44.11 PRB start 0:162 TDA 4 TBS 7941 est 292079 sched 118632 est BSR 173447 TPC 1
[NR_MAC] ULSCH/PUSCH: 44.10 RNTI d3ea UL sched 44.12 PRB start 0:162 TDA 0 TBS 36897 est 213587 sched 39972 est BSR 173615 TPC 1
[NR_MAC] ULSCH/PUSCH: 44.10 RNTI d3ea UL sched 44.13 PRB start 0:162 TDA 2 TBS 36897 est 213587 sched 76869 est BSR 136718 TPC 1
gNB: adaptive DL/UL MCS based on reported SSB-SINR and measured PUSCH SNR
Currently this is used esp. if the number of rounds is limited to 1
(e.g. disable_harq).
Revert "Removed TRP-scheme byte from UL BF PDU to Interop with Aerial 25-1 (FAPI 10.02)"
This commit broke compatibility with Aerial when compiled with
-DSCF_FAPI_10_04_SRS=ON. It was decided that this should become the
default.
Modify documentation, and use a dedicated image name to make it clear in
the CI that it has SRS.
A future commit will enable to deploy physical simulators via docker.
Hence:
- Move the script to run out of deploy_oc_physim(), to make it more
generic (later commits will introduce other scripts)
- pass the working directory (the function will be moved into
cls_oaicitest, as it fits neither cls_containerize nor cls_cluster
when deploying the tests from source)
- not using ci-scripts: don't hardcode a specific path, just use the
working directory
- avoid helm-specific pods summary, and put it into the general "physim
logs"
- remove helm-specific "release", and use a generic name for results
- always log pod logs and status to debug, even if deployment was not
successful or tests did not finish.
Instead of making the function a class member, make it an instance
member because (1) it is more aligned with other functions, notably,
run(), and (2) especially for RemoteCmd() it can be faster, as
successive exec_script() calls do not require a new SSH connection.
This commit broke compatibility with Aerial when compiled with -DSCF_FAPI_10_04_SRS=ON. It was decided that this should become the default.
This reverts commit 8beb382277.
Instead of only saving this information in the first transmission, also
store it on each retransmission. This should ensure that if some
information changes, we always relate to the last transmission. For
instance, power control information might have changed, and should be
considered in subsequent rounds, if necessary. It also simplifies code.
Fixes: 6294ce715e ("Reorder pf_ul to process retransmission")
In at least the case of mu=1, min_rxtxtime=2 and DDDSU with no UL
symbols (for ULSCH) in the mixed slot, the current state of code does
not allow a UE to attach. This is because at mu=1, Msg3 is k2+delta,
where k2=min_rxtxtime and delta(mu)=3.
Prior, this special case was handled because we had a dedicated Msg3
TDA, which in most cases is not necessary (because the mixed slot
allocates the DCI, and the following mixed slot has the UL grant). Add
code that tries to ensure that we only add the Msg3 TDA in cases when we
need it.
Fixes: 961a646dc7 ("Remove dedicated Msg3 TDA")
reset MSG3 C-RNTI flag in case of failure
If MSG3 with C-RNTI fails, the UE should come back with a
re-establishment (after a given number of RA failures in general). In
that case, the OAI UE wouldn't reset the MSG3 with C-RNTI flag leading
to re-establishment failure.
feat(ldpc_aal): Do not try EAL init if FHI 7.2 is enabled
When FHI 7.2 is enabled, the EAL initialization is done by the FHI and
the attempt to init EAL by ldpc_aal will fail. In that case, it is not
necessary neither to provide a DPDK core list for BBDEV.
This MR offers to skip EAL init in ldpc_aal when FHI 7.2 is enabled in
order to avoid error messages in the log and to allow dropping the
useless DPDK cores argument in that case.
Also add some fixes to the LDPC offload documentation.
NR UE: add support for PDSCH rate matching with NZP CSI-RS
Currently only ZP CSI-RS is considered in function
configure_ratematching_csi, add support for NZP CSI-RS.
Closes#975
If the DCI in PDCCH is not correctly received, no PDSCH would be decoded but counted as no error.
Also if the DCI was not correctly received, a TBS of 0 would be used in some computations and memory allocations.
Fix these not counting if there is no PDSCH decoding, and by using the known TBS instead of the one received from the DCI.
Previously, the TDA reuse condition was wrong: for multiple TDAs with
different k2, the symbol allocation might be the same, in which the
previous logic was using the wrong TDA. Fix the condition, and insert an
assert to ensure the allocated TDA is correct.
Integration: `2025.w36`
* !3613 Speedup complex rotate for aarch64
* !3614 Ldpc encoder zc384 optimization
* !3625 gNB scheduler small fixes
* !3629 Fix for gNB max feedback time parameter
* !3619 Fix RA 2-Step MgsB Ack at UE
* !3626 Upgrade CI to Aerial 25-2
See merge request oai/openairinterface5g!3627
When FHI 7.2 is enabled, the EAL initialization is done by the FHI and
the attempt to init EAL by ldpc_aal will fail.
In that case, it is not necessary neither to provide a DPDK core list
for BBDEV.
This commit offers to skip EAL initialization if it is already initialized
in order to allow dropping the useless DPDK cores argument in that case.
The change relies on `rte_dev_probe` to detect if EAL was already
initialized.
Fix for gNB max feedback time parameter
This bug is causing assertions like the following
Assertion (curr_pucch->active == 0) failed!
In nr_csi_meas_reporting() /oai-ran/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c:282
CSI structure is scheduled in advance. It should be free!
because the PUCCH structure would be smaller than it should be causing
overlapping.
gNB scheduler small fixes
A couple of fixes in gNB scheduling function. Removing a superfluous input from
CCE function and adding a missing call to reset beam allocation.
Ldpc encoder zc384 optimization
This is a modification for the ldpc encoder which improves performance for
high-throughput cases. It contains a newly-generated file for innermost part of
the parity bit generation which, for AVX512, uses the mm512_permutex2var_epi8
instruction and for 128-bit (aarch64) the mm_alignr_epi8 (vextq_s8) in the
computation corresponding to each non-zero bit of the H matrix. This allows for
removing a very large memcpy and reduces the memory demand for the parity matrix
computation. For the moment this is limited to largest case in BG1, namely
Zc=384. This is the only format used when the number of segments after codeblock
segmentation is large (>8). This improves the timing required for ldpc parity
bits generation by more than a factor 2 with AVX512. This significantly reduces
the total time to generate the DLSCH/PDSCH.
See the merge request description for numbers.
Speedup complex rotate for aarch64
This is a simple optimization for aarch64 for the "rotate_cpx_vector" used for
the phase_rotation in 5G NR. It provides a speedup of around 1.5 on high-end
aarch64 targets compared to the SIMDe translated version. It is implemented with
native NEON intrinsics and was largely inspired by suggestions from ChatGPT 5 :-)
newly-generated files for innermost part of the parity bit
generation which, for AVX512, uses the mm512_permutex2var_epi8
instruction and for 128-bit (aarch64) the mm_alignr_epi8 (vextq_s8) in
the computation corresponding to each non-zero bit of the H matrix.
It is generated with ldpctest -n0 -g1. the changes for this are in a
future MR. I did these changes to compare with the GPU version
(ldpc_encoder_cuda), so that the CPU version is as fast as possible. The
generator will come when we merge the GPU encoder/decoder which also has
a generator for the CUDA version. it was difficult to extract the
changes in ldpctest/ldpc_encoder.c so I just took the generated file.
This allows for removing a very large memcpy and reduces the memory
demand for the parity matrix computation. For the moment this is limited
to largest case in BG1, namely Zc=384. This is the only format used when
the number of segments after codeblock segmentation is large (>8). This
improves the timing required for ldpc parity bits generation by more
than a factor 2 with AVX512. This significantly reduces the total time
to generate the DLSCH/PDSCH
Redirect to files and manual analysis as done in this Dockerfile is not
necessary since we just output all relevant build files to stdout.
Simplify to do the same here.
See: 35361db76b ("build_oai: don't redirect compilations to a file")
Fix OAIUE-OTA pipeline and increase tested traffic
I tried to "fix" the OAIUE pipeline in !3610 (merged) for making it more reliable, but inadvertently introduced many ULSCH DTX for UL traffic. Fix this, and increase DL traffic.
See merge request oai/openairinterface5g!3621
Integration: `2025.w35`
* !3604 Consider PDSCH EPRE to DMRS EPRE in NR UE
* !3606 Fix SRS TLV unpack
* !3602 Update RFsim CN
* !3516 [FHI72 M-plane] CM improvements and PM implementation
* !3538 add a new graphical T tracer to see gNB MAC scheduling decisions
* !3425 RFSim test for 10 UEs/process
Closes#950
See merge request oai/openairinterface5g!3610
RFSim test for 10 UEs/process
This MR adds a testcase and changes required to run 10 UEs in a single
process with RFSim
- Added deregistration for all connected UEs
- Refactored MAC/RRC instance handling
- made map_current_symbol thread safe
- made opeanir0_cfg thread safe and local
- Added 10UE/process testcase
Some code in T tracers is used by both LTE and NR.
In LTE, we expect 10 subframes per frame, and the logging is done with
this assumption. We have one tick per subframe.
In NR, we deal with slots, not subframes. And we have n ticks per frame
(depending on mu). As of today, only n=20 is tested (corresponding to
mu=1).
A previous commit introduced 'subframes_per_frame' which had the correct
meaning for LTE but was truly 'slots per frame' for NR. This creates
confusion.
Let's replace 'subframe' by 'tick' to reduce confusion.
Update RFsim CN
- Update RFsim CNs to latest version
- update the MBIM stop script to remove IP addresses (we don't use this
script directly, so it does not have an impact)
[FHI72 M-plane] CM improvements and PM implementation
Configuration Management:
- addition of the RU username in the fhi_72 section of the config file;
previously hardcoded to oranbenetel
- modification of the frequency offset, frame structure, fft size,
cyclic prefix, and Tx gain;
- addition of the managed delay node;
for Tx/Rx endpoints.
Performance Management implementation where OAI gNB
activates/deactivates available RU performance measurements.
- Replaced ITTI message queues with notifiedFIFO for RRC to MAC communication in UE.
- Enables correct message delivery to multiple MAC instances running in parallel threads.
- Introduced `nr_mac_rrc_message_t` union for MAC-RRC messages.
- Updated all relevant message handling and initialization code to use notifiedFIFO.
Performance Management support explanation.
Example run modified according to:
- modification of the frequency offset, frame structure, fft size, cyclic prefix, and Tx gain;
- addition of the managed delay node;
for Tx/Rx endpoints.
Introduced a parameter start_up_timing which indicates if PM activation is supported during the start-up
procedure. We initialize this parameter, based on the vendor.
Notification interval is set to 10s.
Definition in o-ran-uplane-conf.yang model:
"Gain correction of RF path linked with array element or array layers.
Common part of overall gain_correction.
gain_correction = common array-carrier gain-correction + eAxC gain correction."
Fix SRS TLV unpack
This MR changes the type of a variable to get the last index in which we
unpack the full 32 bits in a SRS TLV to int16 instead of uint16, in
order to be -1 when the TLV length is 0, thus skipping unpacking. This
only affects the SRS.indications sent by Aerial L1, which don't have
padding in the TLV, in case of OAI L1, we unpack in "full" 32 bit blocks
until the end of the TLV, if the length is 0, the unpacking loop exits
immediately. Furthermore, it also adds a check for the Report Type
parameter value in handle_nr_srs_measurements. If this value is zero,
according to SCF 222.10.04 Table 3-129 means a null report, so we can
skip processing it.
- Use MAX_NUM_NR_UE_INST in NR UE MAC to control number of MAC instances.
- Modify the MAC interface slightly so that nr_l2_init_ue only initializes one instance
Use MAX_NUM_NR_UE_INST for number of NR UE RRC instances. Change the RRC
interface slightly so nr_rrc_init_ue initializes only one RRC instance pointed
to by the id given to the function
Integration: `2025.w34`
* !3555 Remove dead code and variables, simplify code
* !3591 separate computation of size and value for DCI precoding information
* !3550 some work for better interoperability with srsRAN DU
* !3562 cleaning syntax of nr-ru.c
* !3598 Align add_boolean_option as per CMake documentation use only ON/OFF for uniformity
* !3407 Taps client for vrtsim
* !3035 NR L1 common channel level functions
* !3589 RF emulator and improvements of the timers
* !3577 Fix for UECAP file handling in dora/phytest mode
* !3600 Fix for UE TCI state ID configuration
* !3599 DLSCH scheduler: fix bugs in UE sorting
See merge request oai/openairinterface5g!3597
The CI detects whether a UE connected (and has a PDU session) by trying
to read the IP address. It therefore assumes that as long as the UE is
not connected, no IP would be present.
With the existing stop_quectel_mbim.sh script, this was not the case; it
would simply leave the IP address. Modify this script to flush all IP
addresses on disconnect to remedy this.
DLSCH scheduler: fix bugs in UE sorting
Fix two issues/bugs when sorting UEs in the DLSCH scheduler following
the PF metric, which should improve fairness.
RF emulator and improvements of the timers
RF emulator:
Add an RF library emulating a real device without the need of a real
device. This is thought to enable using phy-test without requiring a
radio device or channel simulation. The library synchronizes on the
real time clock, drops TX and generate noise on RX. Noise generation
can be disabled and the noise level configured.
Timers improvements:
- Fix standard deviation for merged timers
- Add display of ULSCH decoding timers
- Add decoding timer in AAL
Update the comparator() to properly sort UEs based on their coefficient
by appliey a consistent logic of -1/0/1 (see man qsort) for
smaller/equal/larger. The previous logic was only sorting based on 0/1
(equal/larger), which would result in some UEs with a high coefficient
not necessarily advancing to the start of the list, which could reduce
the likelihood of them being scheduled when they actually should (in
other words, this should improve fairness).
See also: 62e4025bc8 ("Integrate inactivity scheduling into main
allocation loop")
Taps client for vrtsim
The MR allows vrtsim to connect to the Raytracing Channel Emulator (CE later).
https://gitlab.eurecom.fr/oai/raytracing-channel-emulator
Additional Ubuntu packages required:
- libnanomsg-dev
- flatbuffers-compiler
- libflatbuffers-dev
Everything was tested on the same host. Follow the steps below to
successfully replicate:
1. Build nr-softmodem dependencies
2. Build nr-softmodem for (gNB, nrUE) with OAI_VRTSIM_TAPS_CLIENTset to ON.
3. Start the core network (Optional) follow this tutorial
4. Start the gNB
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf --gNBs.[0].min_rxtxtime 6 --device.name vrtsim --vrtsim.role server --vrtsim.timescale 0.5 --vrtsim.taps-socket ipc:///tmp/ru_socket_0
5. Start the nrUE
sudo ./nr-uesoftmodem -C 3619200000 -r 106 --numerology 1 --ssb 516 --band 78 --device.name vrtsim --vrtsim.taps-socket ipc:///tmp/ue_socket_0
6. Start the CE Server, once the UE and gNB are running properly, so the
server can connect to IPC sockets
7. Start CE client; the binaries can be downloaded from a pipeline run
or from this link
8. Move the UE in the CE client to generate a new taps array and
populate the taps in softmodems
Align add_boolean_option as per CMake documentation use only ON/OFF for uniformity
The add_boolean_option of CMake is not uniform everywhere. We were using
either True/False or ON/OFF. It is better to be uniform to avoid
confusion.
As an example, see here CMake documentation for an example:
https://cmake.org/cmake/help/latest/module/CMakeDependentOption.html#example-basic-usage
There are also some minor spelling corrections.
some work for better interoperability with srsRAN DU
Just add the minimum to get some user plane traffic going on.
When doing user plane traffic, in the CU logs we have a lot of:
[GTPU] NR-RAN container type: 1 not supported
That will be fixed in another MR, not here.
Interoperability testing with srsRAN DU shows than when receiving
RRCReconfigurationCompleteIndicator in a UEContextModificationRequest
the DU replies in the UEContextModificationResponse with an empty
CellGroupConfig.
This CellGroupConfig is encoded as 2 zero bytes. Let's ignore this
message when we receive it, don't forward it to the UE in a
RRC Reconfiguration, as it should per standard (38.473 8.3.4.2):
If the CellGroupConfig IE is included in the DU to CU RRC Information
IE contained in the UE CONTEXT MODIFICATION RESPONSE message, the
gNB-CU shall perform RRC Reconfiguration as described in TS 38.331 [8].
The CellGroupConfig IE shall transparently be signaled to the UE as
specified in TS 38.331 [8].
To be removed/reworked in the future if the interoperability
situation improves.
This is in 3GPP TS 38.425.
Because it was not done, there was a problem of interoperability
between openair CU and srsran DU. No DL traffic was reaching the UE.
A new GTPU API function is introduced: gtpv1uSendDirectWithNRUSeqNum().
It is only used in the gNB CU, in PDCP. So it was decided to not add a
new parameter to gtpv1uSendDirect() but instead add a new API function.
Replace the unwieldy unix socket implementation of peer information
exchange with an authorative connection descriptor file that
informs the client of the connection method an number of antennas
on the server.
This allows the server to run without the client and allows the
client to reconnect as long as the server is running, as many times
as needed.
Move the channel state management outside the channel implementation.
This simplifies the channel implementation but forces users of the
channel to manage it's state manually.
Add handling for error states in vrtsim which allows to close the
softmodems with CTRL+C without hanging, improving user experience
- Client detection of stale timer.
- Abort state for client and server
Added a libary that can connect to a channel emulator and provide taps
as they are generated.
- Enable connection from vrtsim to channel emulation server
- Depends on flatbuffers definition file from raytracing-channel-emulator
- Depends on libanomsg-dev and flatbuffers-compiler (Ubuntu) or equivalent
- Added a compile time option ENABLE_TAPS_CLIENT to prevent other users
from being affected by additional dependencies
separate computation of size and value for DCI precoding information
This removes stuff that is only relevant for the gNB from the common
functions and moves it to the gNB scheduler functions (related to UL
precoding). In principle no functional change.
2 functions with same name as static to make it clearer they are separate.
remove unused copy of log_level global var.
remove threequarter sampling variable from the radio board general
configuration. The decision of sampling rate is made above. A better
behavior can be done later, like ask to the radio board what sampling
rate it can do,then use it to decide the appropiate sampling rate from
the gNB configuration. In UE case, it is another issue, as the sampling
rate would change after we decode SIB1, but also it is not developped
yet.
Think: NR with different number of slots per frame depending on mu.
The name 'subframes_per_frame' is a bit ambiguous. It is valid for LTE,
but for NR it should be 'slots_per_frame'.
For example, for sub-carrier spacing of 30KHz, we have 20 slots per
frame, so in this case subframes_per_frame = 20. In reality whatever
the numerology, there is always 10 subframes per frame in NR.
But how to name this variable which is used both for LTE and NR cases?
'subframes_or_slots_per_frame'? It's a bit long and also ambiguous.
Conclusion: no big deal I think. 'subframes_per_frame' and so be it.
- Allow client to exit cleanly if server is down
- Ensure timing_thread is joined only once avoiding exit_function loop
- Free noise_device
- Save previously sent samples for channel modelling
Add a simple RF emulator library with no real RF.
It only synchronizes the gNB with the real time clock.
It is to be used for stress test or benchmarking in phy-test mode.
self.htmlFile.write(' <div class="well well-lg">End of Test Report -- Copyright <span class="glyphicon glyphicon-copyright-mark"></span> 2018 <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.
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config : {
global_log_level = "info";
pdcp_log_level = "info";
rrc_log_level = "info";
f1ap_log_level = "info";
ngap_log_level = "info";
};
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.