P2P: Add option for adding extra delay to p2p_find
authorJouni Malinen <jouni@qca.qualcomm.com>
Thu, 23 Aug 2012 15:20:58 +0000 (18:20 +0300)
committerJouni Malinen <j@w1.fi>
Thu, 23 Aug 2012 15:20:58 +0000 (18:20 +0300)
A new optional delay=<search delay in milliseconds> parameter can now be
used with p2p_find command to request an extra delay between search
iterations. This can be used, e.g., to make p2p_find friendlier to
concurrent operations by avoiding it from taking 100% of the radio
resources.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>

src/drivers/driver_test.c
src/p2p/p2p.c
src/p2p/p2p.h
src/p2p/p2p_i.h
wpa_supplicant/README-P2P
wpa_supplicant/ctrl_iface.c
wpa_supplicant/dbus/dbus_new_handlers_p2p.c
wpa_supplicant/p2p_supplicant.c
wpa_supplicant/p2p_supplicant.h

index 7a96b9b..a1285ed 100644 (file)
@@ -2824,7 +2824,7 @@ static int wpa_driver_test_p2p_find(void *priv, unsigned int timeout, int type)
        wpa_printf(MSG_DEBUG, "%s(timeout=%u)", __func__, timeout);
        if (!drv->p2p)
                return -1;
-       return p2p_find(drv->p2p, timeout, type, 0, NULL, NULL);
+       return p2p_find(drv->p2p, timeout, type, 0, NULL, NULL, 0);
 }
 
 
index 16196ce..85d5062 100644 (file)
@@ -920,7 +920,7 @@ static void p2p_free_req_dev_types(struct p2p_data *p2p)
 int p2p_find(struct p2p_data *p2p, unsigned int timeout,
             enum p2p_discovery_type type,
             unsigned int num_req_dev_types, const u8 *req_dev_types,
-            const u8 *dev_id)
+            const u8 *dev_id, unsigned int search_delay)
 {
        int res;
 
@@ -954,6 +954,8 @@ int p2p_find(struct p2p_data *p2p, unsigned int timeout,
        p2p->find_type = type;
        p2p_device_clear_reported(p2p);
        p2p_set_state(p2p, P2P_SEARCH);
+       p2p->search_delay = search_delay;
+       p2p->in_search_delay = 0;
        eloop_cancel_timeout(p2p_find_timeout, p2p, NULL);
        p2p->last_p2p_find_timeout = timeout;
        if (timeout)
@@ -1009,7 +1011,7 @@ int p2p_other_scan_completed(struct p2p_data *p2p)
                "now that previous scan was completed");
        if (p2p_find(p2p, p2p->last_p2p_find_timeout, p2p->find_type,
                     p2p->num_req_dev_types, p2p->req_dev_types,
-                    p2p->find_dev_id) < 0)
+                    p2p->find_dev_id, p2p->search_delay) < 0)
                return 0;
        return 1;
 }
@@ -2940,6 +2942,14 @@ int p2p_listen_end(struct p2p_data *p2p, unsigned int freq)
                        p2p_set_timeout(p2p, 0, 100000);
                        return 1;
                }
+               if (p2p->search_delay) {
+                       wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Delay "
+                               "search operation by %u ms",
+                               p2p->search_delay);
+                       p2p_set_timeout(p2p, p2p->search_delay / 1000,
+                                       (p2p->search_delay % 1000) * 1000);
+                       return 1;
+               }
                p2p_search(p2p);
                return 1;
        }
@@ -3134,6 +3144,16 @@ static void p2p_state_timeout(void *eloop_ctx, void *timeout_ctx)
                /* Check if we timed out waiting for PD req */
                if (p2p->pending_action_state == P2P_PENDING_PD)
                        p2p_timeout_prov_disc_req(p2p);
+               if (p2p->search_delay && !p2p->in_search_delay) {
+                       wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Delay "
+                               "search operation by %u ms",
+                               p2p->search_delay);
+                       p2p->in_search_delay = 1;
+                       p2p_set_timeout(p2p, p2p->search_delay / 1000,
+                                       (p2p->search_delay % 1000) * 1000);
+                       break;
+               }
+               p2p->in_search_delay = 0;
                p2p_search(p2p);
                break;
        case P2P_CONNECT:
index d8a3ff1..138f3e7 100644 (file)
@@ -830,12 +830,13 @@ enum p2p_discovery_type {
  *     containing num_req_dev_types * WPS_DEV_TYPE_LEN bytes; %NULL if no
  *     requested device types.
  * @dev_id: Device ID to search for or %NULL to find all devices
+ * @search_delay: Extra delay in milliseconds between search iterations
  * Returns: 0 on success, -1 on failure
  */
 int p2p_find(struct p2p_data *p2p, unsigned int timeout,
             enum p2p_discovery_type type,
             unsigned int num_req_dev_types, const u8 *req_dev_types,
-            const u8 *dev_id);
+            const u8 *dev_id, unsigned int search_delay);
 
 /**
  * p2p_stop_find - Stop P2P Find (Device Discovery)
index 027cad2..3c50556 100644 (file)
@@ -427,6 +427,10 @@ struct p2p_data {
 
        u8 go_timeout;
        u8 client_timeout;
+
+       /* Extra delay in milliseconds between search iterations */
+       unsigned int search_delay;
+       int in_search_delay;
 };
 
 /**
index bb4c2ad..c71fc1c 100644 (file)
@@ -71,7 +71,8 @@ over the main control interface.
 
 Device Discovery
 
-p2p_find [timeout in seconds] [type=<social|progressive>]
+p2p_find [timeout in seconds] [type=<social|progressive>] \
+       [dev_id=<addr>] [delay=<search delay in ms>]
 
 The default behavior is to run a single full scan in the beginning and
 then scan only social channels. type=social will scan only social
@@ -81,6 +82,11 @@ progressively one channel at the time in the Search state rounds. This
 will help in finding new groups or groups missed during the initial
 full scan.
 
+The optional dev_id option can be used to specify a single P2P peer to
+search for. The optional delay parameter can be used to request an extra
+delay to be used between search iterations (e.g., to free up radio
+resources for concurrent operations).
+
 p2p_listen [timeout in seconds]
 
 Start Listen-only state (become discoverable without searching for
index 4fd83b9..b15ad11 100644 (file)
@@ -2958,6 +2958,7 @@ static int p2p_ctrl_find(struct wpa_supplicant *wpa_s, char *cmd)
        enum p2p_discovery_type type = P2P_FIND_START_WITH_FULL;
        u8 dev_id[ETH_ALEN], *_dev_id = NULL;
        char *pos;
+       unsigned int search_delay = 0;
 
        if (os_strstr(cmd, "type=social"))
                type = P2P_FIND_ONLY_SOCIAL;
@@ -2972,7 +2973,14 @@ static int p2p_ctrl_find(struct wpa_supplicant *wpa_s, char *cmd)
                _dev_id = dev_id;
        }
 
-       return wpas_p2p_find(wpa_s, timeout, type, 0, NULL, _dev_id);
+       pos = os_strstr(cmd, "delay=");
+       if (pos) {
+               pos += 6;
+               search_delay = atoi(pos);
+       }
+
+       return wpas_p2p_find(wpa_s, timeout, type, 0, NULL, _dev_id,
+                            search_delay);
 }
 
 
index c05e460..aee8b3a 100644 (file)
@@ -127,7 +127,7 @@ DBusMessage * wpas_dbus_handler_p2p_find(DBusMessage *message,
        }
 
        wpas_p2p_find(wpa_s, timeout, type, num_req_dev_types, req_dev_types,
-                     NULL);
+                     NULL, 0);
        os_free(req_dev_types);
        return reply;
 
index 27b7e34..9cd2ff5 100644 (file)
@@ -3950,7 +3950,7 @@ static void wpas_p2p_clear_pending_action_tx(struct wpa_supplicant *wpa_s)
 int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout,
                  enum p2p_discovery_type type,
                  unsigned int num_req_dev_types, const u8 *req_dev_types,
-                 const u8 *dev_id)
+                 const u8 *dev_id, unsigned int search_delay)
 {
        wpas_p2p_clear_pending_action_tx(wpa_s);
        wpa_s->p2p_long_listen = 0;
@@ -3965,7 +3965,8 @@ int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout,
        wpa_supplicant_cancel_sched_scan(wpa_s);
 
        return p2p_find(wpa_s->global->p2p, timeout, type,
-                       num_req_dev_types, req_dev_types, dev_id);
+                       num_req_dev_types, req_dev_types, dev_id,
+                       search_delay);
 }
 
 
index 8ecd24c..678dadb 100644 (file)
@@ -53,7 +53,7 @@ enum p2p_discovery_type;
 int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout,
                  enum p2p_discovery_type type,
                  unsigned int num_req_dev_types, const u8 *req_dev_types,
-                 const u8 *dev_id);
+                 const u8 *dev_id, unsigned int search_delay);
 void wpas_p2p_stop_find(struct wpa_supplicant *wpa_s);
 int wpas_p2p_listen(struct wpa_supplicant *wpa_s, unsigned int timeout);
 int wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,