Patchwork Add an option to suppress provision discovery during P2P Join

login
register
mail settings
Submitter Jithu Jance
Date Nov. 25, 2011, 9:06 a.m.
Message ID <6C370B347C3FE8438C9692873287D2E1195AE35D62@SJEXCHCCR01.corp.ad.broadcom.com>
Download mbox | patch
Permalink /patch/127646/
State Accepted
Commit ec437d9e748a44d6dc31fb54e9f601e092f7dfcf
Headers show

Comments

Jithu Jance - Nov. 25, 2011, 9:06 a.m.
Hi Jouni,

I have generated a patch addressing your suggestions below. Please see whether its fine.

>Anyway, the proper way to address this is to extend
>p2p_prov_disc behavior

I have extended the p2p_prov_disc command to include an optional "join" argument. This will allow to include GROUP ID.

> For this particular case of joining a running group, I think it would be
> fine to store the information when the extended p2p_prov_disc command is
> used and that could then be used on the following p2p_connect join
> operation.



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

---
 src/drivers/driver.h                        |    2 +-
 src/p2p/p2p.c                               |   30 +++++++++++++++++++
 src/p2p/p2p.h                               |   18 ++++++++++++
 src/p2p/p2p_i.h                             |    6 ++++
 src/p2p/p2p_pd.c                            |    7 ++++
 wpa_supplicant/ctrl_iface.c                 |    6 +++-
 wpa_supplicant/dbus/dbus_new_handlers_p2p.c |    2 +-
 wpa_supplicant/driver_i.h                   |    4 +-
 wpa_supplicant/p2p_supplicant.c             |   41 +++++++++++++++++++++-----
 wpa_supplicant/p2p_supplicant.h             |    2 +-
 wpa_supplicant/wpa_cli.c                    |   16 ++++++----
 11 files changed, 114 insertions(+), 20 deletions(-)

--
1.7.4.1
Jouni Malinen - Dec. 6, 2011, 8:02 p.m.
On Fri, Nov 25, 2011 at 01:06:05AM -0800, Jithu Jance wrote:
> I have generated a patch addressing your suggestions below. Please see whether its fine.

> I have extended the p2p_prov_disc command to include an optional "join" argument. This will allow to include GROUP ID.

Thanks! Applied.


PS.

The patch was whitespace damaged (most tabs converted to spaces). Please
try to fix your mail client not to do that for any future contribution
or at least include the patch as an attachment so that I do not need to
apply the changes manually.

Patch

diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index ce25d03..03e6047 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -2197,7 +2197,7 @@  struct wpa_driver_ops {
         * struct wpa_driver_capa.
         */
        int (*p2p_prov_disc_req)(void *priv, const u8 *peer_addr,
-                                u16 config_methods);
+                                u16 config_methods, int join);

        /**
         * p2p_sd_request - Schedule a service discovery query
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index c307505..27acb4b 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -113,6 +113,36 @@  static const char * p2p_state_txt(int state)
        }
 }

+int 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;
+       else
+       wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: "
+               "Device ("MACSTR") not Found", MAC2STR(iface_addr));
+}

 void p2p_set_state(struct p2p_data *p2p, int new_state)
 {
diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h
index 1501a20..05a50fe 100644
--- a/src/p2p/p2p.h
+++ b/src/p2p/p2p.h
@@ -1035,6 +1035,24 @@  void p2p_wps_success_cb(struct p2p_data *p2p, const u8 *mac_addr);
  */
 void p2p_group_formation_failed(struct p2p_data *p2p);

+/**
+ * p2p_clear_provisioning_info - Clear any stored provisioning info
+ * @p2p: P2P module context from p2p_init()
+ * @mac_addr: Peer Interface address
+ *
+ * This function is used to clear stored WPS provisioning info
+ */
+void p2p_clear_provisioning_info(struct p2p_data *p2p, const u8 *iface_addr);
+
+/**
+ * p2p_get_provisioning_info - get any stored provisioning info
+ * @p2p: P2P module context from p2p_init()
+ * @mac_addr: Peer Device address
+ *
+ * This function is used to retreive stored WPS provisioning Info for a given
+ * peer mac_addr.
+ */
+int p2p_get_provisioning_info(struct p2p_data *p2p, const u8 *addr);

 /* Event notifications from lower layer driver operations */

diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h
index 9d72a1c..081ef2d 100644
--- a/src/p2p/p2p_i.h
+++ b/src/p2p/p2p_i.h
@@ -73,6 +73,12 @@  struct p2p_device {
         */
        u16 req_config_methods;

+       /**
+        * wps_prov_info - Store provision info till Group formation is
+        * completed (failure or success).
+        */
+       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)
diff --git a/src/p2p/p2p_pd.c b/src/p2p/p2p_pd.c
index f7ff06c..ac086b9 100644
--- a/src/p2p/p2p_pd.c
+++ b/src/p2p/p2p_pd.c
@@ -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;
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index b2789be..015a692 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -2463,6 +2463,7 @@  static int p2p_ctrl_prov_disc(struct wpa_supplicant *wpa_s, char *cmd)
 {
        u8 addr[ETH_ALEN];
        char *pos;
+       int join = FALSE;

        /* <addr> <config method> */

@@ -2474,7 +2475,10 @@  static int p2p_ctrl_prov_disc(struct wpa_supplicant *wpa_s, char *cmd)
                return -1;
        pos++;

-       return wpas_p2p_prov_disc(wpa_s, addr, pos);
+       if (os_strstr(pos, "join") != NULL)
+               join = TRUE;
+
+       return wpas_p2p_prov_disc(wpa_s, addr, pos, join);
 }


diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
index f2c5a18..39faeae 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
@@ -692,7 +692,7 @@  DBusMessage * wpas_dbus_handler_p2p_prov_disc_req(DBusMessage *message,
            os_strcmp(config_method, "pushbutton"))
                return wpas_dbus_error_invalid_args(message, NULL);

-       if (wpas_p2p_prov_disc(wpa_s, peer_addr, config_method) < 0)
+       if (wpas_p2p_prov_disc(wpa_s, peer_addr, config_method, join) < 0)
                return wpas_dbus_error_unknown_error(message,
                                "Failed to send provision discovery request");

diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index 8b584db..d61b3fd 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -569,12 +569,12 @@  static inline int wpa_drv_p2p_set_params(struct wpa_supplicant *wpa_s,

 static inline int wpa_drv_p2p_prov_disc_req(struct wpa_supplicant *wpa_s,
                                            const u8 *peer_addr,
-                                           u16 config_methods)
+                                           u16 config_methods, int join)
 {
        if (!wpa_s->driver->p2p_prov_disc_req)
                return -1;
        return wpa_s->driver->p2p_prov_disc_req(wpa_s->drv_priv, peer_addr,
-                                               config_methods);
+                                               config_methods, join);
 }

 static inline u64 wpa_drv_p2p_sd_request(struct wpa_supplicant *wpa_s,
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index c6484af..13003a6 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -2294,6 +2294,12 @@  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);
@@ -2503,6 +2509,15 @@  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 already have the provisioning info. Proceed to Join */
+                       wpa_printf(MSG_DEBUG, "P2P: Provisioning for "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) {
@@ -3256,6 +3271,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)
@@ -3274,35 +3292,42 @@  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);
 }


 int wpas_p2p_prov_disc(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
-                      const char *config_method)
+                      const char *config_method, int join)
 {
        u16 config_methods;

-       if (os_strcmp(config_method, "display") == 0)
+       if (os_strncmp(config_method, "display", 7) == 0)
                config_methods = WPS_CONFIG_DISPLAY;
-       else if (os_strcmp(config_method, "keypad") == 0)
+       else if (os_strncmp(config_method, "keypad", 6) == 0)
                config_methods = WPS_CONFIG_KEYPAD;
-       else if (os_strcmp(config_method, "pbc") == 0 ||
-                os_strcmp(config_method, "pushbutton") == 0)
+       else if (os_strncmp(config_method, "pbc", 3) == 0 ||
+                os_strncmp(config_method, "pushbutton", 10) == 0)
                config_methods = WPS_CONFIG_PUSHBUTTON;
-       else
+       else {
+               wpa_printf(MSG_DEBUG, "P2P: Unkown config method");
                return -1;
+       }

        if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) {
                return wpa_drv_p2p_prov_disc_req(wpa_s, peer_addr,
-                                                config_methods);
+                                                config_methods, join);
        }

        if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled)
                return -1;

        return p2p_prov_disc_req(wpa_s->global->p2p, peer_addr,
-                                config_methods, 0);
+                                config_methods, join);
 }


diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index 9a13f9f..33b22db 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -43,7 +43,7 @@  struct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s,
 void wpas_p2p_wps_success(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
                          int registrar);
 int wpas_p2p_prov_disc(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
-                      const char *config_method);
+                      const char *config_method, int join);
 void wpas_send_action_tx_status(struct wpa_supplicant *wpa_s, const u8 *dst,
                                const u8 *data, size_t data_len,
                                enum p2p_send_action_result result);
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index 3311a01..9ebb0ab 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -2074,15 +2074,19 @@  static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
        char cmd[128];
        int res;

-       if (argc != 2) {
-               printf("Invalid P2P_PROV_DISC command: needs two arguments "
-                      "(address and config method\n"
-                      "(display, keypad, or pbc)\n");
+       if (argc != 2 && argc != 3) {
+               printf("Invalid P2P_PROV_DISC command: needs at least "
+                               "two arguments, address and config method\n"
+                      "(display, keypad, or pbc) and an optional join\n");
                return -1;
        }

-       res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s",
-                         argv[0], argv[1]);
+       if(argc == 3)
+               res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s %s",
+                                 argv[0], argv[1], argv[2]);
+       else
+               res = os_snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s %s",
+                                 argv[0], argv[1]);
        if (res < 0 || (size_t) res >= sizeof(cmd))
                return -1;
        cmd[sizeof(cmd) - 1] = '\0';