395 Commits

Author SHA1 Message Date
Robert Schmidt
69a017f57b Merge remote-tracking branch 'Thecave3/e3-agent-framework' into integration_2026_w27
Implementation of the E3 Agent for dApps and E3AP (no service models) (#204)

These changes introduce an E3 Agent for dApps in the OAI codebase. dApps
are real-time microservices designed to operate within the O-RAN
ecosystem, enabling sub-10 ms Artificial Intelligence (AI) routines in
the Radio Access Network (RAN).

The E3 Agent enables spectrum sensing, frequency-domain signal logging,
and dynamic PRB (Physical Resource Block) policies through IPC/ZMQ
communication with dApps or xApps.

The dApps are designed for co-location with the CU/DU, where it can
interact directly with user-plane data to enable different network
management scenarios such as optimizing network slicing, scheduling, and
resource management.  A python library for the creation of the dApps is
available here [1].

Additional information about dApps:

- Paper on the dApp architecture [2]
- dApp framework presentation [3]
- Tutorial on dApp deployment on OAI [4]

As agreed in the original MR [5], this PR includes only the agent lifecycle,
configuration parsing, build plumbing, and the nr-softmodem init/destroy
hook.

It registers zero service models, so it builds and runs as an idle
agent. Concrete service models (e.g. spectrum sensing) and the PHY/MAC
hooks that drive them follow in later PRs.

Opt-in and dependencies

- Gated behind the E3_AGENT CMake option (OFF by default) / the
  --build-e3 build flag.  The default build is unaffected — e3ap is only
  compiled and linked into nr-softmodem when E3_AGENT=ON.

- When enabled, requires the external libe3 library [6] (vendor-neutral
  E3AP C++ lib), discovered via pkg_check_modules(CLIBE3 REQUIRED
  libe3). It is not vendored.

  Install libe3 (Debian/Ubuntu):

      git clone https://github.com/wineslab/libe3 && cd libe3
      ./build_libe3 -I      # installs deps: build-essential cmake pkg-config libzmq3-dev asn1c nlohmann-json3-dev libsctp-dev ...
      ./build_libe3 --install      # release build + installation

Build & test

Tested in RFsim: the gNB initializes the E3 agent, opens its setup
socket (/tmp/dapps/setup), registers zero service models, and runs
without crashing.  Configuration

The agent reads an optional E3Configuration section from the gNB config
file (parsed only when E3_AGENT=ON). If absent, it falls back to
built-in defaults (posix/ipc).

    E3Configuration : {
        link = "zmq";        # posix | zmq
        transport = "ipc";   # tcp | sctp | ipc
    };

The same parameters can be overridden on the command line (no
config-file edit required):

    sudo ./nr-softmodem -O <gnb.conf> ... --E3Configuration.link zmq --E3Configuration.transport ipc

Validated link/transport combinations: (zmq,ipc) (zmq,tcp) (posix,tcp)
(posix,sctp) (posix,ipc).

Notes

- I have added a new log component E3AP specific for the ops performed
  by the E3 Agent.
- This PR ships no gNB config file; the E3Configuration block / CLI
  override above is the documented way to enable the agent. Example
  configs follow in the next PRs.

[1] https://pypi.org/project/dapps/
[2] https://arxiv.org/pdf/2501.16502
[3] https://openrangym.com/o-ran-frameworks/dapps
[4] https://openrangym.com/tutorials/dapps-oai
[5] https://gitlab.eurecom.fr/oai/openairinterface5g/-/merge_requests/3361
[6] https://github.com/wineslab/libe3

Reviewed-by: Teodora Vladić <teodora.vladic@openairinterface.org>
Reviewed-by: Sagar Arora <sagar.arora@openairinterface.org>
Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org>
2026-07-02 18:35:23 +02:00
Andrea Lacava
29c20ac232 e3ap: add E3 agent lifecycle and nr-softmodem init hook
Add the E3 agent lifecycle on top of libe3: configuration mapping,
agent creation/init/start, dApp report and status-change handlers,
and xApp control and subscription-query helpers. Wire e3_init() and
e3_destroy() into nr-softmodem under the E3_AGENT guard.

The agent registers no concrete service models: service models (such
as spectrum sensing) live in their own modules and register
themselves, keeping the framework decoupled from any specific use
case.

Signed-off-by: Andrea Lacava <thecave003@gmail.com>
2026-07-02 09:53:52 -04:00
Robert Schmidt
61a1e8c0d8 Remove common_lib.h includes
After having removed eth_params_t from all L2/L3 files, we can reduce
the scope of common_lib.h, and remove the include from many files.

Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
2026-06-30 11:34:09 +02:00
francescomani
36ed4d9ff1 get gnb ownership of RC to avoid compiling ENB_APP_SRC in NR
Signed-off-by: francescomani <email@francescomani.it>
2026-05-12 18:42:58 +02:00
francescomani
d5c0e580ab removed few more unused parameters
Signed-off-by: francescomani <email@francescomani.it>
2026-05-01 14:29:58 +02:00
francescomani
6c39ea2b0b remove unnecessary pdcp_run hack in nr-softmodem
Signed-off-by: francescomani <email@francescomani.it>
2026-05-01 13:54:33 +02:00
Bartosz Podrygajlo
384886ce48 Ensure trx_stop is called before trx_end
Make sure the radio libs are stopped before `end()` call. This allows
for a cleaner exit under most circumstances. Some libraries like zmq_radio
don't exit cleanly without it.
2026-04-22 22:34:02 +02:00
francescomani
0b3216f889 further compilation cleanup 2026-03-31 16:45:25 +02:00
Robert Schmidt
8107939f08 Change OAI license to CSSL v1.0 (and others)
- all RAN code, CI code, configuration files, dockerfiles, in CSSL v1.0
- all deployment code (openshift, charts, ancillary files like shell
  scripts), in MIT
- documentation in CC-BY-4.0
- exceptions might apply and are listed in NOTICE
- there is a new LICENSES folder with all licenses
- CONTRIBUTIONS.md has been updated accordingly

For automated changes based on OAI PL v1.1:

    perl -i~ -0pe 's/\/\*.*Licensed to the OpenAirInterface.*openairinterface.org\n#?/\/*\n * SPDX-License-Identifier: LicenseRef-CSSL-1.0\n/s' **/*.{c,h,cpp}
    perl -i~ -0pe 's/\/\*.*Licensed to the OpenAirInterface.*openairinterface.org\n#?/\/*\n * SPDX-License-Identifier: LicenseRef-CSSL-1.0\n/s' **/*.ts
    perl -i~ -0pe 's/<!--.*Licensed to the OpenAirInterface.*openairinterface.org\n.*-->/<!-- SPDX-License-Identifier: LicenseRef-CSSL-1.0 -->/s' **/*.xml

The rest (cmake, files with missing license, cmake) manually.
2026-03-27 16:36:37 +01:00
Raghavendra Dinavahi
0b100620f4 Changed uplink_frequency_offset from int32 to int64, required for NTN-FR2 2026-03-09 11:50:30 +01:00
Robert Schmidt
82315ead3e Fail early if configuration module can not initialize properly
In the case that the config module cannot load the driver for libconfig
or yaml, currently, there might be a cascade of errors that are
difficult for users to understand. For instance (partially redacted for
clarity):

    [CONFIG] Error calling dlopen(libparams_libconfig.so): libparams_libconfig.so: cannot open shared object file: No such file or directory
    [CONFIG] config module "libconfig" couldn't be loaded
    [CONFIG] config_get, section log_config skipped, config module not properly initialized
    [LOG] init aborted, configuration couldn't be performed
    [CONFIG] config_get, section (null) skipped, config module not properly initialized
    [CONFIG] /home/francesco/openairinterface5g/common/config/config_userapi.c 68 nfapi has no processed integer availablle
    [CONFIG] config_get, section (null) skipped, config module not properly initialized

    Assertion (get_softmodem_params()->default_pdu_session_id == -1) failed!
    In get_common_options() /home/francesco/openairinterface5g/executables/softmodem-common.c:161
    Use uicc0.pdu_sessions.[0].id to change the requested PDU session ID (is 0)

Here, the error is the missing shared object, but a user is more likely
to look at the last error instead of the first.

This commit addresses it by checking early for
CONFIG_ISFLAGSET(CONFIG_ABORT), and stopping if it is set. Additionally
changes include making functions static, removing late
CONFIG_ISFLAGSET() checks, and the CONFIG_ISFLAGSET() in
load_configmodule(), because at that time "uniqCfg" is not set yet and
thus does not do anything (this is likely a regression of an earlier
cleanup).

See-also: f50d5f5a9b ("make multiple config instead of one implicit
  global")
2026-02-19 17:06:29 +01:00
Bartosz Podrygajlo
315fe92253 Enable imscope for split7.2 2026-02-03 10:04:42 +01:00
Thomas Schlichter
877b8ed0a0 remove some unused global variables from nr-softmodem.c and nr-uesoftmodem.c 2026-01-26 11:41:33 +01:00
Xin Zhe Khooi
c978d1664f nr-softmodem: ensure RU is ready before L1 init in NFAPI PNF mode
PROBLEM: In PNF mode, L1 is started from nfapi_pnf.c without verifying RU
readiness. The only gate is config_sync_var, but nr_softmodem.c sets this before
the RU  (e.g., FHI-72) is actually started. As a result, START_REQUEST can
trigger L1  init while the RU is not yet ready -- this is an issue when using
FHI72 with  DPDK BBDEV, where a pre-mature L1 init will crash the entire program
as DPDK BBDEV depends on xRAN's DPDK EAL.

FIX: Perform RU readiness checks before setting config_sync_var in NFAPI PNF mode.
This aligns PNF behavior with other modes and prevents L1 from starting before the
RU is operational.
2026-01-19 17:04:13 +01:00
Robert Schmidt
1140c59bbd Merge remote-tracking branch 'origin/fix-OAI_RNGSEED-usage' into integration_2025_w49 (!3786)
Consistently use OAI_RNGSEED env variable for RNG

use OAI_RNGSEED env variable everywhere. Hide normal table
initialization of Ziggurat generator from outside. Fix atoi() to use
stroul()
2025-12-01 15:20:23 +01:00
Laurent THOMAS
a1b4220a91 Exclusively use OAI_RNGSEED env variable everywhere
Hide normal table initialization of Ziggurat generator from outside to
force the usage of randominit() for RNG initialization. In this step,
remove the randominit() seed parameter and only rely on OAI_RNGSEED for
a consistent RNG initialization, as this parameter was used differently
("0" as fixed number or to force a random seed).

Now, only use OAI_RNGSEED env variable to force the usage of a fixed
seed.
2025-12-01 12:10:31 +01:00
Jaroslava Fiedlerova
0226510c4a Merge remote-tracking branch 'origin/fapi-stop-exchange' into integration_2025_w48 (!3561)
Implementation of STOP exchange

This implements the STOP.request/indication for all 3 transport mechanisms, the
VNF will send the STOP.request to the PNF, indicating it will disconnect, and
await a STOP.indication from the PNF

The WLS VNF is reworked to be able to start before the PNF, by calling call
rte_eal_init and rte_dev_probe to determine if dpdk has been initialized
properly, before calling rte_eal_init in the intended process when it is
appropriate to do so
2025-11-27 15:01:39 +01:00
Robert Schmidt
d3026267b3 Merge remote-tracking branch 'origin/remove-sched-response-doc' into integration_2025_w46 (!3757)
Remove schedule response and update L1 threading documentation

This merge requests removes the somewhat superfluous "schedule response"
mechanism. "schedule response" was run after running the scheduler
itself and copied various FAPI messages into a global msgDataTx
structure from which the various TX/RX jobs were triggered. It is not
necessary, though, given that the scheduler is run inside the tx_func()
(running the TX jobs of the L1), and so the scheduler output FAPI
messages can directly be read into a variable of the existing
NR_Sched_Rsp_t type. This allows to delete a couple of hundred lines of
code (while retaining functionality), and simplifies the msgDataTx type
(which is still there to trigger TX job (including the scheduler) from
the ru thread).

In short, prior, there was this call chain:

- tx_func() calls run_scheduler_monolithic() (through fptr
  NR_slot_indication())
  - get some memory through allocate_sched_response() which has enough
    space for NR_Sched_Rsp_t type variable
  - call the scheduler and fill the variable
  - call nr_schedule_response() (through fptr NR_schedule_response())
    which copies into L1: to msgDataTx for TX, to separate structures
    for RX

this is changed to

- tx_func() runs one message at a time, hence we can use memory in the
  data segment for NR_Sched_Rsp_t. It calls run_scheduler_monolithic()
  through the fptr
  - pointers into NR_Sched_Rsp_t are passed to the scheduler, which
    fills as before
  - we return, memory is in its right place and does not need an extra
    copy.

Additionally, this merge request updates documentation on threading and
cleans up some unused code along the way.
2025-11-14 22:03:01 +01:00
Robert Schmidt
5ac381dd59 Remove dead code 2025-11-14 18:17:29 +01:00
Teodora
b6bda6d974 RIC IP address within fr_args_t struct is not const anymore
Related FlexRIC commit ID: fd26e7474d
2025-11-13 11:58:11 +01:00
Rúben Soares Silva
e08d904af0 Implementation of STOP exchange
This implements the STOP.request/indication for all 3 transport mechanisms, the VNF will send the STOP.request to the PNF, indicating it will disconnect, and await a STOP.indication from the PNF

The WLS VNF is reworked to be able to start before the PNF, by calling call rte_eal_init and rte_dev_probe to determine if dpdk has been initialized properly, before calling rte_eal_init in the intended process when it is appropriate to do so
2025-10-23 14:08:37 +01:00
francescomani
b8683dd351 check command line for unknown options at gNB 2025-09-16 10:22:05 +02:00
Robert Schmidt
8ccd944db2 Merge remote-tracking branch 'origin/rf_emulator_and_timers_fix' into integration_2025_w34 (!3589)
RF emulator and improvements of the timers

RF emulator:
Add an RF library emulating a real device without the need of a real
device.  This is thought to enable using phy-test without requiring a
radio device or channel simulation.  The library synchronizes on the
real time clock, drops TX and generate noise on RX.  Noise generation
can be disabled and the noise level configured.

Timers improvements:
- Fix standard deviation for merged timers
- Add display of ULSCH decoding timers
- Add decoding timer in AAL
2025-08-21 15:22:44 +02:00
Robert Schmidt
89e6e53f8c Remove --emulate-rf option and corresponding code
With the RFemulator, there is no need for a dedicated --emulate-rf
option anymore. For all uses of --emulate-rf, RFemulator should be used
instead.
2025-08-21 10:53:03 +02:00
Laurent THOMAS
4b47d26ea2 remove dirty and unused functions with global vars (not working anyway) 2025-08-20 09:36:48 +02:00
Laurent THOMAS
c2d9f17242 remove a dependancy of gNB to LTE that is not used and adds global vars to gNB 2025-08-20 09:36:48 +02:00
Robert Schmidt
465d7de5a9 Remove --usim-test command line option
Remove the --usim-test option: to my knowledge, it's not used by users,
and is misleadingly placed in various places where there should not be a
difference w.r.t. USIM configuration.

When making the changes, I assumed that --usim-test would be 0 (the
default), which is the case in all executables when not specified in
options except for the nr_dlsim, nr_pbchsmi, nr_ulsim simulators.

The only exception is the initialization of PDCP from the MAC, which is
not correct (the PDCP is in the CU, so it does not make sense to call it
from the MAC which is in the DU). Instead, always initialize from main,
even in the NSA case (NSA was covered by the incorrect initialization
from MAC).

This in turn let to some more cleanup around function du_rlc_data_req().
After receiving GTP packets at the DU, they were given to the PDCP to
enqueue the packet at RLC. This does not work anymore, since the PDCP is
not initialized; it also does not seem necessary, as this enqueue
functionality is necessary to decouple PDCP and RLC to avoid deadlocks
in monolithic, but in split-mode, this cannot happen. Instead, call
directly into the RLC when receiving GTP packets.
2025-07-23 12:12:59 +02:00
Robert Schmidt
02bc14d8c1 get xran stats
Get xran stats in the trx_oran_get_stats function
and use trx_oran_get_stats upon stopping and ending RF.

Co-authored-by: Romain Beurdouche <romain.beurdouche@eurecom.fr>
2025-07-09 14:55:44 +02:00
Robert Schmidt
f0ca66adcd Remove unused MAC types and includes
Using the USIM interface in the MAC is non-sensical (violates layer
separation). Add header include in nr-softmodem.c, which previously came
through nr_mac_gNB.h -> usim_interface.h.
2025-06-10 18:00:49 +02:00
Robert Schmidt
a1e1405ee6 Start E1 before gNB_app
In phy-test and do-ra modes, we will trigger a UE context creation after
F1 Setup (because the DU is ready), in a later commit. However, before
this commit, E1 is started after the gnb_app (which triggers F1 Setup).
E1 starts an (integrated) CU-UP; if the E1 Setup arrives after the F1
setup (which creates a UE context), then the E1 setup handler will drop
the newly created RRC context for a do-ra/phy-test mode.

Avoid/minimize this by starting E1 first, so that E1 setup is done
before F1 Setup is completed (this does not make sure the problem does
not happen, but lowers the risk of the above problem).
2025-05-01 10:03:23 +02:00
Robert Schmidt
8ee0b8efdf Introduce mac_top_destroy_gNB(): free MAC memory 2025-04-24 17:22:42 +02:00
Cedric Roux
b89b3abd13 API change: new arguments to time_manager_start() 2025-04-18 09:05:39 +02:00
Cedric Roux
7cbedb1575 time management module
This commit introduces a time management module.

See doc/time_management.md for details.
2025-04-18 09:02:54 +02:00
Jaroslava Fiedlerova
315ed8e564 Merge remote-tracking branch 'origin/nr-gnb-config-refactor' into integration_2025_w16 (!3293)
Cleanup and refactor initial gNB configuration

This is follow-up on !3048 (merged). Major changes in this MR:
- Add config functions to reduce redundant code repeated in multiple places in the file
- Add macros to reduce redundant code in gNB configuration
- Refactor RCconfig_NR_NG
- Cleanup obsolete and commented out code
- Refactor includes in executables/nr-gnb.c
- Introduce platform type plmn_id_t for consistency across the stack: F1AP, NGAP can now use the same struct type
- And other minor formatting
2025-04-17 19:56:58 +02:00
Bartosz Podrygajlo
1ab8a58a2f Refactor TUN Interface Management and Move to SDAP Layer
This commit refactors the TUN interface management by moving its creation
and configuration from the PDCP layer to the SDAP layer for UE.

Key changes include:

- Introduced `tun_generate_ue_ifname` and `tun_destroy` functions for better
  TUN interface lifecycle management.
- Added support for creating and destroying UE-specific TUN interfaces in SDAP.
- Refactored `nr_pdcp_module_init` to remove TUN-related logic and moved it
  to SDAP.
- Updated NAS and SDAP layers to handle PDU session-specific TUN interface
  creation and configuration.
- Enhanced SDAP entity management to include TUN socket handling and thread
  lifecycle.
- Updated NAS message handling to initialize default PDU session TUN
  interfaces in NOS1 mode.
- Use a single SDAP thread function for gNB and UE
- Allow noS1 mode also in SA on gNB

These changes improve modularity by isolating TUN interface management within
the SDAP layer, aligning with the 3GPP architecture, and simplifying the PDCP
layer.

Co-Authored-By: Robert Schmidt <robert.schmidt@openairinterface.org>
2025-04-16 15:03:18 +02:00
Guido Casati
65e9ad7fdf Move get_node_type after init_gNB 2025-04-15 15:28:36 +02:00
Guido Casati
1cdd684e24 Use plmn_id_t in RRC struct 2025-04-15 15:28:36 +02:00
francescomani
535d8e7765 other SIBs scheduling configuration in SIB1 2025-04-14 10:15:45 +02:00
francescomani
cea4412b3b do not include LTE defs_common into 5G code 2025-04-01 18:53:09 +02:00
francescomani
38734ee31c remove nr_mac_extern file 2025-03-03 17:00:26 +01:00
Robert Schmidt
723acf7e60 Merge remote-tracking branch 'origin/more-layer1-cleaning' into integration_2025_w05 (!3218)
More Layer1 cleaning

Cleanup, see commits for info
2025-01-31 08:00:37 +01:00
Laurent THOMAS
5416be3736 move byte2m128i in a more logical place 2025-01-30 17:14:10 +01:00
Bartosz Podrygajlo
ab75a7ccfb Add IQ file recording and IQ file viewer to ImScope
This commit introduces the following changes to ImScope:
 - Added the ability to record IQ data using the same mechanism as ImScope.
 - Added a new executable target `imscope_iq_file_viewer` for viewing IQ files.
 - Introduced a command line argument `--imscope-record` that enables data recording mode.
 - Refactored a lot of the scope code

Usage:
 - To record IQ data, run a modem with `--imscope-record` flag.
   The recording happens whenever a modem calls dumpScopeData, which currently is
   done only in gNB on PUSCH DTX and PUSCH CRC NOK.
   There is a limit of ~1GB of files written by the thread in a signle run to avoid
   accidentally exhausting disk space.
   If a directory `imscope-dump` is available the data will be recorded there in .imscope
   files. Otherwise files are written to the directory the modem was run. This is done so that
   the directory can be mapped in a docker container.

 - To view recorded IQ files, use the new executable `imscope_iq_file_viewer`. This can be done by running:
      ```
      ./imscope_iq_file_viewer <path_to_iq_file>
      ```
   Replace `<path_to_iq_file>` with the path to the IQ file you want to view.
2025-01-28 16:54:54 +01:00
Robert Schmidt
1b44f6448b Allow to use multiple PUCCH at once
We are required to store multiple PUCCH (e.g., for multiple UEs).
However, nr_fill_pucch() automatically freed the previously active PUCCH
structure. Of course(!) this does not make sense.

However, the problem is that init_nr_transport() allocated only one
PUCCH structure. Also this does not make sense to me. The problem was
that slot_ahead was 0, which logically cannot happen in this function
(because slot_ahead is illogical, we must give the radio some time). The
reason is that it uses if_inst->sl_ahead, which, prior to this commit,
was not set.

The init_nr_transport() function is called normally from main() through
init_eNB_afterRU(). In this case, we initialize if_inst->sl_ahead to
what is set in main(). In the PNF case, however, we call
init_nr_transport() from the PNF thread, when receiving the start
request. In the main(), we wait for this to happen, before setting
if_inst->sl_ahead. Hence, initializing this variable (which we should
safely be able to do) before solves the problem.
2025-01-27 10:59:15 +01:00
Robert Schmidt
4132fcc597 Place NFAPI waiting after RU init; don't wait for F1 if in PNF
harmonize with monolithic
2025-01-22 18:29:55 +01:00
Laurent THOMAS
e0ca70c36d replace a set of #define by a C bit array, remove duplicated extern global variable declaration 2025-01-09 15:28:25 +01:00
Robert Schmidt
68ae3ea11c Implement start_L1L2()
Implements the re-start of the L1 after it has been stopped through
stop_L1(). It takes into account some changes, such as bandwidth, or
frequency, when restarting the L1. To this end, it also triggers a
gNB-DU configuration update message on each restart to inform the CU
about any changes in the DU. FDD has not been tested.
2024-12-16 16:18:11 +01:00
Robert Schmidt
8e32f566fc Refactor code to stop L1
Refactor L1 stopping code into a function. The function is basically the
same as what we were doing at the end of main() of nr-softmodem.c.

This will be reused to support the "soft-restart" functionality in the
next commits.
2024-12-16 16:18:10 +01:00
Laurent THOMAS
279d49415f remove un-necessary global variables 2024-12-04 12:26:36 +01:00
Guido Casati
893102a104 Refactor includes in nr-softmodem.c 2024-11-18 11:25:02 +01:00