P2P: Filter 6 GHz channels if peer doesn't support them
When 6 GHz channels are included in channel list of P2P Action frames but some peer devices don't support the 6 GHz feature and cannot parse P2P IE data correctly, P2P handshake will fail. Remove 6 GHz channels from the P2P Action frames if the peer doesn't support 6 GHz feature to avoid such failures. Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
This commit is contained in:
parent
d5a9944b84
commit
b9e2826b9d
5 changed files with 54 additions and 14 deletions
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "common.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "common/ieee802_11_common.h"
|
||||
#include "common/qca-vendor.h"
|
||||
#include "wps/wps_i.h"
|
||||
#include "p2p_i.h"
|
||||
|
@ -149,7 +150,7 @@ void p2p_buf_add_pref_channel_list(struct wpabuf *buf,
|
|||
|
||||
|
||||
void p2p_buf_add_channel_list(struct wpabuf *buf, const char *country,
|
||||
struct p2p_channels *chan)
|
||||
struct p2p_channels *chan, bool is_6ghz_capab)
|
||||
{
|
||||
u8 *len;
|
||||
size_t i;
|
||||
|
@ -161,6 +162,9 @@ void p2p_buf_add_channel_list(struct wpabuf *buf, const char *country,
|
|||
|
||||
for (i = 0; i < chan->reg_classes; i++) {
|
||||
struct p2p_reg_class *c = &chan->reg_class[i];
|
||||
|
||||
if (is_6ghz_op_class(c->reg_class) && !is_6ghz_capab)
|
||||
continue;
|
||||
wpabuf_put_u8(buf, c->reg_class);
|
||||
wpabuf_put_u8(buf, c->channels);
|
||||
wpabuf_put_data(buf, c->channel, c->channels);
|
||||
|
|
|
@ -142,6 +142,7 @@ static struct wpabuf * p2p_build_go_neg_req(struct p2p_data *p2p,
|
|||
u8 group_capab;
|
||||
size_t extra = 0;
|
||||
u16 pw_id;
|
||||
bool is_6ghz_capab;
|
||||
|
||||
#ifdef CONFIG_WIFI_DISPLAY
|
||||
if (p2p->wfd_ie_go_neg)
|
||||
|
@ -179,7 +180,10 @@ static struct wpabuf * p2p_build_go_neg_req(struct p2p_data *p2p,
|
|||
p2p_buf_add_ext_listen_timing(buf, p2p->ext_listen_period,
|
||||
p2p->ext_listen_interval);
|
||||
p2p_buf_add_intended_addr(buf, p2p->intended_addr);
|
||||
p2p_buf_add_channel_list(buf, p2p->cfg->country, &p2p->channels);
|
||||
is_6ghz_capab = is_p2p_6ghz_capable(p2p) &&
|
||||
p2p_is_peer_6ghz_capab(p2p, peer->info.p2p_device_addr);
|
||||
p2p_buf_add_channel_list(buf, p2p->cfg->country, &p2p->channels,
|
||||
is_6ghz_capab);
|
||||
p2p_buf_add_device_info(buf, p2p, peer);
|
||||
p2p_buf_add_operating_channel(buf, p2p->cfg->country,
|
||||
p2p->op_reg_class, p2p->op_channel);
|
||||
|
@ -278,6 +282,7 @@ static struct wpabuf * p2p_build_go_neg_resp(struct p2p_data *p2p,
|
|||
u8 group_capab;
|
||||
size_t extra = 0;
|
||||
u16 pw_id;
|
||||
bool is_6ghz_capab;
|
||||
|
||||
p2p_dbg(p2p, "Building GO Negotiation Response");
|
||||
|
||||
|
@ -330,15 +335,21 @@ static struct wpabuf * p2p_build_go_neg_resp(struct p2p_data *p2p,
|
|||
p2p_buf_add_intended_addr(buf, p2p->intended_addr);
|
||||
if (status || peer == NULL) {
|
||||
p2p_buf_add_channel_list(buf, p2p->cfg->country,
|
||||
&p2p->channels);
|
||||
&p2p->channels, false);
|
||||
} else if (peer->go_state == REMOTE_GO) {
|
||||
is_6ghz_capab = is_p2p_6ghz_capable(p2p) &&
|
||||
p2p_is_peer_6ghz_capab(p2p, peer->info.p2p_device_addr);
|
||||
p2p_buf_add_channel_list(buf, p2p->cfg->country,
|
||||
&p2p->channels);
|
||||
&p2p->channels, is_6ghz_capab);
|
||||
} else {
|
||||
struct p2p_channels res;
|
||||
|
||||
is_6ghz_capab = is_p2p_6ghz_capable(p2p) &&
|
||||
p2p_is_peer_6ghz_capab(p2p, peer->info.p2p_device_addr);
|
||||
p2p_channels_intersect(&p2p->channels, &peer->channels,
|
||||
&res);
|
||||
p2p_buf_add_channel_list(buf, p2p->cfg->country, &res);
|
||||
p2p_buf_add_channel_list(buf, p2p->cfg->country, &res,
|
||||
is_6ghz_capab);
|
||||
}
|
||||
p2p_buf_add_device_info(buf, p2p, peer);
|
||||
if (peer && peer->go_state == LOCAL_GO) {
|
||||
|
@ -1085,6 +1096,7 @@ static struct wpabuf * p2p_build_go_neg_conf(struct p2p_data *p2p,
|
|||
struct p2p_channels res;
|
||||
u8 group_capab;
|
||||
size_t extra = 0;
|
||||
bool is_6ghz_capab;
|
||||
|
||||
p2p_dbg(p2p, "Building GO Negotiation Confirm");
|
||||
|
||||
|
@ -1128,7 +1140,9 @@ static struct wpabuf * p2p_build_go_neg_conf(struct p2p_data *p2p,
|
|||
p2p_buf_add_operating_channel(buf, (const char *) resp_chan,
|
||||
resp_chan[3], resp_chan[4]);
|
||||
p2p_channels_intersect(&p2p->channels, &peer->channels, &res);
|
||||
p2p_buf_add_channel_list(buf, p2p->cfg->country, &res);
|
||||
is_6ghz_capab = is_p2p_6ghz_capable(p2p) &&
|
||||
p2p_is_peer_6ghz_capab(p2p, peer->info.p2p_device_addr);
|
||||
p2p_buf_add_channel_list(buf, p2p->cfg->country, &res, is_6ghz_capab);
|
||||
if (go) {
|
||||
p2p_buf_add_group_id(buf, p2p->cfg->dev_addr, p2p->ssid,
|
||||
p2p->ssid_len);
|
||||
|
|
|
@ -758,7 +758,7 @@ void p2p_buf_add_listen_channel(struct wpabuf *buf, const char *country,
|
|||
void p2p_buf_add_operating_channel(struct wpabuf *buf, const char *country,
|
||||
u8 reg_class, u8 channel);
|
||||
void p2p_buf_add_channel_list(struct wpabuf *buf, const char *country,
|
||||
struct p2p_channels *chan);
|
||||
struct p2p_channels *chan, bool is_6ghz_capab);
|
||||
void p2p_buf_add_config_timeout(struct wpabuf *buf, u8 go_timeout,
|
||||
u8 client_timeout);
|
||||
void p2p_buf_add_intended_addr(struct wpabuf *buf, const u8 *interface_addr);
|
||||
|
|
|
@ -24,6 +24,7 @@ static struct wpabuf * p2p_build_invitation_req(struct p2p_data *p2p,
|
|||
u8 *len;
|
||||
const u8 *dev_addr;
|
||||
size_t extra = 0;
|
||||
bool is_6ghz_capab;
|
||||
|
||||
#ifdef CONFIG_WIFI_DISPLAY
|
||||
struct wpabuf *wfd_ie = p2p->wfd_ie_invitation;
|
||||
|
@ -74,7 +75,10 @@ static struct wpabuf * p2p_build_invitation_req(struct p2p_data *p2p,
|
|||
p2p->op_channel);
|
||||
if (p2p->inv_bssid_set)
|
||||
p2p_buf_add_group_bssid(buf, p2p->inv_bssid);
|
||||
p2p_buf_add_channel_list(buf, p2p->cfg->country, &p2p->channels);
|
||||
is_6ghz_capab = is_p2p_6ghz_capable(p2p) &&
|
||||
p2p_is_peer_6ghz_capab(p2p, peer->info.p2p_device_addr);
|
||||
p2p_buf_add_channel_list(buf, p2p->cfg->country, &p2p->channels,
|
||||
is_6ghz_capab);
|
||||
if (go_dev_addr)
|
||||
dev_addr = go_dev_addr;
|
||||
else if (p2p->inv_role == P2P_INVITE_ROLE_CLIENT)
|
||||
|
@ -155,8 +159,14 @@ static struct wpabuf * p2p_build_invitation_resp(struct p2p_data *p2p,
|
|||
reg_class, channel);
|
||||
if (group_bssid)
|
||||
p2p_buf_add_group_bssid(buf, group_bssid);
|
||||
if (channels)
|
||||
p2p_buf_add_channel_list(buf, p2p->cfg->country, channels);
|
||||
if (channels) {
|
||||
bool is_6ghz_capab;
|
||||
|
||||
is_6ghz_capab = is_p2p_6ghz_capable(p2p) &&
|
||||
p2p_is_peer_6ghz_capab(p2p, peer->info.p2p_device_addr);
|
||||
p2p_buf_add_channel_list(buf, p2p->cfg->country, channels,
|
||||
is_6ghz_capab);
|
||||
}
|
||||
p2p_buf_update_ie_hdr(buf, len);
|
||||
|
||||
#ifdef CONFIG_WIFI_DISPLAY
|
||||
|
|
|
@ -124,9 +124,15 @@ static void p2ps_add_pd_req_attrs(struct p2p_data *p2p, struct p2p_device *dev,
|
|||
}
|
||||
|
||||
if (shared_group ||
|
||||
(prov->conncap & (P2PS_SETUP_CLIENT | P2PS_SETUP_NEW)))
|
||||
(prov->conncap & (P2PS_SETUP_CLIENT | P2PS_SETUP_NEW))) {
|
||||
bool is_6ghz_capab;
|
||||
|
||||
is_6ghz_capab = is_p2p_6ghz_capable(p2p) &&
|
||||
p2p_is_peer_6ghz_capab(
|
||||
p2p, dev->info.p2p_device_addr);
|
||||
p2p_buf_add_channel_list(buf, p2p->cfg->country,
|
||||
&p2p->channels);
|
||||
&p2p->channels, is_6ghz_capab);
|
||||
}
|
||||
|
||||
if ((shared_group && !is_zero_ether_addr(intended_addr)) ||
|
||||
(prov->conncap & (P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_NEW)))
|
||||
|
@ -356,9 +362,15 @@ static struct wpabuf * p2p_build_prov_disc_resp(struct p2p_data *p2p,
|
|||
}
|
||||
|
||||
if (persist ||
|
||||
(conncap & (P2PS_SETUP_CLIENT | P2PS_SETUP_GROUP_OWNER)))
|
||||
(conncap & (P2PS_SETUP_CLIENT | P2PS_SETUP_GROUP_OWNER))) {
|
||||
bool is_6ghz_capab;
|
||||
|
||||
is_6ghz_capab = is_p2p_6ghz_capable(p2p) &&
|
||||
p2p_is_peer_6ghz_capab(
|
||||
p2p, dev->info.p2p_device_addr);
|
||||
p2p_buf_add_channel_list(buf, p2p->cfg->country,
|
||||
&p2p->channels);
|
||||
&p2p->channels, is_6ghz_capab);
|
||||
}
|
||||
|
||||
if (!persist && conncap)
|
||||
p2p_buf_add_connection_capability(buf, conncap);
|
||||
|
|
Loading…
Reference in a new issue