From 9c830d917800bff3a53c157063afcf9cd3087399 Mon Sep 17 00:00:00 2001 From: Qiwei Cai Date: Thu, 3 Nov 2022 10:33:09 +0800 Subject: [PATCH] P2P: Track peer 6 GHz capability more robustly It's necessary to maintain knowledge of the 6 GHz capability of the peer. Since the Device Capability field migth change between frames depending on the context in which they are used, loooking at the last received message might not always provide accurate information. Add supports_6ghz bool variable in struct p2p_device, initialize it to false and set to true if the P2P_DEV_CAPAB_6GHZ_BAND_CAPABLE bit is set to 1 in any P2P frame that includes the P2P Capability attribute. This boolean would not be cleared to false at any point in time so that the info doesn't disappear dynamically. Signed-off-by: Jouni Malinen --- src/p2p/p2p.c | 15 ++++++++++++++- src/p2p/p2p_go_neg.c | 6 ++++++ src/p2p/p2p_i.h | 3 +++ src/p2p/p2p_pd.c | 4 ++++ 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index a5e3c15c7..a5a11a883 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -440,6 +440,7 @@ static struct p2p_device * p2p_create_device(struct p2p_data *p2p, return NULL; dl_list_add(&p2p->devices, &dev->list); os_memcpy(dev->info.p2p_device_addr, addr, ETH_ALEN); + dev->support_6ghz = false; return dev; } @@ -608,6 +609,8 @@ static void p2p_copy_wps_info(struct p2p_data *p2p, struct p2p_device *dev, dev->info.group_capab = msg->capability[1]; } + p2p_update_peer_6ghz_capab(dev, msg); + if (msg->ext_listen_timing) { dev->ext_listen_period = WPA_GET_LE16(msg->ext_listen_timing); dev->ext_listen_interval = @@ -631,6 +634,15 @@ static void p2p_copy_wps_info(struct p2p_data *p2p, struct p2p_device *dev, } +void p2p_update_peer_6ghz_capab(struct p2p_device *dev, + const struct p2p_message *msg) +{ + if (msg->capability && + (msg->capability[0] & P2P_DEV_CAPAB_6GHZ_BAND_CAPABLE)) + dev->support_6ghz = true; +} + + static void p2p_update_peer_vendor_elems(struct p2p_device *dev, const u8 *ies, size_t ies_len) { @@ -2077,6 +2089,7 @@ static void p2p_add_dev_from_probe_req(struct p2p_data *p2p, const u8 *addr, } } + p2p_update_peer_6ghz_capab(dev, &msg); os_get_reltime(&dev->last_seen); p2p_parse_free(&msg); return; /* already known */ @@ -5598,7 +5611,7 @@ bool p2p_is_peer_6ghz_capab(struct p2p_data *p2p, const u8 *addr) if (!dev) return false; - return !!(dev->info.dev_capab & P2P_DEV_CAPAB_6GHZ_BAND_CAPABLE); + return dev->support_6ghz; } diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c index e3d704b8e..afd89699f 100644 --- a/src/p2p/p2p_go_neg.c +++ b/src/p2p/p2p_go_neg.c @@ -904,6 +904,9 @@ void p2p_process_go_neg_req(struct p2p_data *p2p, const u8 *sa, p2p_add_dev_info(p2p, sa, dev, &msg); } + if (dev) + p2p_update_peer_6ghz_capab(dev, &msg); + if (p2p->go_neg_peer && p2p->go_neg_peer == dev) eloop_cancel_timeout(p2p_go_neg_wait_timeout, p2p, NULL); @@ -1230,6 +1233,7 @@ void p2p_process_go_neg_resp(struct p2p_data *p2p, const u8 *sa, return; } dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE; + p2p_update_peer_6ghz_capab(dev, &msg); if (msg.dialog_token != dev->dialog_token) { p2p_dbg(p2p, "Unexpected Dialog Token %u (expected %u)", @@ -1525,6 +1529,8 @@ void p2p_process_go_neg_conf(struct p2p_data *p2p, const u8 *sa, return; } + p2p_update_peer_6ghz_capab(dev, &msg); + if (dev->go_state == REMOTE_GO && msg.group_id) { /* Store SSID for Provisioning step */ p2p->ssid_len = msg.group_id_len - ETH_ALEN; diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h index 52f27c865..d6405c049 100644 --- a/src/p2p/p2p_i.h +++ b/src/p2p/p2p_i.h @@ -149,6 +149,7 @@ struct p2p_device { struct wpabuf *go_neg_conf; int sd_pending_bcast_queries; + bool support_6ghz; }; struct p2p_sd_query { @@ -864,6 +865,8 @@ void p2p_continue_find(struct p2p_data *p2p); struct p2p_device * p2p_add_dev_from_go_neg_req(struct p2p_data *p2p, const u8 *addr, struct p2p_message *msg); +void p2p_update_peer_6ghz_capab(struct p2p_device *dev, + const struct p2p_message *msg); void p2p_add_dev_info(struct p2p_data *p2p, const u8 *addr, struct p2p_device *dev, struct p2p_message *msg); int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, diff --git a/src/p2p/p2p_pd.c b/src/p2p/p2p_pd.c index 1a78e14ef..c4960fae2 100644 --- a/src/p2p/p2p_pd.c +++ b/src/p2p/p2p_pd.c @@ -619,6 +619,8 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems); } + p2p_update_peer_6ghz_capab(dev, &msg); + if (!msg.adv_id) { allowed_config_methods |= WPS_CONFIG_PUSHBUTTON; if (!(msg.wps_config_methods & allowed_config_methods)) { @@ -1367,6 +1369,8 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa, dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems); } + p2p_update_peer_6ghz_capab(dev, &msg); + if (dev->dialog_token != msg.dialog_token) { p2p_dbg(p2p, "Ignore Provision Discovery Response with unexpected Dialog Token %u (expected %u)", msg.dialog_token, dev->dialog_token);