Skip to content

Wi-Fi: rfkill unblock, Wi-Fi country, 'password' alias, sta_leave no-op; plus bench findings - #39

Open
aetjansen wants to merge 4 commits into
SensorsIot:mainfrom
aetjansen:fix/ap-rfkill-and-password
Open

aetjansen wants to merge 4 commits into
SensorsIot:mainfrom
aetjansen:fix/ap-rfkill-and-password

Conversation

@aetjansen

Copy link
Copy Markdown

Four Wi-Fi fixes (three commits) found while bringing up an ESP32-S3 DUT on a Pi testbench, plus a list of other findings (not fixed here) in case they are useful.

Fixes in this PR

1. WLAN rfkill soft-blocked → ap_start fails (a40d842)
After a Pi reboot on Debian 13, WLAN is rfkill soft-blocked and POST /api/wifi/ap_start fails with rfkill: WLAN soft blocked. install.sh unblocked Bluetooth only. It now unblocks WLAN too, and ap_start/sta_join unblock it before starting (idempotent).

2. password key silently gives an open network (a40d842)
The ap_start handler reads the passphrase from pass, but Harness FSD Appendix D documented password. A caller following the FSD got an open network with no error (our DUT refused it with reason 210). All three handlers now accept either key; Appendix D documents pass and the open-network behaviour.

3. No Wi-Fi country → WLAN re-blocked without a reboot (1ca431c)
A one-off rfkill unblock wlan did not hold: Raspberry Pi OS re-blocked WLAN within minutes while no Wi-Fi country was set. After raspi-config nonint do_wifi_country CH it stayed up. install.sh now sets WIFI_COUNTRY (default CH, matching the country_code already written to hostapd.conf), and wifi_controller reads the same variable instead of hardcoding it.

4. sta_leave without a joined station breaks the AP's DHCP (64bb039)
POST /api/wifi/sta_leave while the bench runs its AP (no sta_join before it) still ran the station teardown (dhcpcd --release, address flush). The AP kept beaconing and accepting associations and ap_status said active, but no client got a DHCP lease until the AP was restarted. sta_leave now returns early when no station is joined.

Other findings (not fixed here)

  • Flash: last byte of a page-multiple image left unprogrammed. /api/flash of an app image whose length is a multiple of 256 (0x145100) reported "Hash of data verified", but read-back showed the last byte as 0xff, and the bootloader rejected the image. Other lengths were fine. Workaround: pad images to 4 KB. Not yet reduced to a minimal reproduction.
  • Serial buffer stores each line twice (/api/serial/output).
  • No race-free serial command/answer: a DUT answers faster than a monitor opened after the write can attach; reading the passive buffer with since= works. A combined "write, then wait for pattern" call would help.
  • enter-portal assumes WiFiManager (form fields, and AP started when no credentials are stored). A DUT with its own portal (JSON API, started from its UI) has to be driven with sta_join + /api/wifi/http instead.
  • Native-USB ESP32-S3 is reset twice: once by /api/serial/reset, and again ~3.5 s later when the serial proxy re-opens the port.
  • Chip-detection probe resets a sleeping DUT: an S3 in light sleep drops USB-Serial/JTAG and re-enumerates; about 8 s later the probe resets it (reset reason ESP_RST_USB). So light sleep cannot be observed on the bench. Suggestion: skip the probe when a slot's DUT re-enumerates within a short window.
  • Pi dropped off the network after DUT USB activity (twice: during a flash, and after a DUT unplug/replug); only a power cycle brought it back. Possibly the DUT slots and the Pi's USB-Ethernet uplink share a hub.
  • HTTP relay: it follows redirects (so a captive portal's 302 is mostly observed as its landing page), and there is no way to send a DNS query through wlan0. A follow_redirects: false option and a DNS-query endpoint would let captive portals be tested end to end.

Thanks for the harness — it made on-hardware testing of this project possible.

🤖 Generated with Claude Code

Arno Jansen and others added 4 commits September 26, 2026 07:57
Two faults found while commissioning a DUT on the bench:

- After a Pi reboot on Debian 13, WLAN is rfkill soft-blocked and
  POST /api/wifi/ap_start fails with 'rfkill: WLAN soft blocked'.
  install.sh unblocked bluetooth only. It now unblocks wlan too, and
  ap_start/sta_join unblock it before starting (idempotent).
- The ap_start handler reads the passphrase from 'pass', but Harness
  FSD Appendix D documented 'password'. A caller following the FSD got
  an OPEN network with no error. All three handlers now accept either
  key, and Appendix D documents 'pass' and the open-network behaviour.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…onfigurable

Setting only 'rfkill unblock wlan' did not hold on the bench: Raspberry
Pi OS re-blocked WLAN within minutes, without a reboot, while no Wi-Fi
country was set. After 'raspi-config nonint do_wifi_country CH' the AP
stayed up. install.sh now sets WIFI_COUNTRY (default CH, matching the
country_code the portal already wrote), and wifi_controller reads the
same variable for hostapd.conf instead of hardcoding CH.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Called while the bench runs its AP (no sta_join before it), the station
teardown released DHCP and flushed wlan0, removing the AP's own address:
the AP kept beaconing and accepting associations but gave out no leases
until it was restarted. Found by the music-buddy DUT (every join after a
test fixture's cleanup sta_leave associated and then timed out on DHCP).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sta_join saved only ssid, password and channel of the running AP, so the
AP that sta_leave brought back had no DNS forwarding and no NAT even when
it was started with internet=True: DUTs rejoined but could no longer
resolve names or reach NTP. Found by the music-buddy DUT (its clock never
synchronised after a captive-portal test).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant