]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
NAN USD: Fix state machine stall seen with listen failure
authorAjay Davanageri <ajay.davanageri@synaptics.corp-partner.google.com>
Tue, 22 Jul 2025 08:46:38 +0000 (14:16 +0530)
committerJouni Malinen <j@w1.fi>
Tue, 30 Sep 2025 09:18:09 +0000 (12:18 +0300)
If the driver returns -EBUSY for remain_on_channel operation, NAN USD
state-machine gets stuck and no further listen is configured from
wpa_supplicant. Clear the states and re-triggers the nan_de_timer to
restart the listen operation in such case.

Signed-off-by: Ajay Davanageri <ajay.davanageri@synaptics.corp-partner.google.com>
wpa_supplicant/nan_usd.c

index b2d195ca751163eb795ee57b1aeff86fd8ea1808..14253b89cb6f7a2bf5e0ab38598cb18432b682e0 100644 (file)
@@ -9,6 +9,7 @@
 #include "utils/includes.h"
 
 #include "utils/common.h"
+#include "utils/eloop.h"
 #include "common/nan_de.h"
 #include "wpa_supplicant_i.h"
 #include "offchannel.h"
@@ -181,6 +182,16 @@ static void wpas_nan_usd_listen_work_done(struct wpa_supplicant *wpa_s)
 }
 
 
+static void wpas_nan_usd_remain_on_channel_timeout(void *eloop_ctx,
+                                                  void *timeout_ctx)
+{
+       struct wpa_supplicant *wpa_s = eloop_ctx;
+       struct wpas_nan_usd_listen_work *lwork = timeout_ctx;
+
+       wpas_nan_usd_cancel_remain_on_channel_cb(wpa_s, lwork->freq);
+}
+
+
 static void wpas_nan_usd_start_listen_cb(struct wpa_radio_work *work,
                                         int deinit)
 {
@@ -208,6 +219,12 @@ static void wpas_nan_usd_start_listen_cb(struct wpa_radio_work *work,
                wpa_printf(MSG_DEBUG,
                           "NAN: Failed to request the driver to remain on channel (%u MHz) for listen",
                           lwork->freq);
+               eloop_cancel_timeout(wpas_nan_usd_remain_on_channel_timeout,
+                                    wpa_s, ELOOP_ALL_CTX);
+               /* Restart the listen state after a delay */
+               eloop_register_timeout(0, 500,
+                                      wpas_nan_usd_remain_on_channel_timeout,
+                                      wpa_s, lwork);
                wpas_nan_usd_listen_work_done(wpa_s);
                return;
        }
@@ -351,6 +368,8 @@ int wpas_nan_usd_init(struct wpa_supplicant *wpa_s)
 
 void wpas_nan_usd_deinit(struct wpa_supplicant *wpa_s)
 {
+       eloop_cancel_timeout(wpas_nan_usd_remain_on_channel_timeout,
+                            wpa_s, ELOOP_ALL_CTX);
        nan_de_deinit(wpa_s->nan_de);
        wpa_s->nan_de = NULL;
 }