]> git.ipfire.org Git - thirdparty/hostap.git/blobdiff - wpa_supplicant/offchannel.c
P2P: Move p2p_long_listen into struct wpa_global
[thirdparty/hostap.git] / wpa_supplicant / offchannel.c
index 6b3f83c413ace0e8a4a9607ab1984d55e99e0e2c..77c425fac9259864012138f19049dc5113ee48aa 100644 (file)
@@ -23,8 +23,29 @@ wpas_get_tx_interface(struct wpa_supplicant *wpa_s, const u8 *src)
 {
        struct wpa_supplicant *iface;
 
-       if (os_memcmp(src, wpa_s->own_addr, ETH_ALEN) == 0)
+       if (os_memcmp(src, wpa_s->own_addr, ETH_ALEN) == 0) {
+#ifdef CONFIG_P2P
+               if (wpa_s->p2p_mgmt && wpa_s != wpa_s->parent &&
+                   wpa_s->parent->ap_iface &&
+                   os_memcmp(wpa_s->parent->own_addr,
+                             wpa_s->own_addr, ETH_ALEN) == 0 &&
+                   wpabuf_len(wpa_s->pending_action_tx) >= 2 &&
+                   *wpabuf_head_u8(wpa_s->pending_action_tx) !=
+                   WLAN_ACTION_PUBLIC) {
+                       /*
+                        * When P2P Device interface has same MAC address as
+                        * the GO interface, make sure non-Public Action frames
+                        * are sent through the GO interface. The P2P Device
+                        * interface can only send Public Action frames.
+                        */
+                       wpa_printf(MSG_DEBUG,
+                                  "P2P: Use GO interface %s instead of interface %s for Action TX",
+                                  wpa_s->parent->ifname, wpa_s->ifname);
+                       return wpa_s->parent;
+               }
+#endif /* CONFIG_P2P */
                return wpa_s;
+       }
 
        /*
         * Try to find a group interface that matches with the source address.
@@ -205,10 +226,10 @@ void offchannel_send_action_tx_status(
        }
 
 #ifdef CONFIG_P2P
-       if (wpa_s->p2p_long_listen > 0) {
+       if (wpa_s->global->p2p_long_listen > 0) {
                /* Continue the listen */
                wpa_printf(MSG_DEBUG, "P2P: Continuing long Listen state");
-               wpas_p2p_listen_start(wpa_s, wpa_s->p2p_long_listen);
+               wpas_p2p_listen_start(wpa_s, wpa_s->global->p2p_long_listen);
        }
 #endif /* CONFIG_P2P */
 }
@@ -289,6 +310,8 @@ int offchannel_send_action(struct wpa_supplicant *wpa_s, unsigned int freq,
 
                iface = wpas_get_tx_interface(wpa_s, src);
                wpa_s->action_tx_wait_time = wait_time;
+               if (wait_time)
+                       wpa_s->action_tx_wait_time_used = 1;
 
                ret = wpa_drv_send_action(
                        iface, wpa_s->pending_action_freq,
@@ -377,13 +400,14 @@ void offchannel_send_action_done(struct wpa_supplicant *wpa_s)
        wpabuf_free(wpa_s->pending_action_tx);
        wpa_s->pending_action_tx = NULL;
        if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX &&
-           wpa_s->action_tx_wait_time)
+           (wpa_s->action_tx_wait_time || wpa_s->action_tx_wait_time_used))
                wpa_drv_send_action_cancel_wait(wpa_s);
        else if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) {
                wpa_drv_cancel_remain_on_channel(wpa_s);
                wpa_s->off_channel_freq = 0;
                wpa_s->roc_waiting_drv_freq = 0;
        }
+       wpa_s->action_tx_wait_time_used = 0;
 }