diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 2fe032d86..239c3e87b 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -4180,6 +4180,7 @@ static const struct global_parse_data global_fields[] = { { IPV4(ip_addr_mask), 0 }, { IPV4(ip_addr_start), 0 }, { IPV4(ip_addr_end), 0 }, + { INT_RANGE(p2p_cli_probe, 0, 1), 0 }, #endif /* CONFIG_P2P */ { FUNC(country), CFG_CHANGED_COUNTRY }, { INT(bss_max_count), 0 }, diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index 545a4bd74..d8ca054f0 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -967,6 +967,18 @@ struct wpa_config { */ int p2p_no_group_iface; + /** + * p2p_cli_probe - Enable/disable P2P CLI probe request handling + * + * If this parameter is set to 1, a connected P2P Client will receive + * and handle Probe Request frames. Setting this parameter to 0 + * disables this option. Default value: 0. + * + * Note: Setting this property at run time takes effect on the following + * interface state transition to/from the WPA_COMPLETED state. + */ + int p2p_cli_probe; + /** * okc - Whether to enable opportunistic key caching by default * diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index 2508ca9c8..e9465671c 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -1131,6 +1131,9 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) if (config->p2p_ignore_shared_freq) fprintf(f, "p2p_ignore_shared_freq=%u\n", config->p2p_ignore_shared_freq); + if (config->p2p_cli_probe) + fprintf(f, "p2p_cli_probe=%u\n", + config->p2p_cli_probe); #endif /* CONFIG_P2P */ if (config->country[0] && config->country[1]) { fprintf(f, "country=%c%c\n", diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index d89e2704e..a12ffb943 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -1874,6 +1874,7 @@ static void wpas_p2p_clone_config(struct wpa_supplicant *dst, d->wps_nfc_dh_privkey = wpabuf_dup(s->wps_nfc_dh_privkey); d->wps_nfc_dh_pubkey = wpabuf_dup(s->wps_nfc_dh_pubkey); } + d->p2p_cli_probe = s->p2p_cli_probe; } @@ -2384,7 +2385,14 @@ static void wpas_stop_listen(void *ctx) wpa_s->roc_waiting_drv_freq = 0; } wpa_drv_set_ap_wps_ie(wpa_s, NULL, NULL, NULL); - wpa_drv_probe_req_report(wpa_s, 0); + + /* + * Don't cancel Probe Request RX reporting for a connected P2P Client + * handling Probe Request frames. + */ + if (!wpa_s->p2p_cli_probe) + wpa_drv_probe_req_report(wpa_s, 0); + wpas_p2p_listen_work_done(wpa_s); } diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index e833c3aca..97c947c7d 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -728,6 +728,30 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, wpa_s->normal_scans = 0; } +#ifdef CONFIG_P2P + /* + * P2PS client has to reply to Probe Request frames received on the + * group operating channel. Enable Probe Request frame reporting for + * P2P connected client in case p2p_cli_probe configuration property is + * set to 1. + */ + if (wpa_s->conf->p2p_cli_probe && wpa_s->current_ssid && + wpa_s->current_ssid->mode == WPAS_MODE_INFRA && + wpa_s->current_ssid->p2p_group) { + if (state == WPA_COMPLETED && !wpa_s->p2p_cli_probe) { + wpa_dbg(wpa_s, MSG_DEBUG, + "P2P: Enable CLI Probe Request RX reporting"); + wpa_s->p2p_cli_probe = + wpa_drv_probe_req_report(wpa_s, 1) >= 0; + } else if (state != WPA_COMPLETED && wpa_s->p2p_cli_probe) { + wpa_dbg(wpa_s, MSG_DEBUG, + "P2P: Disable CLI Probe Request RX reporting"); + wpa_s->p2p_cli_probe = 0; + wpa_drv_probe_req_report(wpa_s, 0); + } + } +#endif /* CONFIG_P2P */ + if (state != WPA_SCANNING) wpa_supplicant_notify_scanning(wpa_s, 0); diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index bc6425d66..f39fe23d9 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -818,6 +818,7 @@ struct wpa_supplicant { unsigned int p2p_peer_oob_pk_hash_known:1; unsigned int p2p_disable_ip_addr_req:1; unsigned int p2ps_join_addr_valid:1; + unsigned int p2p_cli_probe:1; int p2p_persistent_go_freq; int p2p_persistent_id; int p2p_go_intent;