xDevSM
Overview
The xDevSM API framework provides xApp developers with a SDK exposing simple APIs to streamline the procedures defined by different E2SM protocols, facilitating interactions between the xApp, the near-RT RIC, and the E2 termination on the RAN.
It wraps and orchestrates message encoding/decoding, RMR-based communication, and SM-specific behavior. Internally, it delegates encoding and decoding tasks to the sm_framework, which defines the core logic for each Service Model (KPM, RC, and CCC).
xDevSM is built on top of ricxappframe python framework.
The architecture separates three main layers:
- xApp API Layer — developer-facing classes (
BasexDevSMXapp,xDevSMRMRXapp, wrappers). - Service Model Wrappers — expose KPM, RC, and CCC functionalities.
- sm_framework — performs actual encoding/decoding (internal).
⚠️ The xDevSM framework is designed to operate exclusively with the O-RAN Software Community (OSC) Near-RT RIC.
ℹ️ The current version has been tested with the OSC RIC Release J.
Supported Service Model Actions
| Service Model | Action Type | Supported Actions |
|---|---|---|
| KPM (Key Performance Measurement) | Measurement Actions | • Common Condition-based Measurement, UE-level Measurement |
| RC (RAN Control) | Control Actions | • QoS Flow Mapping Configuration • Slice-level PRB Quota Action (only monolithic gNBs) • Connected Mode Mobility Control |
| CCC (Cell Configuration and Control) | Report Actions | • Cell-level RAN Configuration Reporting (REPORT Style 2, periodic event trigger) — e.g. O-NRCellDU attributes |
Installation
xDevSM is distributed as the xdevsm package on PyPI:
pip install xdevsm
ℹ️ The package bundles the prebuilt
sm_frameworkencoders (.so) as package data and is published as a source distribution, so a linux-x86_64 environment and Python 3.11 are required (matching the O-RAN SC Near-RT RIC deployment target). Python 3.12+ is not supported:ricxappframedepends onricsdl, which pinshiredis==2.0.0, and that version cannot be built on 3.12 or later.No
LD_LIBRARY_PATHsetup is needed — the bundled encoders are loaded relative to the installed package. A C compiler is required, though:hiredis==2.0.0ships no wheel for 3.11, so pip builds it from source. Slim base images therefore needgccinstalled (the fullpython:3.11-bullseyeimage already has it).
For local development (tests, editable install):
git clone https://github.com/wineslab/xDevSM.git
cd xDevSM
pip install -e ".[dev]"
pytest tests/ -v
Importing
Everything lives under the top-level xdevsm package. The developer-facing classes are also
re-exported from the package root for convenience:
# Convenience (recommended)
from xdevsm import xDevSMRMRXapp, XappKpmFrame, XappCccFrame, RadioBearerControl
# Or import from the fully-qualified submodules
from xdevsm.handlers.xDevSM_rmr_xapp import xDevSMRMRXapp
from xdevsm.decorators.kpm.kpm_frame import XappKpmFrame
from xdevsm.decorators.ccc.ccc_frame import XappCccFrame
Class Hierarchy
BasexDevSMXapp
└── xDevSMRMRXapp
└── BaseXDevSMWrapper
├── xAppReportService
│ ├── XappKpmFrame
│ └── XappCccFrame
└── xAppControlService
├── RadioBearerControl
├── RadioResourceAllocationControl
└── ConnectedModeMobilityControl
ℹ️ A detailed diagram is available here.
1. BasexDevSMXapp
Defines the core xApp interface that integrates xDevSM functionality with RMR. Provides the fundamental methods used by all xDevSM-based xApps.
Base class implementing the RMR communication layer. It provides generic send(), receive(), and terminate() methods for message passing between xApps and the Near-RT RIC.
| Method | Description |
|---|---|
handle(xapp, summary, sbuf) |
Method called by the ricxappframe. Entry point for processing received messages (Indication and RIC CONTROL Messages`). Should be overridden by subclasses. |
send(self, *args, **kwargs) |
Sends a message via RMR after encoding. Input depends on the underlying E2SM. |
terminate() |
Gracefully stops the xApp. |
get_ran_function_description(json_ran_info) |
Uses the sm_framework to decode the RAN function description depending on the SM. |
3. xDevSMRMRXapp
Purpose:
Extends BasexDevSMXapp to provide additional functionality specific to the xDevSM architecture.
Key Methods:
| Method | Description |
|---|---|
register_handler(handler) |
Registers callback handlers. |
register_shutdown(handler) |
Registers a shutdown handler for cleanup tasks. |
get_ran_info() |
Returns E2 node-related encoded information. |
This class is used as the base class for wrapper components.
4. BaseXDevSMWrapper
Purpose:
Provides a composition interface that connects Service Model–specific APIs (KPM, RC, etc.) with an instance of xDevSMRMRXapp. This allows to decorate the xApp with Service Model realted behavior.
Attributes:
xapp_handler— instance ofBasexDevSMXapp.
Usage:
This class is not used directly but extended by RIC service bases (xAppReportService, xAppControlService) and then by Service Model–specific decorators (e.g. XappKpmFrame, RadioResourceAllocationControl) that expose the actual APIs.
5. XappKpmFrame
Purpose: Implements the external API for the Key Performance Measurement (KPM) Service Model.
Internally, it uses encoding and decoding classes from the sm_framework to handle message serialization before E2AP wrapping and RMR transmission.
Common Operations:
- Encode KPM Subscription Requests.
- Decode and Parse received KPM Indications.
Example:
xapp_gen = xDevSMRMRXapp(...)
kpm_api = XappKpmFrame(xapp_handler)
kpm_api.subscribe(gnb=self.selected_gnb,
ev_trigger=ev_trigger_tuple,
func_def=func_def_sub_dict,
ran_period_ms=1000,
sst=self.sst, sd=
self.sd)
6. XappCccFrame
Purpose:
Implements the external API for the Cell Configuration and Control (CCC) Service Model (ORAN-E2SM-CCC, RAN Function OID 1.3.6.1.4.1.53148.1.1.2.4, SM ID 149). Like XappKpmFrame, it is a REPORT-type decorator and extends xAppReportService, mirroring the KPM lifecycle (subscribe → indication decode → callback).
Unlike KPM and RC, E2SM-CCC uses a JSON wire encoding rather than ASN.1, so the CCC encoders/decoders in sm_framework/py_oran/ccc/ are pure-Python and never cross into the native .so libraries.
Common Operations:
- Encode CCC Subscription Requests — periodic Event Trigger (Format 3) + cell-level Action Definition (Format 2, REPORT Style 2).
- Decode and parse received CCC Indications via
CccIndicationHeader/CccIndicationMessage.
Supported REPORT style:
| Style | Description |
|---|---|
| REPORT Style 2 — Cell Level | Reports RAN Configuration Structures (e.g. O-NRCellDU) and a selected set of attributes (arfcnDL, bSChannelBwDL, bWPList, …) per cell. |
Example:
xapp_gen = xDevSMRMRXapp("0.0.0.0", route_file=args.route_file)
ccc_xapp = XappCccFrame(xapp_gen,
logger=xapp_gen.logger,
server=xapp_gen.server,
xapp_name=xapp_gen.get_xapp_name(),
rmr_port=xapp_gen.rmr_port,
http_port=xapp_gen.http_port,
pltnamespace=xapp_gen.get_pltnamespace(),
app_namespace=xapp_gen.get_app_namespace())
# Wire callbacks
xapp_gen.register_handler(ccc_xapp.handle)
ccc_xapp.register_ind_msg_callback(handler=indication_callback) # (hdr, msg, meid, sub_id)
ccc_xapp.register_sub_fail_callback(handler=sub_failed_callback)
# Subscribe to a periodic cell-level REPORT on O-NRCellDU
ccc_xapp.subscribe(gnb=selected_gnb,
ran_period_ms=1000,
ran_cfg_structure_name="O-NRCellDU",
attributes=["arfcnDL", "bSChannelBwDL", "bWPList"])
# or the one-call helper for those three target attributes:
ccc_xapp.subscribe_arfcn_bw_bwps(gnb=selected_gnb, ran_period_ms=1000)
ℹ️ The indication callback signature is
handler(ind_hdr, ind_msg, meid, sub_id). Iterate the reported cells/structures withind_msg.cells()/ind_msg.iter_structures().
7. xAppReportService
Purpose: Provides the base class for Report-type Service Models. Handles subscription management, indication message routing, and decoding.
Common Responsibilities:
- Build and send E2 subscription requests.
- Route incoming indication messages to registered callbacks.
- Interface with
sm_frameworkfor decoding RAN function descriptions.
Specializations:
| Subclass | Description |
|---|---|
XappKpmFrame |
Implements KPM-specific subscription and indication handling. |
XappCccFrame |
Implements CCC-specific (Cell Configuration and Control) subscription and indication handling over a JSON encoding. |
8. xAppControlService
Purpose: Provides the base class for the Radio Control (RC) Service Model. Defines shared functionality across different RC control operations.
Common Responsibilities:
- Initialize and validate RC messages.
- Interface with
sm_frameworkfor encoding and decoding. - Offer helper methods for constructing Control Requests.
- Handle RIC Control Acknowledge and Failure messages.
Specializations:
| Subclass - Style | Description | Control Action Id Support |
|---|---|---|
RadioBearerControl - 1 |
Handles bearer-level control (QoS, bearer setup/release). | (2) QoS flow mapping configuration |
RadioResourceAllocationControl - 2 |
Manages resource allocation (e.g., PRB or scheduling). | (6) Slice-level PRB quota |
ConnectedModeMobilityControl - 3 |
Manages handover and mobility-related control procedures. | (1) Handover control |
Each subclass defines Service Model–specific operations and message structures, invoking the appropriate encoder/decoder from sm_framework.rc.
ℹ️ Control parameters can be modified using getter and setter methods.
Example: Radio Bearer Control Initialization
xapp_gen = xDevSMRMRXapp("0.0.0.0", route_file=args.route_file)
rc_xapp = RadioBearerControl(xapp_gen,
logger=logger,
server=xapp_gen.server,
xapp_name=xapp_gen.get_xapp_name(),
rmr_port=xapp_gen.rmr_port,
http_port=xapp_gen.http_port,
mrc=xapp_gen._mrc,
pltnamespace=xapp_gen.get_pltnamespace(),
app_namespace=xapp_gen.get_app_namespace(),
# control parameters
drb_id=args.drb_id,
qos_flow_id=args.qos_flow_id,
qos_flow_mapping_indication=args.qos_flow_mapping_indication
)
Example: Radio Resource Allocation Control
xapp_gen = xDevSMRMRXapp("0.0.0.0")
rc_xapp = RadioResourceAllocationControl(xapp_gen,
logger=logger,
server=xapp_gen.server,
xapp_name=xapp_gen.get_xapp_name(),
rmr_port=xapp_gen.rmr_port,
http_port=xapp_gen.http_port,
mrc=xapp_gen._mrc,
pltnamespace=xapp_gen.get_pltnamespace(),
app_namespace=xapp_gen.get_app_namespace(),
# control parameters
plmn_identity="00F110",
sst=1,
sd=1,
min_prb_policy_ratio=10,
max_prb_policy_ratio=70,
dedicated_prb_policy_ratio=5
)
Example: Connected Mode Mobility Control
xapp_gen = xDevSMRMRXapp("0.0.0.0")
rc_xapp = ConnectedModeMobilityControl(xapp_gen,
logger=logger,
server=xapp_gen.server,
xapp_name=xapp_gen.get_xapp_name(),
rmr_port=xapp_gen.rmr_port,
http_port=xapp_gen.http_port,
mrc=xapp_gen._mrc,
pltnamespace=xapp_gen.get_pltnamespace(),
app_namespace=xapp_gen.get_app_namespace(),
# control parameters
plmn_identity="00F110",
nr_cell_id="00000000000000000000111000000001"
)
9. Service Model Encoder/Decoder
The sm_framework provides the internal logic for encoding and decoding messages according to the KPM, RC, and CCC Service Models. The xDevSM decorators are organized by RIC service direction: xAppReportService and xAppControlService are the generic bases for report- and control-style services, and any service model (KPM, RC, CCC, ...) plugs in by extending the appropriate base — for example XappKpmFrame and XappCccFrame extend xAppReportService, and RadioResourceAllocationControl extends xAppControlService.
ℹ️ KPM and RC serialize through ctypes bindings to the native
.solibraries, whereas CCC (E2SM-CCC) uses a pure-Python JSON codec insm_framework/py_oran/ccc/.
[ xApp code ] → [ xDevSM API ] → [ sm_framework (encode/decode) ] → [ E2AP + RMR ]
Developers using xDevSM do not directly call sm_framework; it is fully managed by the wrapper classes.
10. Example xApps
For end-to-end examples of KPM, RC, and CCC xApps built on top of this API, see:
This repository contains working implementations that demonstrate:
- How to set-up an xApp based on xDevSM.
- Registration of handlers.
- Sending and receiving encoded Service Model messages.
The CCC basic xApp (ccc_xapp.py) is a minimal reference: it subscribes to a periodic O-NRCellDU REPORT (Style 2 / Event Trigger Format 3) and pretty-prints every incoming indication (cell identity, frequencies, SSB, BWP list, …).
11. Extending the API
To support a new Service Model (E2SM):
- Implement the encoder/decoder in
sm_framework/<new_sm>/. - Create a new wrapper subclass (e.g.,
XappNewSMFrame) extendingBaseXDevSMWrapper. - Implement SM-specific methods (e.g.,
send_<msg>(),handle_<msg>()). - Register handlers for the new message types in your xApp.
12. Other Sources
A detailed step-by-step tutorial for setting up a deployment to begin working with xDevSM is available here.
How To Cite
If you use xDevSM, please reference the following paper:
A.Feraudo, S. Maxenti, A. Lacava, P. Bellavista, M. Polese, and T. Melodia, "xDevSM: Streamlining xApp Development With a Flexible Framework for O-RAN E2 Service Models," Proceedings of the 18th ACM Workshop on Wireless Network Testbeds, Experimental evaluation & Characterization (WiNTECH), November, 2024.
License
This project is licensed under Apache License Version 2.0 - see License File for more details.
Organizations
| Wireless Networks and Embedded Systems Lab | |
|---|---|
| Mobile Middleware Research Group |
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file xdevsm-0.1.0.tar.gz.
File metadata
- Download URL: xdevsm-0.1.0.tar.gz
- Upload date:
- Size: 2.8 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
39e792db886f8d5c459c002d32c184f81acd58a377b23783c4cc090eef1ae237
|
|
| MD5 |
b80b462736f4f6f623e0d82614e6c611
|
|
| BLAKE2b-256 |
08fa54333cf3cac61c66cfec97dd890d52e53a7a5038bc4356da0d932c98369e
|
Provenance
The following attestation bundles were made for xdevsm-0.1.0.tar.gz:
Publisher:
tag-and-release.yml on wineslab/xDevSM
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
xdevsm-0.1.0.tar.gz -
Subject digest:
39e792db886f8d5c459c002d32c184f81acd58a377b23783c4cc090eef1ae237 - Sigstore transparency entry: 2438000824
- Sigstore integration time:
-
Permalink:
wineslab/xDevSM@de6b6480aa6e3e380ac3a2cfa6eb6019d200ff79 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/wineslab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
tag-and-release.yml@de6b6480aa6e3e380ac3a2cfa6eb6019d200ff79 -
Trigger Event:
push
-
Statement type: