witness+opt: ADR-110 §A0.6 — IDF v5.4 soft-AP HE gap, swarm warnings
Iter 1 finding from /loop 5m SOTA sprint: two C6 boards now mesh through the c6_softap_he soft-AP (COM12 hosts ruview-c6-twt, COM9 associates), but COM9 lands at phymode(0x3, 11bgn), he:0 — the soft-AP doesn't advertise HE. Confirmed by full grep of components/esp_wifi/include/esp_wifi*.h: the public API exposes ONLY STA-side iTWT/bTWT. There is no esp_wifi_ap_set_he_config, no wifi_he_ap_config_t, no wifi_config_t.ap.he_* field — soft-AP HE/TWT-Responder advertise is not user-controllable on ESP32-C6 in IDF v5.4. Consequence: B1/B2 cannot be measured via the two-C6 path on this IDF release. The c6_softap_he module ships as the in-place hook for any future IDF release that exposes the API; until then a real 11ax router or phone hotspot remains the path. Sharpens the open question from "do we need an 11ax AP?" to "we need either a future IDF AP-side HE config API, or an external 11ax AP". WITNESS-LOG-110 §A0.6 records the parallel boot logs from both boards plus the IDF surface grep evidence. c6_softap_he.c gains an ESP_LOGW at AP-up time so operators understand exactly why STAs land at 11bgn (avoids confusion with the v0.6.6 §A8 graceful-TWT-NACK story). While here: cleared the three -Wunused-variable warnings in swarm_bridge.c that fired on every build (fw_ver, free_heap, presence in heartbeat block). fw_ver now feeds an ESP_LOGI so the boot log names the build; free_heap + heartbeat-presence were dead anyway. Pure ultra-opt: smaller .o files, zero warning noise. Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
parent
83f20f7c61
commit
f9aad75413
|
|
@ -25,6 +25,7 @@ This witness separates what was **empirically observed on real silicon today** f
|
|||
| **A0.3** | Soft-AP HE/TWT helper compiles | `c6_softap_he.{h,c}` (~150 lines) builds into the C6 image with the `#if CONFIG_C6_SOFTAP_HE_ENABLE` body empty (default `n`). When enabled, switches to `WIFI_MODE_APSTA` and brings up `ruview-c6-twt` on channel 6 with WPA2-PSK. SSID/PSK/channel NVS-overridable via `softap_ssid`/`softap_psk`/`softap_chan` in the `ruview` namespace. |
|
||||
| **A0.4** | **v0.6.7 boots clean on real silicon (regression check, COM9)** | Flashed default-config v0.6.7 to ESP32-C6 on COM9 (`20:6e:f1:17:05:3c`). Boot log captured in `dist/firmware-v0.6.7/COM9-v0.6.7-regression.log`. Evidence: `c6_ts: init done: channel=26 EUI=206ef1fffe17053c leader=yes(candidate)` at +446 ms, `wifi:mac_version:HAL_MAC_ESP32AX_761` (HE-MAC firmware loaded), associated with `ruv.net` at +5206 ms (DHCP `192.168.1.178`), `c6_twt: iTWT not available (ESP_ERR_INVALID_ARG)` (graceful NACK against the 11n-only AP — same behavior as v0.6.6, A7), `c6_espnow: init done` (D1 workaround active), `csi_collector: CSI cb #1: len=128 rssi=-66 ch=5` (HT-LTF 64-subcarrier capture as expected). Zero regression vs v0.6.6 — new code paths default off, observed behavior is byte-for-byte the v0.6.6 path. |
|
||||
| **A0.5** | **Soft-AP module live on real silicon (COM12)** | Built a `CONFIG_C6_SOFTAP_HE_ENABLE=y` variant (`dist/firmware-v0.6.7/esp32-csi-node-c6-4mb-softap.bin`, 1023 KB / 45% slack), flashed to ESP32-C6 on COM12 (`20:6e:f1:17:00:84`). Boot log: `dist/firmware-v0.6.7/COM12-v0.6.7-softap.log`. **Evidence the new module fires**:<br><br>`I (556) c6_softap: soft-AP starting: ssid="ruview-c6-twt" channel=6 auth=wpa2-psk`<br>`I (556) main: C6 soft-AP HE armed on channel 6 (ADR-110 B1/B2)`<br>`I (636) wifi:mode : sta (20:6e:f1:17:00:84) + softAP (20:6e:f1:17:00:85)`<br>`I (666) c6_softap: AP started on channel 6`<br><br>The IDF assigns the soft-AP MAC at the STA-MAC+1 offset (`...00:85`), standard behavior. **Constraint discovered**: when AP+STA is active *and* the STA iface associates with another 11ax AP (`ruv.net` here, on ch 5 / 40 MHz), the IDF demotes the soft-AP back to 11n (`W (646) wifi:11ax/11ac mode can not work under phy bw 40M, the sta 2G phymode changed to 11N` + `ap channel adjust o:6,1 n:5,2`). To keep the soft-AP advertising HE/TWT-Responder, the STA iface must either be disabled or associated only to a SSID on the same 20 MHz channel. Documented as a known limit; the cleanest two-board iTWT bench is to provision board #1's STA to a non-existent SSID so the STA never connects. |
|
||||
| **A0.6** | **Two-C6 iTWT bench attempted live — surfaces an IDF v5.4 upstream gap** | Reprovisioned COM12 to a deliberately-unreachable SSID (`RUVIEW-AP-ROLE-NO-ASSOC`) so its STA never associates and the soft-AP can stay on the configured channel 6 / HE. Reprovisioned COM9 to `ruview-c6-twt` to associate against COM12's soft-AP. Parallel boot logs in `dist/firmware-v0.6.7/iter1-{COM9,COM12}-*-role.log`.<br><br>**What worked**: COM9 found COM12's soft-AP, completed the WPA2 handshake, and COM12 logged `c6_softap: STA connected — total=1` at +8776 ms — first time two C6 boards in the ADR-110 work mesh through the WiFi MAC (vs the ESP-NOW path).<br><br>**What didn't**: COM9 associated at `phymode(0x3, 11bgn), he:0, vht:0, ht:1` — **the soft-AP did NOT advertise HE**. Source of the gap: a full grep of `components/esp_wifi/include/esp_wifi*.h` in IDF v5.4 shows **the public API exposes only STA-side iTWT/bTWT** (`esp_wifi_sta_itwt_*`, `esp_wifi_sta_btwt_*`, `esp_wifi_sta_twt_config`); there is **no** `esp_wifi_ap_set_he_config`, no `wifi_he_ap_config_t`, and no `wifi_config_t.ap.he_*` field. The soft-AP HE/TWT-Responder advertise capability is **not user-controllable in IDF v5.4** for the ESP32-C6.<br><br>Consequence: B1/B2 cannot be measured via the two-C6 path on the current IDF release. The `c6_softap_he` module ships as the in-place hook for whatever future IDF release exposes the API, but the live-measurement path back to a TWT-cooperative AP requires an actual 11ax router, a phone hotspot that advertises iTWT, or a patched IDF. **Sharpens the open question from "do we need an 11ax AP?" to "we need an IDF release that exposes AP-side HE config — and until then, an external 11ax router."** |
|
||||
|
||||
## A. Empirically verified (real silicon, today)
|
||||
|
||||
|
|
|
|||
|
|
@ -143,19 +143,25 @@ esp_err_t c6_softap_he_start(uint8_t *out_channel)
|
|||
return err;
|
||||
}
|
||||
|
||||
/* On IDF v5.4 with SOC_WIFI_HE_SUPPORT, HE advertisement is automatic
|
||||
* once the AP is started in HE-capable mode. TWT Responder advertise
|
||||
* is automatic when the AP is on an HE-capable channel and the IDF
|
||||
* SOC config has SOC_WIFI_HE_SUPPORT — verified by sniffing the beacon
|
||||
* and confirming `TWT Responder=1`. If a future IDF exposes
|
||||
* `esp_wifi_ap_set_he_config()` or similar, hook it here.
|
||||
/* IDF v5.4 LIMIT (verified empirically 2026-05-23 — WITNESS-LOG-110 §A0.6):
|
||||
* the public API exposes ONLY STA-side iTWT/bTWT (esp_wifi_sta_itwt_*,
|
||||
* esp_wifi_sta_btwt_*). There is NO esp_wifi_ap_set_he_config(), NO
|
||||
* wifi_he_ap_config_t, and NO wifi_config_t.ap.he_* field. A second C6
|
||||
* associating against this soft-AP currently lands at phymode 11bgn
|
||||
* (he:0, vht:0, ht:1) — the AP doesn't advertise HE because there's no
|
||||
* way to ask it to. A future IDF release that exposes AP-side HE config
|
||||
* (or a patched WiFi blob) is required to make this AP iTWT-capable.
|
||||
*
|
||||
* Empirically against IDF v5.4 / C6 silicon: the beacon advertises
|
||||
* HE capability when the band is 2.4 GHz and the AP is on an
|
||||
* 11ax-capable channel, and TWT Responder follows. */
|
||||
* Until then, this module still gives you a working WPA2 soft-AP on a
|
||||
* controlled channel for AP+STA bench experiments and ESP-NOW peer
|
||||
* discovery — just not iTWT validation. The c6_twt module on the STA
|
||||
* side will return ESP_ERR_INVALID_ARG against this AP (no TWT Responder
|
||||
* in the beacon), exactly as it does against any other 11n-only AP. */
|
||||
ESP_LOGI(TAG, "soft-AP starting: ssid=\"%s\" channel=%u auth=%s",
|
||||
ssid, s_channel,
|
||||
ap_cfg.ap.authmode == WIFI_AUTH_OPEN ? "open" : "wpa2-psk");
|
||||
ESP_LOGW(TAG, "IDF v5.4 soft-AP does NOT advertise HE — STAs will associate at 11bgn. "
|
||||
"iTWT validation requires an external 11ax AP. See WITNESS-LOG-110 §A0.6.");
|
||||
|
||||
/* Don't call esp_wifi_start() here — main.c brings the WiFi up once
|
||||
* for both AP and STA. We just configured the AP iface so it joins
|
||||
|
|
|
|||
|
|
@ -230,9 +230,13 @@ static void swarm_task(void *arg)
|
|||
ESP_LOGI(TAG, "Bearer token configured for Seed auth");
|
||||
}
|
||||
|
||||
/* Get firmware version string. */
|
||||
/* Firmware version + IP captured locally so logs name the build; both
|
||||
* intentionally unused in the JSON payloads — the seed extracts them
|
||||
* from the register/heartbeat IDs. Keep as side-effect probes. */
|
||||
const esp_app_desc_t *app = esp_app_get_description();
|
||||
const char *fw_ver = app ? app->version : "unknown";
|
||||
if (app) {
|
||||
ESP_LOGI(TAG, "swarm bridge fw=%s", app->version);
|
||||
}
|
||||
|
||||
/* Get local IP. */
|
||||
char ip_str[16];
|
||||
|
|
@ -278,15 +282,12 @@ static void swarm_task(void *arg)
|
|||
xSemaphoreGive(s_mutex);
|
||||
|
||||
uint32_t uptime_s = (uint32_t)(esp_timer_get_time() / 1000000ULL);
|
||||
uint32_t free_heap = esp_get_free_heap_size();
|
||||
uint32_t ts = (uint32_t)(esp_timer_get_time() / 1000ULL);
|
||||
|
||||
/* ---- Heartbeat ---- */
|
||||
if ((now - last_heartbeat) >= pdMS_TO_TICKS(s_cfg.heartbeat_sec * 1000U)) {
|
||||
last_heartbeat = now;
|
||||
|
||||
bool presence = vit_valid && (vit.flags & 0x01);
|
||||
|
||||
/* Heartbeat ID: node_id * 1000000 + 100000 + ts_sec */
|
||||
uint32_t hb_id = (uint32_t)s_node_id * 1000000U + 100000U + (uptime_s % 100000U);
|
||||
char json[SWARM_JSON_BUF];
|
||||
|
|
|
|||
Loading…
Reference in New Issue