]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
nl80211: Add a handler for NL80211_CMD_FRAME_WAIT_CANCEL events
authorJouni Malinen <quic_jouni@quicinc.com>
Thu, 3 Feb 2022 22:12:13 +0000 (00:12 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 3 Feb 2022 22:13:12 +0000 (00:13 +0200)
This can be helpful in figuring out when the driver has stopped waiting
on a specific channel and would need a remain-on-channel command to
continue listening on that channel.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
src/drivers/driver.h
src/drivers/driver_common.c
src/drivers/driver_nl80211_event.c

index d3312a34d8f80f0abb6ee3e722fe8a752cd43f72..85be4c38449fa711373c264e21b552b9fb026d04 100644 (file)
@@ -5129,6 +5129,15 @@ enum wpa_event_type {
         * is required to provide more details of the frame.
         */
        EVENT_UNPROT_BEACON,
+
+       /**
+        * EVENT_TX_WAIT_EXPIRE - TX wait timed out
+        *
+        * This event is used to indicate when the driver has completed
+        * wait for a response frame based on a TX request that specified a
+        * non-zero wait time and that has not been explicitly cancelled.
+        */
+       EVENT_TX_WAIT_EXPIRE,
 };
 
 
index 1cb976011d2b64c1e4bca607f603f8d4b4134a06..741521c6719ec6fe7fb8a1ad6f9e63586711a0d5 100644 (file)
@@ -90,6 +90,7 @@ const char * event_to_string(enum wpa_event_type event)
        E2S(WDS_STA_INTERFACE_STATUS);
        E2S(UPDATE_DH);
        E2S(UNPROT_BEACON);
+       E2S(TX_WAIT_EXPIRE);
        }
 
        return "UNKNOWN";
index 0f0a01d0180bcb191d9393f603a31ef109b0e0f3..fd2146793a56a6ecd633d53619e02170eec2ccae 100644 (file)
@@ -2855,6 +2855,40 @@ nl80211_control_port_frame_tx_status(struct wpa_driver_nl80211_data *drv,
 }
 
 
+static void nl80211_frame_wait_cancel(struct wpa_driver_nl80211_data *drv,
+                                     struct nlattr *cookie_attr)
+{
+       unsigned int i;
+       u64 cookie;
+       bool match = false;
+
+       if (!cookie_attr)
+               return;
+       cookie = nla_get_u64(cookie_attr);
+
+       for (i = 0; i < drv->num_send_frame_cookies; i++) {
+               if (cookie == drv->send_frame_cookies[i]) {
+                       match = true;
+                       break;
+               }
+       }
+       wpa_printf(MSG_DEBUG,
+                  "nl80211: TX frame wait expired for cookie 0x%llx%s",
+                  (long long unsigned int) cookie,
+                  match ? " (match)" : "");
+       if (!match)
+               return;
+
+       if (i < drv->num_send_frame_cookies - 1)
+               os_memmove(&drv->send_frame_cookies[i],
+                          &drv->send_frame_cookies[i + 1],
+                          (drv->num_send_frame_cookies - i - 1) * sizeof(u64));
+       drv->num_send_frame_cookies--;
+
+       wpa_supplicant_event(drv->ctx, EVENT_TX_WAIT_EXPIRE, NULL);
+}
+
+
 static void do_process_drv_event(struct i802_bss *bss, int cmd,
                                 struct nlattr **tb)
 {
@@ -3101,6 +3135,9 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
                                                     tb[NL80211_ATTR_ACK],
                                                     tb[NL80211_ATTR_COOKIE]);
                break;
+       case NL80211_CMD_FRAME_WAIT_CANCEL:
+               nl80211_frame_wait_cancel(drv, tb[NL80211_ATTR_COOKIE]);
+               break;
        default:
                wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event "
                        "(cmd=%d)", cmd);