From fa9f381f203613967e27d93307b5eb252c608f5e Mon Sep 17 00:00:00 2001 From: Daisuke Niwa Date: Wed, 5 Nov 2014 20:35:09 +0900 Subject: [PATCH] P2P: Allow a specific channel to be specified in P2P_FIND The optional freq= 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 --- src/p2p/p2p.c | 15 ++++++++++++++- src/p2p/p2p.h | 6 +++++- wpa_supplicant/README-P2P | 6 ++++-- wpa_supplicant/ctrl_iface.c | 15 ++++++++++++--- wpa_supplicant/dbus/dbus_new_handlers_p2p.c | 2 +- wpa_supplicant/p2p_supplicant.c | 4 ++-- wpa_supplicant/p2p_supplicant.h | 2 +- 7 files changed, 39 insertions(+), 11 deletions(-) diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index d62874ec4..32f68334d 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -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, diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 9edbfb927..2402db6a7 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -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 diff --git a/wpa_supplicant/README-P2P b/wpa_supplicant/README-P2P index a1d96fb59..6a5b03212 100644 --- a/wpa_supplicant/README-P2P +++ b/wpa_supplicant/README-P2P @@ -73,7 +73,7 @@ Device Discovery p2p_find [timeout in seconds] [type=] \ [dev_id=] [dev_type=] \ - [delay=] [seek=] + [delay=] [seek=] [freq=] 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 diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index ec198b294..e92d8635e 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -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); } diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c index 24822bfd8..0eff76386 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c +++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c @@ -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; diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 097b623b9..6ffe59588 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -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); } diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h index 1cf157364..b7861786c 100644 --- a/wpa_supplicant/p2p_supplicant.h +++ b/wpa_supplicant/p2p_supplicant.h @@ -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);