void p2p_channels_remove_freqs(struct p2p_channels *chan, const struct wpa_freq_range_list *list) { size_t o, c; if (list == NULL) return; o = 0; while (o < chan->reg_classes) { struct p2p_reg_class *op = &chan->reg_class[o]; c = 0; while (c < op->channels) { int freq = p2p_channel_to_freq(op->reg_class, op->channel[c]); if (freq > 0 && freq_range_list_includes(list, freq)) { op->channels--; os_memmove(&op->channel[c], &op->channel[c + 1], op->channels - c); } else c++; } if (op->channels == 0) { chan->reg_classes--; os_memmove(&chan->reg_class[o], &chan->reg_class[o + 1], (chan->reg_classes - o) * sizeof(struct p2p_reg_class)); } else o++; } }
static int is_in_chanlist(struct hostapd_iface *iface, struct hostapd_channel_data *chan) { if (!iface->conf->acs_ch_list.num) return 1; return freq_range_list_includes(&iface->conf->acs_ch_list, chan->chan); }
int p2p_supported_freq_go(struct p2p_data *p2p, unsigned int freq) { u8 op_reg_class, op_channel; if (p2p_freq_to_channel(freq, &op_reg_class, &op_channel) < 0) return 0; return p2p_channels_includes(&p2p->cfg->channels, op_reg_class, op_channel) && !freq_range_list_includes(&p2p->no_go_freq, freq); }
static void hostapd_get_hw_mode_any_channels(struct hostapd_data *hapd, struct hostapd_hw_modes *mode, int acs_ch_list_all, int **freq_list) { int i; for (i = 0; i < mode->num_channels; i++) { struct hostapd_channel_data *chan = &mode->channels[i]; if ((acs_ch_list_all || freq_range_list_includes(&hapd->iface->conf->acs_ch_list, chan->chan)) && !(chan->flag & HOSTAPD_CHAN_DISABLED)) int_array_add_unique(freq_list, chan->freq); } }
int p2p_is_no_go_freq(struct p2p_data *p2p, unsigned int freq) { return freq_range_list_includes(&p2p->no_go_freq, freq); }
int hostapd_drv_do_acs(struct hostapd_data *hapd) { struct drv_acs_params params; int ret, i, acs_ch_list_all = 0; u8 *channels = NULL; unsigned int num_channels = 0; struct hostapd_hw_modes *mode; int *freq_list = NULL; if (hapd->driver == NULL || hapd->driver->do_acs == NULL) return 0; os_memset(¶ms, 0, sizeof(params)); params.hw_mode = hapd->iface->conf->hw_mode; /* * If no chanlist config parameter is provided, include all enabled * channels of the selected hw_mode. */ if (!hapd->iface->conf->acs_ch_list.num) acs_ch_list_all = 1; mode = hapd->iface->current_mode; if (mode) { channels = os_malloc(mode->num_channels); if (channels == NULL) return -1; for (i = 0; i < mode->num_channels; i++) { struct hostapd_channel_data *chan = &mode->channels[i]; if (!acs_ch_list_all && !freq_range_list_includes( &hapd->iface->conf->acs_ch_list, chan->chan)) continue; if (hapd->iface->conf->acs_exclude_dfs && (chan->flag & HOSTAPD_CHAN_RADAR)) continue; if (!(chan->flag & HOSTAPD_CHAN_DISABLED)) { channels[num_channels++] = chan->chan; int_array_add_unique(&freq_list, chan->freq); } } } else { for (i = 0; i < hapd->iface->num_hw_features; i++) { mode = &hapd->iface->hw_features[i]; hostapd_get_hw_mode_any_channels(hapd, mode, acs_ch_list_all, &freq_list); } } params.ch_list = channels; params.ch_list_len = num_channels; params.freq_list = freq_list; params.ht_enabled = !!(hapd->iface->conf->ieee80211n); params.ht40_enabled = !!(hapd->iface->conf->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET); params.vht_enabled = !!(hapd->iface->conf->ieee80211ac); params.ch_width = 20; if (hapd->iface->conf->ieee80211n && params.ht40_enabled) params.ch_width = 40; /* Note: VHT20 is defined by combination of ht_capab & vht_oper_chwidth */ if (hapd->iface->conf->ieee80211ac && params.ht40_enabled) { if (hapd->iface->conf->vht_oper_chwidth == VHT_CHANWIDTH_80MHZ) params.ch_width = 80; else if (hapd->iface->conf->vht_oper_chwidth == VHT_CHANWIDTH_160MHZ || hapd->iface->conf->vht_oper_chwidth == VHT_CHANWIDTH_80P80MHZ) params.ch_width = 160; } ret = hapd->driver->do_acs(hapd->drv_priv, ¶ms); os_free(channels); return ret; }