P2P: Add support for 60 GHz social channel
Support 60 GHz band in P2P module by selecting random social channel from all supported social channels in 2.4 GHz and 60 GHz bands. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
b6ebdfbedd
commit
1595eb93ae
4 changed files with 108 additions and 36 deletions
|
@ -1287,8 +1287,8 @@ static void p2p_prepare_channel_best(struct p2p_data *p2p)
|
|||
} else if (p2p_channel_random_social(&p2p->cfg->channels,
|
||||
&p2p->op_reg_class,
|
||||
&p2p->op_channel) == 0) {
|
||||
p2p_dbg(p2p, "Select random available social channel %d from 2.4 GHz band as operating channel preference",
|
||||
p2p->op_channel);
|
||||
p2p_dbg(p2p, "Select random available social channel (op_class %u channel %u) as operating channel preference",
|
||||
p2p->op_reg_class, p2p->op_channel);
|
||||
} else {
|
||||
/* Select any random available channel from the first available
|
||||
* operating class */
|
||||
|
@ -4095,6 +4095,13 @@ void p2p_set_managed_oper(struct p2p_data *p2p, int enabled)
|
|||
}
|
||||
|
||||
|
||||
int p2p_config_get_random_social(struct p2p_config *p2p, u8 *op_class,
|
||||
u8 *op_channel)
|
||||
{
|
||||
return p2p_channel_random_social(&p2p->channels, op_class, op_channel);
|
||||
}
|
||||
|
||||
|
||||
int p2p_set_listen_channel(struct p2p_data *p2p, u8 reg_class, u8 channel,
|
||||
u8 forced)
|
||||
{
|
||||
|
|
|
@ -1691,6 +1691,20 @@ void p2p_set_client_discoverability(struct p2p_data *p2p, int enabled);
|
|||
*/
|
||||
void p2p_set_managed_oper(struct p2p_data *p2p, int enabled);
|
||||
|
||||
/**
|
||||
* p2p_config_get_random_social - Return a random social channel
|
||||
* @p2p: P2P config
|
||||
* @op_class: Selected operating class
|
||||
* @op_channel: Selected social channel
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* This function is used before p2p_init is called. A random social channel
|
||||
* from supports bands 2.4 GHz (channels 1,6,11) and 60 GHz (channel 2) is
|
||||
* returned on success.
|
||||
*/
|
||||
int p2p_config_get_random_social(struct p2p_config *p2p, u8 *op_class,
|
||||
u8 *op_channel);
|
||||
|
||||
int p2p_set_listen_channel(struct p2p_data *p2p, u8 reg_class, u8 channel,
|
||||
u8 forced);
|
||||
|
||||
|
|
|
@ -149,6 +149,15 @@ int p2p_freq_to_channel(unsigned int freq, u8 *op_class, u8 *channel)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (freq >= 58320 && freq <= 64800) {
|
||||
if ((freq - 58320) % 2160)
|
||||
return -1;
|
||||
|
||||
*op_class = 180; /* 60 GHz, channels 1..4 */
|
||||
*channel = (freq - 56160) / 2160;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -482,7 +491,7 @@ int p2p_channel_select(struct p2p_channels *chans, const int *classes,
|
|||
int p2p_channel_random_social(struct p2p_channels *chans, u8 *op_class,
|
||||
u8 *op_channel)
|
||||
{
|
||||
u8 chan[3];
|
||||
u8 chan[4];
|
||||
unsigned int num_channels = 0;
|
||||
|
||||
/* Try to find available social channels from 2.4 GHz */
|
||||
|
@ -493,11 +502,18 @@ int p2p_channel_random_social(struct p2p_channels *chans, u8 *op_class,
|
|||
if (p2p_channels_includes(chans, 81, 11))
|
||||
chan[num_channels++] = 11;
|
||||
|
||||
/* Try to find available social channels from 60 GHz */
|
||||
if (p2p_channels_includes(chans, 180, 2))
|
||||
chan[num_channels++] = 2;
|
||||
|
||||
if (num_channels == 0)
|
||||
return -1;
|
||||
|
||||
*op_class = 81;
|
||||
*op_channel = p2p_channel_pick_random(chan, num_channels);
|
||||
if (*op_channel == 2)
|
||||
*op_class = 180;
|
||||
else
|
||||
*op_class = 81;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -286,8 +286,10 @@ static int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
|
|||
struct wpa_supplicant *wpa_s = ctx;
|
||||
struct wpa_driver_scan_params *params = NULL;
|
||||
struct wpabuf *wps_ie, *ies;
|
||||
unsigned int num_channels = 0;
|
||||
int social_channels_freq[] = { 2412, 2437, 2462, 60480 };
|
||||
size_t ielen;
|
||||
u8 *n;
|
||||
u8 *n, i;
|
||||
|
||||
if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
|
||||
return -1;
|
||||
|
@ -341,25 +343,34 @@ static int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
|
|||
|
||||
switch (type) {
|
||||
case P2P_SCAN_SOCIAL:
|
||||
params->freqs = os_malloc(4 * sizeof(int));
|
||||
params->freqs = os_calloc(ARRAY_SIZE(social_channels_freq) + 1,
|
||||
sizeof(int));
|
||||
if (params->freqs == NULL)
|
||||
goto fail;
|
||||
params->freqs[0] = 2412;
|
||||
params->freqs[1] = 2437;
|
||||
params->freqs[2] = 2462;
|
||||
params->freqs[3] = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(social_channels_freq); i++) {
|
||||
if (p2p_supported_freq(wpa_s->global->p2p,
|
||||
social_channels_freq[i]))
|
||||
params->freqs[num_channels++] =
|
||||
social_channels_freq[i];
|
||||
}
|
||||
params->freqs[num_channels++] = 0;
|
||||
break;
|
||||
case P2P_SCAN_FULL:
|
||||
break;
|
||||
case P2P_SCAN_SOCIAL_PLUS_ONE:
|
||||
params->freqs = os_malloc(5 * sizeof(int));
|
||||
params->freqs = os_calloc(ARRAY_SIZE(social_channels_freq) + 2,
|
||||
sizeof(int));
|
||||
if (params->freqs == NULL)
|
||||
goto fail;
|
||||
params->freqs[0] = 2412;
|
||||
params->freqs[1] = 2437;
|
||||
params->freqs[2] = 2462;
|
||||
params->freqs[3] = freq;
|
||||
params->freqs[4] = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(social_channels_freq); i++) {
|
||||
if (p2p_supported_freq(wpa_s->global->p2p,
|
||||
social_channels_freq[i]))
|
||||
params->freqs[num_channels++] =
|
||||
social_channels_freq[i];
|
||||
}
|
||||
if (p2p_supported_freq(wpa_s->global->p2p, freq))
|
||||
params->freqs[num_channels++] = freq;
|
||||
params->freqs[num_channels++] = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -3468,7 +3479,7 @@ struct p2p_oper_class_map {
|
|||
u8 min_chan;
|
||||
u8 max_chan;
|
||||
u8 inc;
|
||||
enum { BW20, BW40PLUS, BW40MINUS, BW80 } bw;
|
||||
enum { BW20, BW40PLUS, BW40MINUS, BW80, BW2160 } bw;
|
||||
};
|
||||
|
||||
static struct p2p_oper_class_map op_class[] = {
|
||||
|
@ -3493,6 +3504,7 @@ static struct p2p_oper_class_map op_class[] = {
|
|||
* removing invalid channels.
|
||||
*/
|
||||
{ HOSTAPD_MODE_IEEE80211A, 128, 36, 161, 4, BW80 },
|
||||
{ HOSTAPD_MODE_IEEE80211AD, 180, 1, 4, 1, BW2160 },
|
||||
{ -1, 0, 0, 0, 0, BW20 }
|
||||
};
|
||||
|
||||
|
@ -3864,7 +3876,6 @@ static int _wpas_p2p_in_progress(void *ctx)
|
|||
int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
|
||||
{
|
||||
struct p2p_config p2p;
|
||||
unsigned int r;
|
||||
int i;
|
||||
|
||||
if (wpa_s->conf->p2p_disabled)
|
||||
|
@ -3916,23 +3927,32 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
|
|||
p2p.config_methods = wpa_s->wps->config_methods;
|
||||
}
|
||||
|
||||
if (wpas_p2p_setup_channels(wpa_s, &p2p.channels, &p2p.cli_channels)) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"P2P: Failed to configure supported channel list");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (wpa_s->conf->p2p_listen_reg_class &&
|
||||
wpa_s->conf->p2p_listen_channel) {
|
||||
p2p.reg_class = wpa_s->conf->p2p_listen_reg_class;
|
||||
p2p.channel = wpa_s->conf->p2p_listen_channel;
|
||||
p2p.channel_forced = 1;
|
||||
} else {
|
||||
p2p.reg_class = 81;
|
||||
/*
|
||||
* Pick one of the social channels randomly as the listen
|
||||
* channel.
|
||||
*/
|
||||
if (os_get_random((u8 *) &r, sizeof(r)) < 0)
|
||||
if (p2p_config_get_random_social(&p2p, &p2p.reg_class,
|
||||
&p2p.channel) != 0) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"P2P: Failed to select random social channel as listen channel");
|
||||
return -1;
|
||||
p2p.channel = 1 + (r % 3) * 5;
|
||||
}
|
||||
p2p.channel_forced = 0;
|
||||
}
|
||||
wpa_printf(MSG_DEBUG, "P2P: Own listen channel: %d", p2p.channel);
|
||||
wpa_printf(MSG_DEBUG, "P2P: Own listen channel: %d:%d",
|
||||
p2p.reg_class, p2p.channel);
|
||||
|
||||
if (wpa_s->conf->p2p_oper_reg_class &&
|
||||
wpa_s->conf->p2p_oper_channel) {
|
||||
|
@ -3943,14 +3963,17 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
|
|||
"%d:%d", p2p.op_reg_class, p2p.op_channel);
|
||||
|
||||
} else {
|
||||
p2p.op_reg_class = 81;
|
||||
/*
|
||||
* Use random operation channel from (1, 6, 11) if no other
|
||||
* preference is indicated.
|
||||
* Use random operation channel from 2.4 GHz band social
|
||||
* channels (1, 6, 11) or band 60 GHz social channel (2) if no
|
||||
* other preference is indicated.
|
||||
*/
|
||||
if (os_get_random((u8 *) &r, sizeof(r)) < 0)
|
||||
if (p2p_config_get_random_social(&p2p, &p2p.op_reg_class,
|
||||
&p2p.op_channel) != 0) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"P2P: Failed to select random social channel as operation channel");
|
||||
return -1;
|
||||
p2p.op_channel = 1 + (r % 3) * 5;
|
||||
}
|
||||
p2p.cfg_op_channel = 0;
|
||||
wpa_printf(MSG_DEBUG, "P2P: Random operating channel: "
|
||||
"%d:%d", p2p.op_reg_class, p2p.op_channel);
|
||||
|
@ -3967,12 +3990,6 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
|
|||
} else
|
||||
os_memcpy(p2p.country, "XX\x04", 3);
|
||||
|
||||
if (wpas_p2p_setup_channels(wpa_s, &p2p.channels, &p2p.cli_channels)) {
|
||||
wpa_printf(MSG_ERROR, "P2P: Failed to configure supported "
|
||||
"channel list");
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_memcpy(p2p.pri_dev_type, wpa_s->conf->device_type,
|
||||
WPS_DEV_TYPE_LEN);
|
||||
|
||||
|
@ -5084,7 +5101,8 @@ static int wpas_p2p_select_freq_no_pref(struct wpa_supplicant *wpa_s,
|
|||
for (i = 0; i < 3; i++) {
|
||||
params->freq = 2412 + ((r + i) % 3) * 25;
|
||||
if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
|
||||
freq_included(channels, params->freq))
|
||||
freq_included(channels, params->freq) &&
|
||||
p2p_supported_freq(wpa_s->global->p2p, params->freq))
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -5092,11 +5110,28 @@ static int wpas_p2p_select_freq_no_pref(struct wpa_supplicant *wpa_s,
|
|||
for (i = 0; i < 11; i++) {
|
||||
params->freq = 2412 + i * 5;
|
||||
if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
|
||||
freq_included(channels, params->freq))
|
||||
freq_included(channels, params->freq) &&
|
||||
p2p_supported_freq(wpa_s->global->p2p, params->freq))
|
||||
goto out;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "P2P: No 2.4 GHz channel allowed");
|
||||
/* try social channel class 180 channel 2 */
|
||||
params->freq = 58320 + 1 * 2160;
|
||||
if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
|
||||
freq_included(channels, params->freq) &&
|
||||
p2p_supported_freq(wpa_s->global->p2p, params->freq))
|
||||
goto out;
|
||||
|
||||
/* try all channels in reg. class 180 */
|
||||
for (i = 0; i < 4; i++) {
|
||||
params->freq = 58320 + i * 2160;
|
||||
if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
|
||||
freq_included(channels, params->freq) &&
|
||||
p2p_supported_freq(wpa_s->global->p2p, params->freq))
|
||||
goto out;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "P2P: No 2.4 and 60 GHz channel allowed");
|
||||
return -1;
|
||||
out:
|
||||
wpa_printf(MSG_DEBUG, "P2P: Set GO freq %d MHz (no preference known)",
|
||||
|
|
Loading…
Reference in a new issue