P2P: Set channel list per channel instead of per band

This makes the channel list match with driver capabilities without
having to do workaround like disabling channels 12-14.
This commit is contained in:
Jouni Malinen 2010-10-15 18:51:37 +03:00 committed by Jouni Malinen
parent 4ae4650b4c
commit ac8d1011b7

View file

@ -1905,150 +1905,152 @@ static void wpas_invitation_result(void *ctx, int status, const u8 *bssid)
} }
static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s, static int wpas_p2p_default_channels(struct wpa_supplicant *wpa_s,
struct p2p_config *p2p) struct p2p_channels *chan)
{ {
struct hostapd_hw_modes *modes; int i, cla = 0;
u16 num_modes, flags;
int i, cla;
int band24 = 0, band5_low = 0, band5_high = 0;
/* TODO: more detailed selection of channels within reg_class based on wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for 2.4 GHz "
* driver capabilities */ "band");
/* Operating class 81 - 2.4 GHz band channels 1..13 */
chan->reg_class[cla].reg_class = 81;
chan->reg_class[cla].channels = 11;
for (i = 0; i < 11; i++)
chan->reg_class[cla].channel[i] = i + 1;
cla++;
wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for lower 5 GHz "
"band");
/* Operating class 115 - 5 GHz, channels 36-48 */
chan->reg_class[cla].reg_class = 115;
chan->reg_class[cla].channels = 4;
chan->reg_class[cla].channel[0] = 36;
chan->reg_class[cla].channel[1] = 40;
chan->reg_class[cla].channel[2] = 44;
chan->reg_class[cla].channel[3] = 48;
cla++;
wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for higher 5 GHz "
"band");
/* Operating class 124 - 5 GHz, channels 149,153,157,161 */
chan->reg_class[cla].reg_class = 124;
chan->reg_class[cla].channels = 4;
chan->reg_class[cla].channel[0] = 149;
chan->reg_class[cla].channel[1] = 153;
chan->reg_class[cla].channel[2] = 157;
chan->reg_class[cla].channel[3] = 161;
cla++;
chan->reg_classes = cla;
return 0;
}
static struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes,
u16 num_modes,
enum hostapd_hw_mode mode)
{
u16 i;
for (i = 0; i < num_modes; i++) {
if (modes[i].mode == mode)
return &modes[i];
}
return NULL;
}
static int has_channel(struct hostapd_hw_modes *mode, u8 chan)
{
int i;
for (i = 0; i < mode->num_channels; i++) {
if (mode->channels[i].chan == chan) {
return !(mode->channels[i].flag &
(HOSTAPD_CHAN_DISABLED |
HOSTAPD_CHAN_PASSIVE_SCAN |
HOSTAPD_CHAN_NO_IBSS |
HOSTAPD_CHAN_RADAR));
}
}
return 0;
}
struct p2p_oper_class_map {
enum hostapd_hw_mode mode;
u8 op_class;
u8 min_chan;
u8 max_chan;
u8 inc;
};
static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s,
struct p2p_channels *chan)
{
struct hostapd_hw_modes *modes, *mode;
u16 num_modes, flags;
int cla, op;
struct p2p_oper_class_map op_class[] = {
{ HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1 },
{ HOSTAPD_MODE_IEEE80211G, 82, 14, 14, 1 },
{ HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4 },
{ HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4 },
#if 0 /* TODO: 40 MHz channels */
{ HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1 },
{ HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1 },
{ HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8 },
{ HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8 },
{ HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8 },
{ HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8 },
#endif
{ -1, 0, 0, 0, 0 }
};
modes = wpa_drv_get_hw_feature_data(wpa_s, &num_modes, &flags); modes = wpa_drv_get_hw_feature_data(wpa_s, &num_modes, &flags);
if (modes == NULL) { if (modes == NULL) {
wpa_printf(MSG_DEBUG, "P2P: Driver did not support fetching " wpa_printf(MSG_DEBUG, "P2P: Driver did not support fetching "
"of all supported channels; assume dualband " "of all supported channels; assume dualband "
"support"); "support");
band24 = band5_low = band5_high = 1; return wpas_p2p_default_channels(wpa_s, chan);
} else {
for (i = 0; i < num_modes; i++) {
struct hostapd_hw_modes *mode;
mode = &modes[i];
if (mode->mode == HOSTAPD_MODE_IEEE80211G) {
band24 = 1;
} else if (mode->mode == HOSTAPD_MODE_IEEE80211A) {
int j;
for (j = 0; j < mode->num_channels; j++) {
struct hostapd_channel_data *ch;
ch = &mode->channels[j];
if (ch->chan == 36)
band5_low = 1;
else if (ch->chan == 157)
band5_high = 1;
}
}
}
} }
cla = 0; cla = 0;
if (band24) { for (op = 0; op_class[op].op_class; op++) {
wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for " struct p2p_oper_class_map *o = &op_class[op];
"2.4 GHz band"); u8 ch;
struct p2p_reg_class *reg = NULL;
/* Operating class 81 - 2.4 GHz band channels 1..13 */ mode = get_mode(modes, num_modes, o->mode);
p2p->channels.reg_class[cla].reg_class = 81; if (mode == NULL)
#if 0 continue;
p2p->channels.reg_class[cla].channels = 13; for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
for (i = 0; i < 13; i++) if (!has_channel(mode, ch))
p2p->channels.reg_class[cla].channel[i] = i + 1; continue;
#else if (reg == NULL) {
p2p->channels.reg_class[cla].channels = 11; wpa_printf(MSG_DEBUG, "P2P: Add operating "
for (i = 0; i < 11; i++) "class %u", o->op_class);
p2p->channels.reg_class[cla].channel[i] = i + 1; reg = &chan->reg_class[cla];
#endif
cla++; cla++;
reg->reg_class = o->op_class;
#if 0 }
/* Operating class 82 - 2.4 GHz band channel 14 */ reg->channel[reg->channels] = ch;
p2p->channels.reg_class[cla].reg_class = 82; reg->channels++;
p2p->channels.reg_class[cla].channels = 1; }
p2p->channels.reg_class[cla].channel[0] = 14; if (reg) {
cla++; wpa_hexdump(MSG_DEBUG, "P2P: Channels",
#endif reg->channel, reg->channels);
}
#if 0
/* Operating class 83 - 2.4 GHz band channels 1..9; 40 MHz */
p2p->channels.reg_class[cla].reg_class = 83;
p2p->channels.reg_class[cla].channels = 9;
for (i = 0; i < 9; i++)
p2p->channels.reg_class[cla].channel[i] = i + 1;
cla++;
/* Operating class 84 - 2.4 GHz band channels 5..13; 40 MHz */
p2p->channels.reg_class[cla].reg_class = 84;
p2p->channels.reg_class[cla].channels = 9;
for (i = 0; i < 9; i++)
p2p->channels.reg_class[cla].channel[i] = i + 5;
cla++;
#endif
} }
if (band5_low) { chan->reg_classes = cla;
wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for "
"lower 5 GHz band");
/* Operating class 115 - 5 GHz, channels 36-48 */
p2p->channels.reg_class[cla].reg_class = 115;
p2p->channels.reg_class[cla].channels = 4;
p2p->channels.reg_class[cla].channel[0] = 36;
p2p->channels.reg_class[cla].channel[1] = 40;
p2p->channels.reg_class[cla].channel[2] = 44;
p2p->channels.reg_class[cla].channel[3] = 48;
cla++;
#if 0
/* Operating class 116 - 5 GHz, channels 36,44; 40 MHz */
p2p->channels.reg_class[cla].reg_class = 116;
p2p->channels.reg_class[cla].channels = 2;
p2p->channels.reg_class[cla].channel[0] = 36;
p2p->channels.reg_class[cla].channel[1] = 44;
cla++;
/* Operating class 117 - 5 GHz, channels 40,48; 40 MHz */
p2p->channels.reg_class[cla].reg_class = 117;
p2p->channels.reg_class[cla].channels = 2;
p2p->channels.reg_class[cla].channel[0] = 40;
p2p->channels.reg_class[cla].channel[1] = 48;
cla++;
#endif
}
if (band5_high) {
wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for "
"higher 5 GHz band");
/* Operating class 124 - 5 GHz, channels 149,153,157,161 */
p2p->channels.reg_class[cla].reg_class = 124;
p2p->channels.reg_class[cla].channels = 4;
p2p->channels.reg_class[cla].channel[0] = 149;
p2p->channels.reg_class[cla].channel[1] = 153;
p2p->channels.reg_class[cla].channel[2] = 157;
p2p->channels.reg_class[cla].channel[3] = 161;
cla++;
#if 0
/* Operating class 126 - 5 GHz, channels 149,157; 40 MHz */
p2p->channels.reg_class[cla].reg_class = 126;
p2p->channels.reg_class[cla].channels = 2;
p2p->channels.reg_class[cla].channel[0] = 149;
p2p->channels.reg_class[cla].channel[1] = 157;
cla++;
/* Operating class 127 - 5 GHz, channels 153,161; 40 MHz */
p2p->channels.reg_class[cla].reg_class = 127;
p2p->channels.reg_class[cla].channels = 2;
p2p->channels.reg_class[cla].channel[0] = 153;
p2p->channels.reg_class[cla].channel[1] = 161;
cla++;
#endif
}
p2p->channels.reg_classes = cla;
if (modes)
ieee80211_sta_free_hw_features(modes, num_modes); ieee80211_sta_free_hw_features(modes, num_modes);
return 0; return 0;
@ -2161,7 +2163,7 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
} else } else
os_memcpy(p2p.country, "US\x04", 3); os_memcpy(p2p.country, "US\x04", 3);
if (wpas_p2p_setup_channels(wpa_s, &p2p)) { if (wpas_p2p_setup_channels(wpa_s, &p2p.channels)) {
wpa_printf(MSG_ERROR, "P2P: Failed to configure supported " wpa_printf(MSG_ERROR, "P2P: Failed to configure supported "
"channel list"); "channel list");
return -1; return -1;