An xApp for the O-RAN SC near-real-time RIC that turns an A1 policy into an inter-gNB Xn handover on the RAN, over the E2 interface.
A non-real-time RIC application decides which user equipment should move where and expresses that as an A1 policy. This xApp receives the policy, encodes an E2SM-RC RIC Control Request (RIC Control Style 3 "Connected Mode Mobility", Control Action 1 "Handover Control"), sends it to the source gNB, and reports the gNB's answer back on A1.
rApp ──A1 policy (REST)──▶ A1 Mediator ──RMR 20010──▶ Handover xApp
│
pre-flight: E2 Manager + E2SM-KPM
│
RMR 12040 (RIC Control Request)
▼
E2 Termination
│ E2AP / SCTP
▼
source gNB
│ XnAP
▼
target gNB
│
rApp ◀──A1 response──── xApp ◀──RMR 12041 / 12042 (Control Acknowledge / Failure)
The A1 response is only sent once the gNB has answered, so a handover the RAN rejects is reported as a failure rather than a success.
Policy type 20100 by default. The payload:
{
"amf_ue_ngap_id": 1,
"target_nr_cell_id": "0x000001",
"plmn": "00101",
"gnb_cu_ue_f1ap_id": 1,
"e2_node_id": "gnb_<plmn>_<gnb-id>"
}| Field | Required | Meaning |
|---|---|---|
amf_ue_ngap_id |
yes | Identifies the user equipment at the CU-CP. Integer, 0 .. 2^40-1 per TS 38.413 §9.3.3.1 |
target_nr_cell_id |
yes | 36-bit NR Cell Identity of the target cell. Hex string or integer |
plmn |
yes | Must match the RAN's PLMN |
gnb_cu_ue_f1ap_id |
no | Defaults to amf_ue_ngap_id |
e2_node_id |
no | Defaults to the connected E2 node, when there is exactly one |
Create the policy type and an instance through the A1 Mediator:
A1=http://<ric-host>:<a1-nodeport>/A1-P/v2
curl -X PUT "$A1/policytypes/20100" -H 'Content-Type: application/json' -d @policy-type.json
curl -X PUT "$A1/policytypes/20100/policies/ho-1" -H 'Content-Type: application/json' -d '{
"amf_ue_ngap_id": 1,
"target_nr_cell_id": "0x000001",
"plmn": "00101"
}'See BUILD.md for the full guide: building the image, loading it into
the cluster's container runtime, deploying it as a Pod in the ricxapp namespace,
registering it with the application manager, and troubleshooting.
docker build -t handover-xapp:1.0.0 .
kubectl apply -f deploy/handover-xapp.yamlThe image fetches RMR and riclibe2ap from the O-RAN SC package repository and
installs the O-RAN SC Python xApp framework at a pinned commit.
| Variable | Default |
|---|---|
POLICY_TYPE_ID |
20100 |
E2MGR_URI |
http://service-ricplt-e2mgr-http.ricplt:3800 |
SUBMGR_URI |
http://service-ricplt-submgr-http.ricplt:8088/ric/v1 |
RMR_SRC_ID |
container hostname |
RAN_FUNC_ID |
discovered by OID |
KPM_SUBSCRIBE |
false |
KPM_REPORT_PERIOD_MS |
10000 |
KPM_GRANULARITY_MS |
10000 |
KPM_METRICS |
RRC.ConnMean,RRC.ConnMax,RRC.ConnEstabAtt |
PREFLIGHT |
true |
PREFLIGHT_MAX_AGE_S |
3 report periods |
CONTROL_AWAIT |
true |
CONTROL_TIMEOUT_S |
5 |
LOG_LEVEL |
INFO |
RMR_LOG_VLEVEL |
unset |
Command line: --config, --http_server_port (default 8090), --rmr_port
(default 4560), --policy_type_id.
| Endpoint | Purpose |
|---|---|
GET /ric/v1/cells |
Latest measurements per E2 node, from E2SM-KPM indications |
GET /ric/v1/subscriptions |
Subscription state per node |
GET /ric/v1/xapp/health |
Liveness, subscription and indication counters |
This repository is not under a single licence. Files written by coRAN LABS are
Apache-2.0; the library under src/lib and the framework patch under docker/ are the
work of Software Radio Systems Limited under AGPL-3.0 and are used unmodified except
where recorded. See NOTICE for the file-by-file breakdown, the record of
changes made to the AGPL-3.0 files, and what applies when redistributing.