aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRashmi Ramanna <c_ramanr@qti.qualcomm.com>2014-03-25 22:45:52 +0530
committerSteve Kondik <shade@chemlab.org>2014-06-12 14:08:01 -0700
commitd407faf9d6c7dddb90cfaa6f17ce3028f23c4ba9 (patch)
treeb7dbd485fef33dc2984448954a7f9f01cb0b8886
parentc22b7afa246f023a2908efe186ab4cf973bae22d (diff)
downloadandroid_external_wpa_supplicant_8-d407faf9d6c7dddb90cfaa6f17ce3028f23c4ba9.tar.gz
android_external_wpa_supplicant_8-d407faf9d6c7dddb90cfaa6f17ce3028f23c4ba9.tar.bz2
android_external_wpa_supplicant_8-d407faf9d6c7dddb90cfaa6f17ce3028f23c4ba9.zip
P2P: Optimize scan for GO during persistent group invocation
Scan for GO on the negotiated operating channel for few iterations before searching on all the supported channels during persistent group reinvocation. In addition, use the already known SSID of the group in the scans. These optimizations reduce group formation time. CRs-Fixed: 621209 Git-commit: 41d5ce9e0b7b37dd84fbf3c1aa5ed571c32321d4 Git-repo : git://w1.fi/srv/git/hostap.git Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com> Change-Id: Ib081d459336981fbcd265eca6ef5b91e57d06839
-rw-r--r--src/p2p/p2p.c2
-rw-r--r--src/p2p/p2p.h4
-rw-r--r--src/p2p/p2p_invitation.c18
-rw-r--r--wpa_supplicant/events.c3
-rw-r--r--wpa_supplicant/p2p_supplicant.c30
-rw-r--r--wpa_supplicant/scan.c39
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h2
7 files changed, 84 insertions, 14 deletions
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index de19b48d..3e5dc8c2 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -3373,7 +3373,7 @@ static void p2p_timeout_invite_listen(struct p2p_data *p2p)
p2p->cfg->invitation_result(
p2p->cfg->cb_ctx, -1, NULL, NULL,
p2p->invite_peer->info.p2p_device_addr,
- 0);
+ 0, 0);
}
p2p_set_state(p2p, P2P_IDLE);
}
diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h
index 8e077177..5e729fbd 100644
--- a/src/p2p/p2p.h
+++ b/src/p2p/p2p.h
@@ -743,6 +743,8 @@ struct p2p_config {
* @channels: Available operating channels for the group
* @addr: Peer address
* @freq: Frequency (in MHz) indicated during invitation or 0
+ * @peer_oper_freq: Operating frequency (in MHz) advertized by the peer
+ * during invitation or 0
*
* This callback is used to indicate result of an Invitation procedure
* started with a call to p2p_invite(). The indicated status code is
@@ -752,7 +754,7 @@ struct p2p_config {
*/
void (*invitation_result)(void *ctx, int status, const u8 *bssid,
const struct p2p_channels *channels,
- const u8 *addr, int freq);
+ const u8 *addr, int freq, int peer_oper_freq);
/**
* go_connected - Check whether we are connected to a GO
diff --git a/src/p2p/p2p_invitation.c b/src/p2p/p2p_invitation.c
index b5a3058e..870f6bee 100644
--- a/src/p2p/p2p_invitation.c
+++ b/src/p2p/p2p_invitation.c
@@ -281,7 +281,9 @@ void p2p_process_invitation_req(struct p2p_data *p2p, const u8 *sa,
}
}
- if (!p2p_channels_includes(&intersection, p2p->op_reg_class,
+ /* Reselect the channel only for the case of the GO */
+ if (go &&
+ !p2p_channels_includes(&intersection, p2p->op_reg_class,
p2p->op_channel)) {
p2p_dbg(p2p, "Initially selected channel (op_class %d channel %d) not in channel intersection - try to reselect",
p2p->op_reg_class, p2p->op_channel);
@@ -296,7 +298,7 @@ void p2p_process_invitation_req(struct p2p_data *p2p, const u8 *sa,
status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
goto fail;
}
- } else if (!(dev->flags & P2P_DEV_FORCE_FREQ) &&
+ } else if (go && !(dev->flags & P2P_DEV_FORCE_FREQ) &&
!p2p->cfg->cfg_op_channel) {
p2p_dbg(p2p, "Try to reselect channel selection with peer information received; previously selected op_class %u channel %u",
p2p->op_reg_class, p2p->op_channel);
@@ -429,13 +431,23 @@ void p2p_process_invitation_resp(struct p2p_data *p2p, const u8 *sa,
}
if (p2p->cfg->invitation_result) {
+ int peer_oper_freq = 0;
int freq = p2p_channel_to_freq(p2p->op_reg_class,
p2p->op_channel);
if (freq < 0)
freq = 0;
+
+ if (msg.operating_channel) {
+ peer_oper_freq = p2p_channel_to_freq(
+ msg.operating_channel[3],
+ msg.operating_channel[4]);
+ if (peer_oper_freq < 0)
+ peer_oper_freq = 0;
+ }
+
p2p->cfg->invitation_result(p2p->cfg->cb_ctx, *msg.status,
msg.group_bssid, channels, sa,
- freq);
+ freq, peer_oper_freq);
}
p2p_parse_free(&msg);
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 241806a1..cfeb8e8e 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -1335,7 +1335,8 @@ static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s,
return 0;
if (wpa_s->p2p_in_provisioning ||
- wpa_s->show_group_started) {
+ wpa_s->show_group_started ||
+ wpa_s->p2p_in_invitation) {
/*
* Use shorter wait during P2P Provisioning
* state and during P2P join-a-group operation
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 653af4f3..126e1bad 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -457,6 +457,8 @@ static int wpas_p2p_group_delete(struct wpa_supplicant *wpa_s,
wpa_s->p2p_in_provisioning = 0;
}
+ wpa_s->p2p_in_invitation = 0;
+
/*
* Make sure wait for the first client does not remain active after the
* group has been removed.
@@ -2767,7 +2769,7 @@ static void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid,
if (s) {
int go = s->mode == WPAS_MODE_P2P_GO;
wpas_p2p_group_add_persistent(
- wpa_s, s, go, go ? op_freq : 0, 0, NULL,
+ wpa_s, s, go, op_freq, 0, NULL,
go ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0);
} else if (bssid) {
wpa_s->user_initiated_pd = 0;
@@ -2875,7 +2877,8 @@ static void wpas_remove_persistent_client(struct wpa_supplicant *wpa_s,
static void wpas_invitation_result(void *ctx, int status, const u8 *bssid,
const struct p2p_channels *channels,
- const u8 *peer, int neg_freq)
+ const u8 *peer, int neg_freq,
+ int peer_oper_freq)
{
struct wpa_supplicant *wpa_s = ctx;
struct wpa_ssid *ssid;
@@ -2948,6 +2951,14 @@ static void wpas_invitation_result(void *ctx, int status, const u8 *bssid,
neg_freq);
freq = neg_freq;
}
+ else if (peer_oper_freq > 0 && ssid->mode != WPAS_MODE_P2P_GO &&
+ freq_included(channels, peer_oper_freq))
+ freq = peer_oper_freq;
+ else
+ freq = 0;
+
+ wpa_printf(MSG_DEBUG, "P2P: Persistent group invitation success - op_freq=%d MHz SSID=%s",
+ freq, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
wpas_p2p_group_add_persistent(wpa_s, ssid,
ssid->mode == WPAS_MODE_P2P_GO,
@@ -4675,7 +4686,8 @@ int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
static int wpas_start_p2p_client(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *params, int addr_allocated)
+ struct wpa_ssid *params, int addr_allocated,
+ int freq)
{
struct wpa_ssid *ssid;
@@ -4712,6 +4724,8 @@ static int wpas_start_p2p_client(struct wpa_supplicant *wpa_s,
ssid->passphrase = os_strdup(params->passphrase);
wpa_s->show_group_started = 1;
+ wpa_s->p2p_in_invitation = 1;
+ wpa_s->p2p_invite_go_freq = freq;
wpa_supplicant_select_network(wpa_s, ssid);
@@ -4746,16 +4760,16 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
wpa_s->p2p_fallback_to_go_neg = 0;
+ freq = wpas_p2p_select_go_freq(wpa_s, freq);
+ if (freq < 0)
+ return -1;
+
if (ssid->mode == WPAS_MODE_INFRA)
- return wpas_start_p2p_client(wpa_s, ssid, addr_allocated);
+ return wpas_start_p2p_client(wpa_s, ssid, addr_allocated, freq);
if (ssid->mode != WPAS_MODE_P2P_GO)
return -1;
- freq = wpas_p2p_select_go_freq(wpa_s, freq);
- if (freq < 0)
- return -1;
-
if (wpas_p2p_init_go_params(wpa_s, &params, freq, ht40, channels))
return -1;
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 28cfe570..9d9642a1 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -286,6 +286,33 @@ static void wpa_supplicant_optimize_freqs(
}
wpa_s->p2p_in_provisioning++;
}
+
+ if (params->freqs == NULL && wpa_s->p2p_in_invitation) {
+ /*
+ * Optimize scan based on GO information during persistent
+ * group reinvocation
+ */
+ if (wpa_s->p2p_in_invitation < 5 ||
+ wpa_s->p2p_invite_go_freq > 0) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only GO preferred frequency %d MHz during invitation",
+ wpa_s->p2p_invite_go_freq);
+ params->freqs = os_zalloc(2 * sizeof(int));
+ if (params->freqs)
+ params->freqs[0] = wpa_s->p2p_invite_go_freq;
+ }
+ wpa_s->p2p_in_invitation++;
+ if (wpa_s->p2p_in_invitation > 20) {
+ /*
+ * This should not really happen since the variable is
+ * cleared on group removal, but if it does happen, make
+ * sure we do not get stuck in special invitation scan
+ * mode.
+ */
+ wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Clear p2p_in_invitation");
+ wpa_s->p2p_in_invitation = 0;
+ }
+ }
+
#endif /* CONFIG_P2P */
#ifdef CONFIG_WPS
@@ -594,6 +621,18 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
params.num_ssids = 1;
goto ssid_list_set;
}
+ if (wpa_s->p2p_in_invitation) {
+ if (wpa_s->current_ssid) {
+ wpa_printf(MSG_DEBUG, "P2P: Use specific SSID for scan during invitation");
+ params.ssids[0].ssid = wpa_s->current_ssid->ssid;
+ params.ssids[0].ssid_len =
+ wpa_s->current_ssid->ssid_len;
+ params.num_ssids = 1;
+ } else {
+ wpa_printf(MSG_DEBUG, "P2P: No specific SSID known for scan during invitation");
+ }
+ goto ssid_list_set;
+ }
#endif /* CONFIG_P2P */
/* Find the starting point from which to continue scanning */
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index e110d3c5..643b8750 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -603,6 +603,8 @@ struct wpa_supplicant {
u8 p2p_auth_invite[ETH_ALEN];
int p2p_sd_over_ctrl_iface;
int p2p_in_provisioning;
+ int p2p_in_invitation;
+ int p2p_invite_go_freq;
int pending_invite_ssid_id;
int show_group_started;
u8 go_dev_addr[ETH_ALEN];