Cumulative patch from commit 32b62704fac6af74f60b2effb173474e11ff089d
32b6270 Android: Fix ARRAY_SIZE() compilation
7617388 Interworking: Report STATUS:sp_type even if domain is not configured
c20bc9d P2P: Remove compiler warning without CONFIG_IEEE80211N
ca9bc5b P2P: Add VHT support
20ea1ca P2P: Add VHT parameter to P2P operations
53cfad4 nl80211: Mark VHT 80 MHz channels
f2112b2 wpa_supplicant: Add CONFIG_IEEE80211AC
6b02335 hostapd: Mask out not-supported VHT capabilities
7f0303d hostapd: Verify VHT 160/80+80 MHz driver support
c781eb8 hostapd: Verify VHT capabilities are supported by driver
b29b012 Fix some VHT Capabilities definitions
7066a8e hostapd: Fix wrong VHT configuration capabilities flags
6651f1f nl80211: Use max tx power from regulatory domain
7ac3616 nl80211: Replace perror() and printf() calls with wpa_printf()
4d9fb08 WPS: Clear known_wps_freq in addition to after_wps
d20c340 Interworking: Clear known_wps_freq for network selection
f3be6ee tests: Allow test case descriptions to be written into database
1bd05d0 Interworking: Force normal scan for network selection
51e9f22 P2P: Add option to allow additional client channels
556b30d P2P: Add option to remove channels from GO use
e7ecab4 Use ARRAY_SIZE() macro
39044a7 Introduce ARRAY_SIZE() macro
2e94624 DFS: Handle radar event when CAC actived correctly
5eaf240 DFS: Fix overlapped() function to check only DFS channels
345276a DFS: Adjust center freq correctly for VHT20/VHT40
1dc17db DFS: Fix available channels list for VHT80
34068ac nl80211: Add debug prints on nl_recvmsgs() failure
10b8592 nl80211: Make eloop sockets non-blocking
5f65e9f nl80211: Abstract handling of sockets on eloop
e8d1168 nl80211: Register for IBSS auth frames before eloop
03610ad Clean up get_seqnum() use for IPN
29179b8 Stop ctrl_iface monitor send loop on reinit failure
a2a535f Remove unnecessary wpa_s->conf checks
3318376 Add explicit buffer length checks for p2p_build_wps_ie()
0f01201 Verify that readlink() did not truncate result
f5eb9da nl80211: Clean up if_add() for hostapd use
a288da6 OpenSSL: Fix memory leak on error path
6cb4f11 nl80211: Fix strerror() value in P2P Dev debug messages
35f8363 DFS: Add forgotten break statement
2f243b8 Remove os_strncpy()
24f051e Replace remainining strncpy() uses with strlcpy()
41c526f P2P: Fix snprintf buffer length for group ifname backup
Change-Id: I2e1506cb9219a5a37efbb2ae0dc180fb081c809f
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/ap/dfs.c b/src/ap/dfs.c
index 37bbd20..a30861f 100644
--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
@@ -55,13 +55,37 @@
}
-static int dfs_is_ht40_allowed(struct hostapd_channel_data *chan)
+static int dfs_is_chan_allowed(struct hostapd_channel_data *chan, int n_chans)
{
- int allowed[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157,
- 184, 192 };
- unsigned int i;
+ /*
+ * The tables contain first valid channel number based on channel width.
+ * We will also choose this first channel as the control one.
+ */
+ int allowed_40[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157,
+ 184, 192 };
+ /*
+ * VHT80, valid channels based on center frequency:
+ * 42, 58, 106, 122, 138, 155
+ */
+ int allowed_80[] = { 36, 52, 100, 116, 132, 149 };
+ int *allowed = allowed_40;
+ unsigned int i, allowed_no = 0;
- for (i = 0; i < sizeof(allowed) / sizeof(allowed[0]); i++) {
+ switch (n_chans) {
+ case 2:
+ allowed = allowed_40;
+ allowed_no = ARRAY_SIZE(allowed_40);
+ break;
+ case 4:
+ allowed = allowed_80;
+ allowed_no = ARRAY_SIZE(allowed_80);
+ break;
+ default:
+ wpa_printf(MSG_DEBUG, "Unknown width for %d channels", n_chans);
+ break;
+ }
+
+ for (i = 0; i < allowed_no; i++) {
if (chan->chan == allowed[i])
return 1;
}
@@ -92,7 +116,7 @@
/* Skip HT40/VHT uncompatible channels */
if (hapd->iconf->ieee80211n &&
hapd->iconf->secondary_channel) {
- if (!dfs_is_ht40_allowed(chan))
+ if (!dfs_is_chan_allowed(chan, n_chans))
continue;
for (j = 1; j < n_chans; j++) {
@@ -130,7 +154,14 @@
switch (hapd->iconf->vht_oper_chwidth) {
case VHT_CHANWIDTH_USE_HT:
- hapd->iconf->vht_oper_centr_freq_seg0_idx = chan->chan + 2;
+ if (hapd->iconf->secondary_channel == 1)
+ hapd->iconf->vht_oper_centr_freq_seg0_idx =
+ chan->chan + 2;
+ else if (hapd->iconf->secondary_channel == -1)
+ hapd->iconf->vht_oper_centr_freq_seg0_idx =
+ chan->chan - 2;
+ else
+ hapd->iconf->vht_oper_centr_freq_seg0_idx = chan->chan;
break;
case VHT_CHANWIDTH_80MHZ:
hapd->iconf->vht_oper_centr_freq_seg0_idx = chan->chan + 6;
@@ -138,6 +169,7 @@
case VHT_CHANWIDTH_160MHZ:
hapd->iconf->vht_oper_centr_freq_seg0_idx =
chan->chan + 14;
+ break;
default:
wpa_printf(MSG_INFO, "DFS only VHT20/40/80/160 is supported now");
break;
@@ -385,14 +417,15 @@
u8 radar_chan;
int res = 0;
- if (hapd->iface->freq == freq)
- res++;
-
/* Our configuration */
mode = hapd->iface->current_mode;
start_chan_idx = dfs_get_start_chan_idx(hapd);
n_chans = dfs_get_used_n_chans(hapd);
+ /* Check we are on DFS channel(s) */
+ if (!dfs_check_chans_radar(hapd, start_chan_idx, n_chans))
+ return 0;
+
/* Reported via radar event */
switch (chan_width) {
case CHAN_WIDTH_20_NOHT:
@@ -422,6 +455,8 @@
for (i = 0; i < n_chans; i++) {
chan = &mode->channels[start_chan_idx + i];
+ if (!(chan->flag & HOSTAPD_CHAN_RADAR))
+ continue;
for (j = 0; j < radar_n_chans; j++) {
wpa_printf(MSG_DEBUG, "checking our: %d, radar: %d",
chan->chan, radar_chan + j * 4);
@@ -511,29 +546,13 @@
int ht_enabled, int chan_offset, int chan_width,
int cf1, int cf2)
{
- struct hostapd_channel_data *channel;
- int err = 1;
-
if (success) {
/* Complete iface/ap configuration */
set_dfs_state(hapd, freq, ht_enabled, chan_offset,
chan_width, cf1, cf2,
HOSTAPD_CHAN_DFS_AVAILABLE);
+ hapd->cac_started = 0;
hostapd_setup_interface_complete(hapd->iface, 0);
- } else {
- /* Switch to new channel */
- set_dfs_state(hapd, freq, ht_enabled, chan_offset,
- chan_width, cf1, cf2,
- HOSTAPD_CHAN_DFS_UNAVAILABLE);
- channel = dfs_get_valid_channel(hapd);
- if (channel) {
- hapd->iconf->channel = channel->chan;
- hapd->iface->freq = channel->freq;
- err = 0;
- } else
- wpa_printf(MSG_ERROR, "No valid channel available");
-
- hostapd_setup_interface_complete(hapd->iface, err);
}
return 0;
@@ -553,7 +572,13 @@
err = 0;
}
- hapd->driver->stop_ap(hapd->drv_priv);
+ if (!hapd->cac_started) {
+ wpa_printf(MSG_DEBUG, "DFS radar detected");
+ hapd->driver->stop_ap(hapd->drv_priv);
+ } else {
+ wpa_printf(MSG_DEBUG, "DFS radar detected during CAC");
+ hapd->cac_started = 0;
+ }
hostapd_setup_interface_complete(hapd->iface, err);
return 0;
@@ -579,10 +604,6 @@
if (!res)
return 0;
- /* we are working on non-DFS channel - skip event */
- if (res == 0)
- return 0;
-
/* radar detected while operating, switch the channel. */
res = hostapd_dfs_start_channel_switch(hapd);