P2P: Verify local driver preferred frequencies for P2P use cases
Previously the peer operating channel preference was accepted if the indicated frequency was listed in the local preference list from the driver. This was assuming that the driver included only channels that are currently enabled for GO operation. Since that might not be the case, filter the local preference list by doing an explicit validation of the indicated channels for P2P support. This moves the similar validation steps from two other code paths in p2p_check_pref_chan_recv() and p2p_check_pref_chan_no_recv() into a common filtering step in p2p_check_pref_chan() for all three cases. This avoids issues to start the GO in cases where the preferred frequency list from the driver may include channels that are not currently enabled for P2P GO use (e.g., 5 GHz band in world roaming configuration). Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
3a7819f0ad
commit
79329ae0aa
1 changed files with 49 additions and 58 deletions
|
@ -567,26 +567,11 @@ static void p2p_check_pref_chan_no_recv(struct p2p_data *p2p, int go,
|
||||||
* also supported by the peer device.
|
* also supported by the peer device.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < size && !found; i++) {
|
for (i = 0; i < size && !found; i++) {
|
||||||
/*
|
/* Make sure that the common frequency is supported by peer. */
|
||||||
* Make sure that the common frequency is:
|
|
||||||
* 1. Supported by peer
|
|
||||||
* 2. Allowed for P2P use.
|
|
||||||
*/
|
|
||||||
oper_freq = freq_list[i];
|
oper_freq = freq_list[i];
|
||||||
if (p2p_freq_to_channel(oper_freq, &op_class,
|
if (p2p_freq_to_channel(oper_freq, &op_class,
|
||||||
&op_channel) < 0) {
|
&op_channel) < 0)
|
||||||
p2p_dbg(p2p, "Unsupported frequency %u MHz", oper_freq);
|
continue; /* cannot happen due to earlier check */
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!p2p_channels_includes(&p2p->cfg->channels,
|
|
||||||
op_class, op_channel) &&
|
|
||||||
(go || !p2p_channels_includes(&p2p->cfg->cli_channels,
|
|
||||||
op_class, op_channel))) {
|
|
||||||
p2p_dbg(p2p,
|
|
||||||
"Freq %u MHz (oper_class %u channel %u) not allowed for P2P",
|
|
||||||
oper_freq, op_class, op_channel);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
for (j = 0; j < msg->channel_list_len; j++) {
|
for (j = 0; j < msg->channel_list_len; j++) {
|
||||||
|
|
||||||
if (op_channel != msg->channel_list[j])
|
if (op_channel != msg->channel_list[j])
|
||||||
|
@ -607,8 +592,7 @@ static void p2p_check_pref_chan_no_recv(struct p2p_data *p2p, int go,
|
||||||
oper_freq);
|
oper_freq);
|
||||||
} else {
|
} else {
|
||||||
p2p_dbg(p2p,
|
p2p_dbg(p2p,
|
||||||
"None of our preferred channels are supported by peer!. Use: %d MHz for oper_channel",
|
"None of our preferred channels are supported by peer!");
|
||||||
dev->oper_freq);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -634,29 +618,9 @@ static void p2p_check_pref_chan_recv(struct p2p_data *p2p, int go,
|
||||||
msg->pref_freq_list[2 * j + 1]);
|
msg->pref_freq_list[2 * j + 1]);
|
||||||
if (freq_list[i] != oper_freq)
|
if (freq_list[i] != oper_freq)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/*
|
|
||||||
* Make sure that the found frequency is:
|
|
||||||
* 1. Supported
|
|
||||||
* 2. Allowed for P2P use.
|
|
||||||
*/
|
|
||||||
if (p2p_freq_to_channel(oper_freq, &op_class,
|
if (p2p_freq_to_channel(oper_freq, &op_class,
|
||||||
&op_channel) < 0) {
|
&op_channel) < 0)
|
||||||
p2p_dbg(p2p, "Unsupported frequency %u MHz",
|
continue; /* cannot happen */
|
||||||
oper_freq);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!p2p_channels_includes(&p2p->cfg->channels,
|
|
||||||
op_class, op_channel) &&
|
|
||||||
(go ||
|
|
||||||
!p2p_channels_includes(&p2p->cfg->cli_channels,
|
|
||||||
op_class, op_channel))) {
|
|
||||||
p2p_dbg(p2p,
|
|
||||||
"Freq %u MHz (oper_class %u channel %u) not allowed for P2P",
|
|
||||||
oper_freq, op_class, op_channel);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
p2p->op_reg_class = op_class;
|
p2p->op_reg_class = op_class;
|
||||||
p2p->op_channel = op_channel;
|
p2p->op_channel = op_channel;
|
||||||
os_memcpy(&p2p->channels, &p2p->cfg->channels,
|
os_memcpy(&p2p->channels, &p2p->cfg->channels,
|
||||||
|
@ -671,9 +635,7 @@ static void p2p_check_pref_chan_recv(struct p2p_data *p2p, int go,
|
||||||
"Freq %d MHz is a common preferred channel for both peer and local, use it as operating channel",
|
"Freq %d MHz is a common preferred channel for both peer and local, use it as operating channel",
|
||||||
oper_freq);
|
oper_freq);
|
||||||
} else {
|
} else {
|
||||||
p2p_dbg(p2p,
|
p2p_dbg(p2p, "No common preferred channels found!");
|
||||||
"No common preferred channels found! Use: %d MHz for oper_channel",
|
|
||||||
dev->oper_freq);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -684,6 +646,8 @@ void p2p_check_pref_chan(struct p2p_data *p2p, int go,
|
||||||
unsigned int freq_list[P2P_MAX_PREF_CHANNELS], size;
|
unsigned int freq_list[P2P_MAX_PREF_CHANNELS], size;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
u8 op_class, op_channel;
|
u8 op_class, op_channel;
|
||||||
|
char txt[100], *pos, *end;
|
||||||
|
int res;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Use the preferred channel list from the driver only if there is no
|
* Use the preferred channel list from the driver only if there is no
|
||||||
|
@ -699,6 +663,39 @@ void p2p_check_pref_chan(struct p2p_data *p2p, int go,
|
||||||
if (p2p->cfg->get_pref_freq_list(p2p->cfg->cb_ctx, go, &size,
|
if (p2p->cfg->get_pref_freq_list(p2p->cfg->cb_ctx, go, &size,
|
||||||
freq_list))
|
freq_list))
|
||||||
return;
|
return;
|
||||||
|
/* Filter out frequencies that are not acceptable for P2P use */
|
||||||
|
i = 0;
|
||||||
|
while (i < size) {
|
||||||
|
if (p2p_freq_to_channel(freq_list[i], &op_class,
|
||||||
|
&op_channel) < 0 ||
|
||||||
|
(!p2p_channels_includes(&p2p->cfg->channels,
|
||||||
|
op_class, op_channel) &&
|
||||||
|
(go || !p2p_channels_includes(&p2p->cfg->cli_channels,
|
||||||
|
op_class, op_channel)))) {
|
||||||
|
p2p_dbg(p2p,
|
||||||
|
"Ignore local driver frequency preference %u MHz since it is not acceptable for P2P use (go=%d)",
|
||||||
|
freq_list[i], go);
|
||||||
|
if (size - i - 1 > 0)
|
||||||
|
os_memmove(&freq_list[i], &freq_list[i + 1], size - i - 1);
|
||||||
|
size--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Preferred frequency is acceptable for P2P use */
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = txt;
|
||||||
|
end = pos + sizeof(txt);
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
res = os_snprintf(pos, end - pos, " %u", freq_list[i]);
|
||||||
|
if (os_snprintf_error(end - pos, res))
|
||||||
|
break;
|
||||||
|
pos += res;
|
||||||
|
}
|
||||||
|
*pos = '\0';
|
||||||
|
p2p_dbg(p2p, "Local driver frequency preference (size=%u):%s",
|
||||||
|
size, txt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if peer's preference of operating channel is in
|
* Check if peer's preference of operating channel is in
|
||||||
|
@ -708,21 +705,15 @@ void p2p_check_pref_chan(struct p2p_data *p2p, int go,
|
||||||
if (freq_list[i] == (unsigned int) dev->oper_freq)
|
if (freq_list[i] == (unsigned int) dev->oper_freq)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i != size) {
|
if (i != size &&
|
||||||
|
p2p_freq_to_channel(freq_list[i], &op_class, &op_channel) == 0) {
|
||||||
/* Peer operating channel preference matches our preference */
|
/* Peer operating channel preference matches our preference */
|
||||||
if (p2p_freq_to_channel(freq_list[i], &op_class, &op_channel) <
|
|
||||||
0) {
|
|
||||||
p2p_dbg(p2p,
|
|
||||||
"Peer operating channel preference is unsupported frequency %u MHz",
|
|
||||||
freq_list[i]);
|
|
||||||
} else {
|
|
||||||
p2p->op_reg_class = op_class;
|
p2p->op_reg_class = op_class;
|
||||||
p2p->op_channel = op_channel;
|
p2p->op_channel = op_channel;
|
||||||
os_memcpy(&p2p->channels, &p2p->cfg->channels,
|
os_memcpy(&p2p->channels, &p2p->cfg->channels,
|
||||||
sizeof(struct p2p_channels));
|
sizeof(struct p2p_channels));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
p2p_dbg(p2p,
|
p2p_dbg(p2p,
|
||||||
"Peer operating channel preference: %d MHz is not in our preferred channel list",
|
"Peer operating channel preference: %d MHz is not in our preferred channel list",
|
||||||
|
|
Loading…
Reference in a new issue