Ocudu RAN Monitor and Operate
Monitor, operate, and query a running Ocudu 5G RAN stack. Collect real-time JSON metrics over WebSocket, read YAML configuration files, start/stop components, and run connectivity tests.
Prerequisites
- Ocudu gNB must be running with remote control enabled in its config:
metrics: enable_json: true remote_control: enabled: true bind_addr: 0.0.0.0 # or 127.0.0.1 for localhost-only port: 8001 - Python 3.8+ with the
websocket-clientpackage:pip install websocket-client
Environment
This is how the 5G stack is deployed:
| Component | Runs on | Details |
|---|---|---|
| Ocudu gNB | Host (bare metal) | Binary at ~/ocudu/build/apps/gnb/gnb, config at ~/gnb_zmq.yaml |
| srsUE | Host (bare metal) | Binary at ~/srsRAN_4G/build/srsue/src/srsue, config at ~/ue_zmq.conf |
| Open5GS 5GC | Docker | Container name: open5gs_5gc, manages AMF/SMF/UPF |
| RF transport | ZMQ | Simulated radio link between gNB and UE via ZMQ sockets |
Checking if components are running
# Check gNB (runs on host, not Docker)
ps aux | grep gnb | grep -v grep
# Check UE (runs on host, not Docker)
ps aux | grep srsue | grep -v grep
# Check 5G Core (runs on Docker)
docker ps | grep open5gs
# Check gNB logs
tail -30 /tmp/gnb.log
Important: The gNB and UE are NOT Docker containers. Do not use docker commands to manage them. They are native host processes.
Starting components
Start in this order: 5GC first → gNB → UE.
# 1. Start 5G Core (if not running)
cd ~/ocudu/docker && docker compose up -d 5gc
# 2. Start gNB (requires sudo, runs in foreground)
cd ~/ocudu/build/apps/gnb && sudo ./gnb -c ~/gnb_zmq.yaml
# 3. Start UE (requires sudo, runs in foreground, in a separate terminal)
cd ~/srsRAN_4G/build/srsue/src && sudo ./srsue ~/ue_zmq.conf
Note: Both gNB and UE run in the foreground as interactive processes. They occupy their terminal session.
Stopping components
Stop in reverse order: UE first → gNB → 5GC.
Method 1 — Interactive (if you have terminal access):
Type q and press Enter in the running gNB or UE terminal session to gracefully shut down.
Method 2 — Programmatic (recommended for AI agent):
# Stop gNB via WebSocket quit command (clean shutdown via SIGTERM)
python3 -c "import websocket, json; ws = websocket.create_connection('ws://127.0.0.1:8001'); ws.send(json.dumps({'cmd': 'quit'})); ws.close()"
# Stop UE via signal (graceful shutdown)
sudo kill -SIGTERM $(pgrep -f srsue)
# Stop 5G Core
cd ~/ocudu/docker && docker compose down
Warning: Always confirm with the user before stopping any component. Stopping the gNB disconnects all UEs.
Connectivity testing
The UE's network interface runs inside a network namespace called ue1. To send traffic through the UE:
# Ping the UPF gateway (tests UE → gNB → 5GC path)
sudo ip netns exec ue1 ping 10.45.1.1
# Ping an external host (requires NAT on 5GC)
sudo ip netns exec ue1 ping 8.8.8.8
# Check UE's IP address and routes
sudo ip netns exec ue1 ip addr show
sudo ip netns exec ue1 ip route show
Important: Do NOT use regular ping from the host — it bypasses the RAN entirely. Always use sudo ip netns exec ue1 to route traffic through the UE's PDU session.
Step 1 — Get Connection Details
Ask the user for:
- WebSocket URL — host and port of the gNB remote control interface (default:
127.0.0.1:8001) - Config file path — path to the gNB YAML config file (optional, for config queries)
Step 2 — Collect Metrics
Use the helper script to grab a metrics snapshot:
python3 <SKILL_DIR>/scripts/ws_metrics.py --url <HOST>:<PORT> --count 3 --timeout 10
Arguments:
| Argument | Default | Description |
|---|---|---|
--url |
127.0.0.1:8001 |
WebSocket host:port |
--count |
3 |
Number of metric messages to collect |
--timeout |
10 |
Connection timeout in seconds |
--pretty |
(flag) | Pretty-print JSON output |
The script connects, subscribes to metrics, collects the specified number of messages, then cleanly disconnects. Output is one JSON object per line on stdout.
Important: Each metrics message covers a different layer of the stack. You will typically receive separate messages for:
- Scheduler metrics (per-UE and per-cell)
- MAC metrics
- CU-CP metrics (NGAP + RRC)
- Executor metrics
- App resource usage
- RU/OFH metrics (if Open Fronthaul is used)
- RLC metrics (per-bearer)
Collect at least 3 messages to get a representative cross-section.
Step 3 — Interpret Metrics
After collecting metrics, parse the JSON. Refer to references/metrics_schema.md for the complete field reference.
Common Questions and Which Fields to Check
| User Question | Metrics to Check |
|---|---|
| "How many UEs are connected?" | Count entries in cells[].ue_list[] |
| "What's the signal quality?" | ue_list[].cqi, ue_list[].pusch_snr_db, ue_list[].pusch_rsrp_db |
| "What's the throughput?" | ue_list[].dl_brate (bps), ue_list[].ul_brate (bps) |
| "Are there packet drops?" | ue_list[].dl_nof_nok, ue_list[].ul_nof_nok — compute error rate as nok / (ok + nok) * 100 |
| "Is the AMF connected?" | cu-cp.ngaps.ngap[].connected (boolean) |
| "Any scheduling issues?" | cells[].cell_metrics.nof_failed_pdcch_allocs, late_dl_harqs, late_ul_harqs |
| "System resource usage?" | app_resource_usage.cpu_usage_percent, memory_usage_mb, power_consumption_watts |
| "Executor bottlenecks?" | executor_metrics.cpu_load, task_avg, enqueue_avg |
| "Fronthaul issues?" | ru.ofh.timing_stats.nof_skipped_symbols, cells[].ul.rx_window_stats |
Step 4 — Read Configuration (Optional)
To answer questions about how the gNB is configured, read and parse the YAML config file:
cat <CONFIG_FILE_PATH>
Refer to references/config_params.md for the key configuration sections and parameters.
Important Notes
- Operations: This skill can start, stop, and monitor gNB/UE. Always confirm with the user before starting or stopping components.
- Bitrate units:
dl_brateandul_bratefrom the scheduler are in bits per second (bps). Convert: divide by 1e6 for Mbps. - CQI range: 0–15 (15 = best). A value of -1 means no CQI report received.
- MCS range: 0–28 (higher = more efficient modulation).
- PUSCH SNR: in dB. Clamped to [-99.9, 99.9].
nullmeans no measurement. - RSRP: in dBm. Clamped to [-99.9, 0.0].
nullmeans no measurement. - Timing Advance:
ta_ns,pusch_ta_ns,pucch_ta_ns,srs_ta_nsare in nanoseconds. - BSR (Buffer Status Report): in bytes, from the UE's perspective.
- PHR (Power Headroom): in dB.
nullif not reported. - Latency values:
average_latency,max_latencyin scheduler cell metrics are in microseconds. - MAC latency:
average_latency_us,min_latency_us,max_latency_usare in microseconds. - No authentication: The WebSocket interface has zero authentication. It is bound to
127.0.0.1by default for security. - Metrics periodicity: Metrics are pushed periodically (configurable, typically every 1 second). Each call to
ws_metrics.pygets a snapshot. - Multiple metric types per connection: Different metric categories arrive as separate JSON messages. A single subscribe call yields multiple messages over time.