Skip to main content

Configure Mobility and Cell State

The NRCell resource is the operator surface. Everything on this page is done with kubectl against your cells. The controller applies your changes to the running network live (no gNB restarts, no pod rollouts for mobility-only edits) and records them durably so restarts converge to the same state. How that works is How Mobility Reaches the CU-CP; the per-command machinery underneath is the runtime commands reference, and you should not need it for anything here.

All examples assume cells in racora-system:

kubectl get nrcells -n racora-system

Neighbor Relations: Enabling Handover​

Declare which cells are handover neighbors. Relations are directional: for normal two-way mobility, declare both directions.

# on cell nr-n78-b210
spec:
neighbors:
- nrCellRef: nr-n78-b210-node1 # name of the neighbor NRCell
reportConfigs: [2] # measurement configs for this relation
# (default [2] = the built-in A3)
kubectl patch nrcell nr-n78-b210 -n racora-system --type=merge \
-p '{"spec":{"neighbors":[{"nrCellRef":"nr-n78-b210-node1","reportConfigs":[2]}]}}'
kubectl patch nrcell nr-n78-b210-node1 -n racora-system --type=merge \
-p '{"spec":{"neighbors":[{"nrCellRef":"nr-n78-b210","reportConfigs":[2]}]}}'

That is the entire handover configuration for cells under one CU. With the built-in defaults, a UE hands over when a neighbor measures 3 dB stronger than its serving cell for 100 ms.

Physical prerequisite: the two cells must be frame-aligned (clockSource: gpsdo with GPS lock on both radios), or the neighbor is invisible to UEs whatever you configure; why is on How Mobility Reaches the CU-CP, checking lock on Connect a Radio.

Automatic Neighbor Relations (ANR)​

You do not have to declare every relation yourself. CU-IP's ANR function watches which cells UEs actually measure together (the substrate's co-measurement graph) and manages spec.neighbors for you: sustained overlap between two cells adds the relation on both, and a relation ANR created is removed again once the evidence stays weak or stale.

Provenance is tracked in status; every applied relation carries where it came from:

kubectl get nrcell nr-n78-b210 -n racora-system -o jsonpath='{.status.neighbors}' | jq
# [{"nrCellRef":"nr-n78-b210-node1","reportConfigs":[2],
# "source":"anr","appliedAt":"…","nci":"0x66C001"}]

Which relations ANR may add and remove, and the ownership modes, are on How Decisions Become Network State.

Tuning and disabling live on the CU-IP side: chart values racora-cu.cuIp.engines and racora-cu.cuIp.engineConfig (thresholds, sustain windows, and an ownership: report-only shadow mode that evaluates and logs without acting; drop anr from engines to turn the function off). Controller-side apply gates are under racora-controller.decisions.

Tuning Handover Behavior​

Measurement report configs are defined under spec.mobility and referenced by id from relations; ids 1 and 2 are built in (How Mobility Reaches the CU-CP). Report configs are CU-wide: define each id once, on one cell (or identically on all). Two cells that define the same id differently get the lexicographically first cell's definition, and the other carries a ReportConfigConflict condition.

A "stickier" A3 for closely spaced cells, with a wider trigger margin and a dead band against ping-pong:

# on one cell
spec:
mobility:
reportConfigs:
- reportCfgId: 3
reportType: event_triggered
eventTriggeredReportType: a3
measTriggerQuantity: rsrp
measTriggerQuantityOffsetDb: 6 # neighbor must win by 6 dB
hysteresisDb: 3 # ±3 dB dead-band around that
timeToTriggerMs: 100
reportIntervalMs: 1024
neighbors:
- nrCellRef: nr-n78-b210-node1
reportConfigs: [3] # relation now uses the tuned config

(and point the other direction's relation at [3] too.)

Ping-pong at hysteresisDb: 0 is not a fault: each bounce is a successful handover tracking the strongest cell. The offset and hysteresis choose the trade between stickiness and responsiveness.

Serving-cell periodic measurement reporting is per-cell:

spec:
periodicReportCfgId: 1 # must reference a periodical config; id 1 built-in

Other Events and Thresholds​

A3 (neighbor better than serving by an offset) is the handover default, but a report configuration can use any of the A1 to A6 events: eventTriggeredReportType: a1|a2|a4|a5 with measTriggerQuantityThresholdDb (and measTriggerQuantityThreshold2Db for A5) instead of the offset; periodicHoRsrpOffsetDb lets a periodical report trigger handovers when a neighbor is that much stronger (in 0.5 dB units; -1, the default, disables it). The field list with every range is the NRCell API.

Administrative Cell State​

spec:
adminState: Locked # Unlocked (default) | Locked
cellBarred: false # true = on air but UEs may not camp

Locked performs a graceful stop (connected UEs are released cleanly, then the cell leaves the air) and the intent persists: the cell stays down across DU pod restarts and node reboots until you set Unlocked again. cellBarred is independent: the cell keeps transmitting but rejects camping.

When locking a cell long-term, also remove the neighbor relations that point at it: a lock does not touch other cells' measurement configuration (How Mobility Reaches the CU-CP). A handover commanded toward a locked cell is rejected by the CU-CP (runtime commands).

What Happens When You Edit​

Mobility and admin edits are applied to the running CU-CP live, within about a second, and recorded in its boot configuration; a connected UE picks them up at its next RRC reconfiguration (How Mobility Reaches the CU-CP). Radio-facing fields (pci, gains, ARFCN) are different: they rebuild the DU configuration and roll the DU pod, a brief cell restart. Mobility and admin edits never do.

Verifying Your Change​

# the controller applied it (look for the runtime sync line):
kubectl logs -n racora-system deploy/racora-controller | grep "mobility runtime sync"

# the CU-CP has it (registry log; relations, report configs, admin state):
kubectl exec -n centralized-unit deploy/cu-cp -c cu-cp -- \
grep -aE "Added neighbor relation|Updated report config|admin_state" /tmp/cu_cp.log | tail

A cell's administrative and operational state on demand is the cell_status command in the runtime commands reference. Handover activity itself is visible in the Grafana "RAN Mobility" dashboard and in the CU-CP log (Trigger intra-CU … handover, then "Intra CU Handover Target Routine" finished successfully); see Read Logs and Traces.