diff options
| -rw-r--r-- | src/p2p/p2p.c | 2 | ||||
| -rw-r--r-- | src/p2p/p2p.h | 4 | ||||
| -rw-r--r-- | src/p2p/p2p_invitation.c | 18 | ||||
| -rw-r--r-- | wpa_supplicant/events.c | 3 | ||||
| -rw-r--r-- | wpa_supplicant/p2p_supplicant.c | 30 | ||||
| -rw-r--r-- | wpa_supplicant/scan.c | 39 | ||||
| -rw-r--r-- | wpa_supplicant/wpa_supplicant_i.h | 2 |
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, ¶ms, 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]; |
