]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Skip duplicated provision discovery on join
authorJithu Jance <jithu@broadcom.com>
Tue, 6 Dec 2011 19:44:57 +0000 (21:44 +0200)
committerJouni Malinen <j@w1.fi>
Tue, 6 Dec 2011 19:44:57 +0000 (21:44 +0200)
If p2p_prov_disc join command is used prior to p2p_connect join,
skip the duplicated provision discovery exchange.

Signed-hostap: Jithu Jance <jithu@broadcom.com>

src/p2p/p2p.c
src/p2p/p2p.h
src/p2p/p2p_i.h
src/p2p/p2p_pd.c
wpa_supplicant/p2p_supplicant.c

index c30750586ee6cf37449667174cd66b99bba7db63..a4ba81d15262176683110b03ab70506d56aa8962 100644 (file)
@@ -114,6 +114,34 @@ static const char * p2p_state_txt(int state)
 }
 
 
+u16 p2p_get_provisioning_info(struct p2p_data *p2p, const u8 *addr)
+{
+       struct p2p_device *dev = NULL;
+
+       if (!addr || !p2p)
+               return 0;
+
+       dev = p2p_get_device(p2p, addr);
+       if (dev)
+               return dev->wps_prov_info;
+       else
+               return 0;
+}
+
+
+void p2p_clear_provisioning_info(struct p2p_data *p2p, const u8 *iface_addr)
+{
+       struct p2p_device *dev = NULL;
+
+       if (!iface_addr || !p2p)
+               return;
+
+       dev = p2p_get_device_interface(p2p, iface_addr);
+       if (dev)
+               dev->wps_prov_info = 0;
+}
+
+
 void p2p_set_state(struct p2p_data *p2p, int new_state)
 {
        wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: State %s -> %s",
index 1501a20146b94b13940f5841f64126b373f55346..4735acee698a5b5ce907dcd7dcb2bac615adb6be 100644 (file)
@@ -1035,6 +1035,28 @@ void p2p_wps_success_cb(struct p2p_data *p2p, const u8 *mac_addr);
  */
 void p2p_group_formation_failed(struct p2p_data *p2p);
 
+/**
+ * p2p_get_provisioning_info - Get any stored provisioning info
+ * @p2p: P2P module context from p2p_init()
+ * @addr: Peer P2P Device Address
+ * Returns: WPS provisioning information (WPS config method) or 0 if no
+ * information is available
+ *
+ * This function is used to retrieve stored WPS provisioning info for the given
+ * peer.
+ */
+u16 p2p_get_provisioning_info(struct p2p_data *p2p, const u8 *addr);
+
+/**
+ * p2p_clear_provisioning_info - Clear any stored provisioning info
+ * @p2p: P2P module context from p2p_init()
+ * @iface_addr: Peer P2P Interface Address
+ *
+ * This function is used to clear stored WPS provisioning info for the given
+ * peer.
+ */
+void p2p_clear_provisioning_info(struct p2p_data *p2p, const u8 *iface_addr);
+
 
 /* Event notifications from lower layer driver operations */
 
index 9d72a1c7d2c5dc1a58cfe66e6387301f45042f70..1b9c94b1ea32c8dd463b96849a4f28b80fb05c7c 100644 (file)
@@ -73,6 +73,14 @@ struct p2p_device {
         */
        u16 req_config_methods;
 
+       /**
+        * wps_prov_info - Stored provisioning WPS config method
+        *
+        * This is used to store pending WPS config method between Provisioning
+        * Discovery and connection to a running group.
+        */
+       u16 wps_prov_info;
+
 #define P2P_DEV_PROBE_REQ_ONLY BIT(0)
 #define P2P_DEV_REPORTED BIT(1)
 #define P2P_DEV_NOT_YET_READY BIT(2)
index f7ff06c0e6972619e8d72bf3a4cb297e9c4e0db0..ac086b9bd08d587c55abc8e604b2e7b899138558 100644 (file)
@@ -267,6 +267,10 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
                        MAC2STR(sa));
                dev->flags |= P2P_DEV_PD_PEER_KEYPAD;
        }
+
+       /* Store the provisioning info */
+       dev->wps_prov_info = msg.wps_config_methods;
+
        p2p_parse_free(&msg);
 
 out:
@@ -352,6 +356,9 @@ int p2p_prov_disc_req(struct p2p_data *p2p, const u8 *peer_addr,
        if (config_methods == 0)
                return -1;
 
+       /* Reset provisioning info */
+       dev->wps_prov_info = 0;
+
        dev->req_config_methods = config_methods;
        if (join)
                dev->flags |= P2P_DEV_PD_FOR_JOIN;
index 564517f7c2a3be12ddfe1e3f6181b3902e5db403..e76656b4b7fbde3536000c51fbb27ea807add3d7 100644 (file)
@@ -2296,6 +2296,14 @@ void wpas_p2p_deinit(struct wpa_supplicant *wpa_s)
 {
        if (wpa_s->driver && wpa_s->drv_priv)
                wpa_drv_probe_req_report(wpa_s, 0);
+
+       if (wpa_s->go_params) {
+               /* Clear any stored provisioning info */
+               p2p_clear_provisioning_info(
+                       wpa_s->global->p2p,
+                       wpa_s->go_params->peer_interface_addr);
+       }
+
        os_free(wpa_s->go_params);
        wpa_s->go_params = NULL;
        eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL);
@@ -2505,6 +2513,21 @@ static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s,
                        break;
                }
 
+               if ((p2p_get_provisioning_info(wpa_s->global->p2p,
+                                              wpa_s->pending_join_dev_addr) ==
+                    method)) {
+                       /*
+                        * We have already performed provision discovery for
+                        * joining the group. Proceed directly to join
+                        * operation without duplicated provision discovery. */
+                       wpa_printf(MSG_DEBUG, "P2P: Provisioning discovery "
+                                  "with " MACSTR " already done - proceed to "
+                                  "join",
+                                  MAC2STR(wpa_s->pending_join_dev_addr));
+                       wpa_s->pending_pd_before_join = 0;
+                       goto start;
+               }
+
                if (p2p_prov_disc_req(wpa_s->global->p2p,
                                      wpa_s->pending_join_dev_addr, method, 1)
                    < 0) {
@@ -3258,6 +3281,9 @@ void wpas_p2p_wps_success(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
                return;
        }
 
+       /* Clear any stored provisioning info */
+       p2p_clear_provisioning_info(wpa_s->global->p2p, peer_addr);
+
        eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s->parent,
                             NULL);
        if (wpa_s->global->p2p)
@@ -3276,6 +3302,13 @@ void wpas_p2p_wps_failed(struct wpa_supplicant *wpa_s,
                           "provisioning not in progress");
                return;
        }
+
+       if (wpa_s->go_params) {
+               p2p_clear_provisioning_info(
+                       wpa_s->global->p2p,
+                       wpa_s->go_params->peer_interface_addr);
+       }
+
        wpas_notify_p2p_wps_failed(wpa_s, fail);
 }