P2P: Use specific go_bssid field instead of generic bssid field
The bssid field stores the value of the P2P Device Address, not the P2P
interface address, but the interface address is the one that is used for
the BSSID of the resulting GO (see
http://lists.infradead.org/pipermail/hostap/2023-February/041392.html
for details).
This was fixed in the patch that was eventually upstreamed. Align it
here.
Bug: 233925359
Test: set up GO on a device with P2P test app, discovered GO on client
device with wifi picker, switched to P2P test app on client device and
joined the group, looked at logs to verify that scan retry mechanism
works as expected (only GO frequency scanned)
Test: persistent connection using WiFi Direct in Settings menu - connect, disconnect, reconnect (no dialog box).
Change-Id: I5aa732c6f72d6e287896d7fc4e0d5b08a1035627
diff --git a/wpa_supplicant/aidl/p2p_iface.cpp b/wpa_supplicant/aidl/p2p_iface.cpp
index 2afd75b..7f92de1 100644
--- a/wpa_supplicant/aidl/p2p_iface.cpp
+++ b/wpa_supplicant/aidl/p2p_iface.cpp
@@ -122,11 +122,6 @@
wpa_network->disabled = 2;
// set necessary fields
- if (!isAnyEtherAddr(group_owner_bssid)) {
- os_memcpy(wpa_network->bssid, group_owner_bssid, ETH_ALEN);
- wpa_network->bssid_set = 1;
- }
-
wpa_network->ssid = (uint8_t *)os_malloc(ssid.size());
if (wpa_network->ssid == NULL) {
wpa_config_remove_network(wpa_s->conf, wpa_network->id);
@@ -194,7 +189,7 @@
if (wpas_p2p_group_add_persistent(
wpa_s, wpa_network, 0, 0, freq, 0, ht40, vht,
- CONF_OPER_CHWIDTH_USE_HT, he, 0, NULL, 0, 0, is6GhzAllowed(wpa_s), P2P_JOIN_LIMIT, true)) {
+ CONF_OPER_CHWIDTH_USE_HT, he, 0, NULL, 0, 0, is6GhzAllowed(wpa_s), P2P_JOIN_LIMIT, isAnyEtherAddr(group_owner_bssid) ? NULL : group_owner_bssid)) {
ret = -1;
}
@@ -1618,7 +1613,7 @@
} else if (ssid->disabled == 2) {
if (wpas_p2p_group_add_persistent(
wpa_s, ssid, 0, 0, 0, 0, ht40, vht,
- CONF_OPER_CHWIDTH_USE_HT, he, edmg, NULL, 0, 0, is6GhzAllowed(wpa_s), 0, false)) {
+ CONF_OPER_CHWIDTH_USE_HT, he, edmg, NULL, 0, 0, is6GhzAllowed(wpa_s), 0, NULL)) {
return createStatus(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN);
} else {
return ndk::ScopedAStatus::ok();
diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c
index 0f986bb..1a43ee2 100644
--- a/wpa_supplicant/bss.c
+++ b/wpa_supplicant/bss.c
@@ -249,11 +249,11 @@
const u8 *ssid, size_t ssid_len)
{
struct wpa_bss *bss;
- if (!wpa_supplicant_filter_bssid_match(wpa_s, bssid))
+
+ if (bssid && !wpa_supplicant_filter_bssid_match(wpa_s, bssid))
return NULL;
dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
- if ((!bssid ||
- os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0) &&
+ if ((!bssid || os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0) &&
bss->ssid_len == ssid_len &&
os_memcmp(bss->ssid, ssid, ssid_len) == 0)
return bss;
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 27397e9..68a62da 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -7128,7 +7128,7 @@
return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq,
vht_center_freq2, 0, ht40, vht,
vht_chwidth, he, edmg,
- NULL, 0, 0, allow_6ghz, 0, false);
+ NULL, 0, 0, allow_6ghz, 0, NULL);
}
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
index 9d1728c..a178d87 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
@@ -356,10 +356,10 @@
int persistent_group = 0;
int freq = 0;
int retry_limit = 0;
- int force_go_bssid = 0;
char *iface = NULL;
unsigned int group_id = 0;
struct wpa_ssid *ssid;
+ u8 go_bssid_buf[ETH_ALEN], *go_bssid = NULL;
dbus_message_iter_init(message, &iter);
@@ -383,15 +383,18 @@
retry_limit = entry.int32_value;
if (retry_limit <= 0)
goto inv_args_clear;
- } else if (os_strcmp(entry.key, "force_go_bssid") == 0 &&
- entry.type == DBUS_TYPE_BOOLEAN) {
- force_go_bssid = entry.bool_value;
} else if (os_strcmp(entry.key, "persistent_group_object") ==
0 &&
- entry.type == DBUS_TYPE_OBJECT_PATH)
+ entry.type == DBUS_TYPE_OBJECT_PATH) {
pg_object_path = os_strdup(entry.str_value);
- else
+ } else if (os_strcmp(entry.key, "go_bssid") == 0 &&
+ entry.type == DBUS_TYPE_STRING) {
+ if (hwaddr_aton(entry.str_value, go_bssid_buf))
+ goto inv_args_clear;
+ go_bssid = go_bssid_buf;
+ } else {
goto inv_args_clear;
+ }
wpa_dbus_dict_entry_clear(&entry);
}
@@ -437,7 +440,7 @@
if (wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 0, 0, 0,
0, 0, 0, 0, NULL, 0, 0,
false, retry_limit,
- force_go_bssid)) {
+ go_bssid)) {
reply = wpas_dbus_error_unknown_error(
message,
"Failed to reinvoke a persistent group");
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 926ba7a..cf1a403 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -3331,7 +3331,7 @@
wpa_s->conf->p2p_go_edmg, NULL,
go ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0,
1, is_p2p_allow_6ghz(wpa_s->global->p2p), 0,
- false);
+ NULL);
} else if (bssid) {
wpa_s->user_initiated_pd = 0;
wpa_msg_global(wpa_s, MSG_INFO,
@@ -3562,7 +3562,7 @@
P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE :
0, 1,
is_p2p_allow_6ghz(wpa_s->global->p2p), 0,
- false);
+ NULL);
}
@@ -4648,7 +4648,7 @@
persistent_go->mode ==
WPAS_MODE_P2P_GO ?
P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE :
- 0, 0, false, 0, false);
+ 0, 0, false, 0, NULL);
} else if (response_done) {
wpas_p2p_group_add(wpa_s, 1, freq,
0, 0, 0, 0, 0, 0, false);
@@ -4771,7 +4771,7 @@
NULL,
persistent_go->mode == WPAS_MODE_P2P_GO ?
P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0, 0,
- is_p2p_allow_6ghz(wpa_s->global->p2p), 0, false);
+ is_p2p_allow_6ghz(wpa_s->global->p2p), 0, NULL);
} else {
wpas_p2p_group_add(wpa_s, 1, freq, 0, 0, 0, 0, 0, 0,
is_p2p_allow_6ghz(wpa_s->global->p2p));
@@ -6996,7 +6996,7 @@
static int wpas_start_p2p_client(struct wpa_supplicant *wpa_s,
struct wpa_ssid *params, int addr_allocated,
int freq, int force_scan, int retry_limit,
- bool force_go_bssid)
+ const u8 *go_bssid)
{
struct wpa_ssid *ssid;
int other_iface_found = 0;
@@ -7039,9 +7039,9 @@
if (params->passphrase)
ssid->passphrase = os_strdup(params->passphrase);
- if (force_go_bssid && params->bssid_set) {
+ if (go_bssid) {
ssid->bssid_set = 1;
- os_memcpy(ssid->bssid, params->bssid, ETH_ALEN);
+ os_memcpy(ssid->bssid, go_bssid, ETH_ALEN);
}
wpa_s->show_group_started = 1;
@@ -7091,7 +7091,7 @@
const struct p2p_channels *channels,
int connection_timeout, int force_scan,
bool allow_6ghz, int retry_limit,
- bool force_go_bssid)
+ const u8 *go_bssid)
{
struct p2p_go_neg_results params;
int go = 0, freq;
@@ -7161,7 +7161,7 @@
return wpas_start_p2p_client(wpa_s, ssid, addr_allocated, freq,
force_scan, retry_limit,
- force_go_bssid);
+ go_bssid);
} else {
return -1;
}
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index e113c62..b7e8aa2 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -53,7 +53,7 @@
const struct p2p_channels *channels,
int connection_timeout, int force_scan,
bool allow_6ghz, int retry_limit,
- bool force_go_bssid);
+ const u8 *go_bssid);
struct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid);
enum wpas_p2p_prov_disc_use {
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 88d7e6e..3fd86be 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -466,15 +466,19 @@
}
if (bss && !disabled_freq(wpa_s, bss->freq)) {
params->freqs = os_calloc(2, sizeof(int));
- if (params->freqs)
+ if (params->freqs) {
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "P2P: Scan only the known GO frequency %d MHz during invitation",
+ bss->freq);
params->freqs[0] = bss->freq;
+ }
}
}
/*
* Optimize scan based on GO information during persistent
* group reinvocation
*/
- if (params->freqs == NULL && wpa_s->p2p_in_invitation < 5 &&
+ if (!params->freqs && wpa_s->p2p_in_invitation < 5 &&
wpa_s->p2p_invite_go_freq > 0) {
if (wpa_s->p2p_invite_go_freq == 2 ||
wpa_s->p2p_invite_go_freq == 5) {