P2P: Wait until ongoing scan completes before starting P2P find
The P2P_FIND command was failing if it was issued at the moment when a scan operation was in progress. Avoid returning failure in this case by scheduling the P2P find to start once the ongoing scan is completed. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
545cfc4bf3
commit
39185dfa54
6 changed files with 61 additions and 1 deletions
|
@ -106,6 +106,8 @@ static const char * p2p_state_txt(int state)
|
||||||
return "INVITE";
|
return "INVITE";
|
||||||
case P2P_INVITE_LISTEN:
|
case P2P_INVITE_LISTEN:
|
||||||
return "INVITE_LISTEN";
|
return "INVITE_LISTEN";
|
||||||
|
case P2P_SEARCH_WHEN_READY:
|
||||||
|
return "SEARCH_WHEN_READY";
|
||||||
default:
|
default:
|
||||||
return "?";
|
return "?";
|
||||||
}
|
}
|
||||||
|
@ -878,6 +880,7 @@ int p2p_find(struct p2p_data *p2p, unsigned int timeout,
|
||||||
p2p_device_clear_reported(p2p);
|
p2p_device_clear_reported(p2p);
|
||||||
p2p_set_state(p2p, P2P_SEARCH);
|
p2p_set_state(p2p, P2P_SEARCH);
|
||||||
eloop_cancel_timeout(p2p_find_timeout, p2p, NULL);
|
eloop_cancel_timeout(p2p_find_timeout, p2p, NULL);
|
||||||
|
p2p->last_p2p_find_timeout = timeout;
|
||||||
if (timeout)
|
if (timeout)
|
||||||
eloop_register_timeout(timeout, 0, p2p_find_timeout,
|
eloop_register_timeout(timeout, 0, p2p_find_timeout,
|
||||||
p2p, NULL);
|
p2p, NULL);
|
||||||
|
@ -903,6 +906,13 @@ int p2p_find(struct p2p_data *p2p, unsigned int timeout,
|
||||||
eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL);
|
eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL);
|
||||||
eloop_register_timeout(P2P_SCAN_TIMEOUT, 0, p2p_scan_timeout,
|
eloop_register_timeout(P2P_SCAN_TIMEOUT, 0, p2p_scan_timeout,
|
||||||
p2p, NULL);
|
p2p, NULL);
|
||||||
|
} else if (res == 1) {
|
||||||
|
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Could not start "
|
||||||
|
"p2p_scan at this point - will try again after "
|
||||||
|
"previous scan completes");
|
||||||
|
res = 0;
|
||||||
|
p2p_set_state(p2p, P2P_SEARCH_WHEN_READY);
|
||||||
|
eloop_cancel_timeout(p2p_find_timeout, p2p, NULL);
|
||||||
} else {
|
} else {
|
||||||
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Failed to start "
|
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Failed to start "
|
||||||
"p2p_scan");
|
"p2p_scan");
|
||||||
|
@ -914,6 +924,19 @@ int p2p_find(struct p2p_data *p2p, unsigned int timeout,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int p2p_other_scan_completed(struct p2p_data *p2p)
|
||||||
|
{
|
||||||
|
if (p2p->state != P2P_SEARCH_WHEN_READY)
|
||||||
|
return 0;
|
||||||
|
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Starting pending P2P find "
|
||||||
|
"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) < 0)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void p2p_stop_find_for_freq(struct p2p_data *p2p, int freq)
|
void p2p_stop_find_for_freq(struct p2p_data *p2p, int freq)
|
||||||
{
|
{
|
||||||
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Stopping find");
|
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Stopping find");
|
||||||
|
@ -2947,6 +2970,8 @@ static void p2p_state_timeout(void *eloop_ctx, void *timeout_ctx)
|
||||||
case P2P_INVITE_LISTEN:
|
case P2P_INVITE_LISTEN:
|
||||||
p2p_timeout_invite_listen(p2p);
|
p2p_timeout_invite_listen(p2p);
|
||||||
break;
|
break;
|
||||||
|
case P2P_SEARCH_WHEN_READY:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1542,4 +1542,11 @@ int p2p_set_oper_channel(struct p2p_data *p2p, u8 op_reg_class, u8 op_channel,
|
||||||
*/
|
*/
|
||||||
int p2p_in_progress(struct p2p_data *p2p);
|
int p2p_in_progress(struct p2p_data *p2p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* p2p_other_scan_completed - Notify completion of non-P2P scan
|
||||||
|
* @p2p: P2P module context from p2p_init()
|
||||||
|
* Returns: 0 if P2P module is idle or 1 if an operation was started
|
||||||
|
*/
|
||||||
|
int p2p_other_scan_completed(struct p2p_data *p2p);
|
||||||
|
|
||||||
#endif /* P2P_H */
|
#endif /* P2P_H */
|
||||||
|
|
|
@ -201,6 +201,11 @@ struct p2p_data {
|
||||||
* P2P_INVITE_LISTEN - Listen during Invite
|
* P2P_INVITE_LISTEN - Listen during Invite
|
||||||
*/
|
*/
|
||||||
P2P_INVITE_LISTEN,
|
P2P_INVITE_LISTEN,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* P2P_SEARCH_WHEN_READY - Waiting to start Search
|
||||||
|
*/
|
||||||
|
P2P_SEARCH_WHEN_READY,
|
||||||
} state;
|
} state;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -355,6 +360,7 @@ struct p2p_data {
|
||||||
int inv_persistent;
|
int inv_persistent;
|
||||||
|
|
||||||
enum p2p_discovery_type find_type;
|
enum p2p_discovery_type find_type;
|
||||||
|
unsigned int last_p2p_find_timeout;
|
||||||
u8 last_prog_scan_class;
|
u8 last_prog_scan_class;
|
||||||
u8 last_prog_scan_chan;
|
u8 last_prog_scan_chan;
|
||||||
int p2p_scan_running;
|
int p2p_scan_running;
|
||||||
|
|
|
@ -1009,6 +1009,18 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
|
||||||
|
|
||||||
wpa_supplicant_notify_scanning(wpa_s, 0);
|
wpa_supplicant_notify_scanning(wpa_s, 0);
|
||||||
|
|
||||||
|
#ifdef CONFIG_P2P
|
||||||
|
if (wpa_s->p2p_cb_on_scan_complete && !wpa_s->global->p2p_disabled &&
|
||||||
|
wpa_s->global->p2p != NULL) {
|
||||||
|
wpa_s->p2p_cb_on_scan_complete = 0;
|
||||||
|
if (p2p_other_scan_completed(wpa_s->global->p2p) == 1) {
|
||||||
|
wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Pending P2P operation "
|
||||||
|
"stopped scan processing");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_P2P */
|
||||||
|
|
||||||
scan_res = wpa_supplicant_get_scan_results(wpa_s,
|
scan_res = wpa_supplicant_get_scan_results(wpa_s,
|
||||||
data ? &data->scan_info :
|
data ? &data->scan_info :
|
||||||
NULL, 1);
|
NULL, 1);
|
||||||
|
|
|
@ -94,6 +94,7 @@ static int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
|
||||||
struct wpabuf *wps_ie, *ies;
|
struct wpabuf *wps_ie, *ies;
|
||||||
int social_channels[] = { 2412, 2437, 2462, 0, 0 };
|
int social_channels[] = { 2412, 2437, 2462, 0, 0 };
|
||||||
size_t ielen;
|
size_t ielen;
|
||||||
|
int was_in_p2p_scan;
|
||||||
|
|
||||||
if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
|
if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -144,13 +145,19 @@ static int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
was_in_p2p_scan = wpa_s->scan_res_handler == wpas_p2p_scan_res_handler;
|
||||||
wpa_s->scan_res_handler = wpas_p2p_scan_res_handler;
|
wpa_s->scan_res_handler = wpas_p2p_scan_res_handler;
|
||||||
ret = wpa_drv_scan(wpa_s, ¶ms);
|
ret = wpa_drv_scan(wpa_s, ¶ms);
|
||||||
|
|
||||||
wpabuf_free(ies);
|
wpabuf_free(ies);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret) {
|
||||||
wpa_s->scan_res_handler = NULL;
|
wpa_s->scan_res_handler = NULL;
|
||||||
|
if (wpa_s->scanning || was_in_p2p_scan) {
|
||||||
|
wpa_s->p2p_cb_on_scan_complete = 1;
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -3351,6 +3358,7 @@ void wpas_p2p_stop_find(struct wpa_supplicant *wpa_s)
|
||||||
wpa_s->p2p_long_listen = 0;
|
wpa_s->p2p_long_listen = 0;
|
||||||
eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
|
eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
|
||||||
eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
|
eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
|
||||||
|
wpa_s->p2p_cb_on_scan_complete = 0;
|
||||||
|
|
||||||
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) {
|
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) {
|
||||||
wpa_drv_p2p_stop_find(wpa_s);
|
wpa_drv_p2p_stop_find(wpa_s);
|
||||||
|
|
|
@ -476,6 +476,8 @@ struct wpa_supplicant {
|
||||||
P2P_GROUP_REMOVAL_IDLE_TIMEOUT,
|
P2P_GROUP_REMOVAL_IDLE_TIMEOUT,
|
||||||
P2P_GROUP_REMOVAL_UNAVAILABLE
|
P2P_GROUP_REMOVAL_UNAVAILABLE
|
||||||
} removal_reason;
|
} removal_reason;
|
||||||
|
|
||||||
|
unsigned int p2p_cb_on_scan_complete:1;
|
||||||
#endif /* CONFIG_P2P */
|
#endif /* CONFIG_P2P */
|
||||||
|
|
||||||
struct wpa_ssid *bgscan_ssid;
|
struct wpa_ssid *bgscan_ssid;
|
||||||
|
|
Loading…
Reference in a new issue