Skip to content

Implementation of the E3 Agent for dApps and E3AP (no service models)#204

Merged
4 commits merged into
duranta-project:developfrom
Thecave3:e3-agent-framework
Jul 4, 2026
Merged

Implementation of the E3 Agent for dApps and E3AP (no service models)#204
4 commits merged into
duranta-project:developfrom
Thecave3:e3-agent-framework

Conversation

@Thecave3

Copy link
Copy Markdown
Collaborator

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.

Additional information about dApps:

As agreed in the original MR, 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 unaffectede3ap is only compiled and linked into nr-softmodem
    when E3_AGENT=ON.

  • When enabled, requires the external libe3 library (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.

@Thecave3 Thecave3 self-assigned this Jun 17, 2026
@Thecave3 Thecave3 added 5G-NR Perform 5G Tests gNB labels Jun 17, 2026
@Thecave3 Thecave3 added this to the REVIEW_CAN_START milestone Jun 18, 2026
@durantabot

Copy link
Copy Markdown
Collaborator

@Thecave3 Thecave3 changed the title Implementation of the E3 Agent for dApps and E3APs (no service models) Implementation of the E3 Agent for dApps and E3AP (no service models) Jun 18, 2026
@Thecave3 Thecave3 requested a review from rorsc June 18, 2026 14:07
@durantabot

Copy link
Copy Markdown
Collaborator

CI Build: #423 | Failed on the following stages:

Comment thread openair2/E3AP/e3_agent.c
Comment thread openair2/E3AP/CMakeLists.txt
Comment thread openair2/E3AP/config/e3_config.h
Comment thread openair2/E3AP/config/e3_config.c
@arora-sagar

Copy link
Copy Markdown
Member

@Thecave3 Are you planning to put a document/tutorial on how to use the E3 agent with the dApps framework?

Also, it will be nice if the document covers the definition and explanation of dApps

@arora-sagar

Copy link
Copy Markdown
Member

Also, a CI testing scenario would be good, so we can make sure that the implementation is working consistently.

@Thecave3

Copy link
Copy Markdown
Collaborator Author

@Thecave3 Are you planning to put a document/tutorial on how to use the E3 agent with the dApps framework?

Also, it will be nice if the document covers the definition and explanation of dApps

Yes sure, I can add a README.md inside the E3AP folder if it helps. There is already a tutorial on deploying and using dApps with OAI at https://openrangym.com/tutorials/dapps-oai that covers the full setup, from installing the dApp library to running a spectrum-sharing example against the gNB. A more focused document specific to the E3 agent configuration (the E3Configuration block, link/transport options, and how to wire a new service model)

Also, a CI testing scenario would be good, so we can make sure that the implementation is working consistently.

The plan is to add a CI stage that installs libe3 (from its repo) before invoking --build-e3, similar to how FlexRIC is handled. I was thinking of deferring this to a later PR that includes also a Service Model so it can be reviewed independently from the agent framework itself. Any advise on what is the best approach and what would you like to check here?

@Thecave3

Copy link
Copy Markdown
Collaborator Author

I left the TOC to be aligned with other .md files in the repo, but it's not rendered in github.

@durantabot

Copy link
Copy Markdown
Collaborator

CI Build: #432 | Failed on the following stages:
The pipeline may have failed due to CI, validation, or scripting error. See the build for more details.

@Thecave3

Copy link
Copy Markdown
Collaborator Author

Not sure if this is related with the PR

Found unhandled hudson.remoting.ProxyException exception:
org.kohsuke.github.HttpException: {
  "message": "Bad credentials",
  "documentation_url": "https://docs.github.com/rest",
  "status": "401"
}
	PluginClassLoader for github-api//org.kohsuke.github.GitHubConnectorResponseErrorHandler$1.onError(GitHubConnectorResponseErrorHandler.java:88)
	PluginClassLoader for github-api//org.kohsuke.github.GitHubClient.detectKnownErrors(GitHubClient.java:504)
	PluginClassLoader for github-api//org.kohsuke.github.GitHubClient.sendRequest(GitHubClient.java:464)
	PluginClassLoader for github-api//org.kohsuke.github.GitHubClient.sendRequest(GitHubClient.java:427)
	PluginClassLoader for github-api//org.kohsuke.github.Requester.fetch(Requester.java:85)
	PluginClassLoader for github-api//org.kohsuke.github.GHRepository.read(GHRepository.java:147)
	PluginClassLoader for github-api//org.kohsuke.github.GHPerson.getRepository(GHPerson.java:162)
	PluginClassLoader for pipeline-githubnotify-step//org.jenkinsci.plugins.pipeline.githubstatusnotification.GitHubStatusNotificationStep.getRepoIfValid(GitHubStatusNotificationStep.java:270)
	PluginClassLoader for pipeline-githubnotify-step//org.jenkinsci.plugins.pipeline.githubstatusnotification.GitHubStatusNotificationStep.access$100(GitHubStatusNotificationStep.java:80)
	PluginClassLoader for pipeline-githubnotify-step//org.jenkinsci.plugins.pipeline.githubstatusnotification.GitHubStatusNotificationStep$Execution.run(GitHubStatusNotificationStep.java:383)
	PluginClassLoader for pipeline-githubnotify-step//org.jenkinsci.plugins.pipeline.githubstatusnotification.GitHubStatusNotificationStep$Execution.run(GitHubStatusNotificationStep.java:365)
	PluginClassLoader for workflow-step-api//org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution$1$1.call(AbstractSynchronousNonBlockingStepExecution.java:47)
	hudson.security.ACL.impersonate2(ACL.java:446)
	PluginClassLoader for workflow-step-api//org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution$1.run(AbstractSynchronousNonBlockingStepExecution.java:44)
	java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
	java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
	java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	java.base/java.lang.Thread.run(Thread.java:1583)

@rorsc

rorsc commented Jun 25, 2026

Copy link
Copy Markdown
Member

Not sure if this is related with the PR

[...]

I don't think so, it was on notifying Github. The actual build was/is fine. you can ignore that

@rorsc

rorsc commented Jun 25, 2026

Copy link
Copy Markdown
Member

I left the TOC to be aligned with other .md files in the repo, but it's not rendered in github.

Good, thanks. I left them in case people have links to Gitlab (which is now a mirror), so the TOC would show there. On Github, it automatically renders a TOC which you access by clicking on a button at the top right.

@teodora-vladic teodora-vladic self-requested a review June 25, 2026 09:16
Comment thread openair2/CMakeLists.txt Outdated
Comment thread openair2/E3AP/config/e3_config.c Outdated
Comment thread openair2/E3AP/CMakeLists.txt Outdated
Comment thread openair2/E3AP/CMakeLists.txt
Comment thread openair2/E3AP/config/e3_config.c
Comment thread openair2/E3AP/e3_agent.c Outdated
Comment thread openair2/E3AP/e3_agent.c Outdated
Comment thread openair2/E3AP/config/e3_config.h
@durantabot

Copy link
Copy Markdown
Collaborator

@durantabot

Copy link
Copy Markdown
Collaborator

CI Build: #475 | Failed on the following stages:

@sgarg00 sgarg00 added the retrigger-ci Re-run CI label Jun 26, 2026
@github-actions github-actions Bot removed the retrigger-ci Re-run CI label Jun 26, 2026
@sgarg00 sgarg00 added the retrigger-ci Re-run CI label Jun 26, 2026
@github-actions github-actions Bot removed the retrigger-ci Re-run CI label Jun 26, 2026
@durantabot

Copy link
Copy Markdown
Collaborator

@durantabot

Copy link
Copy Markdown
Collaborator

@rorsc rorsc mentioned this pull request Jun 30, 2026

@rorsc rorsc left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please make so that all commits compile, I think it's a small change and would be potentially useful if we need to verify stuff later, or for bisecting

Comment thread openair2/CMakeLists.txt
Comment thread openair2/E3AP/CMakeLists.txt
Comment thread openair2/E3AP/e3_agent.c Outdated
Comment thread openair2/E3AP/README.md Outdated
@arora-sagar

Copy link
Copy Markdown
Member

@Thecave3 Are you planning to put a document/tutorial on how to use the E3 agent with the dApps framework?
Also, it will be nice if the document covers the definition and explanation of dApps

Yes sure, I can add a README.md inside the E3AP folder if it helps. There is already a tutorial on deploying and using dApps with OAI at https://openrangym.com/tutorials/dapps-oai that covers the full setup, from installing the dApp library to running a spectrum-sharing example against the gNB. A more focused document specific to the E3 agent configuration (the E3Configuration block, link/transport options, and how to wire a new service model)

Thanks for the documentation.

Also, a CI testing scenario would be good, so we can make sure that the implementation is working consistently.

The plan is to add a CI stage that installs libe3 (from its repo) before invoking --build-e3, similar to how FlexRIC is handled. I was thinking of deferring this to a later PR that includes also a Service Model so it can be reviewed independently from the agent framework itself. Any advise on what is the best approach and what would you like to check here?

Yes, it is fine to do it in another PR.

Thecave3 added 4 commits July 2, 2026 09:51
Introduce the E3_AGENT CMake option (default OFF) and the matching
--build-e3 flag in build_oai so the E3 agent for O-RAN dApps can be
compiled opt-in. Gate the E3AP subdirectory and the nr-softmodem
linkage behind the option, and register an E3AP log component
together with its legacy T-tracer message IDs.

The E3 interface (nGRG) lets the gNB exchange real-time reports and
controls with external dApps. Keeping it behind a build flag leaves
the default CI build unchanged and avoids pulling in the external
libe3 dependency unless the agent is explicitly requested.

Signed-off-by: Andrea Lacava <thecave003@gmail.com>
Add the E3AP CMake target, which links the external libe3 library
discovered via pkg-config, and the E3Configuration parser that reads
the link and transport selection from the gNB configuration file and
validates the supported link/transport combinations.

libe3 is kept external and is only required when E3_AGENT is enabled.

Signed-off-by: Andrea Lacava <thecave003@gmail.com>
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>
Signed-off-by: Andrea Lacava <thecave003@gmail.com>
rorsc added a commit that referenced this pull request Jul 2, 2026
…ration_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>
@durantabot

Copy link
Copy Markdown
Collaborator

@rorsc rorsc closed this pull request by merging all changes into duranta-project:develop in 0dab3bb Jul 4, 2026
@Thecave3 Thecave3 deleted the e3-agent-framework branch July 5, 2026 15:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

5G-NR Perform 5G Tests gNB

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants