Skip to content

Roaming between two UniFi U7 Pro Max APs

Setup on 2026-10-13

Part Details
APs AP A on 5 GHz ch 48/80 and AP B on 5 GHz ch 40/80 (runbook), both with the home SSID: WPA2/WPA3 transition with 802.11r (AKM 2, 8 and 9: PSK, SAE, FT-SAE). Firmware not noted yet
Client A phone with a private address, HE, two streams, on 5 GHz
Sensor The Pi next to AP A (at −34 dBm), the Mac next to it. capA on 5240/80; capB locked onto AP B on 5200/80 (strongest neighbor with the same SSID, 14–15 dB weaker)
Method The app records; Wi-Fi off and on at the start; the phone carried to AP B with traffic, then back. The sensor stays put

Walk at normal power: no roam

22:54, 94 s. During the walk the phone came in at −63 to −74 dBm at the sensor, which stands next to AP A. Its traffic stayed on ch 48 and it sent one probe request. The AP transmits stronger than the phone, so the phone heard AP A at about −70 dBm or better, around the threshold where an iPhone starts to look for another AP.

Walk with AP A at Low power: an 802.11r roam

23:04, 139 s; testdata/sessions/u7-phone-ft-roam (anonymized). Seconds after 23:05:45:

t Frame
0.20–0.37 Probe requests from the phone
0.512 FT authentication (algorithm 2) to AP B. AP B sends an ACK and no answer
0.727–0.833 Block Acks from the phone to AP A: it went back to ch 48 and kept receiving data
0.853 FT authentication again; AP B answers at 0.857
0.859–0.869 Reassociation request and response (status 0), FT-SAE, no 4-way
0.885 First data with AP B

Without a connection: 36 ms, from the phone's last frame to AP A (0.833) to the reassociation response. Off the air 20 ms; waits 3 ms for the client and 13 ms for the AP. The 341 ms between the two FT authentications fit AP B first fetching the PMK-R1 from the R0KH (AP A, by its R0KH-ID) before it answers; that is not verified.

A protected frame in the clear

3 ms after M4 of the reconnect at the start (23:04:34, PMK caching with FT-SAE), AP A sent the phone a neighbor report response twice:

Frame PN Body MIC field
First 1 plaintext: Radio Measurement, Neighbor Report Response with AP B's BSSIDs on ch 40 and ch 53 (43 bytes) the last 8 bytes of the body again
2 ms later 3 43 bytes, encrypted random

The first frame has the Protected bit and a CCMP header, but no encryption and no MIC. The sensor has no keys, so the plaintext was on the air. Heard once, by capA only. All other protected frames of the session were encrypted.

The bug class is the one of "Framing Frames" (Schepers, Ranganathan, Vanhoef, USENIX Security 2023). What is still to check is in the plan (docs/status.md).

The search after a seen roam (2026-10-25)

15:17, 712 s, the app and the sensor at 2e29db3; the recording is outside the repo. AP A's 5 GHz on ch 48/80 at Low power, AP B's moved to ch 100/80 at Auto, outside AP A's 80 MHz block. The Mac on the IoT SSID (2.4 GHz), awdl0 down. The sensor and the Mac at the desk by AP A, the phone 1 m from the sensor with a video; capA on AP A (5240/80), capB on AP B (5500/80, strongest neighbor with the same SSID, 7.3 dB weaker).

Time What
15:19:15 The phone carried to the living room by AP B roams to it with 802.11r (FT-SAE), 19 ms without a connection, heard by both radios
15:21:34.3 The phone's last frame heard, to AP B on capB
15:21:35.1 capB chosen by hand on 6 GHz ch 37 (6135, AP A's 6 GHz BSS, at its 160 MHz): neither radio on ch 100
15:22:35.4 The search, 61 s after the last frame: capB to 5500/80 ("search: the client's last channel"), capA to the sweep
15:22:35.8 Found: the phone's frames to AP B on capB, 0.4 s after its tune
15:22:36.9 capA locked on AP B (5500/80), capB back on the chosen 6135

capB held AP B, the BSS of the phone's last frame. Before 5b61c1e it held capA's lock, AP A's ch 48, which the phone had left. No drop counted; BA success 99.5 % towards the phone and 100 % from it; undecided, nothing abnormal; roaming Good with the one roam.

An idle phone against the search's 60 s

From 15:25 the phone lay locked by AP B, the video stopped, for 4.5 minutes to the end of the same session. It sent QoS Null frames to AP B, setting power save on and off, one of them every minute at :38.9, and a few Block Acks. The longest silence was 29.3 s (15:27:09 to 15:27:38), the next 26.4 and 21.5 s: no search started. One phone on one AP, at most half the threshold; the other clients have not been measured idle.