P2P: Add option for adding extra delay to p2p_find

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>
This commit is contained in:
Jouni Malinen 2012-08-23 18:20:58 +03:00 committed by Jouni Malinen
parent 065d2895b4
commit 37448ede31
9 changed files with 50 additions and 10 deletions

View 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);
}

View 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:

View 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)

View 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;
};
/**

View 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

View 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);
}

View 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;

View 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);
}

View 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,