enum hostapd_chan_status acs_init(struct hostapd_iface *iface) { int err; wpa_printf(MSG_INFO, "ACS: Automatic channel selection started, this may take a bit"); if (iface->drv_flags & WPA_DRIVER_FLAGS_ACS_OFFLOAD) { wpa_printf(MSG_INFO, "ACS: Offloading to driver"); err = hostapd_drv_do_acs(iface->bss[0]); if (err) return HOSTAPD_CHAN_INVALID; return HOSTAPD_CHAN_ACS; } acs_cleanup(iface); err = acs_request_scan(iface); if (err < 0) return HOSTAPD_CHAN_INVALID; hostapd_set_state(iface, HAPD_IFACE_ACS); wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, ACS_EVENT_STARTED); return HOSTAPD_CHAN_ACS; }
static void acsd_cleanup(void) { if (d_info) { acs_cleanup(&d_info->acs_info); ACS_FREE(d_info->cmd_buf); free(d_info); } }
static void acs_study(struct hostapd_iface *iface) { struct hostapd_channel_data *ideal_chan; int err; err = acs_study_options(iface); if (err < 0) { wpa_printf(MSG_ERROR, "ACS: All study options have failed"); goto fail; } ideal_chan = acs_find_ideal_chan(iface); if (!ideal_chan) { wpa_printf(MSG_ERROR, "ACS: Failed to compute ideal channel"); err = -1; goto fail; } iface->conf->channel = ideal_chan->chan; if (iface->conf->ieee80211ac) acs_adjust_vht_center_freq(iface); err = 0; fail: /* * hostapd_setup_interface_complete() will return -1 on failure, * 0 on success and 0 is HOSTAPD_CHAN_VALID :) */ if (hostapd_acs_completed(iface, err) == HOSTAPD_CHAN_VALID) { acs_cleanup(iface); return; } /* This can possibly happen if channel parameters (secondary * channel, center frequencies) are misconfigured */ wpa_printf(MSG_ERROR, "ACS: Possibly channel configuration is invalid, please report this along with your config file."); acs_fail(iface); }
static int acs_request_scan(struct hostapd_iface *iface) { struct wpa_driver_scan_params params; struct hostapd_channel_data *chan; int i, *freq; os_memset(¶ms, 0, sizeof(params)); params.freqs = os_calloc(iface->current_mode->num_channels + 1, sizeof(params.freqs[0])); if (params.freqs == NULL) return -1; freq = params.freqs; for (i = 0; i < iface->current_mode->num_channels; i++) { chan = &iface->current_mode->channels[i]; if (chan->flag & HOSTAPD_CHAN_DISABLED) continue; *freq++ = chan->freq; } *freq = 0; iface->scan_cb = acs_scan_complete; wpa_printf(MSG_DEBUG, "ACS: Scanning %d / %d", iface->acs_num_completed_scans + 1, iface->conf->acs_num_scans); if (hostapd_driver_scan(iface->bss[0], ¶ms) < 0) { wpa_printf(MSG_ERROR, "ACS: Failed to request initial scan"); acs_cleanup(iface); os_free(params.freqs); return -1; } os_free(params.freqs); return 0; }
static void acs_fail(struct hostapd_iface *iface) { wpa_printf(MSG_ERROR, "ACS: Failed to start"); acs_cleanup(iface); hostapd_disable_iface(iface); }