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 int ieee80211n_check_40mhz(struct hostapd_iface *iface) { struct wpa_driver_scan_params params; if (!iface->conf->secondary_channel || iface->conf->noscan) return 0; /* HT40 not used */ hostapd_set_state(iface, HAPD_IFACE_HT_SCAN); wpa_printf(MSG_DEBUG, "Scan for neighboring BSSes prior to enabling " "40 MHz channel"); os_memset(¶ms, 0, sizeof(params)); if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G) ieee80211n_scan_channels_2g4(iface, ¶ms); else ieee80211n_scan_channels_5g(iface, ¶ms); if (hostapd_driver_scan(iface->bss[0], ¶ms) < 0) { wpa_printf(MSG_ERROR, "Failed to request a scan of " "neighboring BSSes"); os_free(params.freqs); return -1; } os_free(params.freqs); iface->scan_cb = ieee80211n_check_scan; return 1; }
static int ieee80211n_check_40mhz(struct hostapd_iface *iface) { struct wpa_driver_scan_params params; int ret; if (!iface->conf->secondary_channel) return 0; /* HT40 not used */ hostapd_set_state(iface, HAPD_IFACE_HT_SCAN); wpa_printf(MSG_DEBUG, "Scan for neighboring BSSes prior to enabling " "40 MHz channel"); os_memset(¶ms, 0, sizeof(params)); if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G) ieee80211n_scan_channels_2g4(iface, ¶ms); else ieee80211n_scan_channels_5g(iface, ¶ms); ret = hostapd_driver_scan(iface->bss[0], ¶ms); os_free(params.freqs); if (ret == -EBUSY) { wpa_printf(MSG_ERROR, "Failed to request a scan of neighboring BSSes ret=%d (%s) - try to scan again", ret, strerror(-ret)); iface->num_ht40_scan_tries = 1; eloop_cancel_timeout(ap_ht40_scan_retry, iface, NULL); eloop_register_timeout(1, 0, ap_ht40_scan_retry, iface, NULL); //DRIVER_RTW Modify //return -1; return 0;//ignore this error } if (ret < 0) { wpa_printf(MSG_ERROR, "Failed to request a scan of neighboring BSSes ret=%d (%s)", ret, strerror(-ret)); return -1; } iface->scan_cb = ieee80211n_check_scan; return 1; }
/* * Main DFS handler * 1 - continue channel/ap setup * 0 - channel/ap setup will be continued after CAC * -1 - hit critical error */ int hostapd_handle_dfs(struct hostapd_iface *iface) { struct hostapd_channel_data *channel; int res, n_chans, n_chans1, start_chan_idx, start_chan_idx1; int skip_radar = 0; if (!iface->current_mode) { /* * This can happen with drivers that do not provide mode * information and as such, cannot really use hostapd for DFS. */ wpa_printf(MSG_DEBUG, "DFS: No current_mode information - assume no need to perform DFS operations by hostapd"); return 1; } iface->cac_started = 0; do { /* Get start (first) channel for current configuration */ start_chan_idx = dfs_get_start_chan_idx(iface, &start_chan_idx1); if (start_chan_idx == -1) return -1; /* Get number of used channels, depend on width */ n_chans = dfs_get_used_n_chans(iface, &n_chans1); /* Setup CAC time */ iface->dfs_cac_ms = dfs_get_cac_time(iface, start_chan_idx, n_chans); /* Check if any of configured channels require DFS */ res = dfs_check_chans_radar(iface, start_chan_idx, n_chans); wpa_printf(MSG_DEBUG, "DFS %d channels required radar detection", res); if (!res) return 1; /* Check if all channels are DFS available */ res = dfs_check_chans_available(iface, start_chan_idx, n_chans); wpa_printf(MSG_DEBUG, "DFS all channels available, (SKIP CAC): %s", res ? "yes" : "no"); if (res) return 1; /* Check if any of configured channels is unavailable */ res = dfs_check_chans_unavailable(iface, start_chan_idx, n_chans); wpa_printf(MSG_DEBUG, "DFS %d chans unavailable - choose other channel: %s", res, res ? "yes": "no"); if (res) { int sec = 0; u8 cf1 = 0, cf2 = 0; channel = dfs_get_valid_channel(iface, &sec, &cf1, &cf2, skip_radar); if (!channel) { wpa_printf(MSG_ERROR, "could not get valid channel"); hostapd_set_state(iface, HAPD_IFACE_DFS); return 0; } iface->freq = channel->freq; iface->conf->channel = channel->chan; iface->conf->secondary_channel = sec; iface->conf->vht_oper_centr_freq_seg0_idx = cf1; iface->conf->vht_oper_centr_freq_seg1_idx = cf2; } } while (res); /* Finally start CAC */ hostapd_set_state(iface, HAPD_IFACE_DFS); wpa_printf(MSG_DEBUG, "DFS start CAC on %d MHz", iface->freq); wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_START "freq=%d chan=%d sec_chan=%d, width=%d, seg0=%d, seg1=%d, cac_time=%ds", iface->freq, iface->conf->channel, iface->conf->secondary_channel, iface->conf->vht_oper_chwidth, iface->conf->vht_oper_centr_freq_seg0_idx, iface->conf->vht_oper_centr_freq_seg1_idx, iface->dfs_cac_ms / 1000); res = hostapd_start_dfs_cac(iface, iface->conf->hw_mode, iface->freq, iface->conf->channel, iface->conf->ieee80211n, iface->conf->ieee80211ac, iface->conf->secondary_channel, iface->conf->vht_oper_chwidth, iface->conf->vht_oper_centr_freq_seg0_idx, iface->conf->vht_oper_centr_freq_seg1_idx); if (res) { wpa_printf(MSG_ERROR, "DFS start_dfs_cac() failed, %d", res); return -1; } return 0; }