P2P: Allow a specific channel to be specified in P2P_FIND

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>
This commit is contained in:
Daisuke Niwa 2014-11-05 20:35:09 +09:00 committed by Jouni Malinen
parent eb78a8d5e3
commit fa9f381f20
7 changed files with 39 additions and 11 deletions

View file

@ -1147,7 +1147,7 @@ int p2p_find(struct p2p_data *p2p, unsigned int timeout,
enum p2p_discovery_type type, enum p2p_discovery_type type,
unsigned int num_req_dev_types, const u8 *req_dev_types, unsigned int num_req_dev_types, const u8 *req_dev_types,
const u8 *dev_id, unsigned int search_delay, const u8 *dev_id, unsigned int search_delay,
u8 seek_count, const char **seek) u8 seek_count, const char **seek, int freq)
{ {
int res; int res;
@ -1230,6 +1230,19 @@ int p2p_find(struct p2p_data *p2p, unsigned int timeout,
p2p, NULL); p2p, NULL);
switch (type) { switch (type) {
case P2P_FIND_START_WITH_FULL: 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: case P2P_FIND_PROGRESSIVE:
res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_FULL, 0, res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_FULL, 0,
p2p->num_req_dev_types, p2p->num_req_dev_types,

View file

@ -1131,13 +1131,17 @@ enum p2p_discovery_type {
* @search_delay: Extra delay in milliseconds between search iterations * @search_delay: Extra delay in milliseconds between search iterations
* @seek_count: Number of ASP Service Strings in the seek_string array * @seek_count: Number of ASP Service Strings in the seek_string array
* @seek_string: ASP Service Strings to query for in Probe Requests * @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 * Returns: 0 on success, -1 on failure
*/ */
int p2p_find(struct p2p_data *p2p, unsigned int timeout, int p2p_find(struct p2p_data *p2p, unsigned int timeout,
enum p2p_discovery_type type, enum p2p_discovery_type type,
unsigned int num_req_dev_types, const u8 *req_dev_types, unsigned int num_req_dev_types, const u8 *req_dev_types,
const u8 *dev_id, unsigned int search_delay, 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 * p2p_notify_scan_trigger_status - Indicate scan trigger status

View file

@ -73,7 +73,7 @@ Device Discovery
p2p_find [timeout in seconds] [type=<social|progressive>] \ p2p_find [timeout in seconds] [type=<social|progressive>] \
[dev_id=<addr>] [dev_type=<device type>] \ [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 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 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 like the default behavior, but it will scan through all the channels
progressively one channel at the time in the Search state rounds. This progressively one channel at the time in the Search state rounds. This
will help in finding new groups or groups missed during the initial 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 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 search for. The optional delay parameter can be used to request an extra

View file

@ -4510,6 +4510,7 @@ static int p2p_ctrl_find(struct wpa_supplicant *wpa_s, char *cmd)
unsigned int search_delay; unsigned int search_delay;
const char *seek[P2P_MAX_QUERY_HASH + 1]; const char *seek[P2P_MAX_QUERY_HASH + 1];
u8 seek_count = 0; u8 seek_count = 0;
int freq = 0;
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
wpa_dbg(wpa_s, MSG_INFO, wpa_dbg(wpa_s, MSG_INFO,
@ -4557,20 +4558,28 @@ static int p2p_ctrl_find(struct wpa_supplicant *wpa_s, char *cmd)
*term = '\0'; *term = '\0';
} }
pos = os_strstr(cmd, "freq=");
if (pos) {
pos += 5;
freq = atoi(pos);
if (freq <= 0)
return -1;
}
if (!seek_count) if (!seek_count)
return wpas_p2p_find(wpa_s, timeout, type, _dev_type != NULL, return wpas_p2p_find(wpa_s, timeout, type, _dev_type != NULL,
_dev_type, _dev_id, _dev_type, _dev_id,
search_delay, 0, NULL); search_delay, 0, NULL, freq);
if (seek_count > P2P_MAX_QUERY_HASH) { if (seek_count > P2P_MAX_QUERY_HASH) {
seek[0] = NULL; seek[0] = NULL;
return wpas_p2p_find(wpa_s, timeout, type, _dev_type != NULL, return wpas_p2p_find(wpa_s, timeout, type, _dev_type != NULL,
_dev_type, _dev_id, _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, 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);
} }

View file

@ -131,7 +131,7 @@ DBusMessage * wpas_dbus_handler_p2p_find(DBusMessage *message,
wpa_s = wpa_s->p2p_dev; wpa_s = wpa_s->p2p_dev;
wpas_p2p_find(wpa_s, timeout, type, num_req_dev_types, req_dev_types, 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); os_free(req_dev_types);
return reply; return reply;

View file

@ -6992,7 +6992,7 @@ int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout,
enum p2p_discovery_type type, enum p2p_discovery_type type,
unsigned int num_req_dev_types, const u8 *req_dev_types, unsigned int num_req_dev_types, const u8 *req_dev_types,
const u8 *dev_id, unsigned int search_delay, 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); wpas_p2p_clear_pending_action_tx(wpa_s);
wpa_s->p2p_long_listen = 0; 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, 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, seek_cnt, seek_string); search_delay, seek_cnt, seek_string, freq);
} }

View file

@ -59,7 +59,7 @@ int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout,
enum p2p_discovery_type type, enum p2p_discovery_type type,
unsigned int num_req_dev_types, const u8 *req_dev_types, unsigned int num_req_dev_types, const u8 *req_dev_types,
const u8 *dev_id, unsigned int search_delay, 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); 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(struct wpa_supplicant *wpa_s, unsigned int timeout);
int wpas_p2p_listen_start(struct wpa_supplicant *wpa_s, unsigned int timeout); int wpas_p2p_listen_start(struct wpa_supplicant *wpa_s, unsigned int timeout);