P2P: Allow discoverable interval for p2p_find to be configured
The new P2P_SET parameter disc_int can now be used to configure discoverable interval for p2p_find operations. The format of the command for setting the values is "P2P_SET disc_int <minDiscoverableInterval> <maxDiscoverableInterval> <max TUs for discoverable interval>". The first two parameters are given in units of 100 TUs (102.4 ms). The third parameter can be used to further limit the interval into a specific TU amount. If it is set to -1, no such additional limitation is enforced. It should be noted that the P2P specification describes the random Listen state interval to be in units of 100 TUs, so setting the max TU value to anything else than -1 is not compliant with the specification and should not be used in normal cases. The default parameters can be set with "P2P_SET disc_int 1 3 -1". Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
23270cd8f5
commit
96beff11d1
5 changed files with 93 additions and 5 deletions
|
@ -214,7 +214,7 @@ void p2p_go_neg_failed(struct p2p_data *p2p, struct p2p_device *peer,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void p2p_listen_in_find(struct p2p_data *p2p)
|
static void p2p_listen_in_find(struct p2p_data *p2p, int dev_disc)
|
||||||
{
|
{
|
||||||
unsigned int r, tu;
|
unsigned int r, tu;
|
||||||
int freq;
|
int freq;
|
||||||
|
@ -235,6 +235,19 @@ static void p2p_listen_in_find(struct p2p_data *p2p)
|
||||||
os_get_random((u8 *) &r, sizeof(r));
|
os_get_random((u8 *) &r, sizeof(r));
|
||||||
tu = (r % ((p2p->max_disc_int - p2p->min_disc_int) + 1) +
|
tu = (r % ((p2p->max_disc_int - p2p->min_disc_int) + 1) +
|
||||||
p2p->min_disc_int) * 100;
|
p2p->min_disc_int) * 100;
|
||||||
|
if (p2p->max_disc_tu >= 0 && tu > (unsigned int) p2p->max_disc_tu)
|
||||||
|
tu = p2p->max_disc_tu;
|
||||||
|
if (!dev_disc && tu < 100)
|
||||||
|
tu = 100; /* Need to wait in non-device discovery use cases */
|
||||||
|
if (p2p->cfg->max_listen && 1024 * tu / 1000 > p2p->cfg->max_listen)
|
||||||
|
tu = p2p->cfg->max_listen * 1000 / 1024;
|
||||||
|
|
||||||
|
if (tu == 0) {
|
||||||
|
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Skip listen state "
|
||||||
|
"since duration was 0 TU");
|
||||||
|
p2p_set_timeout(p2p, 0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
p2p->pending_listen_freq = freq;
|
p2p->pending_listen_freq = freq;
|
||||||
p2p->pending_listen_sec = 0;
|
p2p->pending_listen_sec = 0;
|
||||||
|
@ -2327,6 +2340,7 @@ struct p2p_data * p2p_init(const struct p2p_config *cfg)
|
||||||
|
|
||||||
p2p->min_disc_int = 1;
|
p2p->min_disc_int = 1;
|
||||||
p2p->max_disc_int = 3;
|
p2p->max_disc_int = 3;
|
||||||
|
p2p->max_disc_tu = -1;
|
||||||
|
|
||||||
os_get_random(&p2p->next_tie_breaker, 1);
|
os_get_random(&p2p->next_tie_breaker, 1);
|
||||||
p2p->next_tie_breaker &= 0x01;
|
p2p->next_tie_breaker &= 0x01;
|
||||||
|
@ -2590,7 +2604,7 @@ void p2p_continue_find(struct p2p_data *p2p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p2p_listen_in_find(p2p);
|
p2p_listen_in_find(p2p, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3060,7 +3074,7 @@ static void p2p_timeout_connect(struct p2p_data *p2p)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
p2p_set_state(p2p, P2P_CONNECT_LISTEN);
|
p2p_set_state(p2p, P2P_CONNECT_LISTEN);
|
||||||
p2p_listen_in_find(p2p);
|
p2p_listen_in_find(p2p, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3124,7 +3138,7 @@ static void p2p_timeout_wait_peer_idle(struct p2p_data *p2p)
|
||||||
"P2P: Go to Listen state while waiting for the peer to become "
|
"P2P: Go to Listen state while waiting for the peer to become "
|
||||||
"ready for GO Negotiation");
|
"ready for GO Negotiation");
|
||||||
p2p_set_state(p2p, P2P_WAIT_PEER_CONNECT);
|
p2p_set_state(p2p, P2P_WAIT_PEER_CONNECT);
|
||||||
p2p_listen_in_find(p2p);
|
p2p_listen_in_find(p2p, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3192,7 +3206,7 @@ static void p2p_timeout_invite(struct p2p_data *p2p)
|
||||||
p2p_set_timeout(p2p, 0, 100000);
|
p2p_set_timeout(p2p, 0, 100000);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
p2p_listen_in_find(p2p);
|
p2p_listen_in_find(p2p, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4237,3 +4251,20 @@ int p2p_set_wfd_coupled_sink_info(struct p2p_data *p2p,
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_WIFI_DISPLAY */
|
#endif /* CONFIG_WIFI_DISPLAY */
|
||||||
|
|
||||||
|
|
||||||
|
int p2p_set_disc_int(struct p2p_data *p2p, int min_disc_int, int max_disc_int,
|
||||||
|
int max_disc_tu)
|
||||||
|
{
|
||||||
|
if (min_disc_int > max_disc_int || min_disc_int < 0 || max_disc_int < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
p2p->min_disc_int = min_disc_int;
|
||||||
|
p2p->max_disc_int = max_disc_int;
|
||||||
|
p2p->max_disc_tu = max_disc_tu;
|
||||||
|
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Set discoverable interval: "
|
||||||
|
"min=%d max=%d max_tu=%d", min_disc_int, max_disc_int,
|
||||||
|
max_disc_tu);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -354,6 +354,11 @@ struct p2p_config {
|
||||||
*/
|
*/
|
||||||
size_t ssid_postfix_len;
|
size_t ssid_postfix_len;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* max_listen - Maximum listen duration in ms
|
||||||
|
*/
|
||||||
|
unsigned int max_listen;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* msg_ctx - Context to use with wpa_msg() calls
|
* msg_ctx - Context to use with wpa_msg() calls
|
||||||
*/
|
*/
|
||||||
|
@ -1739,4 +1744,25 @@ int p2p_set_wfd_coupled_sink_info(struct p2p_data *p2p,
|
||||||
const struct wpabuf *elem);
|
const struct wpabuf *elem);
|
||||||
struct wpabuf * wifi_display_encaps(struct wpabuf *subelems);
|
struct wpabuf * wifi_display_encaps(struct wpabuf *subelems);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* p2p_set_disc_int - Set min/max discoverable interval for p2p_find
|
||||||
|
* @p2p: P2P module context from p2p_init()
|
||||||
|
* @min_disc_int: minDiscoverableInterval (in units of 100 TU); default 1
|
||||||
|
* @max_disc_int: maxDiscoverableInterval (in units of 100 TU); default 3
|
||||||
|
* @max_disc_tu: Maximum number of TUs (1.024 ms) for discoverable interval; or
|
||||||
|
* -1 not to limit
|
||||||
|
* Returns: 0 on success, or -1 on failure
|
||||||
|
*
|
||||||
|
* This function can be used to configure minDiscoverableInterval and
|
||||||
|
* maxDiscoverableInterval parameters for the Listen state during device
|
||||||
|
* discovery (p2p_find). A random number of 100 TU units is picked for each
|
||||||
|
* Listen state iteration from [min_disc_int,max_disc_int] range.
|
||||||
|
*
|
||||||
|
* max_disc_tu can be used to futher limit the discoverable duration. However,
|
||||||
|
* it should be noted that use of this parameter is not recommended since it
|
||||||
|
* would not be compliant with the P2P specification.
|
||||||
|
*/
|
||||||
|
int p2p_set_disc_int(struct p2p_data *p2p, int min_disc_int, int max_disc_int,
|
||||||
|
int max_disc_tu);
|
||||||
|
|
||||||
#endif /* P2P_H */
|
#endif /* P2P_H */
|
||||||
|
|
|
@ -225,6 +225,11 @@ struct p2p_data {
|
||||||
*/
|
*/
|
||||||
int max_disc_int;
|
int max_disc_int;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* max_disc_tu - Maximum number of TUs for discoverable interval
|
||||||
|
*/
|
||||||
|
int max_disc_tu;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* devices - List of known P2P Device peers
|
* devices - List of known P2P Device peers
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -4223,6 +4223,30 @@ static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd)
|
||||||
if (os_strcmp(cmd, "disallow_freq") == 0)
|
if (os_strcmp(cmd, "disallow_freq") == 0)
|
||||||
return p2p_ctrl_disallow_freq(wpa_s, param);
|
return p2p_ctrl_disallow_freq(wpa_s, param);
|
||||||
|
|
||||||
|
if (os_strcmp(cmd, "disc_int") == 0) {
|
||||||
|
int min_disc_int, max_disc_int, max_disc_tu;
|
||||||
|
char *pos;
|
||||||
|
|
||||||
|
pos = param;
|
||||||
|
|
||||||
|
min_disc_int = atoi(pos);
|
||||||
|
pos = os_strchr(pos, ' ');
|
||||||
|
if (pos == NULL)
|
||||||
|
return -1;
|
||||||
|
*pos++ = '\0';
|
||||||
|
|
||||||
|
max_disc_int = atoi(pos);
|
||||||
|
pos = os_strchr(pos, ' ');
|
||||||
|
if (pos == NULL)
|
||||||
|
return -1;
|
||||||
|
*pos++ = '\0';
|
||||||
|
|
||||||
|
max_disc_tu = atoi(pos);
|
||||||
|
|
||||||
|
return p2p_set_disc_int(wpa_s->global->p2p, min_disc_int,
|
||||||
|
max_disc_int, max_disc_tu);
|
||||||
|
}
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'",
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'",
|
||||||
cmd);
|
cmd);
|
||||||
|
|
||||||
|
|
|
@ -2760,6 +2760,8 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
|
||||||
|
|
||||||
p2p.p2p_intra_bss = wpa_s->conf->p2p_intra_bss;
|
p2p.p2p_intra_bss = wpa_s->conf->p2p_intra_bss;
|
||||||
|
|
||||||
|
p2p.max_listen = wpa_s->max_remain_on_chan;
|
||||||
|
|
||||||
global->p2p = p2p_init(&p2p);
|
global->p2p = p2p_init(&p2p);
|
||||||
if (global->p2p == NULL)
|
if (global->p2p == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
Loading…
Reference in a new issue