diff --git a/armsrc/bwm_wifi.c b/armsrc/bwm_wifi.c index 4683d4e15..94783199c 100644 --- a/armsrc/bwm_wifi.c +++ b/armsrc/bwm_wifi.c @@ -256,7 +256,26 @@ int bwm_wifi_forward_status(uint8_t *state, uint32_t *ip_out) { } int bwm_wifi_forward_down(void) { - // Single command: the BWM deinits the TCP server + disconnects the STA and - // returns to BLE-only. It persists the disable mode to NVS. - return step(BWM_CMD_SET_TO_WIFI_DISABLE_MODE, NULL, 0, NULL, NULL, 2000, "wifi disable"); + // The ESP tears down the STA + TCP server and persists to NVS BEFORE it acks, + // and its command task blocks during the teardown - so that ack can outlast + // any timeout or be dropped. A plain ack-wait therefore reports failure on a + // disable that actually worked. Instead: fire the disable, then CONFIRM by + // polling the connect status. Once WiFi is gone the status query returns a + // non-timeout error (the subsystem is down) - that is our proof of success. + (void)bwm_cmd(BWM_CMD_SET_TO_WIFI_DISABLE_MODE, NULL, 0, NULL, NULL, 3000); + + uint32_t t0 = GetTickCount(); + while (GetTickCountDelta(t0) < 12000) { // overall cap + uint8_t st = 0; + uint16_t sl = sizeof(st); + int q = bwm_cmd(BWM_CMD_GET_WIFI_CONNECT_STATUS, NULL, 0, &st, &sl, 500); + // ETIMEOUT while the ESP is busy tearing down -> keep waiting. + // SUCCESS with a state -> still up mid-teardown -> keep waiting. + // any other (EFAILED etc.) -> BWM answered but WiFi is gone -> disabled. + if (q != PM3_SUCCESS && q != PM3_ETIMEOUT) { + return PM3_SUCCESS; + } + SpinDelay(300); + } + return PM3_ETIMEOUT; }