feat: wi-fi - expand support and fix issues, add GUI components

This commit is contained in:
2026-08-07 10:36:53 +02:00
parent bbe1df62fd
commit 9eb21eb3e3
67 changed files with 4573 additions and 245 deletions
+58
View File
@@ -633,6 +633,64 @@ check(link_rm is not None and mac_rm is not None and link_rm < mac_rm,
"the link is removed before the MAC that owns it")
d7.p.stdin.close()
# =============================================================================
# An access point that stops acknowledging brings the link down.
#
# IwxLinkUp() used to be nothing but "the state machine reached Connected", and
# only an explicit deauthentication frame moved it off that state. A hotspot
# that simply went away -- slept, changed channel, dropped the station without
# saying so -- therefore left the link reported as up forever: NetIf kept
# choosing wlan0, every packet vanished, and the desktop showed a healthy
# connection while nothing worked. Beacons cannot be used to notice this
# (MacConfigCmd stops asking for them once associated), so the driver watches
# its own frames going unacknowledged instead.
# =============================================================================
print("\n=== a silent access point takes the link down ===")
d8 = Driver()
d8.cmd("MAC " + STA.hex())
d8.cmd(f"CONNECT {AP.hex()} {CHANNEL} 0 OpenNet - -")
d8.cmd("RXMGMT " + mgmt(0xb0, STA, AP, AP, struct.pack('<HHH', 0, 2, 0)).hex())
d8.cmd("SERVICE")
d8.cmd("RXMGMT " + mgmt(0x10, STA, AP, AP,
struct.pack('<HHH', 0x0421, 0, 7 | 0xc000)).hex())
ev = d8.cmd("SERVICE")
check(link_of(ev['result']) == 1, "the open network is associated and the link is up")
# Well short of the threshold: a few unacknowledged frames are ordinary.
ev = d8.cmd("TXSTATUS 0 15")
check(link_of(ev['result']) == 1,
"a handful of unacknowledged frames does not drop the link")
ev = d8.cmd("SERVICE")
check(link_of(ev['result']) == 1, "and the service pass leaves it alone")
# One acknowledgement means the access point is still there; the count restarts.
d8.cmd("TXSTATUS 1 1")
ev = d8.cmd("TXSTATUS 0 15")
check(link_of(ev['result']) == 1,
"an acknowledgement in between restarts the count")
# Anything received from the BSS is equally good proof, and also restarts it.
d8.cmd("RXDATA " + data_from_ds(STA, AP, AP, 0x0800, b'\x45' * 20).hex())
ev = d8.cmd("TXSTATUS 0 15")
check(link_of(ev['result']) == 1,
"a frame received from the BSS restarts the count too")
# Now let it run past the threshold with nothing coming back.
ev = d8.cmd("TXSTATUS 0 16")
check(link_of(ev['result']) == 1,
"the transmit path itself does not tear anything down")
check(not ev['CMD'],
"no firmware command is sent from the completion path")
ev = d8.cmd("SERVICE")
check(state_of(ev['result']) == 0 and link_of(ev['result']) == 0,
"the next service pass drops the link")
check(any(c == MAC_CONFIG and struct.unpack_from('<I', p, 4)[0] == 3
for c, p in ev['CMD']),
"and unwinds the firmware contexts")
d8.p.stdin.close()
print()
if fails:
for f in fails: print("FAILURE:", f)