P2P: Allow a specific channel to be specified in P2P_FIND
authorDaisuke Niwa <daisuke.x.niwa@sonymobile.com>
Wed, 5 Nov 2014 11:35:09 +0000 (20:35 +0900)
committerJouni Malinen <j@w1.fi>
Sat, 28 Feb 2015 19:52:56 +0000 (21:52 +0200)
The optional freq=<MHz> can now be used with the P2P_FIND command to
specify a single channel to scan during the first round of P2P search.
For example, this can be used to replace the full initial scan with a
single channel scan of a known operation channel.

Signed-off-by: Daichi Ueura <daichi.ueura@sonymobile.com>
src/p2p/p2p.c
src/p2p/p2p.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 d62874e..32f6833 100644 (file)
@@ -1147,7 +1147,7 @@ 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, unsigned int search_delay,
-            u8 seek_count, const char **seek)
+            u8 seek_count, const char **seek, int freq)
 {
        int res;
 
@@ -1230,6 +1230,19 @@ int p2p_find(struct p2p_data *p2p, unsigned int timeout,
                                       p2p, NULL);
        switch (type) {
        case P2P_FIND_START_WITH_FULL:
+               if (freq > 0) {
+                       /*
+                        * Start with the specified channel and then move to
+                        * social channels only scans.
+                        */
+                       res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx,
+                                                P2P_SCAN_SPECIFIC, freq,
+                                                p2p->num_req_dev_types,
+                                                p2p->req_dev_types, dev_id,
+                                                DEV_PW_DEFAULT);
+                       break;
+               }
+               /* fall through */
        case P2P_FIND_PROGRESSIVE:
                res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_FULL, 0,
                                         p2p->num_req_dev_types,
index 9edbfb9..2402db6 100644 (file)
@@ -1131,13 +1131,17 @@ enum p2p_discovery_type {
  * @search_delay: Extra delay in milliseconds between search iterations
  * @seek_count: Number of ASP Service Strings in the seek_string array
  * @seek_string: ASP Service Strings to query for in Probe Requests
+ * @freq: Requested first scan frequency (in MHz) to modify type ==
+ *     P2P_FIND_START_WITH_FULL behavior. 0 = Use normal full scan.
+ *     If p2p_find is already in progress, this parameter is ignored and full
+ *     scan will be executed.
  * 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, unsigned int search_delay,
-            u8 seek_count, const char **seek_string);
+            u8 seek_count, const char **seek_string, int freq);
 
 /**
  * p2p_notify_scan_trigger_status - Indicate scan trigger status
index a1d96fb..6a5b032 100644 (file)
@@ -73,7 +73,7 @@ Device Discovery
 
 p2p_find [timeout in seconds] [type=<social|progressive>] \
        [dev_id=<addr>] [dev_type=<device type>] \
-       [delay=<search delay in ms>] [seek=<service name>]
+       [delay=<search delay in ms>] [seek=<service name>] [freq=<MHz>]
 
 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,7 +81,9 @@ channels, i.e., it skips the initial full scan. type=progressive is
 like the default behavior, but it will scan through all the channels
 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.
+full scan. When the type parameter is not included (i.e., full scan), the
+optional freq parameter can be used to override the first scan to use only
+the specified channel after which only social channels are scanned.
 
 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
index ec198b2..e92d863 100644 (file)
@@ -4510,6 +4510,7 @@ static int p2p_ctrl_find(struct wpa_supplicant *wpa_s, char *cmd)
        unsigned int search_delay;
        const char *seek[P2P_MAX_QUERY_HASH + 1];
        u8 seek_count = 0;
+       int freq = 0;
 
        if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
                wpa_dbg(wpa_s, MSG_INFO,
@@ -4557,20 +4558,28 @@ static int p2p_ctrl_find(struct wpa_supplicant *wpa_s, char *cmd)
                        *term = '\0';
        }
 
+       pos = os_strstr(cmd, "freq=");
+       if (pos) {
+               pos += 5;
+               freq = atoi(pos);
+               if (freq <= 0)
+                       return -1;
+       }
+
        if (!seek_count)
                return wpas_p2p_find(wpa_s, timeout, type, _dev_type != NULL,
                                     _dev_type, _dev_id,
-                                    search_delay, 0, NULL);
+                                    search_delay, 0, NULL, freq);
 
        if (seek_count > P2P_MAX_QUERY_HASH) {
                seek[0] = NULL;
                return wpas_p2p_find(wpa_s, timeout, type, _dev_type != NULL,
                                     _dev_type, _dev_id,
-                                    search_delay, 1, seek);
+                                    search_delay, 1, seek, freq);
        }
 
        return wpas_p2p_find(wpa_s, timeout, type, _dev_type != NULL, _dev_type,
-                            _dev_id, search_delay, seek_count, seek);
+                            _dev_id, search_delay, seek_count, seek, freq);
 }
 
 
index 24822bf..0eff763 100644 (file)
@@ -131,7 +131,7 @@ DBusMessage * wpas_dbus_handler_p2p_find(DBusMessage *message,
                wpa_s = wpa_s->p2p_dev;
 
        wpas_p2p_find(wpa_s, timeout, type, num_req_dev_types, req_dev_types,
-                     NULL, 0, 0, NULL);
+                     NULL, 0, 0, NULL, 0);
        os_free(req_dev_types);
        return reply;
 
index 097b623..6ffe595 100644 (file)
@@ -6992,7 +6992,7 @@ 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, unsigned int search_delay,
-                 u8 seek_cnt, const char **seek_string)
+                 u8 seek_cnt, const char **seek_string, int freq)
 {
        wpas_p2p_clear_pending_action_tx(wpa_s);
        wpa_s->p2p_long_listen = 0;
@@ -7005,7 +7005,7 @@ int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout,
 
        return p2p_find(wpa_s->global->p2p, timeout, type,
                        num_req_dev_types, req_dev_types, dev_id,
-                       search_delay, seek_cnt, seek_string);
+                       search_delay, seek_cnt, seek_string, freq);
 }
 
 
index 1cf1573..b786178 100644 (file)
@@ -59,7 +59,7 @@ 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, unsigned int search_delay,
-                 u8 seek_cnt, const char **seek_string);
+                 u8 seek_cnt, const char **seek_string, int freq);
 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_listen_start(struct wpa_supplicant *wpa_s, unsigned int timeout);