Skip to content

[Firmware] ESP32-C6 v0.6.7 pre-built: 0 bytes CSI during valid association, no reassociation after AP-initiated disconnect #1384

Description

@dorofino

Summary

The pre-built ESP32-C6 firmware in firmware/esp32-csi-node/release_bins/c6-adr110/ (v0.6.7 per release_bins/version.txt) exhibits two related failures on a stock ESP32-C6-DevKitC-1:

  1. During a successful WiFi association, the firmware transmits 0.00 B in either direction for the entire session — no CSI packets ever leave the device.
  2. After the AP disconnects the client for inactivity, the firmware never re-associates, even across multiple full reflashes and NVS --reset reprovisionings, and even after switching to a completely different AP.

Because the C6 build routes its console to UART0 (default) and does not enable CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG, there is no on-chip log visibility over the board's USB-Serial-JTAG port, so the WiFi driver state at the point of failure cannot be observed.

Hardware

Item Value
Board ESP32-C6-DevKitC-1 (stock, no soldering)
Chip ESP32-C6 (QFN40) revision v0.2, 160 MHz, Single Core + LP Core, WiFi 6, BT 5, 802.15.4
Base MAC fc:01:2c:XX:XX:XX (redacted)
Crystal 40 MHz
USB mode USB-Serial/JTAG (VID 303A:1001)
Enumerates as USB Serial Device (COM5)

Host

Item Value
OS Windows 11, PowerShell 7
Python 3.13.14
esptool 5.2.0
esp-idf-nvs-partition-gen 0.3.0
Docker Desktop 29.6.1 (Docker image ruvnet/wifi-densepose:latest)

Reproduction

# 1. Shallow clone
git clone --depth 1 https://github.com/ruvnet/RuView.git .

# 2. Flash pre-built C6 firmware (4 MB layout)
python -m esptool --chip esp32c6 --port COM5 --baud 460800 `
  --before usb-reset --after hard-reset write-flash `
  --flash-mode dio --flash-size 4MB `
  0x0     firmware/esp32-csi-node/release_bins/c6-adr110/bootloader.bin `
  0x8000  firmware/esp32-csi-node/release_bins/c6-adr110/partition-table.bin `
  0xf000  firmware/esp32-csi-node/release_bins/c6-adr110/ota_data_initial.bin `
  0x20000 firmware/esp32-csi-node/release_bins/c6-adr110/esp32-csi-node.bin

# 3. Provision NVS (fresh --reset)
python firmware/esp32-csi-node/provision.py `
  --port COM5 --chip esp32c6 `
  --ssid "<SSID>" --password "<PSK>" `
  --target-ip <host-ip> --target-port 5006 --reset

# 4. Start sensing-server
docker run -d --rm --name ruview `
  -e RUVIEW_ALLOW_UNAUTHENTICATED=1 -e CSI_SOURCE=esp32 `
  -p 127.0.0.1:3000:3000 -p 127.0.0.1:3001:3001 -p 5006:5005/udp `
  ruvnet/wifi-densepose:latest

What actually happens

Session 1 — first boot after fresh provision (SUCCESS on association, FAILURE on CSI)

Attempted on AP-A: a UniFi network (WPA2/WPA3-mixed, U6-LR access point).

UniFi event log (times shown relative to t=0 = association):

  • t = 0Connected to AP-A on Ch. 1 (2.4 GHz, 20 MHz), -47 dBm, DHCP lease granted.
  • t = +7m 50sDisconnected by AP. Time Connected: 7m 50s. Data Used: 0.00 B up / 0.00 B down. Last signal -47 dBm.

Corresponding server-side metrics for the same 7m50s window:

GET /api/v1/metrics → { "tick": 0 }
GET /api/v1/sensing/latest → { "status": "no data yet" }
docker logs ruview | grep -i "udp\|csi frame\|frames"  # 0 matches

So: excellent RF (-47 dBm), 100% signal, TX Retries 0.0% at the AP — yet the firmware never transmitted a single UDP packet to the configured target-ip/port during the entire connected session. The AP eventually disassociated it for inactivity.

Session 2 onwards — no reassociation, ever

After the AP-initiated disconnect, the ESP32 has not reappeared in the UniFi client list or in ARP on the host, despite:

  • Multiple esptool --after hard-reset chip-id cycles (confirmed chip responsive: MAC returned each time)
  • Multiple full reflashes (bootloader + partition-table + otadata + app, all hash-verified)
  • Multiple provision.py ... --reset cycles (verified persisted state has SSID + password + target-ip + target-port)
  • Physical USB power-cycle and 30-min cool-down
  • Switching to a completely different APAP-B: an iPhone Personal Hotspot, WPA3-Personal, 2.4 GHz Ch 5, "Maximize Compatibility" ON, 100% signal, host confirmed associated with a fresh DHCP lease — same outcome, 90 s wait, NOT SEEN in ARP.

I.e., after the first AP-initiated disconnect, the C6 firmware appears to permanently stop trying to associate on this hardware — not even to a fresh, different AP that has never seen this MAC before.

Ruled out

Suspect How ruled out
Wrong PSK First association on AP-A succeeded → PSK is correct. State file confirms the same PSK persisted for later attempts.
5 GHz-only AP ESP32-C6 is 2.4 GHz only; both APs tested were on 2.4 GHz (Ch. 1 and Ch. 5).
UniFi bad-client block Reproduced on a completely separate AP (phone hotspot, AP-B) that has no history with this MAC.
Weak signal -47 dBm on AP-A (excellent) and 100% signal on AP-B.
Wrong band-steering AP association on Ch. 1 (2.4 GHz) confirmed by UniFi client detail.
Damaged board esptool consistently talks to the chip on COM5 with the correct MAC and completes full-image flash + verify.
Docker port-forwarding drops CSI frames UniFi client counter shows 0.00 B up from the ESP32 during the entire 7m50s session — packets weren't dropped, they were never sent.
ESP-IDF NVS write bug Verified persisted state matches what was written; also happens after --reset full-wipe writes.

What would help debug

The ESP32-C6 overlay firmware/esp32-csi-node/sdkconfig.defaults.esp32c6 does not set:

CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y

so the default console goes to UART0 (physical pins), which is unreachable on a stock DevKitC-1 without a USB-UART adapter wired to GPIO 16/17. This makes it effectively impossible for a user with only the USB-C DevKitC-1 in hand to see:

  • The WiFi driver's association attempts and disconnect reasons
  • Whether stream_sender_init_with(...) succeeded and whether CSI callbacks are firing
  • Whether the app is stuck at boot, in wifi_init, in DHCP, in a retry loop, or actually running

Ask 1: could the pre-built C6 release binary enable CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y (and matching CONFIG_ESP_CONSOLE_SECONDARY_NONE=y if needed) so ESP-IDF's esp_log output is visible over the board's native USB-Serial/JTAG port?

Concrete questions

  1. Is anyone else seeing "0 bytes over an associated session" on the C6 v0.6.7 pre-built binary? (Would confirm/deny hardware-specific vs firmware-wide.)
  2. What is the intended behavior when the AP disassociates the client — does the firmware auto-reassociate, and if so, is there a Kconfig knob for the retry policy on the C6 overlay?
  3. Should the CSI capture pipeline (which drives all UDP traffic) start unconditionally after WiFi IP_EVENT_STA_GOT_IP, or does it wait for another event that might not fire on the C6 target?

Environment / artefacts

  • Firmware version: firmware/esp32-csi-node/release_bins/c6-adr110/release_bins/version.txt = 0.6.7
  • SHA-256s (matched SHA256SUMS.txt in the same folder):
    • bootloader.bin = b0fb1f217a39c80bc95b5eb8208a0b8572ae64efa0f6d580b76caff4affe0f4d
    • partition-table.bin = 4c2cc4ffd52641e23b779bd57b3908014083ac3c1aab395756478c89e70d81f0
    • ota_data_initial.bin = 7d2c7ac4888bfd75cd5f56e8d61f69595121183afc81556c876732fd3782c62f
    • esp32-csi-node.bin = 4764c5b20a353895f70122816adc98f861ec20e9a8ea9b344dc0648b6341073c
  • Docker image: ruvnet/wifi-densepose:latest, digest sha256:14b2fd3347c16a0959aca37bf5c61f0fabf79cfe8b6d01a60edccb0ab3e24b6a
  • Sensing-server logs (relevant lines):
    INFO sensing_server: UDP listening on 0.0.0.0:5005 for ESP32, MediaTek, Qualcomm CSI, and RTL8720F radar frames
    INFO sensing_server: Data source: esp32 (udp_receiver=true, simulator=false, wifi=false)
    
    No frames received / equivalent log entries appeared for the entire multi-hour session.

Happy to run any additional diagnostics if a follow-up build with console logging or a specific ESP-IDF flag lands.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfirmwareESP32 firmware

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions