aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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];