an incorrect assertion that was enforcing symmetric antenna
configurations only. I removed the assertion and updated the logging for
UE antenna dimensions and the channel model antenna dimensions used to
search in CIRDB.
Signed-off-by: Merkebu Girmay <merkebu.girmay@openairinterface.org>
Preparatory changes for LDPC CUDA integration
This changeset is preparatory work to merge LDPC CUDA offload in !4097.
Notably, it includes changes for cleaning up some defines, updates to
the LDPC interface, and CI specific changes to prepare for the other MR.
The goal is to merge changes in a first step such that, in a second
step, only the actual LDPC CUDA implementation and ancillary changes
(CUDA memory allocations, CI files, ...) need to be merged.
Reviewed-By: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
This memset() seems to be superfluous: following the code flow,
d_to_be_cleared is set on the same condition which guards the memset.
Following nrLDPC_coding_decoder() -> nrLDPC_prepare_TB_decoding() ->
nr_process_decode_segment() -> nr_rate_matching_ldpc_rx(), another
memset() is done using d_to_be_cleared.
Reported-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
CI: Clone from internal git repo
This MR refactors the CI pipeline as a preparatory step for the GitLab
--> GitHub migration. The core idea is to use a dedicated stage
RAN-Local-Repo-Push (introduced in !4017 (merged)) to clone source and
target branches, merges them and push a resulting branch into internal
git mirror. All downstream test jobs then check out exclusively from
that mirror. This makes the CI subpipelines independent of the remote
repository and improves stability in case of disruptions - test jobs
always check out from the internal mirror, not from GitLab/GitHub
directly.
Changes:
- doGitLabMerge.sh removed - merge is now done once in
RAN-Local-Repo-Push, slave jobs check out the pre-merged branch from
the internal mirror via SCM RAN-Local-Repo-Push extended:
- mergeWithTarget boolean parameter makes the merge optional (skipped on
direct push events) source/target remotes replace reliance on origin,
- targetRepo is now a configurable parameter to support fork-based MRs
- CreateTag() removed from Python - testBranch and testRepository
(default: internal mirror) are computed in the Jenkinsfile and passed
directly, two optional override parameters (customBranch,
customRepository) allow targeting a non-default branch or repo
- create_workspace.sh is reduced to git clone --depth=1 --branch
- all eNB_/ran-prefixed Jenkinsfile parameters and Python CLI arguments
renamed to neutral names (sourceBranch, sourceCommit, workspace,
repository,...), both old and new names accepted during the transition
period
Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org>
A later commit (for LDPC CUDA) will reuse add_physim_test(), but is in a
completely different location than the existing physim test definitions.
Hence, move it to global scope for later reuse.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Provide the memory buffer size for storing LLRs across HARQ rounds. then
we don't need to check for this in the API users.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Rename this option from CUDA_ENABLE, as it might otherwise conflict with
another option for LDPC CUDA. For consistency, name the compile option
to CHANNEL_SIM_CUDA. This way, the LDPC CUDA option (ENABLE_LDPC_CUDA
and compile definition LDPC_CUDA) will not conflict, and the
corresponding code is clearly "labelled".
A further change is the use of target_sources to simplify the definition
of the channel_pipeline executable.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Information about sourceBranch and sourceCommit is already encoded in
the testBranch name, making it redundant in the HTML header.
Also remove the Job Trigger and Target Branch lines, as these parameters
provide limited value and are not particularly relevant for the report.
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
"Create new Workspace for server 0/1" no longer makes sense now that
workspace creation is not tied to a specific server index.
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
NR_MAC/PHY: align SRS time_start_position semantics between L2 and L1
Problem
nfapi_nr_srs_pdu_t::time_start_position was being interpreted
inconsistently between OAI MAC (the producer) and the various L1
consumers:
- MAC populated the field with SRS-ResourceMapping.startPosition from
the RRC config — the value 3GPP defines as an offset counted backwards
from the end of the slot (TS 38.331).
- L1 consumers (openair1/PHY/NR_TRANSPORT/srs_rx.c,
openair1/SCHED_NR/phy_procedures_nr_gNB.c) and the MAC's own VRB-map
consumer (gNB_scheduler_srs.c) all re-derived the absolute symbol
index with NR_SYMBOLS_PER_SLOT - 1 - time_start_position.
This works for OAI's in-tree soft L1 (every consumer applies the same
inversion), but external FAPI L1s (NVIDIA Aerial / cuBB) treat
time_start_position as the absolute symbol index per the SCF FAPI 222
PDU semantics. The MAC and external L1 therefore disagreed by one symbol
inversion. Net effect: SRS was scheduled on the wrong OFDM symbol, the
RU sampled noise instead of the SRS, and the channel-matrix returned in
SRS.indication was all zeros for almost every occasion. Fix
Move the inversion to the producer side. MAC populates the PDU with the
absolute symbol index (NR_SYMBOLS_PER_SLOT - 1 - startPosition), and
every consumer uses srs_pdu->time_start_position directly as l0.
The two semantics are mathematically equivalent for OAI's soft L1 (l0 =
NR_SYMBOLS_PER_SLOT - 1 - startPosition either way), so the symbol index
used internally is unchanged on non-Aerial builds. External L1 consumers
now receive the value they expect. Testing status
- [x] OAI L1 + L2
- [x] Aerial L1 in CAT-B / mMIMO mode
- [x] Aerial L1 in CAT-A mode
- [x] RFsim / nrUE end-to-end loopback:
Reviewed-By: Rúben Soares Silva <rsilva@allbesmart.pt>
Add Fedora 44/Ubuntu 26 to list of supported distributions
See commits for more details. Includes a minor cleanup. What I tested
for U22/U24/U26 and F44 is
./build_oai --ninja -c -I -w USRP --gNB --nrUE
Reviewed-By: Luis Pereira <lpereira@allbesmart.pt>
changes in cudaMemadvise/cudaPrefetch API for v13.
Build fails on DGX spark or any Blackwell GPU target without this fix.
It just checks the CUDA version in a couple of places where GPU offload
is used for channel simulation (nr_dlsim,nr_ulsim and
channel_pipeline.cu) and adapts the usage of the CUDA API accordingly.
Reviewed-By: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
Remove CreateTag() and the merge/targetBranch parameters from
CreateWorkspace, passing the final branch name and repository directly
from Jenkins instead. Jenkinsfile computes testBranch and testRepository
(with INTERNAL_REPO as default). create_workspace.sh now does a simple
shallow clone by branch name.
Introduce two optional Jenkins parameters that allow overriding the
default branch reference and git repository URL used across the CI
pipeline.
- customBranch: when set, replaces the entire computed
{sourceBranch}-{commitID}
- customRepository: when set, replaces INTERNAL_REPO as the git remote
used by Create_Workspace to clone the source code onto the test node.
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Use the current OAI CI default UHD version. Update the documentation to
show how to install a recent version.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
The existing patch (generated through sed) works also in UHD versions
beyond 4.8, so allow to use that.
Further, since sed is confusing, store the patch directly. Update the
dockerfiles so that docker copies the right file for UHD 4.8.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Also, for UHD install from packages, add the right version for both
Ubuntu 24 and Ubuntu 26: in U24, use the currently recommended 4.8, and
bump to latest in U26.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
The CI does not use installation of UHD from package, hence this
mechanism is not needed (and should not be, anyway).
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Iterate all NZP-CSI-RS resources per ResourceSet in scheduler
It was necessary to use 2 CSI-RS resources, but it was discovered that
gNB only transmitted the first one.
nr_csirs_scheduling() was comparing nzp_CSI_RS_ResourceId against an
NZP-CSI-RS-ResourceSetId picked from the first entry of the first
matching CSI-ResourceConfig. This silently filtered out every Resource
whose ID did not happen to match the ResourceSet ID, making setups with
more than one NZP-CSI-RS-Resource per UE impossible: only the first
resource was ever transmitted, while the UE kept scheduling reception
for the remaining ones and reported them as missing (RSRP at the noise
floor).
This MR fixes it, and allows multiple Resources per Set.
Reviewed-By: Francesco Mani <email@francescomani.it>
hotfix for correct GFNI detection
Currently, GFNI will be activated for all x86 builds which fails on
older machines (prior to skylake or Zen4). This patch just detects GFNI
from the CPUFLAGS and adds only if it is supported by the x86 target.
Includes two ancillary fixes for correctly using CPUFLAGS and DFTS
compiler optimization flag.
Reviewed-By: Robert Schmidt <robert.schmidt@openairinterface.org>
NAS UE Service Request fixes and improvements for Paging
This MR improves the NAS UE Service Request path and makes
paging-related resume handling more robust. It fixes KSI/KgNB
synchronization, corrects 5G-S-TMSI and encoder/decoder length handling,
and adds Service Accept handling in the NAS_CONN_ESTABLI_CNF path.
It also zero-initializes the initial NAS buffer used during RRC setup
complete to avoid carrying stale data into early NAS message handling.
Reviewed-By: Cedric Roux <cedric.roux@eurecom.fr>
Refactor DLSCH/ULSCH scheduler: extract proportional fair policy behind function pointer interface
Motivation
The current `pf_dl()` is a ~600-line monolithic function that mixes
infrastructure concerns (UE iteration, HARQ management, CCE allocation,
MAC PDU generation) with the scheduling policy (PF priority, RB
allocation, MCS selection). This makes it hard to modify the scheduling
strategy, test alternatives, or offload scheduling to a GPU (cuMAC).
This MR refactors the DL and UL schedulers into a clean separation
between **infrastructure** and **policy**, using function pointers for
beam allocation and scheduling decisions. The data structures
(`nr_dl_candidate_t`, `nr_dl_sched_params_t`) are also designed to map
directly to cuMAC's
`cumacCellGrpUeStatus`/`cumacSchdSol`/`CumacCellGrpPrms`, to make future
integration smooth.
Changes
Goodput tracking fix
`dl_thr_ue` now tracks actual goodput in bps (EWMA of SDU byte deltas
per frame) instead of accumulating raw byte counts per slot, which are
not as straightforward to interpret (due to variations in TDD patterns
mostly). The new calculation matches closely with the throughput
measured with e.g. iperf.
Helper extraction from `pf_dl()` and `post_process_dlsch()`
- `find_first_available_rbs()` — first-fit contiguous RB allocation
- `setup_dl_harq_process()` — HARQ process management
- `generate_dl_mac_pdu()` — MAC CE + RLC data + padding
- `fill_dl_tx_request()` — FAPI TX_req filling
New scheduling interface
- **`nr_dl_candidate_t`** — per-UE flat struct with all immutable inputs
(buffer status, BLER, MCS limits, beam, BWP) and outputs (scheduled,
rbStart, rbSize, MCS). Kept relatively minimal for now, but it should
be easy to add more input metrics in the future.
- **`nr_dl_sched_params_t`** — per-beam cell-level context (VRB map,
available RBs, slot bitmap)
Function pointers (DL)
| Pointer | Default implementation | Role |
|---------|----------------------|------|
| `dl_ri_pmi_select` | `nr_dl_ri_pmi_select_default` | Rank/PMI selection |
| `dl_beam_select` | `nr_dl_beam_select_default` | Beam direction assignment |
| `dl_tda_select` | `nr_dl_tda_select_default` | Time-domain allocation |
| `dl_mcs_select` | `nr_dl_mcs_select_default` | MCS from BLER/SINR |
| `dl_rb_alloc` | `nr_dl_proportional_fair` | PRB allocation (PF policy) |
Function pointers (UL)
| Pointer | Default implementation | Role |
|---------|----------------------|------|
| `ul_ri_tpmi_select` | `nr_ul_ri_tpmi_select_default` | Rank/TPMI from SRS feedback |
| `ul_beam_select` | `nr_ul_beam_select_default` | Beam direction assignment |
| `ul_tda_select` | `nr_ul_tda_select_default` | Time-domain allocation |
| `ul_mcs_select` | `nr_ul_mcs_select_default` | MCS from BLER/SINR |
| `ul_rb_alloc` | `nr_ul_proportional_fair` | PRB allocation (retx first, then PF-sorted new-tx) |
All default implementations are in `gNB_scheduler_dlsch.c` (DL) and
`gNB_scheduler_ulsch.c` (UL).
MCS selection flow
The old `get_mcs_from_bler()` entangled two concerns: updating the BLER
estimate from HARQ feedback and deciding the MCS. These are now split:
- **BLER tracking is infrastructure's job**: `collect_dl_candidates()`
calls `update_dl_bler_stats()` which updates the BLER estimate from
HARQ round statistics.
- **MCS selection is the policy's job**: the proportional fair policy
calls `select_mcs_from_bler()` internally to adapt MCS based on the
BLER value. A different policy could use an entirely different MCS
strategy (e.g. cuMAC has its own `mcsSelectionLUT` + OLLA, one could
decide to opportunistically lower the MCS while increasing the PRB
allocation for reliability in some cases, etc).
For retransmissions, MCS/number of PRBs are passed as hints so the
policy can use them as-is if desired, but we don't enforce it (adaptive
HARQ possible too: the standard requires us to maintain TBS but in
theory it could be achieved via changing the MCS and number of RBs if we
wanted to).
Refactored flow
`nr_dl_schedule()` (formerly `pf_dl()`):
```
collect_dl_candidates() → build candidate array from UE list
schedule_dl_ues() → beam alloc + per-beam policy calls
for each scheduled candidate → CCE/PUCCH/TBS validation + post_process
```
Beam allocation and scheduling policy are two separate function
pointers, allowing each to be developed and tested independently (with
the goal in the future to add a parameter in the config file for each,
and telnet commands to hotswap).
`schedule_dl_ues()` wraps both into a single function: it first calls
beam allocation to assign candidates to beams, then iterates over beams
and calls the scheduling policy for each one. cuMAC performs joint beam
+ PRB allocation on the GPU, so when integrating later it will replace
`schedule_dl_ues()`.
Future work
- Channel matrix H from SRS on candidates for beam-aware scheduling
- Per-RB channel magnitude derived from SRS on candidates
- Config file parameters and telnet commands for hotswapping policies
- cuMAC integration via `schedule_dl_ues()` replacement
Reviewed-By: Robert Schmidt <robert.schmidt@openairinterface.org>
This helps the performance: In the FFTs there is a chain like
dft1024->dft256->dft64->dft16 with nested function calls. This improves
the compilers behaviour when handling the nesting.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Currently, GFNI will be activated for all x86 builds which fails on
older machines (prior to skylake or Zen4). Properly detect based on CPU
flags.
Signed-off-by: Raymond Knopp <raymond.knopp@eurecom.fr>
Process Service Accept when it is delivered through NAS connection
establish confirm.
Changes:
- add `FGS_SERVICE_ACCEPT` branch in `NAS_CONN_ESTABLI_CNF` message
dispatch and call `handle_service_accept
Refs:
- TS 24.501 5.6.1.4, 8.2.17 (Service accept)
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Extend the UE 5GS Service Request path to carry `PDU session status`
inside a NAS message container and cipher only that container value when
valid NAS contexts exist. This aligns the initial Service
Request handling with the TS 24.501 rules for non-cleartext IEs.
Treat the generated Service Request as integrity-protected whenever an
integrity context is available, and keep the post-request KgNB refresh
aligned with the NAS UL count used for that protected message.
Changes:
- update `generateServiceRequest()` in `nr_nas_msg.c` to derive a
`PDU session status` bitmap from configured UE PDU sessions and treat
it as the non-cleartext trigger for the initial Service Request
- build an inner plain Service Request carrying `PDU session status`,
place it in the `NAS message container`, cipher only the container
value with the NAS ciphering context, and keep the outer Service
Request integrity protected
- extend `fgs_service_request` lib to support optional `PDU session status`
and `NAS message container` fields
- decode known optional Service Request TLV IEs with a `switch` and skip
unsupported ones
- add `free_fgs_service_request()` and `eq_fgs_service_request()`
- extend `nas_lib_test` to cover Service Request encoding and decoding
with `PDU session status`, `NAS message container`, and skipped
optional IEs, and initialize the test logging/config stubs
- set the outgoing ngKSI with `set_fgs_ksi(nas)` instead of hardcoding
`NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE`
- move `initialNasMsg->nas_data` allocation into the protected and plain
branches so each path allocates after its final size accounting
- increment `nas->security.nas_count_ul` after integrity MAC computation
- derive a refreshed KgNB with `derive_kgnb()` and send it through
`nas_itti_kgnb_refresh_req()` after the protected Service Request is
built
Refs:
- TS 24.501 §4.4.6 (protection of initial NAS signalling messages)
- TS 24.501 §4.4.4.1 and §4.4.6 allow an initial Service Request to be
integrity protected and unciphered when a valid 5G NAS security
context exists and no NAS message container is included.
- TS 24.501 §8.2.16.1 (Service Request message content)
- TS 24.501 §8.2.16.3 (PDU session status)
- TS 24.501 §9.11.3.33 (NAS message container)
- TS 33.501 §6.4.3.1 (NAS integrity inputs)
- TS 33.501 §6.4.4.1 (NAS confidentiality inputs)
- TS 33.501 §6.8.1.2.2 derives KgNB from the UL NAS COUNT of the NAS
message that moves the UE from CM-IDLE to CM-CONNECTED, unless a
subsequent NAS Security Mode Complete exists, in which case that newer
UL NAS COUNT becomes the freshness input.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Bugfix overflow uint16_t variable when FFT size is 6144
When using USRP X310 and 100 MHz, the sampling rate is 184320000 Msps,
this leads in a FFT size of 6144 that was causing an overflow in the
fft_shift function (6144 * 14 = 86016 > UINT16_MAX)
This bug was introduced recently, by !3834
Reviewed-by: Sakthivel Velumani <s.velumani@northeastern.edu>
When using USRP X310 and 100 MHz, the sampling rate is 184320, this leads in a FFT size of 6144 that was causing an overflow in the fft_shift function (6144 * 14 = 86016 > MAX_INT_16)
Signed-off-by: Luis Pereira <lpereira@allbesmart.pt>
clang was silently upgraded in CI to v21, and now warns
openair2/RRC/NR/rrc_gNB_UE_context.c:70:24: error: default initialization of an object of type 'rrc_gNB_ue_context_t' (aka 'struct rrc_gNB_ue_context_s') with const member leaves the object uninitialized [-Werror,-Wdefault-const-init-field-unsafe]
openair2/RRC/NR/rrc_gNB_UE_context.c:70:24: error: default initialization of an object of type 'rrc_gNB_ue_context_t' (aka 'struct rrc_gNB_ue_context_s') with const member leaves the object uninitialized [-Werror,-Wdefault-const-init-field-unsafe]
openair2/RRC/NR/rrc_gNB_cuup.c:183:13: error: default initialization of an object of type 'seq_arr_t' (aka 'struct seq_arr_s') with const member leaves the object uninitialized [-Werror,-Wdefault-const-init-field-unsafe]
openair2/RRC/NR/rrc_gNB_cuup.c:185:13: error: default initialization of an object of type 'seq_arr_t' (aka 'struct seq_arr_s') with const member leaves the object uninitialized [-Werror,-Wdefault-const-init-field-unsafe]
openair2/RRC/NR/rrc_gNB_du.c:864:13: error: default initialization of an object of type 'seq_arr_t' (aka 'struct seq_arr_s') with const member leaves the object uninitialized [-Werror,-Wdefault-const-init-field-unsafe]
Since this warning is new, and due to -Werror being used, the build now
fails on the same code base. Disable this warning to get it build.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
move vrtsim channel and per-UE param configuration from CLI flags to config file
Add vrtsim channel and per-UE parameter configuration to the gNB config
file. Previously, running a multi-UE vrtsim test required a long list of
CLI flags; these can now be configured directly in the config file under
a vrtsim: section. The gNB can be started with simply:
sudo ./nr-softmodem -O gnb.sa.band78.106prb.vrtsim.2x2.yaml --device.name vrtsim
Reviewed-By: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
Checkout to tested branch is performed via Jenkins SCM checkout from
internal git repository (git@asterix:/home/git/openairinterface5g.git).
Target branch to checkout is given as {sourceBranch}-{sourceCommit},
which was created and pushed to the internal repository in
RAN-Local-Repo-Push stage.
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
3GPP RRC SRS-ResourceMapping.startPosition is defined as an offset
counted backwards from the end of the slot (TS 38.331). OAI MAC was
previously passing the raw RRC value straight into the FAPI SRS PDU's
time_start_position field, and every L1 consumer was then re-deriving
the absolute symbol via NR_SYMBOLS_PER_SLOT - 1 - time_start_position.
External L1 implementations (e.g. NVIDIA Aerial / cuBB) interpret
time_start_position as the absolute symbol index where the SRS lives,
which left the MAC and external L1 disagreeing by one inversion. The
result was SRS being scheduled on the wrong OFDM symbol and the
returned channel matrix being all-zero for most occasions.
Make MAC populate time_start_position with the absolute symbol index
(NR_SYMBOLS_PER_SLOT - 1 - startPosition) and remove the matching
inversion from the L1 consumers so the value flows through unchanged.
The UE side and the shared SRS generator are harmonized to the same
absolute-symbol convention so generate_srs_nr can read nr_srs_info->
l_offset directly regardless of caller (gNB or UE).
* gNB MAC: gNB_scheduler_srs.c invert at PDU-build time; consume the
already-inverted value when computing l0 for the VRB mask.
* gNB PHY: srs_rx.c (fill + get_signal) and SCHED_NR/phy_procedures_
nr_gNB.c use srs_pdu->time_start_position directly as l0.
* UE MAC: nr_ue_scheduler.c invert at PDU-build time.
* UE PHY: phy_procedures_nr_ue.c consumes srs_config_pdu->time_start_
position directly as l0.
* Shared SRS generator: nr_phy_common_srs.c reads nr_srs_info->l_offset
as the absolute symbol index, matching both gNB and UE call sites.
* Simulators: srssim.c and ulsim.c populate both the gNB-side and
UE-side SRS PDUs with the absolute symbol index so the nr_srssim
and nr_ulsim unit tests pass with the new convention.
Signed-off-by: Gabriele Gemmi <g.gemmi@northeastern.edu>
restructuring of UE DLSCH code to handle 2 codewords
While making changes in another MR I realized the mess in the handling
of 2 codewords in UE DLSCH code. The intention of the MR is not much to
support 2 codewords at the UE but the cleanup the code which currently
in many parts is written confusedly in between support and non-support.
The key point is that the two codewords need to be treated separately as
they have their own modulation and coding scheme and their own
retransmission information.
Reviewed-By: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
even if 2 codewords are currently not supported and not tested, the way UE handled the possibility of having 2 codewords was messy, in between support and non-support
the intention of this MR is to cleanup the code more than extend the support
Signed-off-by: Francesco Mani <email@francescomani.it>
NR UE: remove hardcoded 64KB limit for UE capability file
When trying to parse UE capability file (xml converted from a COTS UE),
there will be an error:
[NR_RRC] UE Capabilities XER file /home/ue_caps/ue_cap_20260514_172636.xml is too large (65536)
This is fixed by replacing fixed-size stack buffer with heap allocation
sized to the actual file, allowing large UE capability XER files to be
loaded without hitting the previous 65536-byte limit.
Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org>
!4083 improved encoding time in some nr_dlsim tests running in
RAN-PhySim-GraceHopper-5G pipeline. Update the timing thresholds
accordingly.
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
CI: Cleanup of parameters, change of branch and image naming, remove BuildProxy
MR Summary:
1. Remove merge step from Jenkinsfile-GitLab-Container
Removes the manual git merge step that was previously performed inside
the `RAN-Container-Parent` pipeline before running CI. The
`doGitLabMerge.sh` call and its merge-conflict failure handler are
dropped from the init stage. The `RAN-Local-Repo-Push` stage no longer
wraps triggerSlaveJob in catchError, instead, its failure posts an MR
comment directly on GitLab to report the issue, and abort the follow-up
test stages.
2. Switch to full commit IDs for image and branch naming
Replaces abbreviated 8-character commit hashes with full commit IDs
everywhere they are used to construct Docker image tags and CI branch
names in internal git repository.
3. Remove L2sim proxy build support
For the `RAN-L2-Sim-Test-4G`, the CI now assumes that the required proxy
image is already present on the testing machine. Build proxy step is no
longer needed, since there haven't been any recent updates in the proxy
repo, and the proxyCommit we currently use is outdated anyway.
4. Rename and clean up parameters in Python scripts
Renames legacy ran* / eNB* prefixed attributes to generic names across
all CI Python classes. Also removes duplicate and unused legacy CLI
argument aliases (--eNBRepository, --eNBBranch, --eNBIPAddress, etc.)
from args_parse.py.
|Old name |New name |
|----------------|----------------|
|ranRepository |repository |
|ranBranch |branch |
|ranCommitID |commitID |
|ranAllowMerge |merge |
|ranTargetBranch |targetBranch |
|eNBSourceCodePath|workspace |
Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Collect iperf logs if command fails
The Iperf_Module() checks that the iperf3 command succeeds successfully,
but in case of failure, does not collect the actual logs. Thus, only a
somewhat unhelpful
Iperf client command failed on X -> Y (return code: ZZZ)
is logged, and it might not be clear why it fails. In this command,
always try to collect the logs, which might contain the actual error.
Fixes: f02c84fc ("CI: enable PCF-based dual-DNN multi-QoS in 25PRB
RFSim")
Reviewed-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Remove the `BuildProxy` method, `Build_Proxy` action, `proxyCommit`
attribute, and all associated XML configuration and unit tests.
The oai-lte-5g-multi-ue-proxy repository has not received any updates
in over two years, and the proxy commit currently used for the build
is outdated as well. Although the proxy image is still required by
RAN-L2-Sim-Test-4G and must remain available on the test machine,
building it as part of the CI pipeline is dropped in this commit.
Instead, the CI will now assume that the corresponding proxy image is
already present as an external dependency, similarly to how CN images
are handled.
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Simplify branch handling in CI by removing reliance on shortened commit
hashes and using full commit IDs. This allows to specify branch during
SCM checkout in Jenkins pipeline.
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
The RAN-Container-Parent pipeline retrieves the Jenkinsfile-GitLab-Container
from the develop branch (or from the branch specified for SCM checkout).
The only potential impact of this change concerns modifications to
ci-scripts/checkGitLabMergeRequestLabels.sh. In such cases, updates from the
source branch would not be considered, and the version from develop would be
used instead. This limitation is acceptable, as this script is going to be
removed in the future.
Merge conflict checks are handled in the Local-Repo-Push stage, where the
source branch is merged with the target branch, and the resulting testing
branch is pushed to the internal repository.
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
The Iperf_Module() checks that the iperf3 command succeeds successfully,
but in case of failure, does not collect the actual logs. Thus, only a
somewhat unhelpful
Iperf client command failed on X -> Y (return code: ZZZ)
is logged, and it might not be clear why it fails. In this commit,
always try to collect the logs, which might contain the actual error,
and only add the diagnostic message at the end of the Iperf report
message.
Fixes: f02c84fcfc ("CI: enable PCF-based dual-DNN multi-QoS in 25PRB
RFSim")
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Remove PUCCH formar limitation in PRB size function
F3 can be handled same way as F2 according to 9.2.5.2 of 38.213
Closes#1077
Reviewed-By: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
Replace fixed-size stack buffer with heap allocation sized to the
actual file, allowing large UE capability XER files to be loaded
without hitting the previous 65536-byte limit.
Signed-off-by: Alex Jiao <alex.jiao@keysight.com>
Without explicit casts, each buf byte was promoted to a 32-bit signed
int before shifting. For NR Cell Identity (36-bit, per 3GPP TS 38.423
§9.2.2.9), this causes two problems:
- Shifting buf[0] left by 28 can push bits into or past the sign bit,
producing undefined/implementation-defined behavior.
- The 32-bit intermediate result is too narrow to hold a 36-bit value,
causing silent truncation before the OR-reduction.
Fix by casting each byte to uint64_t prior to the shift, ensuring all
intermediate expressions are evaluated in a 64-bit unsigned domain and
all 36 bits are preserved without overflow.
Fix Wt (orthogonal code) multiplication for PUSCH DMRS length 2 and
noise power estimation
This MR:
- Introduce PUSCH DMRS length as a configurable parameter in nr_ulsim.
- Fix bugs related to the use of PUSCH DMRS length 2.
- Fix the noise power estimation.
Note:
- Still cannot validate PUSCH DMRS length 4, since we need more than 5
layers (DMRS type 1) / 6 layers (DMRS type 2) to test the orthogonal
spreading over time.
- Yet to implement time domain averaging for PUSCH DMRS length 2 to
separate orthogonally over time.
- The main bug here is the noise power estimation (removes the duplicate
division with the number of antennas).
Reviewed-by: Roberto Louro Magueta <rmagueta@allbesmart.pt>
T-tracer: fix UE_PHY_PDSCH_IQ event fields
1. The field was named N_RB_UL and used fp->N_RB_UL in both LTE and NR
demodulation code, but it should use N_RB_DL for PDSCH
2. The tracer ue.c referenced the wrong buffer field name "pusch_comp"
instead of "pdsch_comp", causing a crash on startup
Reviewed-by: Cedric Roux <cedric.roux@eurecom.fr>
Decode the FGC NAS message container length from the encoded 2-octet
field before validating and copying the payload. This matches TS
24.501, where the NAS message container is a type 6 TLV and its length
is carried in octets 2-3.
Changes:
- add `<arpa/inet.h>` for `ntohs`
- change `ielen` from `uint8_t` to `uint16_t` in
`decode_fgc_nas_message_container()`
- read the encoded length with `memcpy`, convert it from network byte
order, and advance the decode pointer by `sizeof(uint16_t)`
Refs:
- TS 124 501 clause 9.11.3.33 "NAS message container"
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Use the stored NAS KSI only when a valid integrity context is present,
instead of treating idle mode alone as proof that no KSI is available.
This keeps outgoing initial NAS messages aligned with the actual NAS
security state tracked by the UE (including when in IDLE state).
Changes:
- update `set_fgs_ksi()` in `openair3/NAS/NR_UE/nr_nas_msg.c` to return
`*nas->ksi & 0x07` only when `security_container`,
`integrity_context`, and `nas->ksi` are present
- remove the unconditional `FGS_IDLE` check and the hardcoded `0x0`
return path
- keep `NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE` as the fallback when no
valid integrity context is available
Refs:
- TS 24.501 (Service Request and ngKSI/security context handling)
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Move the `nas_itti_kgnb_refresh_req()` declaration to the NAS UE header
so call sites use a single shared prototype.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Correct the encoded-size contribution returned by `fill_fgstmsi()` so
Service Request buffer sizing includes the full 5GS mobile identity field.
Changes:
- update `fill_fgstmsi()` return value from 10 to 11 octets: 2-octet length
field plus 7-octet 5G-S-TMSI payload
Refs:
- TS 24.501 8.2.16 (Service request)
- TS 24.501 9.11.3.4 (5GS mobile identity)
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Add defensive initialization and minimum-length validation in Service
Request decoding.
Changes:
- zero-initialize `fgs_service_request_msg_t` at decode entry
- return error when input length is shorter than the first mandatory octet
- add guard before decoding 5GS mobile identity length field to prevent
out-of-bounds access
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Initialize the local NAS message container before it is used in the
RRCSetupComplete generation path to avoid undefined state from stack data.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
1. The field was named N_RB_UL and used fp->N_RB_UL in both LTE and NR
demodulation code, but it should use N_RB_DL for PDSCH
2. The tracer ue.c referenced the wrong buffer field name "pusch_comp"
instead of "pdsch_comp", causing a crash on startup
Signed-off-by: Alex Jiao <alex.jiao@keysight.com>
Integration `2026.w19`
* ci: post MR validation comments only on warnings or errors in pre-ci-check
* ci: skip merge-commit validation for integration branches
* !4088 fixing wrong logic for SIMO and MISO AWGN channels
* !4052 Add OAI - WNC gNB config file
* !4091 Fix build with unit tests, build all in CI
* !4089 Fixing broken nr-cu-nrppa-test simulator and nr-ue-nas-simualtor
* !4099 Allow control signal level at input of OFDM modulator
* !4092 Remove more unused parameters
* !4102 nr-cuup-load-test: avoid unaligned memory access
* !4077 Update microamp FR2 doc for firmware 0.1.174
* !3960 fix: issue 1054 - Config: Creating New Array members via command line arguments
* !3810 UE symbol based PBCH, PSBCH receiver
* !4103 Update CN5G images to stable release `v2.2.1`
* !3814 Multi-QoS Handling and PDU Session Modify
* !4064 FAPI: fix UCI payload byte length for bit_len multiples of 8
* !4078 [M-plane] Improvements, fixes + Add CI M-plane pipeline
Closes#1054, #1075, and #541
See merge request oai/openairinterface5g!4095
Also fixes noise power computation removing the duplicate division over
number of antennas
Signed-off-by: Rakesh Mundlamuri <rakesh.mundlamuri@openairinterface.org>
FAPI: fix UCI payload byte length for bit_len multiples of 8
Problem
When testing with cuBB as the FAPI PNF (L1) and ruSIM, the VNF (OAI L2)
was consistently failing to unpack UCI.indication messages containing
PUCCH format 2/3/4 PDUs with CSI-1 reports:
vnf_handle_nr_uci_indication: Failed to unpack message
pullarray8: pullarray8 no space in buffer
Root cause
All variable-length payload fields in the UCI pack/unpack functions
(HARQ, SR, CSI-1, CSI-2) computed their byte length as:
const uint16_t csi_len = bit_len / 8 + 1;
This formula seems wrong for any bit_len that is an exact multiple of 8.
For example, bit_len=8 gives csi_len=2, but 8 bits fit in exactly 1
byte. The correct ceiling division is (bit_len + 7) / 8.
cuBB packs CSI-1 payload bytes using the correct formula, so for an
8-bit CSI codebook it sends 1 byte. OAI's unpacker computed csi_len=2
and called pullarray8 requesting 2 bytes from a buffer with only 1
remaining, triggering the error.
The failure was also specific to PUCCH 2/3/4 (and would affect PUSCH
UCI) because PUCCH 0/1 carries no variable-length byte arrays — its HARQ
payload is packed as individual uint8 values per ACK bit, so pullarray8
is never called.
Diagnosis
Added NFAPI_TRACE_NOTE logging throughout the unpack chain (enabled via
NFAPI_TRACE_LEVEL=note) to trace PDU type, bitmap, computed lengths, and
buffer remaining bytes at each branch. The following sequence confirmed
the exact failure site:
[N] unpack_nr_uci_indication: sfn=592 slot=9 num_ucis=1 buf_remaining=21
[N] unpack_nr_uci_indication: unpacking UCI[0/1] buf_remaining=21
[N] unpack_nr_uci_indication_body: pdu_type=2 pdu_size=21 buf_remaining=17
[N] unpack_nr_uci_pucch_2_3_4: PUCCH-2/3/4 rnti=0x5c2d pucch_format=0 pduBitmap=0x04 buf_remaining=4
[N] unpack_nr_uci_pucch_2_3_4: PUCCH-2/3/4 CSI-1 csi_part1_bit_len=8 csi_len=2 buf_remaining=1
[N] unpack_nr_uci_pucch_2_3_4: PUCCH-2/3/4 CSI-1 about to pullarray8 csi_len=2 buf_remaining=1
[E] pullarray8: pullarray8 no space in buffer
This was also cross-checked against a pcap capture of the nvipc
interface, which confirmed cuBB sends PDUSize=21 with 1 byte for the
8-bit CSI-1 payload — consistent with (8+7)/8 = 1.
Tentative Fix
Replace bit_len / 8 + 1 with (bit_len + 7) / 8 at all 14 affected sites
across both pack and unpack functions for PUSCH, PUCCH 0/1 (SR/HARQ),
and PUCCH 2/3/4 (SR, HARQ, CSI-1, CSI-2) in nr_fapi_p7.c.
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Reviewed-by: Rúben Soares Silva <rsilva@allbesmart.pt>
Multi-QoS Handling and PDU Session Modify
This MR implements comprehensive QoS flows handling and PDU Session
Modify procedures in the RRC layer, enabling full support for multiple
QoS flows per DRB and dynamic QoS management per 3GPP specs. Key
changes:
1. Multi-QoS Flows Support
- Multiple QoS flows per DRB: Support for multiple QoS flows mapped to a
single DRB
- Intelligent QoS-to-DRB mapping: Implements resource-type-aware
multiplexing based on 3GPP TS 23.501 Table 5.7.4-1
- DC-GBR flows (5QI 82-90): Dedicated DRB, max 1 flow per DRB
- GBR flows (5QI 1-4, 65-67, 71-76): Max 2 flows per DRB
- Non-GBR flows (5QI 5-11, 69-70, 79-80): Max 5 flows per DRB
- Aggregate cap: Maximum 5 flows per DRB
- 5QI validation: Early validation of standardized 5QI values (1-9,
65-90) during QoS flow setup/modify
2. PDU Session Modify Procedures
- Complete E1AP/RRC integration: Full Bearer Context Modification
support with DRB lifecycle management
- DRB To Setup/Modify/Remove lists: Complete support for all DRB
operations in Bearer Context Modification
- QoS flow operations: Support for QoS flow add, modify, and release
operations
- QoS flow mapping: Proper handling of QoS flow modifications in
DRB To Modify List
- Automatic DRB management: DRB setup, modification, and removal
based on QoS flow changes. Reuse existing DRBs if the incoming QoS
flow is compatible.
- Delayed transactions: PDU Session Modify added to delayed
transactions list for proper sequencing
3. GTP-U Tunnel Refactoring
- Architecture alignment:
- N3 tunnels: 1 per PDU session with QFI marking, container for
multiple bearers, supporting multiple QoS flows
- F1-U tunnels: 1 per DRB without QFI marking
- SDAP ownership of QoS: move QoS management to be fully owned by
SDAP
4. QoS Enhancements
- Dynamic5QI support: Full support for Dynamic5QI with packet delay
budget and packet error rate
- GBR QoS flows: Support for Guaranteed Bit Rate QoS flows with
GFBR/MFBR parameters
- DRB QoS aggregation: DRB-level QoS computed from all mapped QoS
flows using ARP priority (not 5QI priority)
- QoS priority level refactoring: Proper type definitions per 3GPP
TS 23.501 (QoS Priority Level: 1-127, ARP Priority Level: 1-15)
Technical Changes
RRC Layer
- Refactored `nr_rrc_add_bearers()` to support intelligent QoS-to-DRB
mapping
- Added `nr_rrc_update_qos()` for QoS flow add/modify with automatic DRB
assignment
- Implemented `nr_rrc_update_pdusession()` for QoS flow release and DRB
cleanup
- Consolidated F1 UE Context Modification Request handling
- Simplified PDU status tracking by removing intermediate states
- Added QoS flow and DRB removal utilities
- Updated RRC bearers tests with comprehensive multi-QoS testing
- Adapted `nr-cuup-load-test.c` to new GTP design
NGAP Layer
- Extended PDU Session Resource Modify Request Transfer with QoS
add/modify/release lists
- Added proper type definitions (`pdusession_mod_req_transfer_t`,
`qos_flow_to_release_t`)
- Fixed NGAP PDU Session Modify transfer encoding
GTP-U Layer
- Refactored tunnel creation API: scalar fields instead of arrays
- Split tunnel creation into `n3_gtpu_create()` and
`f1_drb_gtpu_create()`
- Added bearer-to-QFI mapping structure (`gtpv1u_rb_t`)
- Implemented QFI de-duplication and one-to-one QFI-to-bearer mapping
- Reduced inter-dependencies between LTE and NR
SDAP Layer
- Fixed default DRB tracking: Only one default DRB per SDAP entity per
PDU session (TS 37.324)
- Set default DRB to first DRB added when creating bearers
F1AP Layer
- Added GBR QoS Flow Information IE handling in CU
- Implemented DRB QoS aggregation from multiple QoS flows
- Extended F1AP test cases to support multiple QoS flows
Code Quality Improvements
- Improved error handling throughout the stack
- Enhanced logging and debugging capabilities
- Added comprehensive unit tests for multi-QoS scenarios
- Improved type safety and validation
Testing
The code was validated with Open5gs v2.7.6, OAI CN5G and COTS UE.
How to reproduce with Open5gs:
1. Start Open5gs
2. From the Open5gs web UI: add multiple QFIs to the same DNN.
3. Restart Open5gs
4. Run gNB and UE
The user will see the following:
1. QoS flows arrive via NGAP PDU Session Setup/Modify requests, each
with a QFI and 5QI.
2. The gNB assigns each flow to a DRB, creating a new DRB or reusing an
existing one based on 5QI compatibility (compatible flows, i.e. same
5QI characteristics, share a DRB)
3. At the SDAP layer, packets are tagged with QFI headers; at the GTP-U
layer, uplink packets include QFI in the PDU Session Container for
core network mapping.
Documentation
- Added comprehensive QoS flows handling documentation with 3GPP
standards references
- Updated PDU Session Modify sequence diagrams
Note
* This implementation aligns with:
- 3GPP TS 23.501 (QoS framework)
- 3GPP TS 38.413 (NGAP)
- 3GPP TS 37.324 (SDAP)
- 3GPP TS 38.463 (F1AP)
- 3GPP TS 29.281 (GTP-U)
- 3GPP TS 38.331 (RRC)
* Multi-QoS and PDU Session Modify are both added to this MR since QoS
flows update is triggered by PDU Session Modify in some scenarios
(e.g. with Open5gs, used for validation).
* Core functional changes introduced by commits with prefix "QoS
Handling" or "PDU Session Modify"
* This MR replaces the old !2703.
* This MR adopts relevant CU changes from !2836, namely:
* Adds new shared QoS types
* Add standardized 5QI table and helper
* Dynamic5QI support + validation
* Computation of DRB QoS (aggregate QoS) and priority/GBR
* F1AP DRB-level QoS
* Closes#541 (5QI validation)
* Closes#1075 (Optional NAS-PDU in PDU Session Setup Request)
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Reviewed-by: Rakesh Mundlamuri <rakesh.mundlamuri@openairinterface.org>
- new configuration for PLMN 00105, 40MHz and 100 MHz added on AmariUE
- helm charts for OC CN with PLMN 00105 added to cacofonix, new CN added
to ci_infra.yaml, IP address range of the new CN: 172.21.6.116-118
- test with 1 AmariUE (to be extended in future MR), with SISO
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Running container in privileged mode and host network mode is needed
for running fhi72 gNB with M-plane
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Running container in privileged mode and host network mode is needed
for running fhi72 gNB with M-plane
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
- Build and install libyang (v2.1.111) and libnetconf2 (v2.1.37) from source.
- Build ran-build-fhi72 image with M-plane enabled
- Copy YANG models required for M-plane operation into the container.
- Update gNB Dockerfile to work without M-plane
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
After attach, run UL ping so N3 UL traffic hits the UPF
before the first DL ping. That triggers UL PDR classification
in the UPF and avoids DL GTP-U using the default QFI.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Expand the 25PRB RFSim CI scenario to validate two PDU sessions with
PCF-driven QoS rules and deterministic per-flow traffic ports. Update
iperf execution to use `-B`/`-p` from test args.
Changes:
- Update `container_5g_rfsim_u0_25prb.xml` to add dual-session
validation steps, routing setup, and multi-flow UDP iperf
for UL/DL with explicit bind/port arguments.
- Change `cls_oaicitest.py` to parse bind/port from
`iperf_args`, and return a clear error when the iperf client exits non-zero.
- Update `nrue.uicc.2pdu.conf` to configure
session 2 on `openairinterface` with distinct `nssai_sd` values.
- Extend `5g_rfsimulator/mini_nonrf_config.yaml`
with PCF endpoints, dual slices, dual DNN entries, and PCF policy paths,
and disable local PCC rules in SMF.
- Update `5g_rfsimulator_u0_25prb/docker-compose.yaml`
to add the `oai-pcf` service, mount policy directories, and add ext-dn
route for the second UE subnet.
- Add PCF policy data files for this scenario, in :
`policies/policy_decisions/policy_decision.yaml`
`policies/pcc_rules/pcc_rules.yaml`
`policies/qos_data/qos_data.yaml`
About the ci-scripts:
Co-authored-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
fix: issue 1054 - Config: Creating New Array members via command line arguments
Before this change, if you wanted to use --rfsimulator.[0].serveraddr
server on the command line but if you had no rfsimulator block in your
config file, it would just ignore it and print:
[CONFIG] unknown option: --rfsimulator.[0].serveraddr
[CONFIG] unknown option: server
This is because the config module only processes array members that
already exist in the config file. If the array is empty, the command
args are never checked.
What I changed is, in config_getlist() in config_userapi.c, after it
finishes processing existing array parameters, it checks whether a new
parameter is needed. If so, it matches with the list of parameters
first, then the highest index is found for that parameter using the
strtol,
"--rfsimulator.[0].serveraddr",
"--rfsimulator.[2].serveraddr",
What I changed is, in config_getlist() in config_userapi.c, after it
finishes processing existing array parameters, it checks whether a new
parameter is needed. If so, it matches with the list of parameters
first, then the highest index is found for that parameter using the
strtol,
"--rfsimulator.[0].serveraddr",
"--rfsimulator.[2].serveraddr",
"--rfsimulator.[4].serverport",
"--rfsimulator.[1].serveraddr",
It sets the index as 4, allocates 4 slots, memory is managed via
standard functions then it fills the gap of all the indices.
this closes#1054
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Reviewed-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
bit_len / 8 + 1 overcounts by 1 when bit_len is an exact multiple of 8.
Replace with (bit_len + 7) / 8 across all pack/unpack sites for PUSCH
and PUCCH 2/3/4 SR/HARQ/CSI payloads, and in the utility functions
(eq, copy, size calculator, dump) and unit test fill functions.
Fixes UCI.indication unpack failure against cuBB when CSI-1 report
is 8 bits.
Signed-off-by: Gabriele Gemmi <g.gemmi@northeastern.edu>
nr-cuup-load-test: avoid unaligned memory access
Use memcpy() instead of unaligned pointer access
tests/nr-cuup/nr-cuup-load-test.c:431:16: runtime error: store to misaligned address 0x756d02eca1a2 for type 'uint32_t', which requires 4 byte alignment
tests/nr-cuup/nr-cuup-load-test.c:267:14: runtime error: load of misaligned address 0x756d095edcf6 for type 'uint32_t', which requires 4 byte alignment
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Reviewed-by: Rakesh Mundlamuri <rakesh.mundlamuri@openairinterface.org>
Use memcpy() instead of unaligned pointer access
tests/nr-cuup/nr-cuup-load-test.c:431:16: runtime error: store to misaligned address 0x756d02eca1a2 for type 'uint32_t', which requires 4 byte alignment
tests/nr-cuup/nr-cuup-load-test.c:267:14: runtime error: load of misaligned address 0x756d095edcf6 for type 'uint32_t', which requires 4 byte alignment
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
A RU can have multiple interfaces but for the M-plane purposes,
we need the ethernet interface.
Signed-off-by: Teodora Vladić <teodora.vladic@openairinterface.org>
Fix broken nr-cu-nrppa-test simulator and nr-ue-nas-simualtor
This MR fixes the simulators broken due to the changes from !3993 and
!4010. The changes were related to storing service network name in nas
and routing indicator in uicc
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Allow control signal level at input of OFDM modulator
This simple fix removes an error floor in nr_dlsim tests with 256QAM. It
adds -Q to nr_dlsim to control gNB TX amplitude (like tx_backoff_dB in
gNB RU section). With
./nr_dlsim -R273 -b273 -s30 -e27 -I10 -q1 -n100 -Q30
has 0 errors. The default in nr_dlsim remains -36 dBFs.
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Verify that a given cell's assoc_id (i.e., it's "host DU") is the
assoc_id of the currently treated DU to avoid treating a config update
of another (potentially malicious) DU.
Closes: #1081
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Issue:
With a commercial UE, NGAP traces showed the PDU Session Resource Modify
Response carrying a QoSFlowAddOrModifyResponseList that did not match the
preceding Modify Request: the gNB listed every QoS flow already stored on the
PDU session instead of only the flows present in QoS Flow Add or Modify Request
List for that modify.
e.g. QoSFlowAddOrModifyResponseList including QFI 1,2
QoSFlowAddOrModifyRequestList QFI 2
AMF ErrorIndication with semantic_error after modify
That breaks the intended semantics in TS 38.413, which
expects QoSFlowAddOrModifyResponseList to carry the QFIs from this
procedure’s QoS Flow Add or Modify Request List only.
Changes:
Add a per-flow ngap_pending flag set in nr_rrc_update_qos when a request
item is applied, clear it before each new modify, and build the response
from marked flows only.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
* Extend delay_transaction() and rrc_delay_transaction() to support NGAP_PDUSESSION_MODIFY_REQ
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
This commit extends PDU Session Modify handling with E1AP Bearer Context
Modification integration for QoS flow add/modify/release and DRB lifecycle
updates (setup, modification, removal).
E1AP Bearer Context Modification - DRB Setup Support:
- Extend CU-UP handler (e1_bearer_context_modif) to process DRBs to setup/to remove:
create F1-U tunnels, create/release PDCP-SDAP resources, and update QoS flow mappings
- Extend CU-CP response handler to process DRBs to setup: save F1-U tunnel info,
mark PDU sessions for RRC reconfiguration, and trigger F1 UE Context
Modification Request with both setup and release DRBs
- Update rrc_gNB_process_e1_bearer_context_modif_resp to collect DRBs to
setup/release from E1 response, send F1 UE Context Modification when needed,
and otherwise trigger direct RRC reconfiguration or NGAP modify response.
- Populate the E1AP Bearer Context Modification request with DRB-To-Setup and
DRB-To-Modify lists derived from QoS flow processing. For CP->UP E1 Bearer
Context Modification, Flow Mapping Information in DRB-To-Modify carries
the QoS Flow QoS Parameters List for that DRB: per TS 38.463, when present,
CU-UP replaces the previous mapping for that DRB, and this behavior is now enforced.
RRC PDU Session Modify - QoS and DRB Management:
- Add nr_rrc_apply_qos_add_modify() to process QoS add/modify and map flows to
existing or new DRBs
- Add nr_rrc_apply_qos_release() and nr_rrc_apply_pdusession_modify() to
process QoS release, build E1 DRB setup/modify/remove lists, and prepare
bearer-context modification.
- Refactor nr_rrc_update_qos() processing for QoS add/modify,
with DRB mapping to existing or new DRBs through the modify path helpers
- Extend nr_rrc_update_pdusession() with helpers for QoS
add/modify/release, building E1 DRB modify/setup/remove lists, and
sending bearer-context modification.
- Integrate E1 Bearer Context Modification into PDU Session Modify flow to
propagate DRB changes to CU-UP
- Update default DRB in SDAP configuration after QoS changes
- Add `nr_sdap_entity_update_qos_flows` to replace DRB flow
mappings from E1 flow information and clear stale SDAP role/mapping
state when QFIs are removed.
Code Refactoring:
- Add find_or_add_pdu_session_mod() to create/reuse session entries
in the E1 Bearer Context Modification request while building message.
- Add nr_rrc_send_e1_after_qos_update() to detect DRBs left without mapped
QoS flows, remove them from UE state, and append them to E1 DRBs-to-remove.
- Use rrc_gNB_generate_dedicatedRRCReconfiguration instead of
rrc_gNB_modify_dedicatedRRCReconfiguration, drop the old function
End-to-End PDU Session Modify Flow:
1. AMF -> CU-CP: NGAP PDU Session Resource Modify Request (QoS add/modify/release)
2. CU-CP (RRC): Process QoS flows -> map to DRBs (reuse existing or create new) ->
populate E1AP Bearer Context Modification Request (DRBs to setup/modify/remove)
3. CU-CP -> CU-UP: E1AP Bearer Context Modification Request
4. CU-UP: Create F1-U tunnels for new DRBs -> create/release PDCP-SDAP
resources -> update DRB/QFI mapping information
5. CU-UP -> CU-CP: E1AP Bearer Context Modification Response (F1-U tunnel info)
6. CU-CP: If DRB setup/release exists, send F1 UE Context Modification Request
7. CU-CP: Else if QoS/NAS requires it, send direct RRC Reconfiguration
8. CU-CP: Else complete modify directly with NGAP PDU Session Resource Modify Response
9. UE -> CU-CP: RRC Reconfiguration Complete
10. CU-CP -> AMF: NGAP PDU Session Resource Modify Response
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
This commit extends the PDU Session Resource Modify Request handling (within
PDU Session Modify) to fully support QoS Flow add/modify and release operations
(3GPP TS 38.413 section 9.3.4.3) via the Transfer IE. This is propagated to
RRC which performs PDU Session update, which occurs upon PDU Session Modify.
Refactoring was necessary since type `pdusession_transfer_t` and
`pdusession_resource_item_t` both for setup, were inaccurately used for the modify procedure.
The implementation adds proper type definitions, decoding logic,
and error handling for QoS flow management during PDU session modification transfer,
namely:
- Adds QoS add/modify and release lists to the NGAP Modify Request Transfer type
- Introduces QoS Flow With Cause IE
- Decode new IEs and propagate QoS changes to RRC session state
NGAP PDU Session Modify Request Transfer:
- Add qos_flow_to_release_t structure to represent QoS Flow to Release Items IE
with QFI and release cause (per 3GPP TS 38.413 section 9.3.1.13)
- Introduce pdusession_mod_req_transfer_t structure to properly represent
PDU Session Resource Modify Request Transfer IEs:
* QoS Flow Add or Modify Request List (mandatory)
* QoS Flow to Release List (optional)
- Add pdusession_resource_mod_item_t structure for PDU Session Resource
Modify Request Items, replacing pdusession_resource_item_t, which is for setup
- Update ngap_pdusession_modify_req_t to use the new type-specific structure
- Refactor decodePDUSessionResourceModify() to return
pdusession_mod_req_transfer_t instead of pdusession_transfer_t
- Implement proper decoding of QosFlowAddOrModifyRequestList IE
- Add decoding support for QosFlowToReleaseList (QosFlowListWithCause) IE:
* Extract QFI and cause for each QoS flow to be released
- Improve error handling throughout
ngap_msg_includes.h:
- Add includes for NGAP_QosFlowListWithCause.h and
NGAP_QosFlowWithCauseItem.h to support QoS flow release decoding
NGAP/RRC:
- Update nr_rrc_update_pdusession() function signature to accept
pdusession_resource_mod_item_t instead of pdusession_resource_item_t
- Remove references to unnecessary pdu_session_type and n3_incoming
fields that are not part of the Modify Request Transfer structure
- Update QoS flow update logic to use nb_qos_to_add_modify and
qos_to_add_modify fields from the new transfer structure
This implementation aligns NGAP with 3GPP TS 38.413 specifications
and provides a foundation for handling QoS flow modifications and releases
during PDU session resource modification procedures.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
- Update F1AP test cases to support multiple QoS flows
- Extend RRC bearers test with comprehensive multi-QoS testing
- Extend PDU sessions test to 2 PDU sessions per test
- Introduce template helpers to minimize duplicated code
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Refactor GTP-U tunnel and send APIs so QFI is handled when sending packets,
not stored in tunnel creation state. Update SDAP and CU-UP integration to
use PDU-session keyed N3 mappings and explicit QFI-marked sends.
This commit clarifies layering ownership: GTP-U stays transport-only (TEID
lookup, decapsulation, extension parsing, callback dispatch), while SDAP
owns QoS semantics (QFI handling, QoS-flow-to-DRB policy, default DRB behavior,
and mapping updates); GTP-U does not perform runtime QFI-to-DRB mapping or
synthesize QFI.
Changes:
- remove `outgoing_qfi` from `gtpv1u_gnb_create_tunnel_req_t` and stop storing
QFI as tunnel creation metadata; `newGtpuCreateTunnel(...)` now carries only
transport/tunnel identity parameters (incoming_bearer_id, outgoing_bearer_id,
outgoing_teid, remote address, callbacks)
- add `gtpv1uSendDirectWithQFI()` and pass QFI into `_gtpv1uSendDirect`
to build UL PDU Session Container extensions
- shift QFI handling from tunnel provisioning to per-packet TX APIs: QFI is passed
explicitly only when sending (`gtpv1uSendDirectWithQFI(...)`) and is absent from
non-SDAP/F1 sends (`gtpv1uSendDirect(...)`)
- align N3 tunnel request semantics with session-level keys by setting incoming_rb_id
to PDU session ID on N3 paths, while F1 paths keep DRB ID
- keep `gtpv1uSendDirect()` and `gtpv1uSendDirectWithNRUSeqNum()` on
`NO_QFI`, and enforce non-SDAP RX callback path only when QFI is absent
- update `nr_sdap_rx_entity` to extract/validate QFI from SDAP UL headers,
send UL data with `gtpv1uSendDirectWithQFI`, and use non-QFI send when
SDAP header is disabled
- add disabled-SDAP safety checks in SDAP entity setup/mapping to enforce
single-DRB and single-flow constraints per PDU session
- extend `test_gtp.cpp` with a `multi_qos_flows` scenario and QFI-aware send calls
- update `nr-cuup-load-test.c` bearer setup fields and tunnel creation calls
to match the new API
- update tests/nr-cuup/nr-cuup-load-test.c to set explicit PDU session and
QoS/SDAP parameters (sessionType, qosFlows[0], SDAP header flags), and to
migrate both N3 and F1 tunnel creation calls to the new newGtpuCreateTunnel(...)
signature (without outgoing_qfi)
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
GBR information is optional in F1AP and is only present for GBR flows
(5QI < 5 for NonDynamic5QI, or Dynamic5QI flows with GBR characteristics).
Changes:
- Add optional gbr_qos_flow_information field to f1ap_qos_flow_param_t
structure to propagate NGAP GBR QoS parameters to the DU, for scheduling
resource allocation via nr_rrc_get_f1_qos_flow_param.
- Add GBR QoS flow information IE enc/dec in F1AP lib:
- update encode_qos_flow_param() and decode_qos_flow_param()
- update cp/eq/free
- add GBR tests to f1ap_lib_test.c
This commit is a refactoring of commit 398ae02ab9 from !2836
Co-authored-by: Sriharsha Korada <sriharsha.korada@iis.fraunhofer.de>
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Implement GBR (Guaranteed Bit Rate) QoS flow information extraction from NGAP.
This enables handling in CU of GBR QoS flows
(e.g., voice, video) that require guaranteed and maximum bit rates.
Changes:
- Define qos_bitrate_t structure to encapsulate GFBR and MFBR
- Define gbr_qos_flow_information_t structure for GBR QoS parameters
- Add optional gbr_qos_flow_information field to pdusession_level_qos_parameter_t
- Extract GBR information from NGAP_QosFlowLevelQosParameters in fill_qos()
- Add NGAP_GBR-QosInformation.h include to ngap_msg_includes.h
GBR information is optional in NGAP and is only present for GBR flows
(5QI < 5 for NonDynamic5QI, or Dynamic5QI flows with GBR characteristics).
Bit rates are in kbps.
This commit is a refactoring of commit 398ae02ab9 from !2836
Co-authored-by: Sriharsha Korada <sriharsha.korada@iis.fraunhofer.de>
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Model non-dynamic vs dynamic 5QI characteristics explicitly and propagate the
new layout through NGAP decode and RRC bearer/QoS handling.
Changes:
- Define `non_dynamic_5qi_t`/`dynamic_5qi_t`, PER/PDB bounds, and embed a
`qos_characteristics` union in `pdusession_level_qos_parameter_t`
- Populate the new QoS structures in `fill_qos()`, including optional
allocations for Dynamic 5QI `fiveQI` and NonDynamic `priorityLevelQos`
- Map QoS params to F1AP with `nr_rrc_get_f1_qos_flow_param()` and add range
validation for dynamic priority/PDB/PER and non-dynamic 5QI
- Populate E1 QoS characteristics from the new layout and update QoS modify
handling to manage optional pointer fields (`openair2/RRC/NR/rrc_gNB_NGAP.c`)
- Derive a numeric 5QI via `get_qos_fiveqi()`, handle missing-5QI dynamic flows
conservatively, and extend dedicated-DRB decisions to fall back to dynamic
characteristics
- Add a 5QI range assert in F1AP QoS encoding and extend bearer tests with a
Dynamic 5QI flow
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
DRB QoS IE (mandatory in DRB-Information IE) represents the DRB level QoS,
which shall be computed from multiple QoS flows mapped to the DRB instead
of using only the first QoS flow.
ARP is for admission control/preemption (1-15, 1 = highest priority) and
DRB-level QoS selection should use ARP for admission control decisions.
Changes:
- Use ARP priority (not 5QI priority) for selection (admission control decision)
- Iterate through all flows to find the flow with highest ARP priority (lowest ARP priority_level value
- Add fill_f1_drb_qos to return DRB QoS by value, i.e. QoS characteristics (5QI, priority, delay budget, error rate)
- Replace 'drb.nr.drb_qos = drb.nr.flows[0].param' with proper aggregation
Example: DRB with Flow1 (ARP=10) and Flow2 (ARP=5)
- Old: Would incorrectly use Flow1's QoS
- New: Correctly uses Flow2 (ARP=5) which has higher priority
This commit is a refactoring of commit 398ae02ab9 from !2836
Co-authored-by: Sriharsha Korada <sriharsha.korada@iis.fraunhofer.de>
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
According to 3GPP TS 37.324, there shall be only one default DRB per
SDAP entity (per PDU session). The previous implementation incorrectly
marked all DRBs as default, violating this requirement.
Changes:
- Add default_drb field to nr_sdap_configuration_t to track the default
DRB ID per PDU session
- Arbitrary set default DRB to the first DRB added when creating bearers in a
PDU session
- Update nr_rrc_build_sdap_config_ie() to accept defaultDRB (bool) parameter
instead of hardcoding true
- Use tracked default_drb value when building RRC SDAP Config IE
- Use tracked default_drb value when building E1AP DRB setup structure
Also:
- Fix include style in nr_sdap_configuration.h (<stdbool.h> instead of
"stdbool.h")
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Move 5QI validation from RRC reconfiguration message generation to
where QoS flows are actually added/updated, ensuring validation
happens early in the process.
Changes:
- Remove redundant 5QI validation from rrc_gNB_modify_dedicatedRRCReconfiguration():
that was checking values right before RRC message generation
- Add 5QI validation in add_qos() to reject unsupported 5QI values
during PDU session setup
- Add 5QI validation in nr_rrc_update_qos to skip unsupported 5QI
values during PDU session modify (continues to next flow)
- Add is_5qi_supported() function in rrc_gNB_radio_bearers.c:
validates standardized 5QI values (1-9, 65-90) per 3GPP TS 23.501
Table 5.7.4-1 and checks against the classification map
Also, remove remaining limit to 1 QoS flow per DRB.
Closes#541
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Implement QoS flow multiplexing logic that optimizes DRB usage by classifying
5QI values per 3GPP TS 23.501 Table 5.7.4-1 and applying resource-type-aware
multiplexing limits. The changes are adopted in nr_rrc_add_bearers, which
is the RRC function responsible for adding PDU Sessions and DRBs in RRC.
Key features:
- Classify 5QI by resource type (DC-GBR, GBR, Non-GBR)
- Reuse existing DRBs when QoS characteristics are compatible
- Dedicated DRBs for DC-GBR (5QI 82-90) and high-priority services
- Per-type multiplexing limits: DC-GBR=1, GBR=2, Non-GBR=5
- Aggregate cap: max 5 flows per DRB
Implementation:
- nr_rrc_get_5qi_resource_type():
Maps 5QI values to resource types using lookup table.
DC-GBR: 5QI 82-90, GBR: 5QI 1-4,65-67,71-76, Non-GBR: 5QI 5-11,69-70,79-80.
Unknown 5QIs default to Non-GBR with warning.
- nr_rrc_qos_dedicated_drb():
Identifies 5QIs requiring isolated DRBs (high priority, low-PER).
Includes: DC-GBR: 5QI 82-90, 5QI 4,6-10 (video), 5QI 70 (mission-critical),
5QI 71-73 (live streaming), 5QI 80 (low-latency).
- nr_rrc_count_qos_flows_by_type():
Counts QoS flows mapped to a specific DRB, grouped by resource type.
Used to check capacity and enforce multiplexing limits.
- nr_rrc_find_suitable_drb_for_qos():
Searches existing DRBs in the same PDU session for available capacity.
Checks resource type compatibility, per-type limits, and aggregate cap.
Returns DRB ID if suitable, -1 if new DRB needed.
DC-GBR flows always return -1 (require dedicated DRB).
- nr_rrc_assign_drb_to_qos_flow(), which either reuses a DRB
selected by nr_rrc_find_suitable_drb_for_qos() or creates a new DRB via
nr_rrc_add_drb, assigns its ID to the QoS flow
Note: this commit is multi-QoS ready.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
The new bearer context setup logic is looping through the PDU sessions
to be setup list first and then through the DRB to be setup list.
The function has still room for improvement since e1_bearer_context_setup
is calling a getter for NR_DRB_ToAddModList_t which has another nested
DRB loop. The goal of this commit is to further simplify the logic
by minimizing unnecessary nested loops, improving clarity and preparing
for reuse in Bearer Context Modification.
Main changes:
- Build DRB_ToAddMod list in the DRBs loop and centralize SDAP/PDCP configuration
- Add helpers to fill DRB to be setup and QoS flow handling, to improve organization
and enable reuse in bearer context modification procedures.
Implementation:
- Replace fill_DRB_configList_e1() with fill_rrc_drb_to_addmod()
* Build one NR_DRB_ToAddMod item per DRB from E1 DRB_nGRAN_to_setup
* Accumulate all DRBs into a single NR_DRB_ToAddModList_t per PDU session
- Call e1_add_bearers() once per PDU session with the aggregated list,
- Introduce fill_e1_qos_flows_setup() to populate DRB_nGRAN_setup_t
* Iterate E1AP QoS flows and copy QFIs into the E1 response
- Introduce fill_e1_drb_setup() to encapsulate DRB_nGRAN_setup_t filling
via fill_rrc_drb_to_addmod()
- Refactor e1_bearer_context_setup() to use new helper functions
Note: supports multiple QoS flows per DRB (TS 38.331 compliant)
* Move security parameters setup to caller scope
* Simplify DRB loop logic for better readability
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Refactor GTP-U tunnel creation to align for 3GPP architecture where N3
tunnels are created per PDU session (supporting multiple QoS flows) and
F1-U tunnels are created per DRB. This change simplifies the API and
prepares the codebase for supporting multiple DRBs and QoS flows per
PDU session.
This is the first step of a final design that will consist of:
- 1 GTP-U tunnel create call for each PDU session, each with a DRB mapping
- 1 GTP-U tunnel create call for each DRB (i.e. no QFI, no internal mapping)
API Changes:
- Convert gtpv1u_gnb_create_tunnel_req_t and gtpv1u_gnb_create_tunnel_resp_t
from array-based to scalar fields
* Remove num_tunnels field and array fields (outgoing_teid[], pdusession_id[], etc.)
* Use scalar fields: outgoing_teid, pdusession_id, incoming_rb_id, etc.
- Simplify gtpv1u_create_ngu_tunnel() to handle single tunnel per call
* Remove internal loop that processed multiple tunnels
* Call newGtpuCreateTunnel() once per invocation
* Update response handling to fill single tunnel response
Function Refactoring:
- Split generic drb_gtpu_create() into specialized functions:
* n3_gtpu_create(): Creates N3 tunnel (CU-UP to UPF/core network)
- callback assigned internally: nr_pdcp_data_req_drb, sdap_data_req
- One tunnel per PDU session
- QFI marking
- Supports multiple QoS flows per PDU session
* f1_drb_gtpu_create(): Creates F1-U tunnel (CU-UP to DU or DU side)
- callback assigned internally (cu_f1u_data_req or DURecvCb)
- One tunnel per DRB
- No QFI marking (QFI not used in F1-U)
- Each DRB can carry multiple QoS flows
- Update e1_bearer_context_setup() to loop over DRBs per PDU session
Each item in the PDU Session list contains a list of DRBs, thus
the function helper was adjusted to reflect that:
* Move DRB loop inside PDU session loop
* Create F1-U tunnel for each DRB individually
* Create single N3 tunnel per PDU session (outside DRB loop, with DRB mapping)
Also:
- Add comments to document and improve log messages for clarity
- Consistent error handling with AssertFatal checks
- Update NSA code path (rrc_gNB_nsa.c) to use new scalar API
Note: this commit is already taking into account the multi-QoS flows design
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
This header is pulled by both LTE and NR libraries, therefore is
advised to minimise cross dependencies in LTE/NR. With this change
the only include is common/platform_types.h
Also, remove redundant comments.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Apply QoS flow id as soon as the accept message is parsed, before interface
setup and before any code path that starts the per-session interface thread,
so the first SDUs are not sent with the default 0-initialized QFI 0.
Changes:
- In handle_pdu_session_accept, move set_qfi(...) to immediately before
interface setup.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Only build QoSFlowAddOrModifyResponseList when at least one QFI is present
and fail fast if PDUSessionResourceModifyResponseTransfer encoding does not
produce a valid buffer. This avoids sending malformed modify responses and
makes encoding failures explicit in the NGAP modify response path.
Changes:
- do QoS add/modify response list allocation when nb_of_qos_flow > 0
- add ASN.1 encode result validation
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Remove redundant allocation and duplicate add for AMF_UE_NGAP_ID (asn1cSequenceAdd
already allocates), fixing encoding failure and leak. Fix ASN_STRUCT_FREE_CONTENTS_ONLY
in the unsuccessful-transfer path to free the correct struct.
Changes:
- In ngap_gNB_pdusession_modify_resp(), for AMF_UE_NGAP_ID IE: remove redundant
calloc() and duplicate asn1cSeqAdd() after asn1cSequenceAdd (avoids uninitialized
list element, encoding assertion, and leak).
- In PDU Session Resource Modify Unsuccessful Transfer handling: pass
&pdusessionTransfer to ASN_STRUCT_FREE_CONTENTS_ONLY instead of the unused
NULL pointer pdusessionTransfer_p;
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Replace incorrect mathematical range check with explicit bounds
validation in nr_sdap_delete_entity(). The previous condition
(pdusession_id) * (pdusession_id - NR_MAX_NB_PDU_SESSIONS) > 0
was mathematically incorrect and could fail to properly validate
PDU session IDs.
PDU session ID validation now correctly rejects values outside
the valid range [0, NR_MAX_NB_PDU_SESSIONS]
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
This is a mandatory IE.
Replace hardcoded ActivityNotificationLevel value with configurable field
in e1ap_bearer_setup_req_t structure, enabling proper encoding/decoding
and testability of different notification levels. ActivityNotificationLevel
is now properly encoded from message structure instead of hardcoded value,
enabling different notification levels (DRB, PDU Session, UE) to be
specified per bearer setup request.
Changes:
- Add activity_notification_level_t enum with values: drb, pdu_session, ue
- Add anl field to e1ap_bearer_setup_req_s structure
- Replace hardcoded E1AP_ActivityNotificationLevel_pdu_session with
dynamic value from msg->anl in encode_E1_bearer_context_setup_request
- Add ActivityNotificationLevel IE dec/eq/cp
- Update test and RRC call sites to initialize anl field
- Add E1AP_ActivityNotificationLevel.h include to e1ap_lib_includes.h
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Replace fixed-size PDU session arrays with dynamically allocated
pointers in E1AP bearer context request/response types to reduce
memory footprint and improve scalability.
Memory usage is now proportional to actual PDU session count
instead of always allocating for maximum capacity.
Impact:
- Callers must allocate and free PDU session arrays; E1AP decode/cp
allocate, free_e1ap_context_setup_request/mod_request free them.
Major changes:
- Request/response types (e1ap_messages_types.h): pduSession, pduSessionMod,
pduSessionRem as pointers in setup/mod request and setup/modif response structs.
- E1AP lib: decode allocates with bounds check; cp/eq/free handle pointer members;
e1ap.c frees setup request after handling.
- CU-UP (cucp_cuup_handler): allocate resp.pduSession and modif.pduSessionMod.
- CU-CP side (cuup_cucp_direct, rrc_gNB, rrc_gNB_NGAP): allocate at E1 request
build and call free after send where needed; rrc_gNB_NGAP includes E1AP free decls.
- Tests (e1ap_lib_test, nr-cuup-load-test): allocate PDU session arrays in helpers.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
When building E1AP PDU Session Resource To Modify items, create
dRB_To_Modify_List_NG_RAN only once if there are DRBs to modify, and add
modify items to that list.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Decode paths for PDU Session Resource To Setup and To Setup/Modify must
accept multiple DRB list entries, aligned with multi-DRB RRC behaviour.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Fix wrong bound in the setup list loop: Bearer Context Modification
Response encoding must populate dRB_Setup_List_NG_RAN from
DRBnGRanSetupList[0..numDRBSetup), not numDRBModified.
In encode_E1_bearer_context_mod_response(), change the DRB Setup List
encoding loop from pdu->numDRBModified to pdu->numDRBSetup.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
QoS Priority Level range is 1-127, fits in uint8_t (3GPP TS 23.501 §5.7.3.3).
Refactor qos_priority field in pdusession_level_qos_parameter_t to use
qos_priority_level_t typedef (uint8_t) instead of uint64_t. Also,
improve documentation.
Changes:
- Add qos_priority_level_t typedef (uint8_t), more efficient than uint64_t
- Change pdusession_level_qos_parameter_t.qos_priority from uint64_t
to qos_priority_level_t
- Add MIN_QOS_PRIORITY_LEVEL (1) and MAX_QOS_PRIORITY_LEVEL (127)
defines for range checks
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Since qos_priority_t reprensents the ARP priority level, an integer
(1..15), this commit is renaming it to qos_arp_priority_level_t
typedef (uint8_t) for better clarity and cleaning up unnecessary enum definition.
Changes:
- Rename qos_priority_t to qos_arp_priority_level_t (uint8_t typedef)
for type safety and semantic meaning
- Remove enum with 15 explicit values (not needed, matches spec as integer)
- Add MIN_QOS_ARP_PRIORITY_LEVEL (1) and MAX_QOS_ARP_PRIORITY_LEVEL (15) defines
for bound checks, simpler and more efficient
- Update qos_arp_t struct to use new typedef
References:
- 3GPP TS 23.501 §5.7.2.2!
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Replace NGAP_MAX_PDU_SESSION and E1AP_MAX_NUM_PDU_SESSIONS with
shared NR_MAX_NB_PDU_SESSIONS constant. The value (256) is consistent
with both TS 38.331, TS 38.413 and TS 38.463
All protocol layers (NGAP, E1AP, RRC, SDAP) now use a single
shared constant for maximum PDU sessions per UE, ensuring
consistency across the codebase
E1AP_MAX_NUM_PDU_SESSIONS (was 4) is removed from e1ap_messages_types.h
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
- Remove PDU_SESSION_STATUS_DONE and PDU_SESSION_STATUS_REESTABLISHED
from enum and from get_pdusession_status_text().
- Add rrc_gNB_action_from_pdusession_status(): sets xid for all PDU
sessions and derives RRC transaction action from session status
(NEW, TOMODIFY, TORELEASE) or reestablishment. Add macro
ASSERT_PDU_ACTION_SINGLE to enforce at most one active status
(or reestablishment) per transaction.
- rrc_gNB_generate_dedicatedRRCReconfiguration: replace inline loop
and xid/action logic with a single call to the new helper; stop
transitioning NEW to DONE here.
- rrc_gNB_modify_dedicatedRRCReconfiguration: set xid at loop start;
bypass sessions with status != TOMODIFY (instead of >= DONE); remove
FAILED handling and DONE/xid assignments from loop; add xid to log.
- NGAP: INITIAL_CONTEXT_SETUP_RESP and PDUSESSION_SETUP_RESP check
NEW (not DONE) and set ESTABLISHED when reporting success;
PDUSESSION_MODIFY_REQ sets TOMODIFY (not NEW); PDUSESSION_MODIFY_RESP
checks TOMODIFY (not DONE), drops NEW/ESTABLISHED branch, improves
warning text; HANDOVER_REQUIRED considers only ESTABLISHED (drop DONE).
PDU sessions now move directly from NEW or TOMODIFY to ESTABLISHED in
the NGAP response handlers. One RRC reconfiguration corresponds to one
NGAP procedure (single active PDU session status per transaction).
rrc_gNB_modify_dedicatedRRCReconfiguration remains the separate
entry point for PDU Session Modify.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
PDU Session Modify procedures enable the teardown of a subset of DRBs
and, together with multi-QoS handling, of a subset of QoS flows.
Thus, it is necessary to introduce (1) `rm_qos` to remove a specific QFI
from the RRC list of QoS flows and (2) `nr_rrc_remove_drb_by_id`
to remove a specific DRB by ID, upon successful retrieval of the pointer
to its RRC list item.
- Add rm_qos() to remove QoS flows by QFI from PDU session QoS list
- Add nr_rrc_remove_drb_by_id() to remove DRBs by ID from UE DRB list
- Export find_drb_by_pdusession_id() as public functions for reuse
in PDU session modify procedures
These utilities enable QoS flow release and DRB cleanup operations
required for PDU Session Resource Modify Request handling.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
UE Context Modification Request can be triggered by either DRB setup
(from either PDU Session Setup or Modify) or modify (setup/release in PDU Session Modify).
The goal of this commit is to refactor the handling of UE Context Modification Request
messages by improving clarity and reducing code duplication.
Changes:
- Remove overlapping DRB release function `rrc_gNB_send_f1_drb_release_request` and replace with
unified `rrc_send_f1_ue_context_modification_request` that handles both DRB setup and release.
- Remove inefficient `rrc_gNB_generate_UeContextModificationRequest` and inline
its logic into callers using the new unified helper.
- Fix type safety in DRB release handling: change from `int *drb_to_release` to
`f1ap_drb_to_release_t *rel_drbs` to use proper struct type instead of raw int array.
- `rrc_send_f1_ue_context_modification_request` copies DRB arrays internally before freeing,
allowing safe use of stack-allocated arrays by callers.
- Update `rrc_gNB_process_e1_bearer_context_setup_resp` to use unified helper for DRB setup
when F1 context is already active.
- Update `rrc_gNB_process_e1_bearer_context_modif_resp` to DRB release in a single F1 UE
Context Modification Request call (will be later used for DRB setup, improving efficiency)
- Replace magic number `32` with `E1AP_MAX_NUM_DRBS` constant for better maintainability.
- Update E1AP procedures documentation to reflect unified function name.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
The current trigger_bearer_setup is mixing 2 functionalities: (1) setting up
RRC lists in the UE context (e.g. PDU Sessions, DRBs) (2) filling the E1AP
message to trigger Bearer Context Setup.
This commit is separating the two functionalities.
This is necessary to improve the readability of the code flow supporting
the setup of new bearers before the upcoming QoS-related changes.
* Introduce nr_rrc_add_bearers(rrc, UE, n, sessions) to populate UE context
lists (PDU Sessions, one DRB per session, one QoS per DRB).
* Early CU-UP rejection: apply early is_cuup_associated(rrc) checks at call
sites to fail fast before mutating UE context (this check is the reason
why the original function was a bool).
* trigger_bearer_setup goal is to fill Bearer Context setup message upon reception
of PDU sessions to setup, therefore it was changed to fill the bearer context setup
for all PDU session with status PDU_SESSION_STATUS_NEW.
Signature was changed to return void and read the lists from UE context.
The function is also deriving UP keys and building PDU Session and DRB items
to setup via helpers (e.g. fill_e1_pdusession_to_setup to fill PDU Session to
setup items).
* Enforce single DRB per PDU Session, will be updated in a later commit.
Impact
* Each function has now limited and self-conteined scope:
nr_rrc_add_bearers is responsible for update of RRC lists in the UE context.
trigger_bearer_setup is responsible for preparing the E1 Bearer Context message.
* E1 Bearer Context Setup construction is centralized and clearer.
* The flow is now following these steps:
1) receive NG request to setup PDU Sessions
2) check CUUP association first, early failure if check fails
3) add PDU Session and DRBs to UE context lists
4) trigger Bearer Context Setup Request
The same flow applies to PDU Sessions from the Initial Context Setup (initial_PDUs)
with the only difference that those are stored in a separate list (legacy behavior)
and to NG Handover Request processing.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Include NR_asn_constant.h in rrc_gNB_du.c so NR_maxCellIntra and NR_maxCellInter
are defined during compilation.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
- Common source in NR_PDCP_SRC and derive NR_PDCP_SRC_GNB (gNB) and
NR_PDCP_SRC_UE from it; UE no longer compiles cucp_cuup_handler,
cuup_cucp_if, cuup_cucp_direct, cuup_cucp_e1ap.
- NR_L2_SRC_UE uses NR_PDCP_SRC_UE so UE links only common PDCP sources.
- Add L2_NR compile definition PDCP_CUCP_CUUP; wrap nr_pdcp_e1_if_init
call in nr_pdcp_oai_api.c with #ifdef PDCP_CUCP_CUUP so UE does not
reference it.
UE build no longer depends on E1/CU-CP/CU-UP code or symbols; gNB
keeps full PDCP and E1 interface init.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
1. Refactor channel estimation and freq domain data extraction functions
to take rxdataF of only one symbol.
2. Split the PBCH and PSBCH decoding into two parts. Fisrt part is
called for every symbol and generates LLRs of each symbol. Second
part is called in the last PBCH/PSBCH symbol to decode and send the
payload to MAC.
3. In channel estimation, the loop around rx antennas is taken out to
make the code more modular.
Signed-off-by: Sakthivel Velumani <s.velumani@northeastern.edu>
The previous commit is only necessary because not everything is built in
unit tests...
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Remove unnecessary log
We already check for number of received samples above after receiving.
When aligned to the slot boundary for synchronization, this length of
the samples is no longer samples_per_slot. # Please enter a commit
message to explain why this merge is necessary,
We already check for number of received samples above after receiving.
When aligned to the slot boundary for synchronization, this length
of the samples is no longer samples_per_slot.
Signed-off-by: Rakesh Mundlamuri <rakesh.mundlamuri@openairinterface.org>
Validate signed MR commits and update contribution guidelines
This MR adds validation for signed merge request commits and updates the
contributing guidelines including the requirement for signing commits.
- The CI will warn in the Verify Guidelines stage if any commit in the
merge request is unsigned.
- Checks all commits in the MR source branch that are not present in
the target branch
- It then verifies if all these commits are signed
- Update contributing guidelines to include commit rules and signing
commits using git commit -s.
- The CI will also check if there are any merge commits and fail the
pipeline in that case.
fix (F1 Handover): do not trigger when no DRB is configured
Prevent triggering F1 handover for UEs without any DRB, to align with
3GPP TS 38.473 clause 8.3.1.2 and avoid initiating an invalid UE Context
Setup Request in the F1 handover flow.
Changes:
- Add a preliminary check in nr_rrc_trigger_f1_ho() to verify at least
one DRB exists in ue->drbs
- Abort F1 HO trigger early when no DRB is present, with warning
spsc_q: make compile on older compilers
While compiling the spsc_q unit tests on older compilers, some complain
with
/openairinterface5g/common/utils/ds/tests/test_spsc_q.cpp:11:44: error: use of deleted function ‘spsc_q::spsc_q(spsc_q&&)’
spsc_q_t rb = spsc_q_alloc(2, sizeof(int));
/openairinterface5g/common/utils/ds/spsc_q.h:19:16: error: use of deleted function ‘std::atomic<long unsigned int>::atomic(const std::atomic<long unsigned int>&)’
These compiles cannot copy the atomic. Change the API to avoid this
copy.
"Older" compiler here means g++-11/12.
- Add a new script to validate for signed commits
- Post a GitLab MR Warning comment listing the unsigned commit details
Signed-off-by: Shubhika Garg <shubhika.garg@openairinterface.org>
Prevent triggering F1 handover for UEs without any DRB, to align
with 3GPP TS 38.473 clause 8.3.1.2 and avoid initiating an invalid
UE Context Setup Request in the F1 handover flow.
Changes:
- Add a preliminary check in `nr_rrc_trigger_f1_ho()` to verify at
least one DRB exists in ue->drbs
- Abort F1 HO trigger early when no DRB is present, with warning
Add 200MHz DDDSU Liteon configuration file
Adding 200MHz DDDSU 2x2 Liteon configuration file. I think we should keep
only 200 MHz configuration for both FR2 RUs: Liteon and Microamp.
Achieved throughputs are DL: 980 Mbps UL 90 Mbps
While compiling the spsc_q unit tests on some compilers, some
complain with
/openairinterface5g/common/utils/ds/tests/test_spsc_q.cpp:11:44: error: use of deleted function ‘spsc_q::spsc_q(spsc_q&&)’
spsc_q_t rb = spsc_q_alloc(2, sizeof(int));
/openairinterface5g/common/utils/ds/spsc_q.h:19:16: error: use of deleted function ‘std::atomic<long unsigned int>::atomic(const std::atomic<long unsigned int>&)’
These compiles cannot copy the atomic. Change the API to avoid this
copy.
"Older" compiler here means g++-11/12.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Move the subframe scaling logic outside the PRACH slot loop to prevent the
subframe index from being incorrectly multiplied multiple times when there
are multiple PRACH slots per subframe.
Add AoA selection to vrtsim
Adds AoA as a selection parameter in vrtsim. Different UEs can be
configured at different arrival angles, emulating distinct spatial
locations, which can serve as an enabler for beamforming evaluation.
fix(nrLDPC_coding): Remove ldpc_xdma
Arguments for removing:
- There are no resources to maintain it. Including no machine with the
board.
- There is no clue that someone is actually using it.
- The library is not standard/cannot be generalized. It was designed for
a specific solution and cannot be used for another.
- The standard AAL (BBDev or other) should be privileged for LDPC offload
to a hardware accelerator.
Integration `2026.w17`
* !4054 Minor fixes to gNB/UE behavior in RFsim
* !4062 Minor fixes/cleanup in NGAP lib
* !4036 Fix CSI-RS estimation
* !4055 fix (RRC): do not trigger N2 HO when no active PDU sessions are present
* !3988 asn1c inside local tree
* !3762 L1 gNB type0 PDSCH
* !4069 ctest: fix tests when compiling with sanitizers, ignore build directories, fix spsc_q build
* !4067 Small compilation fixes
* !3444 7.2 FHI with XRAN K release
* !4061 T-Tracer & Data Recording v1.1: UL PHY trace modularization and recording enhancements
* !3975 ZMQ radio
* Increase PRACH queue capacity from 8 to 16
* !4059 CI: Various CI adjustments
Closes#1074 and #1073
See merge request oai/openairinterface5g!4063
CI: Various CI adjustments
- RAN-SA-FHI72-CN5G: activate/inactive carriers on VVDN RU - to check if
it improves reliability and stability of the pipeline
- RAN-SA-FHI72-CN5G: update CN with new IP range - avoid IP address
overlap with CN used in RAN-SA-AERIAL-XXX pipelines
- RAN-SA-B200-Module-SABOX-Container: test with deltaMCS in SC-FDMA test
case
- RAN-NSA-B200-Module-LTEBOX-Container: adjust PRACH DTX threshold to
reduce number of false RA attempts on eNB
- remove retx check in RAN-SA-Multi-Antenna-CN5G and RAN-SA-AERIAL-CN5G -
to avoid false CI failure caused by unsuccessful retx check of
interfering UE
- adjust RAN-SA-Multi-Antenna-CN5G and RAN-SA-AERIAL-CN5G configs to
improve UL throughput
Manual testing showed that lowering the RX gain reduces UL
retransmissions and improves overall UL throughput in the 100 MHz 2x2
test case of the SA-Multi-Antenna CN5G pipeline.
Add vvdn-activate-carriers.sh to verify RU PTP synchronization and
configuration. Activates carriers on VVDN RU by editing sysrepo running
datastore (INACTIVE->ACTIVE).
Add vvdn-inactive-carriers.sh to reverse the operation, setting all
carriers back to INACTIVE via sysrepocfg.
After the changes introduced in !3991, multiple PRACH PDUs can be
pushed from L2 to L1 before being processed. This leads to the PRACH
queues filling up and triggering "PRACH occ queue is full" issues on
the gNB.
This commit increases the queue size from 8 to 16, providing additional
buffering and preventing queue overflows as reported in #1072.
ZMQ radio
This is a zmq radio implementation that attempts to integrate NR UE with
the ocudu project.
OAI integration status:
This can currently be used to connect OAI gnb and OAI UE.
Compilation:
cmake --build . --target nr-softmodem nr-uesoftmodem ldpc params_libconfig zmq_radio
Running
- gNB command:
sudo ./nr-softmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf --gNBs.[0].min_rxtxtime 6 --device.name zmq_radio --zmq.[0].tx_channels tcp://127.0.0.1:4556 --zmq.[0].rx_channels tcp://127.0.0.1:4557
- UE command:
sudo ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --ssb 516 --device.name zmq_radio --zmq.[0].tx_channels tcp://127.0.0.1:4557 --zmq.[0].rx_channels tcp://127.0.0.1:4556
A new CI testcase for 2x2 configuration was added.
OCUDU integration status:
The OAI NR UE enters RRC Connected state.
For more details, please refer to the description of MR !3975.
T-Tracer & Data Recording v1.1: UL PHY trace modularization and recording
enhancements
Based on the plan with @schmidtr and @roux-cedric, we agreed to enhance
the data recording in two phases:
- Phase 1: Update Data Recording framework to get All internal Massive
Updates and enhancements through the whole framework public
- Phase2: Restructure T-Tracer Apps and remove all Mems in gNB and UE
Softmodems to Get data on T-tarcer Apps for all activated Messages
symbol-by-symbol, and related Meta-data, then do the aggregation on
the T-tracer App. So, there is No Memory Creation at all on the 5G NR
Stack.
This Merge Request is for Phase 1. We address the comments given in: !3632
Summary: Refactor T-Tracer instrumentation for UL PHY data capture and
improve the data recording application (v1.0 → v1.1). This MR extracts
inline T() macro calls into modular wrapper functions, adds Unix timestamp
fields to trace messages, implements a 4-state shared memory protocol for
gNB/UE tracers, and delivers an improved synchronized recording architecture
in Python.
Changes:
- T-Tracer: Modular UL PHY trace wrappers
- Add T_messages_creator.c/.h with 7 wrapper functions (log_ul_fd_dmrs,
log_ul_fd_chan_est_dmrs_pos, log_ul_fd_pusch_iq,
log_ul_fd_chan_est_dmrs_interpl, log_ul_payload_rx_bits,
log_ul_payload_tx_bits, log_ul_scrambled_tx_bits) and a static
log_ul_common() helper
- Register T_messages_creator.c in the T library CMake build
- Update T_messages.txt definitions: Remove string timestamps and get
time stamp directly from sending_time of T-macro.
- PHY: Replace inline T() calls with wrappers
- gNB (nr_ulsch_demodulation.c, nr_ul_channel_estimation.c,
phy_procedures_nr_gNB.c): replace inline T() calls with
T_messages_creator wrappers
- UE (nr_ulsch_coding.c, nr_ulsch_ue.c): replace inline T() calls with
log_ul_payload_tx_bits and log_ul_scrambled_tx_bits wrappers
- Remove deprecated log_tools.c/.h and its CMake reference
- T-Tracer gNB & UE apps: Enhancements
- Implement 4-state shared memory protocol (WAIT → CONFIG → RECORD → STOP)
for coordination with the data recording app
- Add event_trace_msg_ul_data struct with 27 UL metadata fields
- Refactor event loop to poll()-based with proper signal handling
- Separate project IDs (gNB=2335, UE=2336) and ftok paths for independent
shared memory segments
- Update shared memory sizing: Limit number of records to
NUM_MESSAGES_PER_SLOT=5, 100 slots
- Data Recording App v1.1
- Improved architecture with thread pool and barrier synchronization
- Frame/slot-based message grouping with per-slot validation
- atexit/signal-based cleanup for graceful shared memory detach
- Delete legacy data_recording_app_v1.0.py
- Library improvements
- config_interface.py: remove legacy YAML config reader, streamline to
JSON-only
- shared_memory_interface.py: new module for shared memory
attach/read/protocol
- wireless_parameters_mapper.py: new module for NR parameter mapping
- data_recording_messages_def.py: updated message definitions for
27-field struct
- sigmf_interface.py, sync_service.py, common_utils.py: remove unused
imports and dead code
- Documentation
- Update data_recording.md for v1.1 architecture and usage
Arguments for removing:
1. There are no resources to maintain it.
Including no machine with the board.
2. There is no clue that someone is actually using it.
3. AAL is privileged for LDPC offload to a hardware accelerator.
7.2 FHI with XRAN K release
Purpose:
Implement the O-RAN 7.2 Fronthaul interface using O-RAN Software Community's
XRAN release K. The new features of the release K can be leveraged and it is
compatible with DPDK version 24.11.4.
For more details please refer to the MR !3444 description.
- refactor timestamp handling
- Replace string-based SENDING_TIME with integer SEC/NSEC fields.
- Designed the shared memory protocol with a 4-state machine (STATE_WAIT=0, STATE_CONFIG=1, STATE_RECORD=2, STATE_STOP=3) for command/control between the recording app and the T-Tracer service
- Implemented two shared memory segments: one for reading commands (addr_rd) and one for writing captured data (addr_wr)
- Created event_trace_msg_ul_data struct mapping all 27 UL metadata fields (frame, slot, datetime, MCS, DMRS parameters, etc.) by name from the T-Tracer database
- Implemented setup_trace_msg_ul_data() using the G() macro to map field names to indices at startup
- Wrote the main event loop using poll() to avoid busy-waiting, with get_event() to receive T-Tracer events from the softmodem socket
Use log_ul_fd_dmrs, log_ul_fd_pusch_iq, log_ul_fd_chan_est_dmrs_pos,
log_ul_fd_chan_est_dmrs_interpl, log_ul_payload_rx_bits.
Remove redundant T_ACTIVE() guards and old timestamp formatting.
ctest: fix tests when compiling with sanitizers, ignore build directories,
fix spsc_q build
- Fix the directory to the current build directory to enable running with
sanitizers with ctest
- add build* to .gitignore to close#1074
- fix spsc_q compilation on non-C++23 compilers to close#1073
Before this change, if you wanted to use --rfsimulator.[0].serveraddr server
on the command line but if you had no rfsimulator block in your config file,
it would just ignore it and print:
[CONFIG] unknown option: --rfsimulator.[0].serveraddr
[CONFIG] unknown option: server
This is because the config module only processes array members that already
exist in the config file. If the array is empty, the command args are never checked.
What I changed is, in config_getlist() in config_userapi.c, after it finishes
processing existing array parameters, it checks whether a new parameter is given
in CLI.
The array number in the parameter(num) should match with the valid index of
that specific array
--cfg.[0].value 1 creates one array with one element
valid_index = num = 1
--cfg.[0].value 1 --cfg.[0].value 2 creates an array with two elements
if the previous CLI number repeats increments the "num"
valid_index = num = 2
--cfg.[1].value 1 --cfg.[0].value 2 error
valid_index < num, expects 0.
This commit was tested with MicroAmp FR2 with 2x2 MIMO,
where PRACH Rx antennas used is 1.
OAI L1 sets the number of PRACH antennas to be the same as for PUSCH.
Ideally, this should be properly fixed. In the meantime, I modified the
logging to debug to reduce noise.
Signed-off-by: Teodora Vladić <teodora.vladic@openairinterface.org>
First process PUSCH and then PRACH because the PUSCH callback
is called before PRACH callback.
Signed-off-by: Teodora Vladić <teodora.vladic@openairinterface.org>
* rename read_prach_data() to xran_rx_prach_read_slot()
* in F release, there is no PRACH queue so `frame` and `slot` are
passed as input; in K release, `frame` and `slot` are taken from the PRACH
queue
Note: since the PUSCH callback is the called before PRACH callback, this
commit is correct but the timing for PRACH processing is just a little
bit late. In previous state, PRACH processing was done inside the
function of PUSCH processing.
=> next commit will just reverse the order.
Signed-off-by: Teodora Vladić <teodora.vladic@openairinterface.org>
* Move PRACH callback in the oaioran.h/c since now used in K release.
* Reset the number of PRACH packets.
* Handle PRACH queue in the same manner as for PUSCH (95c8fa46).
Co-authored-by: Romain Beurdouche <romain.beurdouche@eurecom.fr>
Signed-off-by: Teodora Vladić <teodora.vladic@openairinterface.org>
K releases added RX error counters
This commits adds a printing of these counters with LOG_I
Signed-off-by: Teodora Vladić <teodora.vladic@openairinterface.org>
* Initialize leak detector
* Fill IO config field holding the number of mbufs to be allocated
* Allocate and fill `activeMUs` in the FH config
* Start timing source, worker thread and activate CCs upon starting the FH
* Fill `mu_number[0]` in FH config
* Invert trx_oran end and stop
* Set `neAxcUl`
* Delete duplicated oran_eth_state_t struct definition
* gxran_handle is an array which length is equal to the number of RUs
* Fill BBDev VF token in fh_init
Co-authored-by: Romain Beurdouche <romain.beurdouche@eurecom.fr>
Signed-off-by: Teodora Vladić <teodora.vladic@openairinterface.org>
stdatomic.h is a C++23 feature [1]. Thus, "older" compilers such as
gcc-11 (default in Ubuntu 22) do not know this, and can therefore not
correctly compile spsc_q. Fix this by alternatively including atomic for
C++.
Fixes errors such as
stdatomic.h:40:9: error: ‘_Atomic’ does not name a type
[1] https://en.cppreference.com/cpp/header/stdatomic.h
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
When compiling with sanitizers that require LD_LIBRARY_PATH (see
documentation), ctest could not drive tests as the executables did not
find shared objects. Fix the directory to the current build directory to
enable running with sanitizers.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
L1 gNB type0 PDSCH
PDSCH type0 allows frequency allocation via PRB bitmap (type1 is via
start and number of PRBs) allowing for non contiguous allocation in
frequency domain
Adapt the oran_fhlib_5g code to compile with xran K release.
Like previously E and F, uses preprocessor directives to separate codes for different xran releases.
Notes:
1. Release K of the FHI library supports many numerologies on one instance.
As of now the integration supports only one numerology.
2. Several arrays in the xran interface are indexed by the numerology.
It was ambiguous whether they were indexed by the actual numerology number or by the index of the relevant numerology within the numerology array.
They are actually indexed by the numerology number so that when one is using only numerlogy 1 for example, he should only use perMu[1], fftSize[1], ...
Signed-off-by: Teodora Vladić <teodora.vladic@openairinterface.org>
* create the xran forked repo as a cmake external project - easier to maintain and track the changes
we applied to the original repo
* add xran_DOWNLOAD option - clones and builds latest supported K release
* update the FHI README for K release
Signed-off-by: Teodora Vladić <teodora.vladic@openairinterface.org>
asn1c inside local tree
when /opt/asn1c/bin/asn1c does not exist, we download and use the right
asn1c version locally in the build tree. This simplifies dependancies
management
fix (RRC): do not trigger N2 HO when no active PDU sessions are present
Prevent triggering N2 handover when the UE has no active PDU session by
adding an early check in nr_rrc_trigger_n2_ho(), so we avoid building an
invalid HO Required. This aligns with 3GPP TS 38.413 (§9.2.3.1), where
HANDOVER REQUIRED carries a PDU Session Resource List with at least one
PDU Session Resource Item (range 1..maxnoofPDUSessions).
Relates to #1062 (closed)
Fix CSI-RS estimation
Changed channel estimates buffer to store RB 0 from start of buffer instead
of FFT shift offset. This simplifies channel estimation implementation. There
is also no need to add padding because each symbol/antenna start from offset
0 and/or OFDM symbol size always 32 byte aligned.
This also fixes buffer overflow detected when running UE with OCUDU gNB.
Changed channel estimates buffer to store RB 0 from start of buffer instead of
FFT shift offset. This simplifies channel estimation implementation. There is
also no need to add padding because each symbol/antenna start from offset 0
and/or OFDM symbol size always 32 byte aligned.
This also fixes buffer overflow detected when running UE with OCUDU gNB.
Make sure the radio libs are stopped before `end()` call. This allows
for a cleaner exit under most circumstances. Some libraries like zmq_radio
don't exit cleanly without it.
This commit introduces ZMQ-based radio library. Each pair of RX/TX antennas is
represented by a ZMQ REQ/REP socket pair which streams continuous IQ samples
from radio start until stop.
Usage:
Simplest configuration is to connect OAI NR UE to OAI GNB with the same number
of antennas - by inverting the RX and TX channels in ZMQ radio configuration the
gNBs TX is mapped to UEs RX antennas and vice versa.
Minor fixes/cleanup in NGAP lib
This MR is about a small NGAP-focused cleanup, mainly to reduce clang
warnings and remove dead code.
- Handle unused input parameters in ngap_gNB.c and ngap_gNB_handlers.c.
- Fix clang warning in common/utils/time_meas.h (extra semicolon).
- Removes unused NGAP trace/overload code and related references
(ngap_gNB_trace, ngap_gNB_overload).
Minor fixes to gNB/UE behavior in RFsim
While testing with RFsim thw following issues where found:
- gNB config: wrong PCI was printed during F1 Setup Request preparation
- UE PHY: missing rxdata allocation was causing a crash during intra-freq
measurements
Prevent triggering N2 handover when the UE has no active PDU session
by adding an early check in nr_rrc_trigger_n2_ho(), so we avoid building
an invalid HO Required. This aligns with 3GPP TS 38.413 (§9.2.3.1), where
HANDOVER REQUIRED carries a PDU Session Resource List with at least one
PDU Session Resource Item (range 1..maxnoofPDUSessions).
Retx check frequently fails in OTA pipelines, particularly for interfering
UEs attempting to connect to the cell. This leads to job failures in OTA
pipelines.
Remove the retx check from Multi-Antenna and Aerial pipelines to improve
CI stability and avoid false failures. In these pipelines, iperf test
already validates correct funtionality, making the retx check redundant.
Integration `2026.w16`
* !4040 fix: issue 911 - replace timer oneshot to periodic.
* !4041 Compilation without T: move to physims
* !4046 fix(record_db doc): correct the path for T_messages.txt and mention use of ninja/make
* !3994 Update CN5G images to release v2.2.0 and update traffic generator image
* !4024 Fix fill_srs_channel_matrix
* !3983 Add SIB 3,4 support, configurable SIB2 and refactor CU/DU SIB management
* !4030 Miscellaneous code improvements
* !4039 Verify consistency of CSI report in L2 instead of RRC
* !3991 L1 RX: use queues instead of arrays and linear search for PUCCH, PUSCH, SRS, PRACH
* !4011 CI: remove cppcheck, cleanup in build and license checks
* !4051 Fix EMA cold-start for noise and SNR/RSSI measurements
Closes#1063
See merge request oai/openairinterface5g!4048
Fix EMA cold-start for noise and SNR/RSSI measurements
Initialize n0_subband_power and power control avg_snr/avg_rssi directly
from the first measurement instead of starting from zero.
Starting from zero causes the EMA to converge slowly, leading to
underestimated noise power at gNB startup. This results in inflated SNR
estimates, which triggers UE uplink power ramp-up, antenna saturation,
and a positive feedback loop of increasing noise.
CI: remove cppcheck, cleanup in build and license checks
Remove cppcheck. For those who want to use it, it's now in tools/cppcheck/,
and likely easier to use locally.
Clean up some code for CI build and license check. Remove global variable.
We don't enforce cppcheck through the CI, although it's there since
years. It runs on Ubuntu 18/20, so it's old. For folks, it's likely not
discoverable on how to run it locally. Let's make a fresh start.
This removes cppcheck from all CI-related code. Instead, it adds it
under tools/cppcheck/, including documentation on how to run it locally,
bare-matel or in docker.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Fix a UE crash in the neighbor-measurement task setup by allocating the per-antenna
rxdata pointer array before indexing it in pbch_processing(), and freeing it in
nr_ue_meas_neighboring_cell() after measurements complete.
The crash is triggered by intra-frequency neighbor measurements.
L1 RX: use queues instead of arrays and linear search for PUCCH, PUSCH, SRS, PRACH
This MR is an attempt to reduce the time L1 RX searches in array for the
next job to process, and instead use a queue. This queue is a FIFO,
because the various jobs (FAPI messages) to process come in order, and
need to be processed in order. The MR (hopefully, to be measured)
reduces the amount of time spent searching for the next UE (because the
next job is always at the beginning of the queue), and should scale
better for many UEs.
It does the following:
- introduce two helper libraries for (1) Frame.Slot calculation (sfn_t),
already introduced in !3521 (merged) commit 3102068e, and (2) a ring
buffer with fixed size
- use sfn_t and ring buffer (gNB->pucch_queue) to remove the linear
array for PUCCH (gNB->pucch)
- use sfn_t and ring buffer (gNB->pusch_queue) for some PUSCH lookups.
Because we need to still store PUSCH contexts, gNB->pusch is still
there
- use sfn_t and ring buffer (gNB->srs_queue) to remove the linear array
for SRS (gNB->srs)
- use sfn_t and ring buffers (gNB->prach_ru_queue and
gNB->prach_l1rx_queue) to remove the linear array for PRACH
(gNB->prach_list)
- some minor cleanups, e.g., additional loops over the PUSCH array,
using const, using pointers instead of indices, etc
Miscellaneous code improvements
- A fix in a yaml config file as reported by @Abdo-Gaber
- proper positioning of static functions in a couple of gNB scheduler
files
- some effort to split NR from LTE code in compilation
- harmonization of macros for unused variables
Add SIB 3,4 support, configurable SIB2 and refactor CU/DU SIB management
This MR makes neighbour and inter-frequency configuration drive how
SIB2/SIB3/SIB4 are built and sent from CU to DUs. It standardizes SIB
payloads as byte_array_t with typed SIB IDs across RRC, F1AP and MAC,
reducing ad‑hoc buffer handling. Neighbour parsing, validation and
lookup are tightened.
Changes
- Minor refactor to gNB neighbour parsing and storage (shared PLMN
extraction, safer allocation, etc).
- Represent SIB containers uniformly as byte_array_t plus nr_sib_type_t,
and adapt F1AP, MAC and RRC users to the new container API.
- Make SIB2 cell-reselection information fully config-driven with
explicit bounds checking and SIB2 ASN.1 building from that config.
- Generate SIB3 intra-frequency neighbours from the per-cell neighbour
list and propagate them from CU to DU over F1, with MAC
decoding/attaching them to SystemInformation.
- Generate SIB4 inter-frequency neighbours from a new frequency_list
plus neighbour SIB3/SIB4 offsets, and propagate them from CU to DU
over F1, with MAC decoding/attaching them.
- Add basic ASN.1 round-trip tests for SIB2/SIB3/SIB4 and SIB4 range
checks, and update RRC docs to describe the neighbour/inter-frequency
configuration model.
Testing:
1. in gNB conf file:
cu_sibs = (2, 3, 4);
2. Update neighbour config file with SIB3/SIB4 conf:
(see documentation)
3. run gNB and UE as usual
---
Logs & configs: see MR on Gitlab
Use two queues for PRACH processing:
- prach_ru_queue: pass jobs from TX thread (scheduler) to RU thread. For
split 8, the RU thread itself handles PRACH processing; for split 7.2,
it is the library that is responsible for handling PRACH messages (see
oran_fh_if4p5_south_in())
- prach_l1rx_queue: after jobs have been handled in RU thread, use this
queue to pass jobs to the RX thread. There, preamble detection is
performed, and RACH.indication FAPI messages are filled if a preamble
has been detected.
Together, these queues replace a linear search in a global array that
has been modified by three threads at the same time. The design ensures
that access now is thread-safe, and with less overhead.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Expand RRC usage and handover documentation to describe the two-level
neighbour configuration layout, lookup-key semantics,
and config-time SIB4 grouping behaviour. Expand the example config
to include a `frequency_list` block and per-neighbour SIB3/SIB4
offset fields. Add SIB2 config example.
Update handover-tutorial.md to describe the same nested model and
note that F1 and N2 handover share the same serving-cell keyed
mapping.
Add documentation about SIB3/SIB4 and MeasGaps implementation
in OAI with stress on the shared neighbour configuration data model.
Update FEATURE_SET.
Use the spsc queue to pass jobs from TX thread (scheduler) to RX thread
(handling those jobs), reducing the amount spent searching for SRS jobs,
clarifying the design, and making it thread-safe.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
The structure in which was snr will be a "SRS job" in a follow-up
commit, so the snr parameter cannot be stored in there (and it is also
not necessary to do so, as it can be local to the function handling
nr_srs_rx_procedures()).
Correctly read SRS SNR through FAPI message in nr_ulsim. Switch to SRS
BEAMMANAGEMENT as only this message returns the actual SNR (unlike
CODEBOOK). Add asserts to check what is returned is valid data in the
sense of the test.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Remove useless logging defines. Move srs_estimated_channel_time to where
it is used. Prepare for the next commit by moving UL_INFO to earlier
inside phy_procedures_gNB_uespec_RX().
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
- calculation in float: should be enough precision (it'll go into 16bit
ints later...)
- avoid round: the lower 15bits will be shifted away, the rounding will
have no effect
- group some multiplications to avoid re-computation of the same
results.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
This means that as of this commit, the signal has to be permanently
regenerated. In fact, with the SRS queue to be introduced in a follow-up
commit, we don't have an easy way to cache the sequence generation, as
there is no "index" to which we could refer to (hence, caching would be
tricky).
Instead, the next commits further refactor this to reduce the time for
SRS sequence generation as well as the memory footprint.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Use the spsc queue to pass jobs from TX thread (scheduler) to RX thread
(handling those jobs), reducing the amount spent searching for PUSCH
jobs, clarifying the design, and making it thread-safe.
Since the PUSCH contexts have to be stored somewhere, there is still a
single iteration over all contexts. Removing that is left for future
work. Thus, this commit (together with previous commits) reduces the
number of iterations over all PUSCH entries, only iterating over the
actually requested PUSCH jobs. On the other hand, because only the RX
thread iterates over PUSCH contexts, it should be thread-safe.
Remove flag "handled", which is always 0.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Pass pointers directly instead of ULSCH_id. Put const where possible and
applicable.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Set the FAPI message in nr_ulschsim correctly in line with what
nr_ulsch_procedures() expected. Add an AssertFatal() to verify that the
assumed length of DMRS in the simulator and what is actually set in the
FAPI message matches. Finally, the internal nr_get_G() code (looping
over all PUSCH) does not double the DMRS because Nl == 3 || Nl == 4, so
harmonize in the simulator.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
It is pointless to iterate ulsch_to_decode to find the number of jobs if
we can simply pass it to the function.
Use an additional {} block to limit the amount of indentation.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Amidst all these unnecessary pointers, the pointer on
pusch_vars->ptrs_symbols is necessary to reset the PTRS number of
symbols. For clarity, remove this pointer and use
pusch_vars->ptrs_symbols directly.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Pass pointer to data. This necessitates to move delay from
NR_gNB_ULSCH_t (ULSCH data, including transport channels etc) to
NR_gNB_PUSCH (lower-PHY PUSCH data):
1. This allows to pass a single pointer to nr_pusch_channel_estimation()
2. To me, delay estimation seems to be a lower-PHY calculation, so it
fits better anyway.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Use the spsc queue to pass jobs from TX thread (scheduler) to RX thread
(handling those jobs), reducing the amount spent searching for PUCCH
jobs in an array, clarifying the design, and making it thread-safe.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Because it is SPSC, atomic variables are enough to synchronize the two
threads. Concretely put() is modified to ensure that read_idx is
"acquired" so that the read index has been written, including memory, by
the other thread. "Release" ensures that the write operation (including
the memory to the buffer) is written before it is visible to the other
thread in get() (which in turn "acquires" it). For more information, see
also [1].
The rest of the library has been simplified to work only with put() and
get(), reducing total code and the surface for possible bugs.
This (and the previous) version has been tested with the
threadSanitizer:
TSAN_OPTIONS=halt_on_error=1 ./common/utils/ds/tests/test_spsc_q_perf
On my machine, using Google Benchmark, I measure a considerable 5x speed
improvement:
$ /tmp/benchmark/tools/compare.py benchmarks pthread.json atomic.json
Comparing pthread.json to atomic.json
Benchmark Time CPU Time Old Time New CPU Old CPU New
--------------------------------------------------------------------------------------------------------------
BM_spsc_q/10 -0.8201 -0.0740 266779912 47989020 52387 48512
BM_spsc_q/16 -0.8301 -0.0520 249656592 42428540 51462 48784
BM_spsc_q/32 -0.8003 -0.0841 230248798 45972155 53841 49311
BM_spsc_q/64 -0.7995 -0.0506 210429791 42199674 50690 48124
BM_spsc_q/128 -0.7930 -0.1101 205212273 42483155 52745 46936
BM_spsc_q/160 -0.7880 -0.1663 216644738 45938247 53400 44518
OVERALL_GEOMEAN -0.8057 -0.0904 0 0 0 0
[1] https://en.cppreference.com/w/c/atomic/memory_order.html
Assisted-By: Claude:claude-sonnet-4-6
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Fix fill_srs_channel_matrix
Fix incorrect SRS subcarrier mapping in fill_srs_channel_matrix
The previous implementation of fill_srs_channel_matrix assumed an incorrect
SRS subcarrier mapping, leading to wrong indexing of the estimated channel
in frequency domain.
Update CN5G images to release v2.2.1 and update traffic generator image
- Updated all CN5G image tags to v2.2.1
- Updated image oaisoftwarealliance/trf-gen-cn5g to latest tag supporting
multi-architecture platforms See here
- Enabled iperf3 server in daemon mode in oai-ext-dn
- Handover: Since MR oai/cn5g/oai-cn5g-amf!372 has been merged, the AMF
image tag is updated to the latest release v2.2.1
- upgrade MySQL image to 9.6
This data structure is designed to support the use cases of the L1,
i.e., provide a queue which can be quickly used to order L1 jobs in FIFO
order with simple iteration of jobs to treat. It is a Single-Consumer
Single-Producer queue library.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
phy_procedures_nr_gNB.c calls pack_srs() functions to pack individual
SRS "subPDUs". Correspondingly, the library depends on NFAPI_LIB. In
nr_ulsim, in a later commit, we will need to unpack the SRS.indication,
so remove dummy functions and implement correctly.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
fix(record_db doc): correct the path for T_messages.txt and mention use of ninja/make
The commit !4038 (51d84419) provided the wrong path for T_messages.txt. The path
it provided holds if the T tracer is built manually using make.
A note to explicitly mention the path for T_messages.txt when T tracer is built
using make.
Signed-off-by: Sagar Arora sagar.arora@openairinterface.org
fix: issue 911 - replace timer oneshot to periodic.
Updated SCTP reconnect timer from TIMER_ONE_SHOT to TIMER_PERIODIC so gNB
continuously retries AMF lookup every 30 seconds after disconnect.
Timer is now removed only when ngap_amf_associated_nb > 0, AMF association
is actually back.
Updated SCTP reconnect timer from TIMER_ONE_SHOT to
TIMER_PERIODIC so gNB continuously retries AMF lookup every
30 seconds after disconnect.
Timer is now removed only when ngap_amf_associated_nb > 0,
AMF association is actually back.
at RRC we don't store CSI-MeasConfig information so in some scenarios (see #1063) we may not have the full pictures to understand if what RRC received is a valid configuration
we verify at L2 instead after updating CSI-MeasConfig and if it fails we send a message to RRC
Update the shared neighbour config used by the F1 rfsim pipeline to
enable CU-provided SIB2 and neighbour-derived SIB3/SIB4 inputs.
In `ci-scripts/conf_files/gnb-cu.sa.band78.106prb.conf`
- Add `cu_sibs = (2, 3, 4)
In `ci-scripts/conf_files/neighbour-config.conf`:
- Add a complete `sib2_config` block
- Add `frequency_list` / `frequency_config` for inter-frequency SIB4 fields
- Extend both neighbour entries with per-cell offsets
Add encode/decode helpers and basic round-trip tests for NR SIB2, SIB3
and SIB4 in test_asn1_msg.cpp to ensure we produce decodable messages
with expected fields. Extend SIB4 coverage with an
inter_freq_carrier_freq_info_ranges test that exercises boundary and
out-of-range values for carrier reselection parameters and checks
encoder failures for invalid configurations.
Changes:
- Introduce encode_and_decode_sib2, encode_and_decode_sib3 and
encode_and_decode_sib4 helpers that call do_SIB2_NR, do_SIB3_NR,
do_SIB4_NR and uper_decode and assert non-empty, non-null byte
arrays and successful decoding.
- Add sib2_basic_encode_decode, sib3_basic_encode_decode and
sib4_basic_encode_decode tests that populate minimal but
representative NR_SIB2_t, NR_SIB3_t and NR_SIB4_t instances and
verify selected decoded fields match the originals.
- Add inter_freq_carrier_freq_info_ranges test that builds an NR_SIB4_t
with NR_InterFreqCarrierFreqInfo_t and varies different offsets and
thresholds to confirm valid combinations encode and invalid ones
are rejected.
- Add comprehensive documentation header explaining the structure's role
as single source of truth for neighbor cell information across multiple
protocols (NGAP/XnAP handover, measurement config, DU validation, SIB3/SIB4)
- Add detailed field comments documenting protocol-specific mappings:
* Core identification fields (gNB_ID, nrcell_id, physicalCellId)
* Frequency/RF parameters (absoluteFrequencySSB, subcarrierSpacing, band)
* Handover target identification (plmn, tac)
- Document NGAP/XnAP IE mappings for plmn and tac fields
Remove the isIntraFrequencyNeighbour field and all code that sets or
uses it, simplifying neighbour cell handling and avoiding redundant
state in the RRC gNB code. The flag duplicated information that can be
derived from the neighbour absoluteFrequencySSB and the serving cell
SSB ARFCN, and intra-frequency neighbours are logged in the SIB3
preparation flow.
Changes:
- Remove isIntraFrequencyNeighbour from nr_neighbour_cell_t in
openair2/RRC/NR/nr_rrc_defs.h
- Delete is_intra_frequency_neighbour() and
label_intra_frequency_neighbours() helpers from
openair2/RRC/NR/rrc_gNB_du.c
- Remove calls to label_intra_frequency_neighbours() from
rrc_gNB_process_f1_setup_req() and
rrc_gNB_process_f1_du_configuration_update() in rrc_gNB_du.c
- Stop setting .isIntraFrequencyNeighbour in the local
nr_neighbour_cell_t neighbourConfig initializer in
openair2/RRC/NR/rrc_gNB_mobility.c
Add SIB4 encode/decode helpers and populate SIB4 from configured
inter-frequency carriers and neighbour cells, wiring it into DU F1
Setup handling and MAC SystemInformation.
Changes:
- Add do_SIB4_NR() and NR_SIB4.h inclusion in asn1_msg.c/asn1_msg.h to
UPER-encode NR_SIB4_t into a byte_array_t.
- Extend nr_mac_configure_other_sib() in NR_MAC_gNB/config.c with an
NR_SIB_4 case that validates the SIB container, decodes NR_SIB4_t via
uper_decode, logs failures, and appends SIB4 to SystemInformation.
- Introduce build_inter_freq_carrier_from_cfg() and
get_sib4_inter_freq_neighbors() in rrc_gNB_du.c to build
NR_InterFreqCarrierFreqInfo_t and NR_SIB4_t from inter-frequency and
neighbour cell configuration, skipping invalid or empty carriers.
- Handle NR_SIB_4 in rrc_gNB_process_f1_setup_req() by deriving SIB4
from neighbour/inter-frequency configuration, encoding it with
do_SIB4_NR(), validating the resulting byte_array_t and adding the SI
message for the DU cell when encoding succeeds.
Introduce NR SIB3 encoding in RRC and wire SIB3 neighbour information
into CU–DU F1 Setup and DU SystemInformation. Extend MAC to decode NR
SIB3 from CU-provided SIB containers and attach the decoded SIB3 to the
DU SystemInformation structure.
Changes:
- Add NR_SIB3 ASN.1 include and a do_SIB3_NR() encoder in asn1_msg
so SIB3 can be serialized into a byte_array_t buffer.
- Introduce get_q_offset_asn1() and get_sib3_intra_freq_neighbors() in
rrc_gNB_du.c to build an intra-frequency neighbour cell list for SIB3,
mapping q_OffsetCell dB values to NR_Q_OffsetRange and optionally
filling q_RxLevMinOffsetCell and q_QualMinOffsetCell.
- Limit the number of intra-frequency neighbours in SIB3 to
NR_maxCellIntra, logging a warning and skipping additional cells when
the limit is reached.
- Hook SIB3 construction and encoding into rrc_gNB_process_f1_setup_req()
so SIB type 3 entries are added to the F1 Setup Response when
neighbour configuration and matching neighbours are available.
- Handle NR_SIB_3 in nr_mac_configure_other_sib() by validating the CU
SIB3 container buffer, decoding it with uper_decode into an NR_SIB3_t,
and attaching the resulting SIB3 to the MAC SystemInformation via
add_sib_to_systeminformation().
Introduce typed SIB3/SIB4 neighbour and inter-frequency carrier
configuration structures, wire them into the RRC neighbour and gNB
instances, and centralise parsing and bounds checking of per-frequency
SIB4 parameters from the gNB frequency list.
Changes:
- Define SIB3/SIB4 reselection and offset bound macros in gnb_config.c
and apply them when parsing SIB4 frequency_config and
per-carrier q_RxLevMin/t_ReselectionNR.
- Add add_inter_freq and parse_inter_freq_list helpers in gnb_config.c
to populate a shared inter_freqs seq_arr_t from gNB_CONFIG_STRING_GNB_LIST
frequency_list entries, enforcing unique (ARFCN,SCS) combinations and
logging duplicates.
- Extend neighbour cell parameters in gnb_paramdef.h with SIB3 per-
neighbour offset fields and define frequency_list/frequency_config
option names, descriptor tables, and index constants for SIB4 inter-
frequency configuration.
- Introduce nr_neighbour_cell_neighbor_offset_t, nr_neighbour_cell_sib3_t,
nr_neighbour_cell_sib4_freq_t, nr_neighbour_cell_sib4_t, and
nr_inter_freq_cfg_t in nr_rrc_defs.h, and extend nr_neighbour_cell_t
and gNB_RRC_INST with sib3/sib4 and inter_freqs members respectively.
- udpated fill_neighbour_cell_configuration to use GET_PARAMS_LIST
with params bound check
Introduce a typed SIB2 cell reselection configuration, load it from the
gNB configuration into the RRC gNB instance, and use it to build and
encode SIB2 instead of relying on a fixed SIB2 definition.
Validate SIB2 parameters against explicit bounds and make the SIB2
encoder consume a pre-built ASN.1 structure with safer error handling.
Changes:
- Add SIB2 mobility timer and q-HystSF enums plus SIB2 config structs
(`sib2_speed_state_reselection_pars_t`, `sib2_config_t`) and a
`sib2_config` field on `gNB_RRC_INST` in `nr_rrc_defs.h`.
- Define SIB2 configuration option names, defaults
(`GNB_CONFIG_STRING_SIB2_*`, `GNBSIB2PARAMS_DESC`)
in `gnb_paramdef.h` for q_Hyst, thresholds, mobility timers, scaling
factors and deriveSSB_IndexFromCell.
- Add `sib2_config` parameter keys, defaults, and range/value checks in
`gnb_paramdef.h` (`GNBSIB2PARAMS_DESC`).
- Add SIB2 `fill_sib2_configuration()` in `gnb_config.c` to read SIB2
parameters from the config file log the resulting configuration and
store it in `rrc->sib2_config` via `RCconfig_NRRRC()`.
- Add `get_q_hyst_asn1()` and `get_sib2_from_cfg()` in `rrc_gNB_du.c`, and
update `rrc_gNB_process_f1_setup_req()` to encode/add SIB2 from config with
explicit encode-failure handling and logging.
- Change `do_SIB2_NR` signature in `asn1_msg.h/.c` to
`byte_array_t do_SIB2_NR(const NR_SIB2_t *sib2)`, remove internal default
SIB2 construction, and add ASN.1 constraint/encode error logging.
Unify SIB container handling by introducing a typed SIB enum and storing
SIB payloads as byte_array_t across common NR types, F1AP helpers, MAC,
and RRC DU setup code.
Changes:
- Include byte_array support in nr_common.h, add nr_sib_type_t (NR_SIB_1–NR_SIB_21),
and change nr_SIBs_t to hold only nr_sib_type_t SIB_type.
- Switch f1ap_sib_msg_t in f1ap_messages_types.h to use a byte_array_t SI_container
instead of raw pointer and length fields.
- Update F1AP encode/decode, equality, copy, and free helpers in
f1ap_interface_management.c to work on SI_container.buf / SI_container.len and
use eq_byte_array, copy_byte_array, and free_byte_array.
- Adapt F1AP tests in f1ap_lib_test.c to build and inspect SIB containers via
SI_container.buf and SI_container.len.
- Replace magic SIB numbers with nr_sib_type_t values in gnb_config.c
(get_sys_info and fill_du_sibs) to validate and configure DU SIBs.
- Rework nr_mac_configure_other_sib in NR_MAC_gNB/config.c to decode SIB2
from a byte_array_t container, fix freeing by releasing the decoded sib2 on
failure, and use NR_SIB_2 / NR_SIB_19 for CU/DU SIB selection.
- Add an add_si_msg helper in rrc_gNB_du.c and refactor the SIB2 branch of
rrc_gNB_process_f1_setup_req to populate cell->SI_msg from encoded local
byte array while iterating SIBs with FOR_EACH_SEQ_ARR.
Tighten neighbour-cell config parsing by enforcing parameter constraints in
the descriptor and switching parsing code to name-based lookups with gpd.
Changes:
- Update `GNBNEIGHBOURCELLPARAMS_DESC` in `openair2/GNB_APP/gnb_paramdef.h`
to add checks for `physical id`, `absoluteFrequencySSB`, `scs`, `band`
`tracking_area_code`.
- Remove neighbour-cell parameter index macros.
- Refactor `parse_neighbour_cells_list` in `openair2/GNB_APP/gnb_config.c`
to use `gpd()` lookups for neighbour fields instead of fixed indexes.
- Extend `parse_neighbour_cells_list` with an `n_cell_params` argument and
update `fill_neighbour_cell_configuration` to pass
`sizeofArray(ncell_params)`.
Inline neighbour cell arrays into the RRC neighbour configuration and
update RRC/DU helpers to use const-aware access and shared iteration
helpers when walking neighbour lists and building measurement configs.
Changes:
- Change neighbour_cells in neighbour_cell_configuration_t from a
seq_arr_t * to an embedded seq_arr_t field.
- Initialize and populate the embedded neighbour_cells directly in
parse_neighbour_cells_list in gnb_config.c, dropping dynamic
allocation of the neighbour list container.
- Refactor get_neighbour_cell_by_pci and nr_rrc_get_measconfig in
rrc_gNB.c to access the embedded neighbour_cells via const pointers,
introduce a local meas_cfg and a3_event_list, and iterate neighbour
cells with FOR_EACH_SEQ_ARR.
- Treat neighbour cell configuration entries as const in rrc_gNB_du.c
(get_cell_neighbour_list, label_intra_frequency_neighbours,
valid_du_in_neighbour_configs) and iterate neighbour lists with
FOR_EACH_SEQ_ARR instead of index-based loops.
Outer gNB neighbour_list entries now only declare the serving cell
nr_cellid. The code resolves that field with gpd instead of a fixed column
index.
Changes:
- gnb_paramdef.h: remove unused NEIGHBOUR_CELL_PHYSICAL_ID from
GNB_NEIGHBOUR_LIST_PARAM_LIST (keep NRCELLID only).
- gnb_config.c: in fill_neighbour_cell_configuration, set nr_cell_id
from gpd
Refactor gNB configuration code to share PLMN extraction logic and to
split neighbour-cell configuration into smaller helpers with safer
allocation and clearer list handling.
Changes:
- Add `extract_plmn_from_params()` in `gnb_config_common.c` and declare
it in `gnb_config_common.h` to centralize PLMN extraction from
`paramdef_t`.
- Update `set_plmn_config()` to use `extract_plmn_from_params()` when
filling the PLMN array instead of duplicating field assignments.
- Refactor `fill_neighbour_cell_configuration()` in `gnb_config.c` to
delegate per-cell neighbour parsing to
`parse_neighbour_cells_list()` and sorting to
`sort_neighbour_configuration()`, simplifying the main loop.
- Use `extract_plmn_from_params()` when parsing neighbour PLMNs in
`parse_neighbour_cells_list()` and log each neighbour with its PLMN,
PCI, and other radio parameters before adding it to the sequence.
- Switch allocation of `rrc->neighbour_cell_configuration` in
`fill_neighbour_cell_configuration()` from `malloc` to
`malloc_or_fail()` to enforce consistent handling of allocation
failures.
Change 1: config_check_intval() now uses the correct integer pointer for TYPE_INT
Problem: config_check_intval() previously dereferenced param->uptr regardless
of param->type. For parameters declared as signed (TYPE_INT / TYPE_INT32), the
active union member is param->iptr, and param->uptr may be NULL -> using uptr
makes validation unsafe and type-inconsistent.
What changed: Updated config_check_intval() behavior (signature unchanged).
Handle both param->type, param->iptr and param->uptr.
Change 1: new config_check_uintrange() for unsigned range constraints
Problem: there was a signed range checker (config_check_intrange()) that reads
param->iptr, but there was no dedicated unsigned range validator using param->uptr.
What changed: added config_check_uintrange() in config_userapi.h/.c
The new function reads param->uptr as uint32_t and validates against
param->chkPptr->s2.okintrange[] endpoints.
Change 3: constify input params for f2 function pointers
Problem: checkedparam_t.s2.f2 was typed with non-const input params, even though
range checks only read. A safer const-safe signature is required.
What changed: s2.f2 now takes const configmodule_interface_t *
and const paramdef_t *. config_check_intrange() and config_check_uintrange() use
the same const-qualified parameters.
The previous implementation of fill_srs_channel_matrix assumed an incorrect SRS subcarrier mapping, leading to wrong indexing of the estimated channel in frequency domain
2026-04-06 10:19:34 +01:00
513 changed files with 25268 additions and 13190 deletions
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\
"ip route add 12.1.1.0/24 via 192.168.72.134 dev eth0; sleep infinity"
"ip route add 12.1.1.0/24 via 192.168.72.134 dev eth0;"\
"ip route add 12.1.2.0/24 via 192.168.72.134 dev eth0; sleep infinity"
depends_on:
- oai-upf
networks:
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.