Fix for duplicate wifi events on P4

This commit is contained in:
Ken Van Hoeylandt 2026-08-09 17:06:03 +02:00
parent 8a75bc501e
commit 9487441b97

View File

@ -16,6 +16,7 @@
#include <tactility/drivers/wifi.h> #include <tactility/drivers/wifi.h>
#include <tactility/error_esp32.h> #include <tactility/error_esp32.h>
#include <tactility/log.h> #include <tactility/log.h>
#include <tactility/time.h>
#if defined(CONFIG_SLAVE_SOC_WIFI_SUPPORTED) #if defined(CONFIG_SLAVE_SOC_WIFI_SUPPORTED)
#include <tactility/drivers/esp32_esp_hosted_ota.h> #include <tactility/drivers/esp32_esp_hosted_ota.h>
@ -56,6 +57,15 @@ struct Esp32WifiCtx {
esp_event_handler_instance_t wifiEventHandler = nullptr; esp_event_handler_instance_t wifiEventHandler = nullptr;
esp_event_handler_instance_t ipEventHandler = nullptr; esp_event_handler_instance_t ipEventHandler = nullptr;
// Dedup for WIFI_EVENT/IP_EVENT notifications: on the esp_hosted/Wi-Fi Remote transport
// (e.g. Tab5's P4 host + C6 co-processor), the RPC layer has been observed delivering the
// exact same event twice in a row (same base, same event_id, same millisecond - not two
// genuinely separate occurrences). Native WiFi doesn't exhibit this, but the handler is
// shared, so the guard applies unconditionally; it's a no-op for well-separated real events.
esp_event_base_t lastEventBase = nullptr;
int32_t lastEventId = -1;
TickType_t lastEventTick = 0;
Mutex callbackMutex{}; Mutex callbackMutex{};
WifiCallbackEntry callbacks[WIFI_MAX_CALLBACKS] = {}; WifiCallbackEntry callbacks[WIFI_MAX_CALLBACKS] = {};
size_t callbackCount = 0; size_t callbackCount = 0;
@ -100,6 +110,20 @@ void fire_event(Esp32WifiCtx* ctx, WifiEvent event) {
void on_wifi_or_ip_event(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { void on_wifi_or_ip_event(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) {
auto* ctx = static_cast<Esp32WifiCtx*>(arg); auto* ctx = static_cast<Esp32WifiCtx*>(arg);
// See Esp32WifiCtx::lastEventBase/lastEventId/lastEventTick - collapse an immediate duplicate
// delivery of the same event (observed on the esp_hosted/Wi-Fi Remote transport) into one.
constexpr uint32_t DEDUP_WINDOW_MS = 50; // well under any real re-occurrence of the same event
TickType_t now = get_ticks();
bool is_duplicate = event_base == ctx->lastEventBase && event_id == ctx->lastEventId &&
(now - ctx->lastEventTick) <= millis_to_ticks(DEDUP_WINDOW_MS);
ctx->lastEventBase = event_base;
ctx->lastEventId = event_id;
ctx->lastEventTick = now;
if (is_duplicate) {
LOG_D(TAG, "Ignoring duplicate WiFi event %d", (int)event_id);
return;
}
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
mutex_lock(&ctx->mutex); mutex_lock(&ctx->mutex);
bool was_pending = ctx->stationState == WIFI_STATION_STATE_CONNECTION_PENDING; bool was_pending = ctx->stationState == WIFI_STATION_STATE_CONNECTION_PENDING;