1391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt/* 2391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS - Automatic Channel Selection module 3391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * Copyright (c) 2011, Atheros Communications 4391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * Copyright (c) 2013, Qualcomm Atheros, Inc. 5391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 6391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 7391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * See README for more details. 8391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt */ 9391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 10391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt#include "utils/includes.h" 11391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt#include <math.h> 12391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 13391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt#include "utils/common.h" 14391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt#include "utils/list.h" 15391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt#include "common/ieee802_11_defs.h" 16cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#include "common/wpa_ctrl.h" 17391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt#include "drivers/driver.h" 18391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt#include "hostapd.h" 19391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt#include "ap_drv_ops.h" 20391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt#include "ap_config.h" 21391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt#include "hw_features.h" 22391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt#include "acs.h" 23391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 24391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt/* 25391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * Automatic Channel Selection 26391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * =========================== 27391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 28391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * More info at 29391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ------------ 30391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * http://wireless.kernel.org/en/users/Documentation/acs 31391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 32391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * How to use 33391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ---------- 34391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * - make sure you have CONFIG_ACS=y in hostapd's .config 35391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * - use channel=0 or channel=acs to enable ACS 36391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 37391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * How does it work 38391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ---------------- 39391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 1. passive scans are used to collect survey data 40391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * (it is assumed that scan trigger collection of survey data in driver) 41391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 2. interference factor is calculated for each channel 42391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 3. ideal channel is picked depending on channel width by using adjacent 43391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * channel interference factors 44391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 45391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * Known limitations 46391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ----------------- 47391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * - Current implementation depends heavily on the amount of time willing to 48391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * spend gathering survey data during hostapd startup. Short traffic bursts 49391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * may be missed and a suboptimal channel may be picked. 50391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * - Ideal channel may end up overlapping a channel with 40 MHz intolerant BSS 51391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 52391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * Todo / Ideas 53391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ------------ 54391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * - implement other interference computation methods 55391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * - BSS/RSSI based 56391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * - spectral scan based 57391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * (should be possibly to hook this up with current ACS scans) 58391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * - add wpa_supplicant support (for P2P) 59391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * - collect a histogram of interference over time allowing more educated 60391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * guess about an ideal channel (perhaps CSA could be used to migrate AP to a 61391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * new "better" channel while running) 62391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * - include neighboring BSS scan to avoid conflicts with 40 MHz intolerant BSSs 63391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * when choosing the ideal channel 64391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 65391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * Survey interference factor implementation details 66391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ------------------------------------------------- 67391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * Generic interference_factor in struct hostapd_channel_data is used. 68391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 69391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * The survey interference factor is defined as the ratio of the 70391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * observed busy time over the time we spent on the channel, 71391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * this value is then amplified by the observed noise floor on 72391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * the channel in comparison to the lowest noise floor observed 73391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * on the entire band. 74391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 75391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * This corresponds to: 76391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * --- 77391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * (busy time - tx time) / (active time - tx time) * 2^(chan_nf + band_min_nf) 78391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * --- 79391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 80391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * The coefficient of 2 reflects the way power in "far-field" 81391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * radiation decreases as the square of distance from the antenna [1]. 82391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * What this does is it decreases the observed busy time ratio if the 83391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * noise observed was low but increases it if the noise was high, 84391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * proportionally to the way "far field" radiation changes over 85391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * distance. 86391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 87391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * If channel busy time is not available the fallback is to use channel RX time. 88391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 89391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * Since noise floor is in dBm it is necessary to convert it into Watts so that 90391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * combined channel interference (e.g., HT40, which uses two channels) can be 91391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * calculated easily. 92391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * --- 93391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * (busy time - tx time) / (active time - tx time) * 94391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 2^(10^(chan_nf/10) + 10^(band_min_nf/10)) 95391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * --- 96391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 97391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * However to account for cases where busy/rx time is 0 (channel load is then 98391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 0%) channel noise floor signal power is combined into the equation so a 99391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * channel with lower noise floor is preferred. The equation becomes: 100391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * --- 101391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 10^(chan_nf/5) + (busy time - tx time) / (active time - tx time) * 102391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 2^(10^(chan_nf/10) + 10^(band_min_nf/10)) 103391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * --- 104391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 105391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * All this "interference factor" is purely subjective and only time 106391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * will tell how usable this is. By using the minimum noise floor we 107391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * remove any possible issues due to card calibration. The computation 108391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * of the interference factor then is dependent on what the card itself 109391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * picks up as the minimum noise, not an actual real possible card 110391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * noise value. 111391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 112391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * Total interference computation details 113391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * -------------------------------------- 114391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * The above channel interference factor is calculated with no respect to 115391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * target operational bandwidth. 116391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 117391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * To find an ideal channel the above data is combined by taking into account 118391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * the target operational bandwidth and selected band. E.g., on 2.4 GHz channels 119391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * overlap with 20 MHz bandwidth, but there is no overlap for 20 MHz bandwidth 120391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * on 5 GHz. 121391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 122391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * Each valid and possible channel spec (i.e., channel + width) is taken and its 123391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * interference factor is computed by summing up interferences of each channel 124391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * it overlaps. The one with least total interference is picked up. 125391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 126391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * Note: This implies base channel interference factor must be non-negative 127391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * allowing easy summing up. 128391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 129391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * Example ACS analysis printout 130391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ----------------------------- 131391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 132391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: Trying survey-based ACS 133391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: Survey analysis for channel 1 (2412 MHz) 134391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 1: min_nf=-113 interference_factor=0.0802469 nf=-113 time=162 busy=0 rx=13 135391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 2: min_nf=-113 interference_factor=0.0745342 nf=-113 time=161 busy=0 rx=12 136391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 3: min_nf=-113 interference_factor=0.0679012 nf=-113 time=162 busy=0 rx=11 137391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 4: min_nf=-113 interference_factor=0.0310559 nf=-113 time=161 busy=0 rx=5 138391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 5: min_nf=-113 interference_factor=0.0248447 nf=-113 time=161 busy=0 rx=4 139391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * interference factor average: 0.0557166 140391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: Survey analysis for channel 2 (2417 MHz) 141391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 1: min_nf=-113 interference_factor=0.0185185 nf=-113 time=162 busy=0 rx=3 142391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 2: min_nf=-113 interference_factor=0.0246914 nf=-113 time=162 busy=0 rx=4 143391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 3: min_nf=-113 interference_factor=0.037037 nf=-113 time=162 busy=0 rx=6 144391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 4: min_nf=-113 interference_factor=0.149068 nf=-113 time=161 busy=0 rx=24 145391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 5: min_nf=-113 interference_factor=0.0248447 nf=-113 time=161 busy=0 rx=4 146391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * interference factor average: 0.050832 147391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: Survey analysis for channel 3 (2422 MHz) 148391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 1: min_nf=-113 interference_factor=2.51189e-23 nf=-113 time=162 busy=0 rx=0 149391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 2: min_nf=-113 interference_factor=0.0185185 nf=-113 time=162 busy=0 rx=3 150391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 3: min_nf=-113 interference_factor=0.0186335 nf=-113 time=161 busy=0 rx=3 151391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 4: min_nf=-113 interference_factor=0.0186335 nf=-113 time=161 busy=0 rx=3 152391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 5: min_nf=-113 interference_factor=0.0186335 nf=-113 time=161 busy=0 rx=3 153391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * interference factor average: 0.0148838 154391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: Survey analysis for channel 4 (2427 MHz) 155391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 1: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=162 busy=0 rx=0 156391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 2: min_nf=-114 interference_factor=0.0555556 nf=-114 time=162 busy=0 rx=9 157391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 3: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=161 busy=0 rx=0 158391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 4: min_nf=-114 interference_factor=0.0186335 nf=-114 time=161 busy=0 rx=3 159391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 5: min_nf=-114 interference_factor=0.00621118 nf=-114 time=161 busy=0 rx=1 160391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * interference factor average: 0.0160801 161391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: Survey analysis for channel 5 (2432 MHz) 162391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 1: min_nf=-114 interference_factor=0.409938 nf=-113 time=161 busy=0 rx=66 163391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 2: min_nf=-114 interference_factor=0.0432099 nf=-113 time=162 busy=0 rx=7 164391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 3: min_nf=-114 interference_factor=0.0124224 nf=-113 time=161 busy=0 rx=2 165391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 4: min_nf=-114 interference_factor=0.677019 nf=-113 time=161 busy=0 rx=109 166391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 5: min_nf=-114 interference_factor=0.0186335 nf=-114 time=161 busy=0 rx=3 167391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * interference factor average: 0.232244 168391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: Survey analysis for channel 6 (2437 MHz) 169391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 1: min_nf=-113 interference_factor=0.552795 nf=-113 time=161 busy=0 rx=89 170391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 2: min_nf=-113 interference_factor=0.0807453 nf=-112 time=161 busy=0 rx=13 171391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 3: min_nf=-113 interference_factor=0.0310559 nf=-113 time=161 busy=0 rx=5 172391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 4: min_nf=-113 interference_factor=0.434783 nf=-112 time=161 busy=0 rx=70 173391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 5: min_nf=-113 interference_factor=0.0621118 nf=-113 time=161 busy=0 rx=10 174391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * interference factor average: 0.232298 175391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: Survey analysis for channel 7 (2442 MHz) 176391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 1: min_nf=-113 interference_factor=0.440994 nf=-112 time=161 busy=0 rx=71 177391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 2: min_nf=-113 interference_factor=0.385093 nf=-113 time=161 busy=0 rx=62 178391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 3: min_nf=-113 interference_factor=0.0372671 nf=-113 time=161 busy=0 rx=6 179391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 4: min_nf=-113 interference_factor=0.0372671 nf=-113 time=161 busy=0 rx=6 180391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 5: min_nf=-113 interference_factor=0.0745342 nf=-113 time=161 busy=0 rx=12 181391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * interference factor average: 0.195031 182391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: Survey analysis for channel 8 (2447 MHz) 183391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 1: min_nf=-114 interference_factor=0.0496894 nf=-112 time=161 busy=0 rx=8 184391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 2: min_nf=-114 interference_factor=0.0496894 nf=-114 time=161 busy=0 rx=8 185391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 3: min_nf=-114 interference_factor=0.0372671 nf=-113 time=161 busy=0 rx=6 186391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 4: min_nf=-114 interference_factor=0.12963 nf=-113 time=162 busy=0 rx=21 187391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 5: min_nf=-114 interference_factor=0.166667 nf=-114 time=162 busy=0 rx=27 188391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * interference factor average: 0.0865885 189391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: Survey analysis for channel 9 (2452 MHz) 190391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 1: min_nf=-114 interference_factor=0.0124224 nf=-114 time=161 busy=0 rx=2 191391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 2: min_nf=-114 interference_factor=0.0310559 nf=-114 time=161 busy=0 rx=5 192391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 3: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=161 busy=0 rx=0 193391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 4: min_nf=-114 interference_factor=0.00617284 nf=-114 time=162 busy=0 rx=1 194391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 5: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=162 busy=0 rx=0 195391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * interference factor average: 0.00993022 196391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: Survey analysis for channel 10 (2457 MHz) 197391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 1: min_nf=-114 interference_factor=0.00621118 nf=-114 time=161 busy=0 rx=1 198391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 2: min_nf=-114 interference_factor=0.00621118 nf=-114 time=161 busy=0 rx=1 199391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 3: min_nf=-114 interference_factor=0.00621118 nf=-114 time=161 busy=0 rx=1 200391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 4: min_nf=-114 interference_factor=0.0493827 nf=-114 time=162 busy=0 rx=8 201391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 5: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=162 busy=0 rx=0 202391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * interference factor average: 0.0136033 203391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: Survey analysis for channel 11 (2462 MHz) 204391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 1: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=161 busy=0 rx=0 205391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 2: min_nf=-114 interference_factor=2.51189e-23 nf=-113 time=161 busy=0 rx=0 206391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 3: min_nf=-114 interference_factor=2.51189e-23 nf=-113 time=161 busy=0 rx=0 207391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 4: min_nf=-114 interference_factor=0.0432099 nf=-114 time=162 busy=0 rx=7 208391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 5: min_nf=-114 interference_factor=0.0925926 nf=-114 time=162 busy=0 rx=15 209391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * interference factor average: 0.0271605 210391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: Survey analysis for channel 12 (2467 MHz) 211391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 1: min_nf=-114 interference_factor=0.0621118 nf=-113 time=161 busy=0 rx=10 212391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 2: min_nf=-114 interference_factor=0.00621118 nf=-114 time=161 busy=0 rx=1 213391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 3: min_nf=-114 interference_factor=2.51189e-23 nf=-113 time=162 busy=0 rx=0 214391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 4: min_nf=-114 interference_factor=2.51189e-23 nf=-113 time=162 busy=0 rx=0 215391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 5: min_nf=-114 interference_factor=0.00617284 nf=-113 time=162 busy=0 rx=1 216391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * interference factor average: 0.0148992 217391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: Survey analysis for channel 13 (2472 MHz) 218391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 1: min_nf=-114 interference_factor=0.0745342 nf=-114 time=161 busy=0 rx=12 219391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 2: min_nf=-114 interference_factor=0.0555556 nf=-114 time=162 busy=0 rx=9 220391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 3: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=162 busy=0 rx=0 221391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 4: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=162 busy=0 rx=0 222391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: 5: min_nf=-114 interference_factor=1.58489e-23 nf=-114 time=162 busy=0 rx=0 223391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * interference factor average: 0.0260179 224391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: Survey analysis for selected bandwidth 20MHz 225391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * channel 1: total interference = 0.121432 226391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * channel 2: total interference = 0.137512 227391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * channel 3: total interference = 0.369757 228391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * channel 4: total interference = 0.546338 229391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * channel 5: total interference = 0.690538 230391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * channel 6: total interference = 0.762242 231391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * channel 7: total interference = 0.756092 232391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * channel 8: total interference = 0.537451 233391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * channel 9: total interference = 0.332313 234391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * channel 10: total interference = 0.152182 235391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * channel 11: total interference = 0.0916111 236391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * channel 12: total interference = 0.0816809 237391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: * channel 13: total interference = 0.0680776 238391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * ACS: Ideal channel is 13 (2472 MHz) with total interference factor of 0.0680776 239391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 240391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * [1] http://en.wikipedia.org/wiki/Near_and_far_field 241391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt */ 242391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 243391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 244391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic int acs_request_scan(struct hostapd_iface *iface); 245391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 246391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 247391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic void acs_clean_chan_surveys(struct hostapd_channel_data *chan) 248391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 249391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct freq_survey *survey, *tmp; 250391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 251391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (dl_list_empty(&chan->survey_list)) 252391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 253391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 254391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt dl_list_for_each_safe(survey, tmp, &chan->survey_list, 255391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct freq_survey, list) { 256391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt dl_list_del(&survey->list); 257391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_free(survey); 258391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 259391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 260391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 261391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 262391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic void acs_cleanup(struct hostapd_iface *iface) 263391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 264391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt int i; 265391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct hostapd_channel_data *chan; 266391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 267391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt for (i = 0; i < iface->current_mode->num_channels; i++) { 268391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt chan = &iface->current_mode->channels[i]; 269391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 270391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (chan->flag & HOSTAPD_CHAN_SURVEY_LIST_INITIALIZED) 271391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt acs_clean_chan_surveys(chan); 272391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 273391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt dl_list_init(&chan->survey_list); 274391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt chan->flag |= HOSTAPD_CHAN_SURVEY_LIST_INITIALIZED; 275391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt chan->min_nf = 0; 276391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 277391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 278391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt iface->chans_surveyed = 0; 279391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt iface->acs_num_completed_scans = 0; 280391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 281391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 282391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 283fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void acs_fail(struct hostapd_iface *iface) 284391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 285391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_ERROR, "ACS: Failed to start"); 286391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt acs_cleanup(iface); 2872ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt hostapd_disable_iface(iface); 288391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 289391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 290391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 291391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic long double 292391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtacs_survey_interference_factor(struct freq_survey *survey, s8 min_nf) 293391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 294391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt long double factor, busy, total; 295391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 296391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (survey->filled & SURVEY_HAS_CHAN_TIME_BUSY) 297391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt busy = survey->channel_time_busy; 298391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt else if (survey->filled & SURVEY_HAS_CHAN_TIME_RX) 299391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt busy = survey->channel_time_rx; 300391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt else { 301391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* This shouldn't really happen as survey data is checked in 302391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * acs_sanity_check() */ 303391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_ERROR, "ACS: Survey data missing"); 304391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return 0; 305391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 306391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 307391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt total = survey->channel_time; 308391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 309391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (survey->filled & SURVEY_HAS_CHAN_TIME_TX) { 310391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt busy -= survey->channel_time_tx; 311391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt total -= survey->channel_time_tx; 312391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 313391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 314391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* TODO: figure out the best multiplier for noise floor base */ 315391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt factor = pow(10, survey->nf / 5.0L) + 316391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt (busy / total) * 317391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt pow(2, pow(10, (long double) survey->nf / 10.0L) - 318391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt pow(10, (long double) min_nf / 10.0L)); 319391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 320391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return factor; 321391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 322391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 323391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 324391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic void 325391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtacs_survey_chan_interference_factor(struct hostapd_iface *iface, 326391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct hostapd_channel_data *chan) 327391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 328391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct freq_survey *survey; 329391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt unsigned int i = 0; 330391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt long double int_factor = 0; 331391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 332391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (dl_list_empty(&chan->survey_list)) 333391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 334391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 335391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (chan->flag & HOSTAPD_CHAN_DISABLED) 336391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 337391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 338391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt chan->interference_factor = 0; 339391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 340391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt dl_list_for_each(survey, &chan->survey_list, struct freq_survey, list) 341391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt { 342391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt int_factor = acs_survey_interference_factor(survey, 343391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt iface->lowest_nf); 344391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt chan->interference_factor += int_factor; 345391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_DEBUG, "ACS: %d: min_nf=%d interference_factor=%Lg nf=%d time=%lu busy=%lu rx=%lu", 346391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt ++i, chan->min_nf, int_factor, 347391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt survey->nf, (unsigned long) survey->channel_time, 348391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt (unsigned long) survey->channel_time_busy, 349391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt (unsigned long) survey->channel_time_rx); 350391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 351391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 352391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt chan->interference_factor = chan->interference_factor / 353391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt dl_list_len(&chan->survey_list); 354391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 355391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 356391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 357391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic int acs_usable_ht40_chan(struct hostapd_channel_data *chan) 358391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 359391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt const int allowed[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 360391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 157, 184, 192 }; 361391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt unsigned int i; 362391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 36368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (i = 0; i < ARRAY_SIZE(allowed); i++) 364391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (chan->chan == allowed[i]) 365391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return 1; 366391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 367391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return 0; 368391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 369391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 370391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 371a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidtstatic int acs_usable_vht80_chan(struct hostapd_channel_data *chan) 372a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt{ 373a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt const int allowed[] = { 36, 52, 100, 116, 132, 149 }; 374a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt unsigned int i; 375a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt 376a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt for (i = 0; i < ARRAY_SIZE(allowed); i++) 377a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt if (chan->chan == allowed[i]) 378a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt return 1; 379a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt 380a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt return 0; 381a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt} 382a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt 383a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt 384391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic int acs_survey_is_sufficient(struct freq_survey *survey) 385391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 386391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (!(survey->filled & SURVEY_HAS_NF)) { 387391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_ERROR, "ACS: Survey is missing noise floor"); 388391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return 0; 389391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 390391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 391391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (!(survey->filled & SURVEY_HAS_CHAN_TIME)) { 392391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_ERROR, "ACS: Survey is missing channel time"); 393391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return 0; 394391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 395391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 396391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (!(survey->filled & SURVEY_HAS_CHAN_TIME_BUSY) && 397391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt !(survey->filled & SURVEY_HAS_CHAN_TIME_RX)) { 398391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_ERROR, "ACS: Survey is missing RX and busy time (at least one is required)"); 399391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return 0; 400391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 401391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 402391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return 1; 403391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 404391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 405391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 4064ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidtstatic int acs_survey_list_is_sufficient(struct hostapd_channel_data *chan) 4074ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt{ 4084ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt struct freq_survey *survey; 4094ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 4104ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt dl_list_for_each(survey, &chan->survey_list, struct freq_survey, list) 4114ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt { 4124ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (!acs_survey_is_sufficient(survey)) { 4134ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt wpa_printf(MSG_ERROR, "ACS: Channel %d has insufficient survey data", 4144ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt chan->chan); 4154ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return 0; 4164ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt } 4174ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt } 4184ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 4194ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return 1; 4204ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 4214ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt} 4224ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 4234ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 424391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic int acs_surveys_are_sufficient(struct hostapd_iface *iface) 425391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 426391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt int i; 427391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct hostapd_channel_data *chan; 4284ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt int valid = 0; 429391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 430391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt for (i = 0; i < iface->current_mode->num_channels; i++) { 431391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt chan = &iface->current_mode->channels[i]; 432391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (chan->flag & HOSTAPD_CHAN_DISABLED) 433391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt continue; 434391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 4354ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (!acs_survey_list_is_sufficient(chan)) 4364ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt continue; 4374ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 4384ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt valid++; 439391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 440391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 4414ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt /* We need at least survey data for one channel */ 4424ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return !!valid; 4434ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt} 4444ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 4454ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 4464ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidtstatic int acs_usable_chan(struct hostapd_channel_data *chan) 4474ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt{ 4484ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (dl_list_empty(&chan->survey_list)) 4494ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return 0; 4504ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (chan->flag & HOSTAPD_CHAN_DISABLED) 4514ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return 0; 4524ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (!acs_survey_list_is_sufficient(chan)) 4534ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return 0; 454391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return 1; 455391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 456391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 457391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 458391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic void acs_survey_all_chans_intereference_factor( 459391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct hostapd_iface *iface) 460391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 461391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt int i; 462391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct hostapd_channel_data *chan; 463391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 464391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt for (i = 0; i < iface->current_mode->num_channels; i++) { 465391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt chan = &iface->current_mode->channels[i]; 466391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 467391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (!acs_usable_chan(chan)) 468391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt continue; 469391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 470391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_DEBUG, "ACS: Survey analysis for channel %d (%d MHz)", 471391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt chan->chan, chan->freq); 472391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 473391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt acs_survey_chan_interference_factor(iface, chan); 474391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 475391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_DEBUG, "ACS: * interference factor average: %Lg", 476391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt chan->interference_factor); 477391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 478391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 479391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 480391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 481391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic struct hostapd_channel_data *acs_find_chan(struct hostapd_iface *iface, 482391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt int freq) 483391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 484391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct hostapd_channel_data *chan; 485391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt int i; 486391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 487391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt for (i = 0; i < iface->current_mode->num_channels; i++) { 488391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt chan = &iface->current_mode->channels[i]; 489391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 4904ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (chan->flag & HOSTAPD_CHAN_DISABLED) 491391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt continue; 492391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 493391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (chan->freq == freq) 494391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return chan; 495391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 496391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 497391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return NULL; 498391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 499391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 500391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 501391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt/* 502391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * At this point it's assumed chan->interface_factor has been computed. 503391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * This function should be reusable regardless of interference computation 504391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * option (survey, BSS, spectral, ...). chan->interference factor must be 505391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * summable (i.e., must be always greater than zero). 506391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt */ 507391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic struct hostapd_channel_data * 508391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtacs_find_ideal_chan(struct hostapd_iface *iface) 509391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 5104ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt struct hostapd_channel_data *chan, *adj_chan, *ideal_chan = NULL, 5114ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt *rand_chan = NULL; 512391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt long double factor, ideal_factor = 0; 513391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt int i, j; 514391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt int n_chans = 1; 515391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 516391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* TODO: HT40- support */ 517391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 518391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (iface->conf->ieee80211n && 519391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt iface->conf->secondary_channel == -1) { 520391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_ERROR, "ACS: HT40- is not supported yet. Please try HT40+"); 521391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return NULL; 522391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 523391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 524391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (iface->conf->ieee80211n && 525391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt iface->conf->secondary_channel) 526391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt n_chans = 2; 527391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 528391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (iface->conf->ieee80211ac && 529391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt iface->conf->vht_oper_chwidth == 1) 530391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt n_chans = 4; 531391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 532391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* TODO: VHT80+80, VHT160. Update acs_adjust_vht_center_freq() too. */ 533391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 534391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_DEBUG, "ACS: Survey analysis for selected bandwidth %d MHz", 535391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt n_chans == 1 ? 20 : 536391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt n_chans == 2 ? 40 : 537391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt n_chans == 4 ? 80 : 538391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt -1); 539391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 540391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt for (i = 0; i < iface->current_mode->num_channels; i++) { 541391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt chan = &iface->current_mode->channels[i]; 542391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 5434ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (chan->flag & HOSTAPD_CHAN_DISABLED) 544391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt continue; 545391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 5464ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 547391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* HT40 on 5 GHz has a limited set of primary channels as per 548391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 11n Annex J */ 549391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A && 550391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt iface->conf->ieee80211n && 551391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt iface->conf->secondary_channel && 552391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt !acs_usable_ht40_chan(chan)) { 553391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_DEBUG, "ACS: Channel %d: not allowed as primary channel for HT40", 554391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt chan->chan); 555391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt continue; 556391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 557391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 558a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A && 559a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt iface->conf->ieee80211ac && 560a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt iface->conf->vht_oper_chwidth == 1 && 561a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt !acs_usable_vht80_chan(chan)) { 562a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt wpa_printf(MSG_DEBUG, "ACS: Channel %d: not allowed as primary channel for VHT80", 563a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt chan->chan); 564a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt continue; 565a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt } 566a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt 5674ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt factor = 0; 5684ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (acs_usable_chan(chan)) 5694ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt factor = chan->interference_factor; 570391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 571391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt for (j = 1; j < n_chans; j++) { 572391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt adj_chan = acs_find_chan(iface, chan->freq + (j * 20)); 573391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (!adj_chan) 574391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt break; 575391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 5764ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (acs_usable_chan(adj_chan)) 5774ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt factor += adj_chan->interference_factor; 578391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 579391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 580391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (j != n_chans) { 581391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_DEBUG, "ACS: Channel %d: not enough bandwidth", 582391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt chan->chan); 583391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt continue; 584391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 585391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 586391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* 2.4 GHz has overlapping 20 MHz channels. Include adjacent 587391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * channel interference factor. */ 588391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211B || 589391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G) { 590391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt for (j = 0; j < n_chans; j++) { 591391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* TODO: perhaps a multiplier should be used 592391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * here? */ 593391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 594391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt adj_chan = acs_find_chan(iface, chan->freq + 595391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt (j * 20) - 5); 5964ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (adj_chan && acs_usable_chan(adj_chan)) 597391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt factor += adj_chan->interference_factor; 598391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 599391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt adj_chan = acs_find_chan(iface, chan->freq + 600391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt (j * 20) - 10); 6014ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (adj_chan && acs_usable_chan(adj_chan)) 602391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt factor += adj_chan->interference_factor; 603391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 604391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt adj_chan = acs_find_chan(iface, chan->freq + 605391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt (j * 20) + 5); 6064ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (adj_chan && acs_usable_chan(adj_chan)) 607391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt factor += adj_chan->interference_factor; 608391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 609391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt adj_chan = acs_find_chan(iface, chan->freq + 610391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt (j * 20) + 10); 6114ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (adj_chan && acs_usable_chan(adj_chan)) 612391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt factor += adj_chan->interference_factor; 613391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 614391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 615391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 616391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_DEBUG, "ACS: * channel %d: total interference = %Lg", 617391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt chan->chan, factor); 618391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6194ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (acs_usable_chan(chan) && 6204ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt (!ideal_chan || factor < ideal_factor)) { 621391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt ideal_factor = factor; 622391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt ideal_chan = chan; 623391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 6244ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 6254ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt /* This channel would at least be usable */ 6264ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (!rand_chan) 6274ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt rand_chan = chan; 628391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 629391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6304ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (ideal_chan) { 631391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_DEBUG, "ACS: Ideal channel is %d (%d MHz) with total interference factor of %Lg", 632391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt ideal_chan->chan, ideal_chan->freq, ideal_factor); 6334ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return ideal_chan; 6344ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt } 635391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 6364ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return rand_chan; 637391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 638391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 639391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 640391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic void acs_adjust_vht_center_freq(struct hostapd_iface *iface) 641391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 642b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt int offset; 643b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt 644391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_DEBUG, "ACS: Adjusting VHT center frequency"); 645391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 646391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt switch (iface->conf->vht_oper_chwidth) { 647391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt case VHT_CHANWIDTH_USE_HT: 648b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt offset = 2 * iface->conf->secondary_channel; 649391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt break; 650391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt case VHT_CHANWIDTH_80MHZ: 651b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt offset = 6; 652391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt break; 653391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt default: 654391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* TODO: How can this be calculated? Adjust 655391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * acs_find_ideal_chan() */ 656391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_INFO, "ACS: Only VHT20/40/80 is supported now"); 657b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt return; 658391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 659b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt 660b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt iface->conf->vht_oper_centr_freq_seg0_idx = 661b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt iface->conf->channel + offset; 662391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 663391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 664391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 665391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic int acs_study_survey_based(struct hostapd_iface *iface) 666391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 667391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_DEBUG, "ACS: Trying survey-based ACS"); 668391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 669391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (!iface->chans_surveyed) { 670391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_ERROR, "ACS: Unable to collect survey data"); 671391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return -1; 672391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 673391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 674391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (!acs_surveys_are_sufficient(iface)) { 675391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_ERROR, "ACS: Surveys have insufficient data"); 676391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return -1; 677391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 678391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 679391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt acs_survey_all_chans_intereference_factor(iface); 680391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return 0; 681391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 682391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 683391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 684391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic int acs_study_options(struct hostapd_iface *iface) 685391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 686391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt int err; 687391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 688391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt err = acs_study_survey_based(iface); 689391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (err == 0) 690391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return 0; 691391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 692391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* TODO: If no surveys are available/sufficient this is a good 693391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * place to fallback to BSS-based ACS */ 694391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 695391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return -1; 696391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 697391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 698391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 699391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic void acs_study(struct hostapd_iface *iface) 700391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 701391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct hostapd_channel_data *ideal_chan; 702391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt int err; 703391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 704391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt err = acs_study_options(iface); 705391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (err < 0) { 706391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_ERROR, "ACS: All study options have failed"); 707391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt goto fail; 708391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 709391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 710391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt ideal_chan = acs_find_ideal_chan(iface); 711391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (!ideal_chan) { 712391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_ERROR, "ACS: Failed to compute ideal channel"); 7134ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt err = -1; 714391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt goto fail; 715391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 716391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 717391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt iface->conf->channel = ideal_chan->chan; 718391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 719391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (iface->conf->ieee80211ac) 720391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt acs_adjust_vht_center_freq(iface); 721391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7224ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt err = 0; 7234ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidtfail: 724391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt /* 725391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * hostapd_setup_interface_complete() will return -1 on failure, 726391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * 0 on success and 0 is HOSTAPD_CHAN_VALID :) 727391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt */ 7284ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (hostapd_acs_completed(iface, err) == HOSTAPD_CHAN_VALID) { 729391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt acs_cleanup(iface); 730391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 731391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 732391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 7334ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt /* This can possibly happen if channel parameters (secondary 7344ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt * channel, center frequencies) are misconfigured */ 7354ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt wpa_printf(MSG_ERROR, "ACS: Possibly channel configuration is invalid, please report this along with your config file."); 736391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt acs_fail(iface); 737391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 738391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 739391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 740391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic void acs_scan_complete(struct hostapd_iface *iface) 741391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 742391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt int err; 743391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 744391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt iface->scan_cb = NULL; 745391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 746391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_DEBUG, "ACS: Using survey based algorithm (acs_num_scans=%d)", 747391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt iface->conf->acs_num_scans); 748391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 749391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt err = hostapd_drv_get_survey(iface->bss[0], 0); 750391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (err) { 751391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_ERROR, "ACS: Failed to get survey data"); 75215907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt goto fail; 753391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 754391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 755391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (++iface->acs_num_completed_scans < iface->conf->acs_num_scans) { 756391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt err = acs_request_scan(iface); 757391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (err) { 758391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_ERROR, "ACS: Failed to request scan"); 759cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto fail; 760391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 761391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 762391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return; 763391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 764391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 765391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt acs_study(iface); 766cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return; 767cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtfail: 768cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_acs_completed(iface, 1); 769cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt acs_fail(iface); 770391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 771391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 772391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 773391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic int acs_request_scan(struct hostapd_iface *iface) 774391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 775391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct wpa_driver_scan_params params; 776391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt struct hostapd_channel_data *chan; 777391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt int i, *freq; 778391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 779391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 780391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt params.freqs = os_calloc(iface->current_mode->num_channels + 1, 781391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt sizeof(params.freqs[0])); 782391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (params.freqs == NULL) 783391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return -1; 784391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 785391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt freq = params.freqs; 786391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt for (i = 0; i < iface->current_mode->num_channels; i++) { 787391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt chan = &iface->current_mode->channels[i]; 788391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (chan->flag & HOSTAPD_CHAN_DISABLED) 789391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt continue; 790391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 791391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt *freq++ = chan->freq; 792391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 793391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt *freq = 0; 794391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 795391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt iface->scan_cb = acs_scan_complete; 796391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 797391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_DEBUG, "ACS: Scanning %d / %d", 798391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt iface->acs_num_completed_scans + 1, 799391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt iface->conf->acs_num_scans); 800391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 801391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (hostapd_driver_scan(iface->bss[0], ¶ms) < 0) { 802391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_ERROR, "ACS: Failed to request initial scan"); 803391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt acs_cleanup(iface); 80415907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt os_free(params.freqs); 805391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return -1; 806391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 807391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 808391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt os_free(params.freqs); 809391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return 0; 810391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 811391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 812391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 813391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtenum hostapd_chan_status acs_init(struct hostapd_iface *iface) 814391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{ 815391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt int err; 816391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 817391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_INFO, "ACS: Automatic channel selection started, this may take a bit"); 818391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 819391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt acs_cleanup(iface); 820391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 821391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt err = acs_request_scan(iface); 822391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (err < 0) 823391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return HOSTAPD_CHAN_INVALID; 824391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 825cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_set_state(iface, HAPD_IFACE_ACS); 826cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, ACS_EVENT_STARTED); 827cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 828391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return HOSTAPD_CHAN_ACS; 829391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 830