P2P: Allow channels to be removed from P2P use
A list of disallowed frequencies for P2P channel list can now be configured with P2P_SET disallow_freq. The frequencies (or frequency pairs) are comma separated. For example: wpa_cli p2p_set disallow_freq 2462,5000-6000 The allowed P2P channel list is constructed by removing explicitly disallowed channels from the channel list received from the driver. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
b8a8d6774b
commit
6f3bc72be0
4 changed files with 140 additions and 21 deletions
|
@ -3287,6 +3287,56 @@ static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int p2p_ctrl_disallow_freq(struct wpa_supplicant *wpa_s,
|
||||||
|
const char *param)
|
||||||
|
{
|
||||||
|
struct wpa_freq_range *freq = NULL, *n;
|
||||||
|
unsigned int count = 0, i;
|
||||||
|
const char *pos, *pos2, *pos3;
|
||||||
|
|
||||||
|
if (wpa_s->global->p2p == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* param includes comma separated frequency range.
|
||||||
|
* For example: 2412-2432,2462,5000-6000
|
||||||
|
*/
|
||||||
|
pos = param;
|
||||||
|
while (pos && pos[0]) {
|
||||||
|
n = os_realloc(freq,
|
||||||
|
(count + 1) * sizeof(struct wpa_freq_range));
|
||||||
|
if (n == NULL) {
|
||||||
|
os_free(freq);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
freq = n;
|
||||||
|
freq[count].min = atoi(pos);
|
||||||
|
pos2 = os_strchr(pos, '-');
|
||||||
|
pos3 = os_strchr(pos, ',');
|
||||||
|
if (pos2 && (!pos3 || pos2 < pos3)) {
|
||||||
|
pos2++;
|
||||||
|
freq[count].max = atoi(pos2);
|
||||||
|
} else
|
||||||
|
freq[count].max = freq[count].min;
|
||||||
|
pos = pos3;
|
||||||
|
if (pos)
|
||||||
|
pos++;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
wpa_printf(MSG_DEBUG, "P2P: Disallowed frequency range %u-%u",
|
||||||
|
freq[i].min, freq[i].max);
|
||||||
|
}
|
||||||
|
|
||||||
|
os_free(wpa_s->global->p2p_disallow_freq);
|
||||||
|
wpa_s->global->p2p_disallow_freq = freq;
|
||||||
|
wpa_s->global->num_p2p_disallow_freq = count;
|
||||||
|
wpas_p2p_update_channel_list(wpa_s);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd)
|
static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd)
|
||||||
{
|
{
|
||||||
char *param;
|
char *param;
|
||||||
|
@ -3431,6 +3481,9 @@ static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (os_strcmp(cmd, "disallow_freq") == 0)
|
||||||
|
return p2p_ctrl_disallow_freq(wpa_s, param);
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'",
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'",
|
||||||
cmd);
|
cmd);
|
||||||
|
|
||||||
|
|
|
@ -2030,6 +2030,31 @@ static void wpas_invitation_result(void *ctx, int status, const u8 *bssid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpas_p2p_disallowed_freq(struct wpa_global *global,
|
||||||
|
unsigned int freq)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (global->p2p_disallow_freq == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (i = 0; i < global->num_p2p_disallow_freq; i++) {
|
||||||
|
if (freq >= global->p2p_disallow_freq[i].min &&
|
||||||
|
freq <= global->p2p_disallow_freq[i].max)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void wpas_p2p_add_chan(struct p2p_reg_class *reg, u8 chan)
|
||||||
|
{
|
||||||
|
reg->channel[reg->channels] = chan;
|
||||||
|
reg->channels++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int wpas_p2p_default_channels(struct wpa_supplicant *wpa_s,
|
static int wpas_p2p_default_channels(struct wpa_supplicant *wpa_s,
|
||||||
struct p2p_channels *chan)
|
struct p2p_channels *chan)
|
||||||
{
|
{
|
||||||
|
@ -2040,9 +2065,12 @@ static int wpas_p2p_default_channels(struct wpa_supplicant *wpa_s,
|
||||||
|
|
||||||
/* Operating class 81 - 2.4 GHz band channels 1..13 */
|
/* Operating class 81 - 2.4 GHz band channels 1..13 */
|
||||||
chan->reg_class[cla].reg_class = 81;
|
chan->reg_class[cla].reg_class = 81;
|
||||||
chan->reg_class[cla].channels = 11;
|
chan->reg_class[cla].channels = 0;
|
||||||
for (i = 0; i < 11; i++)
|
for (i = 0; i < 11; i++) {
|
||||||
chan->reg_class[cla].channel[i] = i + 1;
|
if (!wpas_p2p_disallowed_freq(wpa_s->global, 2412 + i * 5))
|
||||||
|
wpas_p2p_add_chan(&chan->reg_class[cla], i + 1);
|
||||||
|
}
|
||||||
|
if (chan->reg_class[cla].channels)
|
||||||
cla++;
|
cla++;
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for lower 5 GHz "
|
wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for lower 5 GHz "
|
||||||
|
@ -2050,11 +2078,16 @@ static int wpas_p2p_default_channels(struct wpa_supplicant *wpa_s,
|
||||||
|
|
||||||
/* Operating class 115 - 5 GHz, channels 36-48 */
|
/* Operating class 115 - 5 GHz, channels 36-48 */
|
||||||
chan->reg_class[cla].reg_class = 115;
|
chan->reg_class[cla].reg_class = 115;
|
||||||
chan->reg_class[cla].channels = 4;
|
chan->reg_class[cla].channels = 0;
|
||||||
chan->reg_class[cla].channel[0] = 36;
|
if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 36 * 5))
|
||||||
chan->reg_class[cla].channel[1] = 40;
|
wpas_p2p_add_chan(&chan->reg_class[cla], 36);
|
||||||
chan->reg_class[cla].channel[2] = 44;
|
if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 40 * 5))
|
||||||
chan->reg_class[cla].channel[3] = 48;
|
wpas_p2p_add_chan(&chan->reg_class[cla], 40);
|
||||||
|
if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 44 * 5))
|
||||||
|
wpas_p2p_add_chan(&chan->reg_class[cla], 44);
|
||||||
|
if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 48 * 5))
|
||||||
|
wpas_p2p_add_chan(&chan->reg_class[cla], 48);
|
||||||
|
if (chan->reg_class[cla].channels)
|
||||||
cla++;
|
cla++;
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for higher 5 GHz "
|
wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for higher 5 GHz "
|
||||||
|
@ -2062,11 +2095,16 @@ static int wpas_p2p_default_channels(struct wpa_supplicant *wpa_s,
|
||||||
|
|
||||||
/* Operating class 124 - 5 GHz, channels 149,153,157,161 */
|
/* Operating class 124 - 5 GHz, channels 149,153,157,161 */
|
||||||
chan->reg_class[cla].reg_class = 124;
|
chan->reg_class[cla].reg_class = 124;
|
||||||
chan->reg_class[cla].channels = 4;
|
chan->reg_class[cla].channels = 0;
|
||||||
chan->reg_class[cla].channel[0] = 149;
|
if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 149 * 5))
|
||||||
chan->reg_class[cla].channel[1] = 153;
|
wpas_p2p_add_chan(&chan->reg_class[cla], 149);
|
||||||
chan->reg_class[cla].channel[2] = 157;
|
if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 153 * 5))
|
||||||
chan->reg_class[cla].channel[3] = 161;
|
wpas_p2p_add_chan(&chan->reg_class[cla], 153);
|
||||||
|
if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 156 * 5))
|
||||||
|
wpas_p2p_add_chan(&chan->reg_class[cla], 157);
|
||||||
|
if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 161 * 5))
|
||||||
|
wpas_p2p_add_chan(&chan->reg_class[cla], 161);
|
||||||
|
if (chan->reg_class[cla].channels)
|
||||||
cla++;
|
cla++;
|
||||||
|
|
||||||
chan->reg_classes = cla;
|
chan->reg_classes = cla;
|
||||||
|
@ -2089,9 +2127,16 @@ static struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int has_channel(struct hostapd_hw_modes *mode, u8 chan, int *flags)
|
static int has_channel(struct wpa_global *global,
|
||||||
|
struct hostapd_hw_modes *mode, u8 chan, int *flags)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
unsigned int freq;
|
||||||
|
|
||||||
|
freq = (mode->mode == HOSTAPD_MODE_IEEE80211A ? 5000 : 2407) +
|
||||||
|
chan * 5;
|
||||||
|
if (wpas_p2p_disallowed_freq(global, freq))
|
||||||
|
return 0;
|
||||||
|
|
||||||
for (i = 0; i < mode->num_channels; i++) {
|
for (i = 0; i < mode->num_channels; i++) {
|
||||||
if (mode->channels[i].chan == chan) {
|
if (mode->channels[i].chan == chan) {
|
||||||
|
@ -2158,15 +2203,15 @@ static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s,
|
||||||
continue;
|
continue;
|
||||||
for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
|
for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
|
||||||
int flag;
|
int flag;
|
||||||
if (!has_channel(mode, ch, &flag))
|
if (!has_channel(wpa_s->global, mode, ch, &flag))
|
||||||
continue;
|
continue;
|
||||||
if (o->bw == BW40MINUS &&
|
if (o->bw == BW40MINUS &&
|
||||||
(!(flag & HOSTAPD_CHAN_HT40MINUS) ||
|
(!(flag & HOSTAPD_CHAN_HT40MINUS) ||
|
||||||
!has_channel(mode, ch - 4, NULL)))
|
!has_channel(wpa_s->global, mode, ch - 4, NULL)))
|
||||||
continue;
|
continue;
|
||||||
if (o->bw == BW40PLUS &&
|
if (o->bw == BW40PLUS &&
|
||||||
(!(flag & HOSTAPD_CHAN_HT40PLUS) ||
|
(!(flag & HOSTAPD_CHAN_HT40PLUS) ||
|
||||||
!has_channel(mode, ch + 4, NULL)))
|
!has_channel(wpa_s->global, mode, ch + 4, NULL)))
|
||||||
continue;
|
continue;
|
||||||
if (reg == NULL) {
|
if (reg == NULL) {
|
||||||
wpa_printf(MSG_DEBUG, "P2P: Add operating "
|
wpa_printf(MSG_DEBUG, "P2P: Add operating "
|
||||||
|
@ -3104,7 +3149,18 @@ static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
|
||||||
wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best 5 GHz "
|
wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best 5 GHz "
|
||||||
"channel %d MHz", params->freq);
|
"channel %d MHz", params->freq);
|
||||||
} else {
|
} else {
|
||||||
params->freq = 2412;
|
int chan;
|
||||||
|
for (chan = 0; chan < 11; chan++) {
|
||||||
|
params->freq = 2412 + chan * 5;
|
||||||
|
if (!wpas_p2p_disallowed_freq(wpa_s->global,
|
||||||
|
params->freq))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (chan == 11) {
|
||||||
|
wpa_printf(MSG_DEBUG, "P2P: No 2.4 GHz channel "
|
||||||
|
"allowed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
wpa_printf(MSG_DEBUG, "P2P: Set GO freq %d MHz (no preference "
|
wpa_printf(MSG_DEBUG, "P2P: Set GO freq %d MHz (no preference "
|
||||||
"known)", params->freq);
|
"known)", params->freq);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2951,6 +2951,8 @@ void wpa_supplicant_deinit(struct wpa_global *global)
|
||||||
os_free(global->params.override_driver);
|
os_free(global->params.override_driver);
|
||||||
os_free(global->params.override_ctrl_interface);
|
os_free(global->params.override_ctrl_interface);
|
||||||
|
|
||||||
|
os_free(global->p2p_disallow_freq);
|
||||||
|
|
||||||
os_free(global);
|
os_free(global);
|
||||||
wpa_debug_close_syslog();
|
wpa_debug_close_syslog();
|
||||||
wpa_debug_close_file();
|
wpa_debug_close_file();
|
||||||
|
|
|
@ -199,6 +199,12 @@ struct p2p_srv_upnp {
|
||||||
char *service;
|
char *service;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct wpa_freq_range {
|
||||||
|
unsigned int min;
|
||||||
|
unsigned int max;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct wpa_global - Internal, global data for all %wpa_supplicant interfaces
|
* struct wpa_global - Internal, global data for all %wpa_supplicant interfaces
|
||||||
*
|
*
|
||||||
|
@ -220,6 +226,8 @@ struct wpa_global {
|
||||||
struct dl_list p2p_srv_upnp; /* struct p2p_srv_upnp */
|
struct dl_list p2p_srv_upnp; /* struct p2p_srv_upnp */
|
||||||
int p2p_disabled;
|
int p2p_disabled;
|
||||||
int cross_connection;
|
int cross_connection;
|
||||||
|
struct wpa_freq_range *p2p_disallow_freq;
|
||||||
|
unsigned int num_p2p_disallow_freq;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue