Skip to content

Follow-ups left open by M6 (#260): EVM, roam baseline, the named test, residuals #566

Open

Description

@josephnef

Part of the 5G-NR RAN EPIC #254. Follow-ups left open when M6 #260 closed on its mechanisms (CHO, DAPS on one channel and across channels, slot migration, per-cell keys, sequence handling and handover state cleanup: #527–#562). The moving-UE test bench is #563; it isn't repeated here.

Deferred from the M6 issue

  • EVM in the measurement reports. cell M6: EVM over F1 (filtered uplink EVM in the measurement reports, F1 v16) #571: filtered EVM in F1 v16 (UeMeas, HeardUe); reported, not used by the A3 (docs/cell-m6.md says why). M6's first deliverable lists RSSI, SNR and EVM. F1 reports only RSSI and SNR, for the DU's own UEs and the UEs it hears (src/cell/F1.h). src/cell/UeRxAttribution.h computes evm_mean_db, but nothing sends it. Doing this needs an F1 version bump, plus a decision on whether the A3 ever uses EVM.
  • The 802.11 roam baseline ("vs the ~100 ms roam ghost bar"). No roam has been measured for comparison. The DL gap at a switch is now 84–123 ms (111–112 plain, same channel; 122–123 across channels with visits), so the claim is "no scan, no re-association, no clock re-acquisition", not yet "a shorter gap". To settle it, measure a plain 802.11 roam on the same radios with the same KPI. docs cell M6: the roam baseline and where the rig suite lives (#566) #572: measured on the same radios (testrig m6_roam_baseline.sh, rtw89 + hostapd + wpa_supplicant): 0.38–0.66 s DL gap per roam, 5.6–5.9 s returning to the first AP (cause not established); the M6 switch is 84–123 ms.
  • The named test. The M6 issue asked for tests/ran_handover.sh. The tests are testrig scripts/m6_*.sh (handover, crossing, crossing3, three_ho, daps, daps_dl, daps_xch, cellkeys, …), and devourer holds only the ctest cell_m6. Either add a devourer-side entry point that documents and runs the rig suite, or record in docs/cell-m6.md that the rig suite lives in testrig. docs cell M6: the roam baseline and where the rig suite lives (#566) #572: docs/cell-m6.md records the rig suite (testrig scripts/m6_*.sh) and what each asserts; devourer keeps the headless ctest.

Residuals recorded in docs/cell-m6.md ("Not covered yet")

  • A UE whose source fades before the handover command loses what it misses before the cross-channel DAPS visits begin. The visits start at the accept. cell M6: the conditional handover — a source lost before the command #574: the conditional handover (RAN_CHO, F1 v18). The CU prepares early, the target grants from the command, and the UE moves on source_lost or target_better. Across channels, with the source killed after the preparation, the UE moves 4 superframes after its last serving beacon with its DL intact (1.002–1.015 of UE2's); without it the UE is stranded (0.21–0.33). Open: no A3 preparation policy has been tuned (the rig forces it).
  • Re-phasing live cells. cell M6: re-phasing a live cell (F1 v19, channel-switch IE v2) #575: RAN_REPHASE (F1 v19, channel-switch IE v2). The CU moves a running DU to the best phase it can reach, with its UEs; the DU steps its TSF at an instant idle in both grids, and its UEs shift with it. On the rig, cell 2 moved 20000 → 51200 live with 1–2 uplinks out of slot; afterwards no suspend gaps, and each DU heard its UE in 0.997–1.000 of superframes (0.90–0.95 before). A move announced and not made costs its UE 8 uplinks, then it is back in slot.
  • More than three cells, and the full tour back into cell 1. A fourth cell needs a seventh radio; the tour needs more than the DUs' 20 dB TX range, which M6 test realism — a moving-UE handover bench (conducted path-loss matrix, then an over-the-air walk) #563 provides.
  • Causes not established (two of the four first listed are now established): the one-uplink loss after switches between cells 51.2 ms apart was Kestrel's beacon timer (the first beacon after a TSF step at the old phase; fixed by the TSF placement in cell M6: the switch's own interruption (inter-frequency DAPS) #560); the 1.3 ms beacon jump was a DU asking for its phase after its beacon had started (fixed by ordering, docs/cell-m6.md). Still open: the non-linear power-to-RSSI relation (M6 test realism — a moving-UE handover bench (conducted path-loss matrix, then an over-the-air walk) #563's calibration should settle it); one m6_daps_dl run with DL to the arriving UE ~111 µs late and 13 uplinks lost, not reproduced; and the roam baseline's 5.6–5.9 s return to the first AP (the kernel stack, outside devourer). All three now established (testrig results/2026-11-14-m6-causes.txt):
  • Neighbour-list residual: cell M6: bound the neighbour-list replay residual — signed freshness window + the live relay measured #578: bounded and measured. With the signing material the residual is a genuine beacon re-aired, in two shapes. A store-and-forward relay is beaten by the phase check — on the rig a live relay's copies land ~645 µs off and are refused (0 stale: fresh signature), while genuine beacons land within 8 µs of phase (300 µs tolerance). An on-phase reflector the phase check cannot distinguish is bounded by the signed freshness window: NS IE v3 signs the window length too (CELL_NL_WINDOW_SF, down to 1 superframe, ~205 ms vs ~13 s), and the window is compared on the shared network-superframe timeline so cells may use different lengths. A copy fresher than the window, on phase, is physically the cell's own signal re-radiated — only distance bounding would stop it.
  • Optional: carry the timing advance in the handover command. cell M6: the UE's timing advance in the handover command (F1 v17) #573: F1 v17 (UeMeas.ta_us, HoCommand.ta_us, RAN_HO_TA); on the rig the target's first uplinks land within 1–2 µs against ~427 µs without it (79–98 uplinks to settle). Slot hits are equal on this layout; the gain is guard margin.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions