fix: Make test_vrtsim stable (#241)
Ensure all resources used by test_vrtsim are unique so that there is no
overlap, which might cause an issue in CI.
Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Add NR O-RU (#211)
This is a PR that will add a functional vrtsim-based nr-oru to the build
system. This is only slightly different SW to the one being presented at
the OAI summer 2026 workshop.
Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Reviewed-By: Merkebu Girmay <merkebu.girmay@openairinterface.org>
fix(vrtsim): Reduce OS scheduler pressure caused by vrtsim timing thread (#235)
Increase the usleep to 20 uS to reduce the pressure on the OS scheduler.
This reduces the number of context switches and increases performance.
The value 20uS is approximately half a symbol in mu1 and shouldn't cause
too much extra delay.
Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org>
NGAP Procedures for Xn Handover: Path Switch Request Path Switch Request Acknowledge (#194)
This PR adds the following NGAP Path Switch procedures to support Xn
handover in accordance with 3GPP TS 38.413v16.2.0.
NGAP Path Switch Request: add encode and ITTI support
- Add a case in TASK_NGAP to support ITTI message from RRC to NGAP
- Add Path Switch Request message type definitions
- Implement encoder for Path Switch Request (3GPP TS 38.413v16.2.0
§9.2.3.8)
* RAN UE NGAP ID (M)
* Source AMF UE NGAP ID (M)
* User Location Information (M)
* UE Security Capabilities (M)
* PDU Session Resource to be Switched in Downlink List (M)
- Add required ASN.1 header includes for Path Switch Request IEs
NGAP Path Switch Request Acknowledge: add decode and handler
- Add handler at NGAP for Path Switch Request Acknowledge from AMF
- Add Path Switch Request Acknowledge message type definitions
- Implement decoder for Path Switch Request Acknowledge (3GPP TS
38.413v16.2.0 §9.2.3.9)
* AMF UE NGAP ID (M)
* RAN UE NGAP ID (M)
* Security Context (M)
* PDU Session Resource Switched List (M)
* Allowed NSSAI (M)
- Add required ASN.1 header includes for Path Switch Request Acknowledge
IEs
Notes:
- Added a case NGAP_PATH_SWITCH_REQ in task_ngap to support ITTI message
from RRC, and this will be allocated at
- RRC when the target gNB receives the RRC complete message from the UE
during Xn handover.
- OAI CN5G does not support any of the NGAP path switch procedures
(request, ack, and failure) as of today to test Xn Handover.
- We tested the procedures in an E2E setup at IISc with two gNBs in
E1+F1+7.2x split containing the Xn handover code and connected to the
same 5G core (used Open5GS & Aether-OnRamp separately), and also did
not observe any Path Switch Failure.
- The implementation of Path Switch Failure at OAI RAN will be done
along with the implementation of Path Switch procedures in OAI CN5G
once the XNAP integration in OAI RAN is complete.
Acknowledgement:
> This work has been partially carried out as part of Xn Handover
development at the Indian Institute of Science (IISc), Bengaluru.
Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Reviewed-By: Guido Casati <guido.casati@openairinterface.org>
Ensure all resources used by test_vrtsim are unique so that there is no overlap,
which might cause an issue in CI.
Signed-off-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
Increase the usleep to 20 uS to reduce the pressure on the OS scheduler. This
reduces the number of context switches and increases performance. The value 20uS
is approximately half a symbol in mu1 and shouldn't cause too much extra delay.
Signed-off-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
- Add a case in TASK_NGAP to support ITTI message from RRC to NGAP
- Add Path Switch Request message type definitions
- Implement encoder for Path Switch Request (3GPP TS 38.413v16.2.0 §9.2.3.8)
- RAN UE NGAP ID (M)
- Source AMF UE NGAP ID (M)
- User Location Information (M)
- UE Security Capabilities (M)
- PDU Session Resource to be Switched in Downlink List (M)
- Add required ASN.1 header includes for Path Switch Request IEs
Co-authored-by: Rakesh BB <rakesh.bb@fsid-iisc.in>
Signed-off-by: Venkatareddy Akumalla <venkatareddy.akumalla@openairinterface.org>
Duranta is a Linux Foundation networking project and does not have
permission to display the trademarked OAI logo
(https://openairinterface.org/logo/), which belongs to the
OpenAirInterface Software Alliance (legal entity "OPENAIRINTERFACE").
Remove logo to avoid any legal problems.
Remove some superfluous text with HTML code in some documentation.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
fix (nas): parse UE Registration Reject and add NAS connection release (#218)
The nrUE NAS task read the Registration Reject cause at a hardcoded
offset and called exit(1). This commits adds processing of
plain/security-protected 5GMM headers, decoding of the mandatory cause
per TS 24.501 §8.2.7, set 5GMM state.
Softmodem is stopped via termination_procedure and local AS detach
(send_nas_detach_req without wait_release -> 1) RRC IDLE 2)
NR_NAS_CONN_RELEASE_IND 3) itti_wait_tasks_unblock).
Changes:
- Add fgmm_registration_reject enc/dec
- Add handle_registration_reject()
- Replace inline FGS_REGISTRATION_REJECT case
- Fix unprotected_allowed() for plain Registration Reject
- Add nas_lib_test round-trip (Illegal_UE / 0x03)
Note: optional IEs (T3346, T3502, EAP) not decoded, §5.5.1.2.5 procedure TODO
Closes: #174
Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org>
fix (f1ap): DRB-Information criticality and non-dynamic fiveQI handling in DU (#223)
Aligns OAI F1AP encoding with TS 38.473 for DRB-Information criticality
on UE Context Modification, and clarifies how non-dynamic fiveQI is
handled across F1AP/E1AP decode and CU RRC.
Non-dynamic fiveQI may name standardized or pre-configured profiles on
the wire (0..255). F1/E1 libs now accept the full ASN range and reject
only out-of-range values. Pre-configured and other non-standardized
non-dynamic 5QI remain unsupported at RRC via the existing
is_5qi_standardized() skip.
DU is now gracefully handling unsupported 5QIs instead of crashing.
Closes: #212
Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org>
The nrUE NAS task mishandled FGS_REGISTRATION_REJECT: it read the 5GMM
cause at a hardcoded offset and called exit(1) from the NAS ITTI task,
which could abort the process while PHY threads were still running.
This commit adds processing of plain/security-protected 5GMM headers,
decoding of the mandatory cause per TS 24.501 §8.2.7, set 5GMM state.
Softmodem is stopped via termination_procedure and local AS detach
(send_nas_detach_req without wait_release -> 1) RRC IDLE 2)
NR_NAS_CONN_RELEASE_IND 3) itti_wait_tasks_unblock).
Ignore duplicate rejects once termination has started.
Changes:
- Add fgmm_registration_reject enc/dec
- Add handle_registration_reject()
- Replace inline FGS_REGISTRATION_REJECT case
- Fix unprotected_allowed() for plain Registration Reject
- Add nas_lib_test round-trip (Illegal_UE / 0x03)
Note: optional IEs (T3346, T3502, EAP) not decoded, stop-on-reject
replaces 21a7f99 exit(1), full §5.5.1.2.5 procedure remains TODO.
Closes#174
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Cleanup NR RU options (#210)
This PR is part of the effort to split LTE and NR code to avoid
cross-compilation as described in #110.
In nr-ru.c, up to now, we relied on if4_tools.c for some if4p5 functions
but what's in that file is strictly LTE using LTE frame parameters, so
it shouldn't work in NR. As a matter of fact, after some investigation
and feedback from @teodora-vladic about 7.2 split, none of those
functions are used in practice in NR and they can be removed. If this
works, we move one step closer to the full compilation split of LTE and
NR.
Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Reviewed-by: Teodora Vladić <teodora.vladic@openairinterface.org>
Bugfix PUCCH Format 2 (#224)
Fix RE offset computation in PUCCH format 2 generation. This fixes DL
retx with OCUDU in the CI.
Reviewed-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
Fix for issue 216 (#221)
When O_ACK <= 2, the reserved HARQ-ACK positions are selected from the
codeword using a d-factor stepping algorithm. The d-factor was computed
and applied at bit granularity, causing it to step through the flat
positions array mid-modulation-group when Qm > 1.
This scattered ACK/placeholder bits across more REs than intended,
mismatching the RE selection of the demultiplexer which operates at RE
granularity. As a result, placeholder positions were marked on REs that
the gNB treats as pure ULSCH, causing those positions to be transmitted
without the normal scrambling sequence XOR. This corrupts the ULSCH soft
bits at the gNB side, leading to PUSCH CRC failure.
Fix: compute the d-factor in RE units and step through the positions
array in strides of d_factor_re * Qm so that whole Qm-bit modulation
groups are always selected or skipped together.
Observed with O_ACK=1, MCS27 (256QAM), beta_offset_idx=11 where
Q_dash_ACK=6 (reserved) vs Q_dash_ACK_actual=3, giving d_factor=2. PUSCH
CRC was KO at third-party signal analyzers (MATLAB/WaveJudge) while the
OCUDU gNB could still decode due to soft LDPC margin.
Closes: #216
Reviewed-by: Francesco Mani <email@francescomani.it>
Reviewed-by: Sakthivel Velumani <s.velumani@northeastern.edu>
When a CU sends a DRB with a non-dynamic 5QI that is not in the
DU MAC lookup table, get_non_dynamic_priority() used to AssertFatal and
abort. Return -1 and log a warning instead, and skip flows with negative
priority when deriving the logical-channel priority so setup can continue.
A more spec-aligned fix would require F1AP UE Context Setup/Modification
Failure (not implemented) in case of a logical error in the DU:
> Where the logical error occurs in a request message of a class 1 procedure,
> and the procedure has a message to report this unsuccessful outcome,
> this message shall be sent with an appropriate cause value.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Non-dynamic fiveQI on F1AP/E1AP may name standardized or pre-configured
profiles (TS 38.473), the range is 0..255. Decode now accepts
MIN_FIVEQI..MAX_FIVEQI (0..255) and fails only when fiveQI is outside
that range. Pre-configured and other non-standardized non-dynamic values
remain unsupported: RRC still skips them via is_5qi_standardized().
Changes:
- F1AP/E1AP: range-check 0..255 only
- improve documentation
Refs:
- 3GPP TS 38.473 §9.3.1.49 (non-dynamic standardized or pre-configured 5QI)
- 3GPP TS 23.501 §5.7.2.1
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
UE Context Modification DRB setup-mod encoding sent id_DRB_Information
with reject criticality. TS 38.473 defines that IE as ignore
(QoSInformation-ExtIEs, id-DRB-Information).
Changes:
- Set QoSInformation extension id_DRB_Information criticality to ignore
in encode_drbs_to_setupmod()
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
When O_ACK <= 2, the reserved HARQ-ACK positions are selected from
the codeword using a d-factor stepping algorithm. The d-factor was
computed and applied at bit granularity, causing it to step through
the flat positions array mid-modulation-group when Qm > 1.
This scattered ACK/placeholder bits across more REs than intended,
mismatching the RE selection of the demultiplexer which operates at
RE granularity. As a result, placeholder positions were marked on
REs that the gNB treats as pure ULSCH, causing those positions to be
transmitted without the normal scrambling sequence XOR. This corrupts
the ULSCH soft bits at the gNB side, leading to PUSCH CRC failure.
Fix: compute the d-factor in RE units and step through the positions
array in strides of d_factor_re * Qm so that whole Qm-bit modulation
groups are always selected or skipped together.
Observed with O_ACK=1, MCS27 (256QAM), beta_offset_idx=11 where
Q_dash_ACK=6 (reserved) vs Q_dash_ACK_actual=3, giving d_factor=2.
PUSCH CRC was KO at third-party signal analyzers (MATLAB/WaveJudge)
while the OCUDU gNB could still decode due to soft LDPC margin.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Alex Jiao <alex.jiao@keysight.com>
Instead of guessing what is the absolute timestamp of each symbol returned
from fronthaul, add absolute hyper frame from GPS Epoch to the O-RU. The
O-RU can calculate the absolute sample index from hyper frame reliably
regardless of the frame/slot/symbol ordering.
Add config file for 1x1 O-DU that matches the edited O-RU config.
Signed-off-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
Added oru_south_read_thread that reads samples from vrtsim.
No UL FH processing is done as of this commit.
Signed-off-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
This function can be used to convert a timespec struct to a
openair0_timestamp. It can be used to synchronize the realtime
clock to the device sample number.
Signed-off-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
Start O-RU fronthaul library inside the O-RU application and start
reading DL IQ data.
Added configuration elements to the ORUs section to support configuring
the library.
Signed-off-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
Added initialization of frame params according to configuration added
in the new ORUs section. Only one ORU is supported right now.
Added example config that allows starting the ORU and verifying manually
that the config is read.
Signed-off-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
Remove an assert on successful dup() of a socket. At least when running
in phy-test mode without noS1, the socket does not exist, and the call
to dup() fails. In that case, we should carry on instead of simply
failing, similarly how the process does not abort when TUN setup fails.
Fixes: 8d2895463b ("Paging UE (SDAP): reattach TUN after idle reset")
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
CI: Add UE timing phytest (#188)
Add a new XML file to also measure UE timings, similarly how we do with
gNB.
Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org>
fh_if4p5_south_in and fh_if4p5_south_out are called in NR for 7.2 split but never actually executed
they are overwritten at runtime in ru_thread
Signed-off-by: Francesco Mani <email@francescomani.it>
Check timing thresholds on both UE and gNB side. If this commit works as
expected, it can replace xml_files/gnb_phytest_usrp_run.xml.
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Allow XML test cases to specify one or more files with timing stats that
define which container log paths to collect and analyze. AnalyzeRTStatsObject
loops over the provided list, falling back to the default gNB files
(nrL1_stats.log, nrMAC_stats.log) when none are specified.
Assisted-by: Claude:claude-sonnet-4-6
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Improvements in UCI on PUSCH implementation at UE (#139)
This MR improves the implementation of UCI on PUSCH at UE side and fixes
some issues found while testing and fixing the revised version.
Tested in ULSIM with MATLAB vectors provided by @sakthivelvelumani in
the following scenarios (bits)
- 2 ACK no CSI
- 7 CSI part1 no ACK no CSI part2
- 1 ACK 7 CSI part1 7 CSI part2
- 3 ACK 4 CSI part1 4 CSI part2
using the command line
./nr_ulsim -m 27 -u 1 -R 51 -r 51 -s 30 -o(path to the file containing the vector)
Closes: #181
Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Reviewed-by: Sakthivel Velumani <s.velumani@northeastern.edu>
Complete NR L2/L3 Paging path from F1AP to NAS (gNB and UE) (#151)
This MR wires a 5G‑NR paging flow across the stack, from F1AP Paging on
the DU down to PCCH scheduling in MAC/RLC, RRC/ASN encode/decode, and
UE‑side NAS Service Request triggering, including the NR UE changes in
L1/L2.
It centralises paging PF/PO computation and PCCH scheduling in MAC,
using shared SSB/Type0‑PDCCH and common PDSCH helpers that are also
reused by SIB1. On the UE, it enables decoding of NR PCCH messages,
matching ng‑5G‑S‑TMSI/fullI‑RNTI, and conditionally initiating a
network‑triggered Service Request when 5GMM state allows it. The change
set includes focused refactors and ASN.1 tests to validate the new
paging encode/decode path.
Changes:
- MAC gNB common helpers: Move SSB/Type0‑PDCCH utilities from the
BCH scheduler into shared MAC primitives and introduce a reusable
Type0‑occasion helper and common PDSCH RB/MCS/TBS sizing
- MAC paging PF/PO responsibility: Add a dedicated PCCH scheduler module
that implements TS 38.304 §7 PF/PO computation (defaultPagingCycle,
nAndPagingFrameOffset, Ns, SFN‑based PF formula and PO slot mapping)
and owns the “is this (frame,slot) a paging occasion for UE_ID?”
decision.
- F1AP -> MAC -> RLC PCCH path (gNB/DU): Have the DU decode F1AP Paging
with CN UE identity, build an NR RRC Paging message (PCCH) in MAC, and
hand it to RLC as a dedicated PCCH SDU together with UE_ID (5G‑S‑TMSI
mod 1024), using per‑module PCCH storage. RAN UE paging identity
is explicitly rejected.
- Direct CU to DU paging path: Implement direct F1 Paging handling
in the NR RRC DL direct interface for RLC PCCH storage for later
scheduling.
- PCCH scheduling and NFAPI integration (gNB MAC): Integrate
schedule_nr_pcch() into the DL scheduler so that when a stored PCCH
SDU exists and the current (frame,slot) is a paging occasion, MAC
resolves the paging search space and CORESET, selects a beam (from SSB),
allocates CCEs and PDSCH resources, builds NFAPI DL_TTI PDUs
(PDCCH + PDSCH with P‑RNTI, DCI 1_0), and populates the matching
TX_DATA PDU, then clears the cached PCCH.
- DCI handling for P‑RNTI paging: Adjust DCI payload preparation
to treat P‑RNTI specially, returning after setting DMRS and antenna
ports and skipping HARQ and UE scheduling state that do not exist for
paging, so paging DCIs no longer touch UE HARQ data structures.
- PHY UE RX Chain: DCI handling for P‑RNTI on UE, monitor DCI on Paging
Occasions, process DCI 1_0 with CRC scrambled by P‑RNTI on the paging
search space, trigger PDSCH decoding for PCCH based on that DCI, deliver
decoded PCCH to upper layers from the PHY/MAC side
- RRC/ASN paging encode API: Replace the legacy buffer‑based do_NR_Paging
with a nr_paging_params_t‑based API returning a byte_array_t,
supporting both ng‑5G‑S‑TMSI and fullI‑RNTI identities, and optional IEs
(e.g. accessType non‑3GPP and pagingCause v17), and encoding via
uper_encode_to_new_buffer, with ownership and failure semantics clearly
defined for callers.
- UE‑side PCCH reception and matching: Add UE MAC to RRC logic
to deliver PCCH SDUs to RRC, decode NR PCCH via a new nr_pcch_decode()
helper into an array of nr_paging_params_t, iterate PagingRecordList on
the UE, compare M‑TMSI/fullI‑RNTI against local identity, and log whether
a paging match was found.
- NAS integration for network‑triggered Service Request: On a UE paging
match, send a NAS_PAGING_IND from RRC to NAS and, when the UE has a
GUTI, is 5GMM‑REGISTERED and in 5GMM‑IDLE, generate and send a Service
Request uplink NAS message
- Tests and validation helpers: Extend nr_asn1 paging tests
to encode Paging via do_NR_Paging, decode it via nr_pcch_decode,
and verify round‑trips for multiple ng‑5G‑S‑TMSI values, accessType,
and fullI‑RNTI bit patterns, using a shared encode/decode helper that
exercises the same decoder path used by the UE.
Notes:
Paging handling currently supports CN UE paging
identity (5G‑S‑TMSI) only. RAN UE paging identity is logged and ignored.
A paging match triggers a Service Request only when the UE has a GUTI,
is 5GMM‑REGISTERED, and in 5GMM‑IDLE. T3346 and suspend‑indication
handling are documented as future work and not implemented here.
Testing:
Tested with Open5gs. How to trigger Paging in Open5GS lab setup:
- Use gNB telnet to request NGAP UE Context Release: `rrc ctx_rel_req
<RRC_UE_ID>`
- Wait until AMF reports CM-IDLE (for example gNB-UEs is now 0).
- Generate downlink data from the Linux host to the UE IP: `ping
<UE_IP>`
- Host-originated downlink data will trigger paging.
Closes#74
Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Reviewed-by: Francesco Mani <email@francescomani.it>
we need to remove the reserved elements from the pool of the avalable ones to compute position of the CSIp1 elements
Signed-off-by: Francesco Mani <email@francescomani.it>
- Add a LOG_I to 'nr_sdap_add_entity' to inform the user
a SDAP entity is being created
- Add LOG_W to `nr_sdap_get_entity` to warn about
empty SDAP entity list
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Add an RRC telnet command that sends a RAN-initiated NGAP UE Context Release
Request with a user-inactivity cause.
Register ctx_rel_req in the RRC telnet command table.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
After the UE answers a network page with a NAS Service Request, it waits
in 5GMM-SERVICE-REQUEST-INITIATED until the AMF replies or the radio
connection drops.
While that wait is active, duplicate pages must be ignored. When SR ends,
NAS must return to 5GMM-REGISTERED so a later page can start a new SR
(TS 24.501).
Changes:
- handle_service_accept(): set FGS_REGISTERED on SERVICE ACCEPT (TS 24.501 §5.6.1.4)
- handle_service_reject(): if SR was pending, set FGS_REGISTERED (§5.6.1.5)
- NR_NAS_CONN_RELEASE_IND: if SR was pending, set FGS_REGISTERED (§5.3.1.3 and §5.6.1.7 l)
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
UE paging can recreate the AS-side SDAP entity while NAS still keeps the
PDU session established. Per TS 38.304 clause 7.1 and TS 24.501 clauses
5.6.2.2.1,5.6.1.2 paging/service request restores user-plane resources
for an established PDU session, it does not imply deleting the UE IP/TUN
interface.
Deleting the UE TUN with SDAP entity teardown breaks user-plane continuity
after re-attach. We need SDAP entity lifetime and UE TUN lifetime to be
decoupled. This commit keeps a UE/PDU-session TUN registry outside the
SDAP entity lifetime. When a UE SDAP entity is recreated, reattach it
to the preserved TUN socket and restart the reader thread. On first PDU
session setup, NAS registers the TUN before attaching the reader.
The sequence is the following: (1) NAS register the iface
(2) sdap entity attaches to the iface (3) UE goes IDLE, SDAP
entity is destroyed, iface is deatched and brought down (4)
UE Service Request, SDAP entity is created (5) iface reattaches
to the SDAP entity and is brought up
UE reattach assumes the PDU session TUN interface was registered
before the SDAP entity is recreated.
DL/UL data is intentionally dropped when SDAP is not yet attached
or QFI is unavailable, rather than queued in this layer.
Changes:
- `nr_sdap.c`: keep a UE/PDU-session TUN registry, duplicate the stored
socket into each SDAP entity, and add attach/detach/destroy helpers.
- `nr_sdap_entity.c`: detach SDAP entities from their TUN reader on
deletion, preserve UE TUN interfaces across idle cleanup, and destroy
gNB TUN interfaces when the gNB entity is removed. Drop downlink SDUs
if the UE SDAP entity is not attached to a TUN socket yet.
- `openair3/NAS/NR_UE/nr_nas_msg.c`: set QFI before UE TUN creation so
first attach can pick up cached QFI.
- `common/utils/tuntap_if.c`: add `tuntap_set_up`/`tuntap_set_down` helpers
for UE interface state reflection and initialize `flags` in `tuntap_destroy`
to avoid maybe-uninitialized build failures.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Fix UE PUCCH resource multiplexing (#154)
TS 38.213 9.5.2 specifies that if the UE wants to send HARQ-ACK and CSI
report on format 2/3/4, then the resource is selected by the PUCCH
resource indicator for sending HARQ-ACK.
In this case the resource set must be >= 1 because O_UCI has HARQ-ACK
and CSI report and is > 2.
So far we use the PUCCH resource of CSI report if HARQ-ACK format is < 2
and CSI report is >= 2. This PR fixes it.
Closes: #90
Reviewed-by: Francesco Mani <email@francescomani.it>
XNAP: Add encode/decode+unit tests for Xn HO Cancel, HO Success, RAN Paging (#178)
Extends the XNAP encode/decode library with three class 2 procedures
from 3GPP TS 38.423 v16.2.0, each with full encode/decode/eq/free
support and an APER round-trip unit test.
Handover Cancel (§9.1.1.6): Sent by the source node to abort an
in-progress handover before the UE has accessed the target cell.
- Source NG-RAN node UE XnAP ID (M)
- Cause (M)
Handover Success (§9.1.1.12): Sent by the target node to confirm the UE
has successfully accessed the target cell.
- Source NG-RAN node UE XnAP ID (M)
- Target NG-RAN node UE XnAP ID (M)
- Requested Target Cell Global ID (M)
RAN Paging (§9.1.1.7): Requests a neighbouring NG-RAN node to page a UE
in RRC_INACTIVE state.
- UE Identity Index Value (M) — 10-bit BIT STRING
- UE RAN Paging Identity (M) — 40-bit I-RNTI BIT STRING
- Paging DRX (M)
- RAN Paging Area (M) — cell-list variant, one PLMN + NR cell IDs
Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Reviewed-By: Guido Casati <guido.casati@openairinterface.org>
- Add RAN Paging message type definitions, including paging DRX
enumeration (§9.2.3.66) and RAN paging area cell-list
structure (§9.2.3.38)
- Implement encoder and decoder for RAN Paging
RAN Paging (3GPP TS 38.423v16.2.0 §9.1.1.7)
- UE Identity Index Value (M)
- UE RAN Paging Identity (M)
- Paging DRX (M)
- RAN Paging Area (M)
- Add equality check and memory management helpers
- Add required ASN.1 header includes for RAN Paging IEs
- Extend XNAP library unit tests to cover RAN Paging
Reviewed-by: Venkatareddy Akumalla <venkatareddy.akumalla@openairinterface.org>
Signed-off-by: Mohammed Safwan <mohammed.safwan@openairinterface.org>
Fix vrtsim antenna configs (#144)
This PR fixes three issues: #130#125, and an unreported issue related
to flaky vrtsim tests. With the new unix domain socket initialization
the unit test framework should be much more robust and not fail
randomly.
Reviewed-By: Merkebu Girmay <merkebu.girmay@openairinterface.org>
Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Change ambigous language in Aerial_FAPI_Split_Tutorial.md (#176)
This PR addresses Issue 1103
(https://gitlab.eurecom.fr/oai/openairinterface5g/-/work_items/1103),
changing one note in Aerial_FAPI_Split_Tutorial.md regarding CN core
allocation when running on the same server. The original wording could
be interpreted as allocating a separate core to each of the core network
functions, when that's not the intended interpretation.
Reviewed-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
As per 38.213 9.5.2 when multiplexing pucch resources of harq ack and csi
report, the resource is selected from the set id >= 1.
Closes: 90
Signed-off-by: Sakthivel Velumani <s.velumani@northeastern.edu>
Refactored the function merge_resources() to minimize code repetition.
The function logic is unchanged.
Assisted-by: Claude Sonnet 4.6
Signed-off-by: Sakthivel Velumani <s.velumani@northeastern.edu>
- Fix vrtsim uneven antenna configurations
- Fix shm_td_iq_channel client-server SHM race
- Set shm size to 2G in unit test docker run to prevent out-of-memory errors
Closes: #130
Signed-off-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
Move the initial IPC from file-based to Unix Domain Socket. The server
keeps a lightweights UDS accept / write thread while the clients attempt
to connect / read from the socket. This makes the communication more robust
because if the server process exits, it will always result in a failure to
connect from the client. With file-based IPC this was not always the case.
Assisted-by: Gemini-3.5:Flash
Closes: #125
Signed-off-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
Prior commits stored PCCH parameters and can decode P-RNTI,
this commit schedules PDCCH monitoring at the right TTIs.
In camped idle the UE must listen for network paging on P-RNTI only on
the correct paging frame (PF) and paging occasion (PO), only if the
paging common search space is set.
On monitor_paging_dci() success it adds P-RNTI to the downlink DCI
config for the existing PHY/MAC paging decode path.
Changes:
- Add monitor_paging_dci():
- resolve paging_SS_id, call config_dci_pdu(TYPE_P_RNTI_) only
when monitor_paging_dci() is true.
- require is_ss_monitor_occasion on the paging search space
- validate T/N/Ns from mac->paging_cfg
- apply TS 38.304 §7.1 PF and i_s
- PF via nr_pcch_sfn_is_pf
- PO index i_s via nr_pcch_po_index
- non-zero type-2 PO window via nr_pcch_type2_po_mo_in_range
Refs:
- 3GPP TS 38.304 §7.1 (PF/PO)
- 3GPP TS 38.213 §10.1 (PDCCH monitoring for paging)
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Keep normal no-redirection RRCRelease on the acquired
camped-cell context while preserving the existing full
GO_TO_IDLE cell-selection path for other idle transitions.
Changes:
- Add UE_IDLE and GO_TO_IDLE_KEEP_CAMPED to represent camped
idle without starting RA.
- Map no-redirection RRCRelease to GO_TO_IDLE_KEEP_CAMPED and
keep SIB1 validity for that path.
- Release connected-mode MAC/BWP0 dedicated config while
preserving common BWP0 and paging PDCCH context.
- Keep the existing full GO_TO_IDLE cleanup for idle transitions
that must perform cell selection.
Refs:
- TS 38.331 §5.3.11
- TS 38.304 §5.2.5, §5.2.6, §7.1
- TS 38.321 §5.12
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Route paging-triggered Service Request through NAS_INITIAL_UL_TRANSFER_REQ so
RRC can buffer the PDU for RRCSetupComplete (dedicatedNAS-Message, TS 38.331)
when no UL-DCCH SRB exists, start MAC RA from RRC_IDLE, or drop the ITTI PDU
with LOG_W if SRB1/SRB2 is already established (NAS paging path is 5GMM-IDLE
only).
Changes:
- Define ITTI NAS_INITIAL_UL_TRANSFER_REQ and
NAS_INITIAL_UL_TRANSFER_REQ() (rrc_messages_def.h,
rrc_messages_types.h).
- Extend NR_UE_RRC_INST_t with pending_initial_nas for setup-complete
transport (rrc_defs.h).
- Refactor ULInformationTransfer+PDCP send into
nr_rrc_ue_send_ul_information_transfer_nas(): on NAS_UPLINK_DATA_REQ,
refuse PDCP when neither SRB1 nor SRB2 is established (free PDU).
- On NAS_INITIAL_UL_TRANSFER_REQ: store NAS in pending_initial_nas when
no SRB, in RRC_STATE_IDLE_NR set ra_trigger to RRC_CONNECTION_SETUP,
call nr_rrc_ue_prepare_RRCSetupRequest(), and nr_rrc_send_msg_to_mac()
with NR_MAC_RRC_START_RA, otherwise replace pending and send on SRB.
- Use forwarded initial NAS messafe in rrc_ue_generate_RRCSetupComplete():
if pending_initial_nas is set, move it into the NAS payload and refresh
security keys when integrity context exists, else generateRegistrationRequest().
- In nr_nas_msg.c, add send_nas_initial_ul_transfer_req() and use it for
paging Service Request instead of send_nas_uplink_data_req()
Refs: TS 24.501, TS 38.331 §5.3.3.4, TS 33.501 §6.8.1.2
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
RRC starts random access via NR_MAC_RRC_START_RA with an explicit
cause. RA trigger is no longer piggybacked on NR_MAC_RRC_CONFIG_RESET.
T300 expiry and RRC re-establishment are the call sites switched in this
commit. MAC handles setup/T300 and re-establishment paths in
nr_mac_start_ra().
Changes:
- Add nr_mac_rrc_types.h (nr_mac_ra_start_cause_t)
- Add nr_mac_rrc_start_ra_t in rrc_messages_types.h
- In rrc_UE.c, add nr_rrc_trigger_mac_ra(), call it from
handle_t300_expiry and nr_rrc_initiate_rrcReestablishment
- In config_ue.c:
- add nr_mac_start_ra() entry point with causes switch
- add nr_rrc_mac_start_ra() handler
- remove T300_EXPIRY, RE_ESTABLISHMENT reset handling
in nr_rrc_mac_config_req_reset, now delegated to
nr_mac_start_ra
- mac_defs.h: drop T300_EXPIRY from NR_UE_MAC_reset_cause_t
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Transfer UE-side paging matches from RRC to NAS so a registered idle UE
can generate and send a Service Request after `NAS_PAGING_IND`. Guard
the path with explicit cause, identity, state, and mode checks so
unsupported cases are logged and ignored.
Changes:
- in `rrc_UE.c`, send `NAS_PAGING_IND` to TASK_NAS_NRUE with cause
`AS_CONNECTION_ESTABLISH` from `rrc_nrue()` when a paging match is found
- in `nr_nas_msg.c`, implement `NAS_PAGING_IND` handling in `nas_nrue()`
- accept only paging indications with cause
`AS_CONNECTION_ESTABLISH`, then require `nas->guti`,
`FGS_REGISTERED`, and `FGS_IDLE` before proceeding
- generate the Service Request with `generateServiceRequest()` and send
it through `send_nas_uplink_data_req()`
Refs:
- TS 23.502 §4.2.3.3 (Network Triggered Service Request)
- TS 24.501 §5.6.2.2.1 (Paging for 5GS services)
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
In NR RRC idle or inactive, decode PCCH SDUs from MAC and scan Paging
records (TS 38.331 §5.3.2.3) for ng-5G-S-TMSI against the UE M-TMSI
(lower 32 bits of fiveG_S_TMSI). PCCH is ignored in other states.
Changes:
- Add nr_rrc_ue_decode_pcch(): call nr_pcch_decode(), compare each
ng-5G-S-TMSI M-TMSI to (fiveG_S_TMSI & UINT32_MAX), return on match
or failure
- In rrc_nrue(), handle NR_RRC_MAC_PCCH_DATA_IND by wrapping sdu/
sdu_size in byte_array_t, calling nr_rrc_ue_decode_pcch()
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
When PHY reports a successful P-RNTI PDSCH decode as
FAPI_NR_RX_PDU_TYPE_PCCH, MAC must deliver the TB to RRC as a raw PCCH
SDU. Add the ITTI indication and a dedicated RX handler in the PHY
interface module, mirroring how BCCH/SIB paths are kept separate
from C-RNTI DLSCH.
Changes:
- Add NR_RRC_MAC_PCCH_DATA_IND ITTI message, NRRrcMacPcchDataInd, and
NR_RRC_MAC_PCCH_DATA_IND() accessor.
- Add send_pcch_rrc() to queue the PCCH SDU toward TASK_RRC_NRUE.
- Add handle_pcch() in NR_IF_Module.c: on successful decode forward the
TB with send_pcch_rrc(), log and drop on LDPC failure.
- Dispatch FAPI_NR_RX_PDU_TYPE_PCCH in nr_ue_dl_processing().
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Implement UE-side DCI format 1_0 for CRC scrambled by P-RNTI: decode the
P-RNTI-specific bitfield, validate the short message indicator,
compute the DL-SCH grant (TBS, TB scaling, fixed
RV/HARQ), and append the DL config PDU when the grant is accepted.
Changes:
- Add extract_10_p_rnti and call it from nr_extract_dci_00_10 for TYPE_P_RNTI_
(replacing AssertFatal).
- In nr_ue_process_dci_dl_10: ignore dedicated pdsch_Config for TYPE_P_RNTI_,
reject reserved SMIs that do not apply. After MCS apply
nr_ue_process_dci_dl_10_p_rnti for TBS/Qm/code rate, RV/HARQ defaults,
tb_scaling scaling factor, and guards. On success set bump the DLSCH DL
config PDU count.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Improve UE DCI PDU configuration robustness by validating monitoring-symbol
inputs before extraction, and add explicit P-RNTI DCI setup for paging
search-space monitoring.
Changes:
- Add guard checks for `monitoringSymbolsWithinSlot` presence, buffer, and
minimum size before computing symbol masks in `config_dci_pdu()`
- Factor out monitoringSymbolsWithinSlot which is common across RNTI cases
and reuse local `monitoringSymbols` pointer for symbol-mask extraction
- Implement `TYPE_P_RNTI_` branch to set symbol mask, `rel15->rnti =
P_RNTI`, and `SubcarrierSpacing` for paging DCI configuration
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Push the 5G-S-TMSI received by UE RRC down to MAC so paging can use
the TS 38.304 UE_ID.
Changes:
- add a paging UE_ID field to the UE MAC paging configuration
- add nr_rrc_mac_config_req_paging_ue_id() to derive UE_ID from
5G-S-TMSI and store it under the MAC interface mutex
- update the NAS_5GMM_IND handling in rrc_nrue() to pass the received
5G-S-TMSI to MAC for paging PF/PO derivation
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Populate UE MAC paging state from SIB1 PCCH-Config so PF/PO-related
parameters are available to the rest of the UE MAC.
Changes:
- Add nr_ue_paging_cfg_t to NR_UE_MAC_INST_s with parsed paging fields
(T, N, Ns, PF_offset, X) and the optional
firstPDCCH-MonitoringOccasionOfPO list (first_mo_of_po[],
first_mo_of_po_count)
- Add configure_pcch_config() to decode SIB1 PCCH-Config via the
common helpers nr_pcch_default_paging_cycle_rf,
nr_pcch_n_and_paging_frame_offset, nr_pcch_ns_per_pf and
nr_pcch_first_pdcch_start_mo
- Add NR_PCCH_MAX_PO constant (TS 38.331 PCCH-Config) and size the
first_mo_of_po[]
- Invoke configure_pcch_config() from nr_rrc_mac_config_req_sib1()
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Map P-RNTI scheduled DLSCH to the UE DLSCH receive indication flow so
paging traffic is also classified like DLSCH together with C-RNTI.
Changes:
- Set `dlsch0->rnti_type` from DLSCH RNTI in scheduled response, using
`TYPE_P_RNTI_` when RNTI is `P_RNTI`
- Extend `nr_ue_dlsch_procedures()` RX indication mapping to include
`TYPE_P_RNTI_` in the DLSCH indication case
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Integration: `2026.w24`
- #145 RLC data req: Use API to fill multiple RLC PDUs at gNB
- #160 ci: maintainer approval for additional file changes and update maintainer's contact
- #146 Unit tests for bit functions
- #142 UE DL Channel compensation and LLR optimization
- #166 CI OCUDU configuration changes
- #170 fix(fhi72): add observability to the O-DU
- #173 fix(f1): DRB Information has criticality ignore
- #171 Local ssb detection
Local ssb detection (#171)
PSS/SSS detection in the UE code uses a global structure that describe
the cell parameters it is not logical because we will populate this
information from what we read in the MIB and the SIB1 later it also
blocks us to make a cell scanner in a logical manner, just calling pss
detection function with a set of detection parameters and a buffer of
digital radio
this MR fixes this and simplifies the code.
Reviewed-by: Sakthivel Velumani <s.velumani@northeastern.edu>
fix(f1): DRB Information has criticality ignore (#173)
See 38.473: this IE is supposed to be "ignore".
Closes: #172
Reviewed-By: Guido Casati <guido.casati@openairinterface.org>
fix(fhi72): add observability to the O-DU (#170)
This change adds printout to packet error/timing counters for the O-DU K
release. In F release these counters are either not present or not
implemented properly.
Reviewed-by: Teodora Vladić <teodora.vladic@openairinterface.org>
At each DL slot, schedule_nr_pcch() scans pcch_queue for records whose
UE paging occasion matches (frame, slot), encodes one PCCH-Message via
do_NR_Paging(), and fills P-RNTI PDCCH/PDSCH NFAPI PDUs.
Paging occasion detection is now owned by MAC via PCCH scheduler
helper that implements PF/PO computation per TS 38.304
§7. Computation is determined by defaultPagingCycle (T),
nAndPagingFrameOffset (N), ns (Ns), with PF formula
(SFN + PF_offset) mod T = (T div N) * (UE_ID mod N),
and PO slot mapping for Ns = 1/2/4. Paging is transmitted only
when (frame, slot) is the UE's paging occasion
(TS 38.304 §7.1) and when a Type2-PDCCH CSS is configured via
pagingSearchSpace, so the UE can receive it.
The RRC PCCH path is simplified accordingly.
Changes
In `openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_pcch.c`:
- Add paging-specific scheduling logic, including `is_paging_occasion()`,
paging-search-space resolution, and `nr_fill_nfapi_dl_PCCH_pdu()`
- Add `schedule_nr_pcch()` implementation to allocate CCE/PDSCH
resources, populate DL/TX NFAPI requests, encode at PO via do_NR_Paging()
In gNB scheduler:
- Invoke `schedule_nr_pcch()` in SA-mode DL scheduling
In `openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c`:
- Add PCCH scheduling helpers to be reused at UE side
Also:
- Remove no longer relevant `rrc_gNB_generate_pcch_msg()` from `rrc_gNB.c`
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Make fh_timer_tick robust against CLOCK_REALTIME jumps. In case of
forward jump the symbol callback will be called for each missed symbol.
In case of backwards jump the function will return without calling
any callbacks. This continues until the local timer catches up to the
last callback symbol.
Signed-off-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
Ensure DL DCI payload preparation for paging with P-RNTI returns,
avoiding use of UE scheduling state and HARQ processes that do
not exist for paging.
Changes:
- Add early return in prepare_dci_dl_payload for TYPE_P_RNTI_
- Defer NR_UE_sched_ctrl_t lookup until after the P-RNTI path to avoid
accessing UE context and HARQ state for paging
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
When the core pages an idle UE, the DU queues paging records unti
MAC can send it on PCCH at the right PF/PO. This commit moves that
buffering into gNB MAC and connects the existing F1AP Paging entry points.
The CN UE paging is therefore routed from F1AP inputs into a MAC-managed
PCCH queue. The unused RRC PCCH generator stub is dropped. This makes paging
delivery path explicit in MAC for later PF/PO scheduling.
Changes:
- f1ap_du_paging.c: decode F1AP Paging and call f1_paging()
- mac_rrc_dl_handler.c: add f1_paging()- CN UE identity only, reject RAN UE,
call nr_mac_pcch_enqueue
- gNB_scheduler_pcch.c (new): queue init/free/enqueue, store identity only
(nr_mac_pcch_record_t: ue_id, fiveg_s_tmsi) in spsc_q
- nr_mac_gNB.h: add nr_mac_pcch_record_t and pcch_queue on NR_COMMON_channels_t
- mac_rrc_dl_direct.c: f1_paging_transfer_direct(), call f1_paging()
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Add PCCH decoding and use in ASN.1 tests.
Changes:
- add `nr_pcch_decode()`
- extend `test_asn1_msg.cpp` with `encode_decode_paging()` round trips
for multiple `ng-5G-S-TMSI` values, `accessType`, and `fullI-RNTI`
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Replace the old buffer-based do_NR_Paging API with a params struct and
byte_array_t return; add support for fullI-RNTI and optional accessType/
pagingCause. Encoding uses uper_encode_to_new_buffer, callers own and
free the returned buffer.
Changes:
- asn1_msg.h:
- Add nr_paging_params_t (ue_identity_type, union ue_identity union
{ m_tmsi or full_i_rnti }, access_type, paging_cause),
- Add NR_PAGING_FULL_I_RNTI_SIZE define.
- asn1_msg.c:
- Implement do_NR_Paging with nr_paging_params_t.
- Support ng-5G-S-TMSI (48-bit, M-TMSI in bytes 2–5)
and fullI-RNTI (40-bit, 5 bytes).
- Set optional accessType (non3GPP) and optional nonCriticalExtension
(pagingRecordList-v1700 with pagingCause-r17).
- Use asn1cCalloc for ASN.1 allocations and encode via
uper_encode_to_new_buffer. On failure free buffer and return empty
byte_array_t.
- rrc_gNB.c: disable do_NR_Paging call in rrc_gNB_generate_pcch_msg
with #if 0 (will be removed in a descendant commit, no need to update
call site yet).
- test_asn1_msg.cpp: update caller in asn1 tests (minimal change, test
will be updated in a later commit)
- common/platform_constants.h: add NR_PCCH_MAX_PAGING_RECORDS
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Expose the RB/MCS/TBS selection helper as a shared MAC function for
common PDSCH instead of keeping as static variant for SIB-specific use
in the BCH scheduler. It will be reused by the PCCH code path in a descendant
commit.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Implement the Type0-PDCCH occasion helper for reusability and
use it in schedule_nr_sib1. Adopt in a descendant commit
in PCCH scheduling as well.
Changes:
- gNB_scheduler_primitives.c: add is_type0_occasion()
- gNB_scheduler_bch.c: in schedule_nr_sib1, replace inline code
with is_type0_occasion
- Rename check_frame_sib1 to check_frame_type0, as it is not
limited to sib1 but applies to PCCH as well.
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
gNB_scheduler_bch.c now calls the shared get_max_ssbs() instead of
duplicating the SSB bitmap size logic in schedule_nr_sib1
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
Move get_max_ssbs and the Type0-PDCCH frame-check logic from
gNB_scheduler_bch.c to gNB_scheduler_primitives.c so they can be
reused (e.g. for both paging and SIB1).
Changes:
- check_frame_sib1() with NULL check for ssb_periodicityServingCell
and clearer logic
- Improved documentation
Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
OAI DFT has scaling issues when the signal is very strong or close to
full scale. So reduce amplitude by 10dB in gnb to prevent
overflow/clipping.
Signed-off-by: Sakthivel Velumani <s.velumani@northeastern.edu>
UE DL Channel compensation and LLR optimization (#142)
- Common channel compensation: Extracted nr_channel_compensation() as a
shared function (AVX2/MRC inline) used by both gNB and UE PDSCH/PUSCH
paths, eliminating duplicated compensation logic.
- Common ML/MMSE 2-layer MIMO: Created shared ML LLR and MMSE routines
for 2-layer spatial multiplexing, shared between gNB and UE
demodulation.
- File segregation: Moved common LLR and channel compensation functions
into dedicated source files for better modularity and reuse.
- nr_dlsim -E flag: Added a command-line argument to enable/disable
ML/MMSE equalization at runtime (MMSE default), enabling side-by-side
performance comparison without recompilation.
- Persistent UE buffer allocation: pdsch_dl_ch_estimates, rxdataF_comp,
dl_ch_mag,dl_ch_magb,dl_ch_magr and rho_dl are now allocated once in
PHY_VARS_NR_UE on first use, resize automatically when dimensions
change (resizeAllowed=true), and are freed at UE teardown in
term_nr_ue_signal. Eliminates per-slot heap allocation/free overhead.
- PTRS restricted to one antenna port: PTRS phase tracking is only valid
for a single port; processing now correctly restricted to avoid
unnecessary computation.
- Reduce rxdataF_comp buffer size: MRC combines all Rx antenna
contributions into a per-layer output, so the first dimension was
reduced from Nl * nb_antennas_rx to Nl, reducing buffer footprint
proportionally.
- 256QAM segfault fix: nr_256qam_llr() on gNB side used a VLA for LLRs
without alignment, causing AVX2 load faults. Fixed with
attribute((aligned(32))).
Reviewed-by: Sakthivel Velumani <s.velumani@northeastern.edu>
nr_channel_estimation() produces combined output of all antenna ports for each layer. So reduced the buffer size from no. of layer times no. of antennas to no. of layers.
Signed-off-by: Rupanjali <rupanjali.srivastava@openairinterface.org>
The current state of PTRS will not work for multiple antenna ports because the function assumes rxdataF_comp has signal for all antenna ports but it doesn't as we do MRC after DMRS compensation.
Signed-off-by: Rupanjali <rupanjali.srivastava@openairinterface.org>
After migration of github, we only use the commit ID for the
pre-ci-check script. This is problematic, because it checks for merges,
excluding the integration branch (expected to have merges), based on the
branch _name_.
In this commit, if a full SHA is detected as the branch "name", use "git
branch --points-at" to get a branch name, then use that to exclude
integration branches (or not). If no branch name is found, the branch
name "" is used, which will trigger the normal merge check (because ""
does not match the integration branch name).
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
RLC data req: Use API to fill multiple RLC PDUs at gNB (#145)
Use the RLC API to fill a transport block for a given LCID with a single
lock-unlock cycle.
This is a (partial) recommit of 4426fb1 which had been reverted later in
commit 8ed54d7.
Reviewed-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Reviewed-by: Francesco Mani <email@francescomani.it>
ci: remove first-time contributor job in workflow and update Jenkins job badges #147
- Remove the first-time contributor GitHub Actions workflow
- Update Jenkins image builder badge URLs to match the current job
names.
The first-time contributor workflow posts an automated welcome message
through github-actions[bot], creating additional bot activity on pull
requests. Contributor onboarding information is better maintained
through project announcements and documentation, where it is easier to
update and more visible to new contributors.
Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org>
- Remove the automated welcome message for first-time contributors.
Contributor related information will be maintained in project
announcements instead, avoiding additional bot activity on PRs.
- Update badge links for the Jenkins image builder jobs.
Signed-off-by: Shubhika Garg <shubhika.garg@openairinterface.org>
Use the RLC API to fill a transport block for a given LCID with a single
lock-unlock cycle.
This is a (partial) recommit of 4426fb1a2e
which had been reverted later in commit 8ed54d7077.
See: 4426fb1a2e ("RLC data req: Add API to fill multiple RLC PDUs in
one TB, use at gNB")
Fixes: 8ed54d7077 ("Refactor DL scheduler into staged pipeline with
pluggable function pointers")
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Migrate the Jenkins dispatch workflow from `pull_request` to
`pull_request_target` so that secrets are available for PRs from forks,
enabling CI to run on external contributions.
- Switch trigger from `pull_request` to `pull_request_target`
- Add `github.event.action` to concurrency group to prevent the `opened`
event from cancelling in-progress CI runs, which caused `detect-changes`
to be skipped on new PRs
- Remap `pull_request_target` back to `pull_request` in the
`X-Github-Event` header for Jenkins compatibility
- Remove `pr-retrigger-ci-instructions`
Co-authored-by: Sagar Arora <sagar.arora@openairinterface.org>
Co-authored-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Signed-off-by: Shubhika Garg <shubhika.garg@openairinterface.org>
- make internal links relative where applicable
- delete link to the wiki, as the documentation is in the main repo, not
the wiki
- remove some "example in oai code" as the examples either don't exist,
or are not in that place, and we can reasonably expect people to grep
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Add GitHub Actions workflow with 5 jobs:
- detect-changes: uses dorny/paths-filter to check whether files under
ci-scripts/ or .github/ were modified
- welcome-first-time-contributor: getting started and useful links for
first time contributors
- pr-retrigger-ci-instructions: instructions on how to retrigger the CI
without any PR changes
- require-maintainer-approval: requires manual approval via the
ci-approval GitHub environment when protected files changed,
preventing untrusted changes from triggering Jenkins automatically
- trigger-jenkins: triggers Jenkins by forwarding the GitHub event
payload via curl, skipping the approval gate when no protected files
changed
Add support for retriggering CI by adding a label to a PR. The label is
removed automatically after Jenkins is triggered, regardless of success
or failure, so it can be re-added at any time for subsequent retriggers.
Assisted-By: Claude:claude-sonnet-4-6
Co-authored-by: Sagar Arora <sagar.arora@openairinterface.org>
Co-authored-by: Shubhika Garg <shubhika.garg@openairinterface.org>
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Make the image tag unique per scheduled run and consistent with the branch
naming convention used in the other pipelines by suffixing the commit hash:
testBranch = "${sourceBranch}-${commitID}"
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Replace the manual fetch-and-merge approach with pre-built PR merge
refs to simplify checkout and eliminate explicit remote management:
- Add Job init stage to set build name and description for traceability
- Add Checkout stage that fetches refs/pull/<N>/merge for PR builds and
checks out targetBranch directly for push builds
- Remove sourceRepo parameter and "Add source repo & fetch branches" stage
- Remove "Merge target into source" stage (merge is handled by the GitHub
PR merge ref at checkout time)
Co-authored-by: Shubhika Garg <shubhika.garg@openairinterface.org>
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Replace GitLab-specific CI infrastructure with GitHub-compatible
equivalents in the main OAI RAN pipeline:
- Rename Jenkinsfile-GitLab-Container to Jenkinsfile-GitHub-Container
- Replace GitLab CI env vars with GitHub PR equivalents provided by
GitHub Integration plugin and GitHub Plugin
- Replace addGitLabMRComment / gitlabCommitStatus with githubPRComment
and githubNotify for PR comments and commit status reporting
- label validation within Jenkinsfile, remove the now-unused
checkGitLabMergeRequestLabels.sh helper script
- Remove git fetch from the pre-ci-check script as we now use
GITHUB_PR_HEAD_SHA. Fetching is redundant and may not retrieve
the PR head commit for fork-based contributions.
Move githubNotify for downstream jobs from triggerDownstreamJob into
finalizeDownstreamJob so each status check links directly to the HTML
test report artifact rather than the generic build page:
- Add downstreamResults map to pass job results (SUCCESS/FAILURE)
from trigger functions to finalizeDownstreamJob without changing the
existing always/failure post-block structure
- Map any non-success result (UNSTABLE, ABORTED) to FAILURE for GitHub
- Add targetUrl: BUILD_URL to the pipeline-level success/failure
githubNotify calls so the top-level check also links to the build
Consolidate GitHub PR comments to reduce noise:
- Buffer mrValidationWarning instead of posting it as a separate comment,
fold it into the final success or failure comment
- Remove the inline Local-Repo-Push-Dev failure comment, append to
failingStages so it appears in the single final failure comment
- Drop the success PR comment for clean builds - post only when there is
a validation warning to report
Assisted-By: Claude:claude-sonnet-4-6
Co-authored-by: Shubhika Garg <shubhika.garg@openairinterface.org>
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Integration: `2026.w22`
* !4140 Fix evaluation of PMI and CQI report when there is no RI report
* !4125 fix(phy): prevent division by zero in nr_csi_rs_pmi_estimation
* !4134 Add SRS LS and RSRP measurement logging for indoor positioning research
* !4086 vrtsim: Refactor peer antenna configuration and taps_client
* !4108 XNAP: Add encode/decode+unit tests for Xn HO Ack, Prep Failure, SN Status Transfer, UE Context Release
* !4096 O-RU fronthaul library
* !4147 1-port CQI report
* !4133 fix(config): fix memory safety, memory leaks, and add unit test coverage
* !4084 gold_cache: replace linear search with open-addressing hash table
* !4150 fix a few issues with unit tests
* !3827 Antenna port indexing of txdataF using FAPI spatial stream indices
* !4138 \[FHI72\] \[M-plane\] Implement dynamic compression
* !4144 fix(fhi72): Fix use-after-free bug in fhi_72 lib
* !3890 Fixes for multiplexing pattern 3 operations in FR2
* !4145 fix(vrtsim): handle CLOCK_REALTIME jump after PTP sync
* !4151 minor: fix nr rlc test make-based compilation
* !4141 wrong usage of extern declaration in C files, header cleanup
* !4153 doc: update 7.2 tutorial hardware and os configuration and add a doc to list supported hardware and OS
* !4066 Separate nfapi_p5.c into LTE and NR implementations
* !4098 \[CI OAI-FlexRIC\] Improve CI pipeline
* !3723 Support for aperiodic SRS at gNB
* !4076 Fix imscope and tracy build
* Fix the undefined `res` parameter if not defined K_RELEASE
* CI: Adjust timing thresholds in RAN-gNB-N300-Timing-Phytest-LDPC
* !3553 Add automated FHI72 4x4 nightly testing
* !4142 CI: Cleanup of Jenkinsfiles and parameters
* Adjust do_SRS after merge of !3723Closes#1086, #1097, #1022, and #1076
See merge request oai/openairinterface5g!4146
CI: Cleanup of Jenkinsfiles and parameters
- pass pre-computed branch from orchestrator to downstream jobs
- pass repository from orchestrator to downstream jobs, repository is now
configurable via ciRepositoryURL parameter of RAN-Container-Parent
- remove eNB_/ran-prefixed Jenkinsfile parameters
- address !4129 (comment 221898) and !4129 (comment 221900) and
!4129 (comment 221927)
Reviewed-By: Robert Schmidt <robert.schmidt@openairinterface.org>
Add automated FHI72 4x4 nightly testing
Add configuration files (conf, YAML, XML) for a new pipeline targeting
nightly high-throughput testing with FHI7.2 RUs. This pipeline is
designed to perform daily performance and stability testing using
either:
- the integration branch (to detect regressions in high-throughput
scenarios), or
- the develop branch (to collect up-to-date performance
metrics and observe long-term stability trends)
Details:
- testing with F1 split: DU runs on stonechat, CU runs on OC
- 4x4 MIMO, 4 DL layers layers with VVDN, LiteON, Metanoia, Bennetel550
and Benetel650 FHI7.2 RUs
- T2 card for LDPC processing
- TDD: DDDSU (special: DDDDDDDDGGGGUU) / DDDSU (special: DDDDDDGGGGUUUU)
for Benetel configrations
Reviewed-By: Robert Schmidt <robert.schmidt@openairinterface.org>
!3827 improved feprx processing time in 2x2 setup with 60MHz BW. Update
the timing thresholds accordingly.
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Avoid the following error in the always post condition:
Error when executing always post condition:
Also: org.jenkinsci.plugins.workflow.actions.ErrorAction$ErrorId: 1540dd3e-f4ca-410c-8c37-8977ada45325
hudson.AbortException: Failed to copy artifacts from RAN-ARM-Cross-Compile-Builder with filter: test_results*.html
Add "optional: true" to copyArtifacts so that a missing HTML report
is handled by the existing placeholder fallback instead of aborting
the post condition.
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Since MR !4116 removed support for building the L2sim proxy, there is no
longer a need to publish the proxy image to Docker Hub.
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Branch names containing '/' are invalid in Docker image tags. Compute a
sanitized testBranch variable once (replacing '/' with '-') in the
Verify Guidelines stage and pass it to both triggerSlaveJob (as the new
testBranch parameter) and triggerCN5GSlaveJob (as fullRanTag).
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
This change enables configuring the repository and branch to test
directly from Jenkins.
The default checkout performed by the testing pipeline is now skipped,
since it does not support parameterized git URLs. Instead, the SCM
checkout is executed during the Build Init step, allowing dynamic
repository selection.
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Jenkinsfile-GitLab-Container now constructs CI testing branch as
{sourceBranch}-{sourceCommit} and passes it explicitly to all downstream
jobs. Both Jenkinsfile and Jenkinsfile-push-local-repo consume it via
params.branch instead of independently reconstructing the name, ensuring
that the branch pushed by RAN-Local-Repo-Push and the branch checked out
by test jobs are always identical.
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
UP3 development UE is used since no dedicated CI UE is available for outdoor
testing. CN with PLMN 20899 can be deployed locally on demand, however for
now always-on CN is used (AMF IP address 172.21.6.5).
The gNB is currently configured with pdsch_AntennaPorts_N1 = 2 instead
of 4, as the proper 8x8 antenna configuration triggers an assertion in
polar procedures (see issue 1067). This will be corrected once the assertion
is resolved.
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Introduce a dedicated Jenkinsfile for nightly 4x4 runs. Increase the timeout
per test step to 150 minutes (vs. standard 60 minutes). Support dynamic branch
selection - if eNB_CommitID or eNB_Branch is set to "latest", the pipeline
resolves the latest develop or integration branch using get-latest-ref.sh script.
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Test description:
- FHI7.2 test with Metanoia RU and Quectel module
- 4 DL layers, 2 UL layers
- stonechat as DU host, CU running on OC
- LDPC processing on the T2 card
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Test description:
- FHI7.2 test with LiteON RU and Quectel module
- 4 DL layers, 2 UL layers
- stonechat as DU host, CU running on OC
- LDPC processing on the T2 card
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
This commit is intended primarily for comparison with CU/DU split deployments,
enabling data collection and performance evaluation across both configurations.
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Test description:
- FHI7.2 test with VVDN RU and Quectel module
- 4 DL layers, 2 UL layers
- stonechat as DU host, CU running on OC
- LDPC processing on the T2 card
Enable automatic retry of DU deployment to recover in case of following failure
during T2 initialization:
EAL: Unable to reset device! Error: 11 (Resource temporarily unavailable)
EAL: 0000:01:00.0 setup device failed
EAL: Driver cannot attach the device (01:00.0)
EAL: Failed to attach device on primary process
[PHY] T2 card 01:00.0 not found
Assertion (itf->nrLDPC_coding_init() == 0) failed!
In load_nrLDPC_coding_interface() /oai-ran/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_interface_load.c:66
error starting LDPC library ldpc (null)
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Use taskset with a dynamic range based on the number of detected processors
for OAI and DPDK build. This ensures both DPDK and OAI build steps use all
available CPU cores on the machine.
Build with XRAN K release
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Fix imscope and tracy build
Make headers required in imscope includable in C++ sources by removing
direct and indirect inclusions of VLAs.
Closes: #1076
Reviewed-By: Robert Schmidt <robert.schmidt@openairinterface.org>
Support for aperiodic SRS at gNB
Add support for aperiodic SRS, which currently, if activated, is
hardcoded to be periodically scheduled every 160 TTIs. The configuration
file has been changed, and instead of
do_SRS = 0/1
is now
do_SRS = "none"/"periodic"/"aperiodic"
Reviewed-By: Robert Schmidt <robert.schmidt@openairinterface.org>
Reviewed-By: Maxime Elkael <m.elkael@northeastern.edu>
[CI OAI-FlexRIC] Improve CI pipeline
1. Run the iperf instead of ping
2. SIGTERM added for nearRT-RIC so it shall gracefully stop in CI;
modify the line for nearRT-RIC service analysis
Reviewed-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Separate nfapi_p5.c into LTE and NR implementations
This MR aims to separate the implementation of the nFAPI P5 and P7
message pack/unpack procedures into 4G and 5G implementations.
This will be followed up with a separation of the VNF and PNF
implementations in 4G and 5G versions as well.
The final goal is to achieve a clean separation between 4G and 5G,
foregoing the need to compile 4G components when we only want to compile
5G ones.
Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org>
doc: update 7.2 tutorial hardware and os configuration and add a doc to list supported hardware and OS
1. The hardware details in the tutorial were very old; now we are using
some new systems
2. There is no need now to mention the old kernel version and firmware
version
3. I removed the configuration with tuned-adm, as it is confusing
sometimes. So it is better to use just GRUB. I have an OAI tuned
profile ready, but I will do it on another MR. I will check if it
works well on kernel 7.X before pushing
4. Add a document to list the tested/supported hardware on which we have
tested OAI. In another MR I will use that document as reference for
other tutorials as well.
Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org>
wrong usage of extern declaration in C files, and header cleanup
wrong usage of extern declaration in C files, instead of headers, and
fix hidden bugs by this wrong extern declaration duplication.
this fixes pure bugs because we cast variables to the wrong types, even
if the bug has no consequence
it also separates 4G/5G include files, as the error is also in the
headers mixup. Clean up header includes in F1AP.
Further remove some "CU/DUuniqinstances".
Reviewed-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
When calculating PRB DL/UL usage per UE, the division with 0 might occur
even though the scheduler was locked. It is expected to happen only while
the last UE is disconnecting.
Signed-off-by: Teodora Vladić <teodora.vladic@openairinterface.org>
Fixes for multiplexing pattern 3 operations in FR2
The standard (section 13 of 38.213) defines 3 SSB and CORESET 0
multiplexing patterns, which differ based on how the two channels are
respectively positioned in time and frequency. For MUX pattern 3, SSB
and CORESET 0 are transmitted in the same slot/symbols but on different
frequencies. With CORESET 0 being directly above or below in frequency
of SSBs, this means it does not start from symbol 0. This configuration
is important for more than 8 SSBs (FR2) to accommodate SIB1 in the
available DL slots (SIB1 in the same slot as its relative SSB), but it
is impractical for anything else. So for any other channel except SSB,
it is necessary to use a different common CORESET than CSET0 (namely
commonControlResourceSet).
This MR attempts to fix an issue in case the CORSET being smaller than
48 PRBs, triggering 2 symbol CORESET configuration, but the BWP being
larger than 48 PRBs so not taking into account the 2 symbol CORESET when
configuring other channels, e.g. PDSCH.
Reviewed-By: Luis Pereira <lpereira@allbesmart.pt>
This test runs the CU-UP, which has a default reconnection timeout of
1s. The test being limited, the following can happen:
- the CU-UP tries to connect, but the load tester did not start yet, so
waits one second
- test for 3s, and additional sleep at the end of 1s (to ensure all
packets are received).
- sum is 5s => timeout hits
Increase the timeout to improve stability.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
the vrtsim unit tests do not run reliably in the CI. Disable it for the
moment while investigating why.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Socket transport was getting imported everytime WLS was not.
This would lead to socket transport to be compiled when Aerial was compiled as well, now only one of the transports gets imported.
Signed-off-by: Rúben Soares Silva <rsilva@allbesmart.pt>
The relevant block for each library is now located in the CMakeLists.txt in the same directory as its sources, instead of the root CMakeLists.txt
The libraries have been renamed to follow a lowercase naming
Signed-off-by: Rúben Soares Silva <rsilva@allbesmart.pt>
Update NFAPI_LIB declaration to include both files.
Remove declaration of UE release functions from nr_nfapi_p7.h as those messages aren't part of 5G related SCF specification
Add NR_TIMING_INFO case to check_nr_fapi_unpack_length
Signed-off-by: Rúben Soares Silva <rsilva@allbesmart.pt>
Update NFAPI_LIB declaration to include both files.
Move measurement request functions from nfapi.c to nfapi_lte_p5.c, as the message is not part of SCF225 (5G), only SCF 082 (LTE)
Signed-off-by: Rúben Soares Silva <rsilva@allbesmart.pt>
For some reason, it's needed to have tty:true on the gNB section of the Aerial docker-compose files, if not, the following error occurs:
The L2 is not able to send messages to the L1, (nfapi_vnf_pnf_list_find(): could not find P5 connection for p5_idx 1)
By making sure the option tty is true on the docker-compose.yaml files, this error does not present itself.
Signed-off-by: Rúben Soares Silva <rsilva@allbesmart.pt>
[FHI72] [M-plane] Implement dynamic compression
- CUS: dynamic compression type implemented -> tested end-to-end with
Benetel RU.
- CUSM: use compression parameters explicitly via gNB config file (if
set) for RU configuration via M-plane -> DL C/U-plane packets are
good. However, not tested with Benetel RU since not supported.
Reviewed-By: Robert Schmidt <robert.schmidt@openairinterface.org>
fix a few issues with unit tests
1. fix unused argument warnings - running ninja tests fails on my system
due to too many warnings.
2. fix google benchmark build - sometimes, when building from scratch
the build will fail due to compiler warnings. I don't know why it
only happens sometimes but I've instead added a warning suppression
as this is not an issue in our code.
3. fix memory leak I've found here: !3827 (comment 224369)
4. fix running two testcases with ninja test or ctest -R. Due to them
being dependent on dlopen they would automatically fail if the user
environemnt was not modified manually outside cmake. I've modified
LD_LIBRARY_PATH for those test cases, meaning you no longer need to
run it with LD_LIBRARY_PATH=. or similar prefix.
Reviewed-By: Robert Schmidt <robert.schmidt@openairinterface.org>
fix(config): fix memory safety, memory leaks, and add unit test coverage
- Fix an out-of-bounds/segmentation fault in config_getlist when parsing
command-line options that do not specify bracket offsets (e.g.
--rfsimulator.serveraddr). Added index bracket verification and
guarded memcpy against NULL pointers on list reallocation.
- Initialize valid_idx to ParamList->numelt in config_getlist to
properly support overriding and appending elements when a
configuration file has existing array items.
- Fix memory leaks in end_configmodule
- Add test cases in test_config_cmdline.cpp
Reviewed-By: Robert Schmidt <robert.schmidt@openairinterface.org>
* use uint8_t instead of int16_t for `iq_width` (the value cannot be
negative)
* move <compression-type> outside the if condition since it's a mandatory
node
* use <compression-method> node
Signed-off-by: Teodora Vladić <teodora.vladic@openairinterface.org>
1-port CQI report
MR to extend the support for CQI reporting to CSI-RS with single port
Reviewed-By: Robert Schmidt <robert.schmidt@openairinterface.org>
Fix dft_test and nr_cuup_functional_test by adding CMAKE_BINARY_DIR to
LD_LIBRARY_PATH. This allows running the tests with `ninja test` or
`ctest -R` without modifying the environment manually.
Signed-off-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
Replace malloc with static memory to reduce possible memory leaks in
test_tpool_vs_actors.
Signed-off-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
This introduces 7.2 ORAN fronthaul library components that will be used
to implement an O-RU.
Directory Structure
- core/: Low-level networking and timing primitives.
* fh_recv: DPDK-based packet reception with callback support.
* fh_send: Immediate packet transmission utilities.
* fh_timer: GPS/System-aligned timing for symbol-accurate operations.
- oru/: O-RU specific application logic.
* oru_packet_processor: Manages C-Plane/U-Plane synchronization, IQ
data (un)packing, and TDD pattern validation
* oru_io: High-level I/O manager that integrates core primitives with
the packet processor.
* oru_fh: future integration that will provide a unified interface for
the entire fronthaul stack
- xran_pkt/: Protocol definition and API.
Architecture Overview
The library is designed for low latency and high throughput, leveraging
DPDK for direct hardware access. A key design principle is the
serialization of timer events and packet reception on the same thread,
which simplifies state management in the packet processor by avoiding
complex locking mechanisms.
For a pictoral representation, check MR !4096
Thread Deployment
1. Fronthaul Worker Thread (DPDK lcore)
This thread runs the fh_recv_run loop. It is responsible for:
- Polling the NIC for incoming eCPRI packets.
- Executing initial packet parsing and processing callbacks.
- Ticking the symbol timer.
2. Application threads
The O-RU application threads can utilize the thread-safe nature of
get_dl_iq and write_ul_iq to do parallel processing as needed.
Testing
Many unit tests were added, most notably a testcase against a PCAP
capture of the OAI O-DU C+UPlane configured with the liteon 4x4 config
(273 prb/jumbo frame)
Assisted-By: Gemini:Flash-3
Assisted-By: Gemini:Flash-3.5
Assisted-By: Gemini:Pro-3.1
Reviewed-By: Teodora Vladić <teodora.vladic@openairinterface.org>
XNAP: Add encode/decode+unit tests for Xn HO Ack, Prep Failure, SN Status Transfer, UE Context Release
This MR extends XnAP message support in accordance with 3GPP TS 38.423 v16.2.0 for the following procedures:
- Xn Handover Request Acknowledge
- Xn Handover Preparation Failure
- Xn SN Status Transfer
- Xn UE Context Release
Additional updates include:
- Implementation of ASN.1 encoder and decoder functions for all listed
procedures
- Addition of equality check helpers for all newly introduced message
structures
- Implementation of memory management (free) helpers
- Extension of XNAP unit tests to cover all implemented procedures
- Harmonization of AS key BIT_STRING conversion macro
Acknowledgement:
> This work was carried out as part of research and development at
> Indian Institute of Science (IISc), Bengaluru.
Reviewed-By: Guido Casati <guido.casati@openairinterface.org>
Most of the encoder/decoder F1 operation has been moved to a library
under openair2/F1AP/lib/. Thus, these includes are not actually
necessary, and are even problematic if code includes this header that is
not linked to F1AP (see next commit).
Remove all header includes, and put only the necessary ones into the
various source files instead (where they belong, as otherwise we get
massive include files that might even affect compile time).
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
- Fix an out-of-bounds/segmentation fault in `config_getlist` when parsing
command-line options that do not specify bracket offsets (e.g.
`--rfsimulator.serveraddr`). Added index bracket verification and guarded
`memcpy` against `NULL` pointers on list reallocation.
- Initialize `valid_idx` to `ParamList->numelt` in `config_getlist` to
properly support overriding and appending elements when a configuration
file has existing array items.
- Fix memory leaks in `end_configmodule`
- Add test cases in `test_config_cmdline.cpp`
Signed-off-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org> and assisted-by Gemini
Replace duplicated KENB_STAR_TO_BIT_STRING and
KGNB_STAR_TO_BIT_STRING macros with the unified
AS_KEY_STAR_TO_BIT_STRING helper across X2AP,
XNAP, M2AP, and M3AP code paths.
Also switch allocation to calloc_or_fail for
safer memory handling.
No functional change intended.
Signed-off-by: Rakesh BB <rakesh.bb@fsid-iisc.in>
- Add Xn SN Status Transfer message type definitions
- Implement encoder and decoder for Xn SN Status Transfer
Xn SN Status Transfer (3GPP TS 38.423v16.2.0 §9.1.1.4)
- Source NG-RAN node UE XnAP ID (M)
- Target NG-RAN node UE XnAP ID (M)
- DRBs Subject To Status Transfer List (M)
- Add equality check and memory management helpers
- Extend XNAP library unit tests to cover SN Status Transfer
Co-authored-by: Venkatareddy Akumalla <venkatareddy@fsid-iisc.in>
Signed-off-by: Rakesh BB <rakesh.bb@fsid-iisc.in>
vrtsim: Refactor peer antenna configuration and taps_client
Refactor peer antenna configuration and taps_client
This commit addresses several architectural issues in vrtsim,
specifically regarding how peer antenna counts are managed. Some
additional changes were made to allow unit tests and several fixes were
delivered.
Key changes:
1. Refactored peer antenna management:
* Removed the redundant 'peer_info_t' structure which overlapped with
ue_config and client_info.
* Added explicit 'peer_tx_ant' and 'peer_rx_ant' fields to
vrtsim_state_t.
* Server now pulls peer info from the UE config, while Client pulls it
from the GNB info published by the server.
2. Refactor taps_client to be thread safe
3. Fixed a bug where only the first antenna IQ was read from underlying
SHM mechanism
4. Test / usability related changes:
* Added support for configurable SHM channel names via
'--vrtsim.shm_channel_name' to prevent IPC conflicts between tests.
* Reduced the sleep() calls inside the code to reduce test runtime and
speedup vrtsim connection initialization and cleanup
* Added a unit tests for:
- transpartent channel mode
- taps_client mode
- cirdb mode
Reviewed-By: Merkebu Girmay <merkebu.girmay@openairinterface.org>
This commit addresses several architectural issues in vrtsim, specifically
regarding how peer antenna counts are managed. Some additional changes
were made to allow unit tests and several fixes were delivered.
Key changes:
1. Refactored peer antenna management:
- Removed the redundant 'peer_info_t' structure which overlapped with
ue_config and client_info.
- Added explicit 'peer_tx_ant' and 'peer_rx_ant' fields to vrtsim_state_t.
- Server now pulls peer info from the UE config, while Client pulls it from
the GNB info published by the server.
2. Refactor taps_client to be thread safe
3. Fixed a bug where only the first antenna IQ was read from underlying SHM
mechanism
4. Test / usability related changes:
- Added support for configurable SHM channel names via
'--vrtsim.shm_channel_name' to prevent IPC conflicts between tests.
- Reduced the sleep() calls inside the code to reduce test runtime and
speedup vrtsim connection initialization and cleanup
- Added a unit tests for:
+ transparent channel mode
+ taps_client mode
+ cirdb mode
Signed-off-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org> and assisted by Gemini
Add SRS LS and RSRP measurement logging for indoor positioning research
This MR adds measurement logging support for indoor positioning research
based on OAI gNB radio measurements.
The goal is to collect timestamped SRS LS channel estimates and averaged
RSRP values during experiments. These measurements are used offline for
Add T traces to store raw RSRP reports and SRS LS estimates
Reviewed-By: Francesco Mani <email@francescomani.it>
Reviewed-By: Robert Schmidt <robert.schmidt@openairinterface.org>
Reviewed-By: Rakesh Mundlamuri <rakesh.mundlamuri@openairinterface.org
1. Beam index:
So far rxdataF and txdataF had beam number as first index to separate freq
domain samples of antenna ports when mulitple beams are served in a slot.
This works fine when the beam is applied to entire symbol / slot but not
suitable for digital beamforming. This commit removes the beam number index
from the data buffers and the buffers hold all the antenna ports in the first
dimension. The antenna port index to be used for each UE in a MU-MIMO or
concurrent analog beam scenario is signalled by L2 via dedicated fields in
the FAPI PDU.
2. Beam ID array changes:
- The gNB and RU struct has a 2D array to hold beam IDs for all symbols in a
frame and all antenna ports. The order is now changes to first: symbol index
and second: antenna port because the RU access all ports' beam IDs for each
symbol / slot at a time. This ordering is optimal for maximizing cache hits.
- The type is now changed from int to uint16_t. So far the L1 had to deduce
the beam number index (done in beam_index_allocation()) from the beam ID sent
by L2 and this is done by initializing the beam_id array to -1 which denoted
no beam id set. Now since L2 explicitely passes the port indices, there is no
need for denoting if a beam id is assigned or not to a slot in L1. And
uint16_t matches with the type used by FAPI to carry beam ID. Since the type
is uin16_t, beam_id array is initialized to 0 and the check for -1 when
passing beam ID 0 to xran is also removed.
3. Number of antenna ports:
The removal of beam index from rxdataF and txdataF buffers resulted in all
antenna ports to be in a single vector. The number of logical ports passed to
L1 is not N1*N2*XP*number of beams per period. The buffer initialization
function is updated to reflect this change. DAS reference config file is
updated in accordance with these changes.
4. oaioran.c:
Remove the check of beam ID = -1 for setting nPrbElm = 0. This is a hack for
LiteON to supposedely improve performance according to Mario. If it's true
then a proper fix would be to pass allocation information from L1 and use it
instead of beam ID.
Signed-off-by: Sakthivel Velumani <s.velumani@northeastern.edu>
1. Added new config parameter to read RU port indices to be used via config
file.
2. When scheduling multiple UE on different beams in a slot, the antenna ports
used for each UE is explicitely passed down via fapi.
3. Fix dig_bf_interface_list by filling beam id for all logical ports used.
Signed-off-by: Sakthivel Velumani <s.velumani@northeastern.edu>
fix(phy): prevent division by zero in nr_csi_rs_pmi_estimation
In simulated environments like ZMQ, interference_plus_noise_power (IPN)
can be computed as zero, which could lead to a division-by-zero crash.
Fix this by ensuring interference_plus_noise_power is at least 1 at the
beginning of nr_csi_rs_pmi_estimation().
Closes: #1086
Reviewed-By: Francesco Mani <email@francescomani.it>
Add an O-RU centered fronthaul library that includes components
from the fronthaul directory.
Signed-off-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org> and assisted-by Gemini
Test the new O-RU packet processor against PCAP capture.
There are two testcases added:
- test_oru_pcap_1 - which tests DL & UL fragmentation using jumbo frames (9600 mtu)
- test_oru_pcap_frag - which injects the same pcap but tests the mtu to 1500 to force
large amounts of UL UPlane fragments
Signed-off-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org> and assisted-by Gemini
This commit introduces the O-RU (O-RAN Radio Unit) packet processor
implementation for handling UL & DL C-plane and U-plane
Key features include:
- Processing of eCPRI headers and Section Type 1 radio app headers.
- Strict timing validation against T2a minimum and maximum bounds for
both C-plane and U-plane symbols.
- A DPDK ring-based job queue for managing symbol processing state
(`dl_symbol_job_t`) across multiple concurrent symbol windows.
- Reordering of received CP & UP data so that produced IQ is always
in order.
- Extraction and buffering of IQ samples for downlink.
- Supports up to 4 fragments per symbol
Signed-off-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org> and assisted-by Gemini
Added a library that encompasses all dpdk requirements for a single O-RU.
Signed-off-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org> and assisted-by Gemini
Added xran_pkt which is a library of imported ORAN/eCPRI packet utilities
from xran library.
- merged xran_up_api.h/c and xran_cp_api.h/c into xran_pkt_api.h/c.
- reformatted the code.
- added unit test
- added an optional executable xran_pcap_dump which can extract some
fields of an ORAN pcap capture to stdout
Signed-off-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org> and assisted-by Gemini
This commit introduces a set of component libraries that can
be used to implement packet processing library for 7.2 fronthaul
interface.
Signed-off-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org> and assisted-by Gemini
Copying large struct one element at a time generates much more assembly code
than memcpy and the code becomes less maintainable. This commit copies parts of
structs using memcpy.
Signed-off-by: Sakthivel Velumani <s.velumani@northeastern.edu>
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>
Add T trace events for SRS least-squares channel estimate samples and individual MAC RSRP reports. These traces support indoor positioning research and offline dataset generation through the existing OAI tracing workflow instead of custom CSV logging.
Signed-off-by: Bingyu Zhou <s240331012@stu.cqupt.edu.cn>
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>
A new test case 5g_zmq_radio_trs is created by copying the folder
5g_zmq_radio_1x1. A gnuradio python script (rotate_zmq.py) generated by
grc is used to read the samples from gNB and apply a freq drift and send
them to a ZMQ sink. The UE reads samples from the ZMQ port on gnuradio.
The gnuradio script is modified to receive message containing freq
offsets from another script (send_freq_offset_zmq.py).
Dockerfile.gnuradio builds an ubuntu 24.04 image and copy both python
scripts.
Modified the docker-compose.yaml to include a new service gnuradio-zmq
that starts by running rotate_zmq.py.
Created container_5g_zmq_ocudu_trs.xml by copying
container_5g_zmq_ocudu_1x1.xml. Included a Custom_Command to run
send_freq_offset_zmq.py and another custom_command to grep the UE stdout
for TRS freq correction.
Added a PUSH socket in zmq_radio.cpp to send carrier frequency to
gnuradio and remove the offset applied so that the test can continue
without a freq offset.
Signed-off-by: Sakthivel Velumani <s.velumani@northeastern.edu>
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>
Add a new Dockerfile for optional features of OAI. Currently only imscope
is added but other features could be added in separate stages.
Build using:
docker build . -f ci-scripts/docker/Dockerfile.build.optional.ubuntu
Signed-off-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
The TracyCZone() macro stayed, but the function containing it changed in
a previous commit.
Fixes: e4b2125f1e ("Refactor PBCH & PSBCH UE procedures")
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
This commit moves certain functions and structs around to prevent including
functions taking VLA arguments in imscope C++ source files.
Signed-off-by: Bartosz Podrygajlo <bartosz.podrygajlo@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>
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>
this is done to be able to set DL TDA after calling config_sched_ctrlSIB1 and knowing the potential configuration of commonControlResourceSet for MUX pattern 3 which duration doesn't depend on the BWP size
Signed-off-by: Francesco Mani <email@francescomani.it>
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>
In simulated environments like ZMQ, interference_plus_noise_power (IPN)
can be computed as zero, which could lead to a division-by-zero crash.
Fix this by ensuring `interference_plus_noise_power` is at least 1 at
the beginning of `nr_csi_rs_pmi_estimation()`.
Signed-off-by: Bartosz Podrygajlo <bartosz.podrygajlo@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>
measurement bitmap for CSI-RS is 0 means CSI-RS for tracking. So don't
return and proceed with processing the CSI-RS.
Signed-off-by: Sakthivel Velumani <s.velumani@northeastern.edu>
TRS resources if configured by gnb, is present in two consequtive slots
and two symbols per slot. LS estimates from the first symbol is saved
and in second symbol frequency offset and time offset is estimated. The
estimated FO is saved in UE global structure which is used in the last
TRS slot. If the FO is above a threshold, the radio's center frequency
is adjusted.
Time offset is estimated but not used because time is already tracked
using PBCH DMRS.
Signed-off-by: Sakthivel Velumani <s.velumani@northeastern.edu>
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>
After detecting PSS, SSS and PBCH there is no need to compensate for FO
in rxbuffer. SIB1 is detected from freshly received samples that are FO
compensated at the radio.
Signed-off-by: Sakthivel Velumani <s.velumani@northeastern.edu>
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>
2026-05-11 16:58:44 +02:00
638 changed files with 36041 additions and 13216 deletions
@@ -69,7 +75,7 @@ To find all READMEs, this command might be handy:
find . -iname "readme*"
```
# RAN repository structure #
## RAN repository structure
The OpenAirInterface (OAI) software is composed of the following parts:
@@ -94,9 +100,9 @@ openairinterface5g
└── tools : Tools for use by the developers/ci machines: code analysis and formatting
```
# How to get support from the OAI Community #
## How to get support from the Community
You can ask your question on the [mailing lists](https://gitlab.eurecom.fr/oai/openairinterface5g/-/wikis/MailingList).
You can ask your question on the [mailing lists](https://github.com/duranta-project/openairinterface5g/wiki/MailingList).
Your email should contain below information:
@@ -107,6 +113,6 @@ Your email should contain below information:
- OAI gNB/DU/CU/CU-CP/CU-UP configuration file in `.conf` format only.
- Logs of OAI gNB/DU/CU/CU-CP/CU-UP in `.log` or `.txt` format only.
- In case your question is related to performance, include a small description of the machine (Operating System, Kernel version, CPU, RAM and networking card) and diagram of your testing environment.
- Known/open issues are present on [GitLab](https://gitlab.eurecom.fr/oai/openairinterface5g/-/issues), so keep checking.
- Known/open issues are present on [Github](https://github.com/duranta-project/openairinterface5g/issues), so keep checking.
Always remember a structured email will help us understand your issues quickly.
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.