From 7cbb5f1a44e73752c576e259386c541905023dc3 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Wed, 8 Mar 2017 10:43:17 +0530 Subject: [PATCH] DFS: Handle pre-CAC expired event As FCC DFS requirement does not explicitly mention about the validity of the (pre-)CAC when channel is switched, it is safe to assume that the pre-CAC result will not be valid once the CAC completed channel is switched or radar detection is not active on the (CAC completed) channel within a time period which is allowed (10 seconds - channel switch time) as per FCC DFS requirement. Use the new driver event to allow the driver to notify expiry of the CAC result on a channel. Move the DFS state of the channel to 'usable' when processing pre-CAC expired event. This means any future operation on that channel will require a new CAC to be completed. This event is applicable only when DFS is not offloaded to the kernel driver. Signed-off-by: Vasanthakumar Thiagarajan --- src/ap/dfs.c | 21 ++++++++++++++++++++- src/ap/dfs.h | 5 ++++- src/ap/drv_callbacks.c | 15 +++++++++++++++ src/common/wpa_ctrl.h | 1 + 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/ap/dfs.c b/src/ap/dfs.c index 23f265d64..295720100 100644 --- a/src/ap/dfs.c +++ b/src/ap/dfs.c @@ -1,7 +1,7 @@ /* * DFS - Dynamic Frequency Selection * Copyright (c) 2002-2013, Jouni Malinen - * Copyright (c) 2013-2015, Qualcomm Atheros, Inc. + * Copyright (c) 2013-2017, Qualcomm Atheros, Inc. * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -806,6 +806,25 @@ int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq, } +int hostapd_dfs_pre_cac_expired(struct hostapd_iface *iface, int freq, + int ht_enabled, int chan_offset, int chan_width, + int cf1, int cf2) +{ + wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_PRE_CAC_EXPIRED + "freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d", + freq, ht_enabled, chan_offset, chan_width, cf1, cf2); + + /* Proceed only if DFS is not offloaded to the driver */ + if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) + return 0; + + set_dfs_state(iface, freq, ht_enabled, chan_offset, chan_width, + cf1, cf2, HOSTAPD_CHAN_DFS_USABLE); + + return 0; +} + + static int hostapd_dfs_start_channel_switch_cac(struct hostapd_iface *iface) { struct hostapd_channel_data *channel; diff --git a/src/ap/dfs.h b/src/ap/dfs.h index be8c0e600..f0fa6f688 100644 --- a/src/ap/dfs.h +++ b/src/ap/dfs.h @@ -1,7 +1,7 @@ /* * DFS - Dynamic Frequency Selection * Copyright (c) 2002-2013, Jouni Malinen - * Copyright (c) 2013, Qualcomm Atheros, Inc. + * Copyright (c) 2013-2017, Qualcomm Atheros, Inc. * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -14,6 +14,9 @@ int hostapd_handle_dfs(struct hostapd_iface *iface); int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq, int ht_enabled, int chan_offset, int chan_width, int cf1, int cf2); +int hostapd_dfs_pre_cac_expired(struct hostapd_iface *iface, int freq, + int ht_enabled, int chan_offset, int chan_width, + int cf1, int cf2); int hostapd_dfs_radar_detected(struct hostapd_iface *iface, int freq, int ht_enabled, int chan_offset, int chan_width, diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c index f69c65529..46b2d4c8a 100644 --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -1121,6 +1121,16 @@ static void hostapd_event_dfs_radar_detected(struct hostapd_data *hapd, } +static void hostapd_event_dfs_pre_cac_expired(struct hostapd_data *hapd, + struct dfs_event *radar) +{ + wpa_printf(MSG_DEBUG, "DFS Pre-CAC expired on %d MHz", radar->freq); + hostapd_dfs_pre_cac_expired(hapd->iface, radar->freq, radar->ht_enabled, + radar->chan_offset, radar->chan_width, + radar->cf1, radar->cf2); +} + + static void hostapd_event_dfs_cac_finished(struct hostapd_data *hapd, struct dfs_event *radar) { @@ -1313,6 +1323,11 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, break; hostapd_event_dfs_radar_detected(hapd, &data->dfs_event); break; + case EVENT_DFS_PRE_CAC_EXPIRED: + if (!data) + break; + hostapd_event_dfs_pre_cac_expired(hapd, &data->dfs_event); + break; case EVENT_DFS_CAC_FINISHED: if (!data) break; diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h index 4649eab95..247bf80cb 100644 --- a/src/common/wpa_ctrl.h +++ b/src/common/wpa_ctrl.h @@ -275,6 +275,7 @@ extern "C" { #define DFS_EVENT_CAC_START "DFS-CAC-START " #define DFS_EVENT_CAC_COMPLETED "DFS-CAC-COMPLETED " #define DFS_EVENT_NOP_FINISHED "DFS-NOP-FINISHED " +#define DFS_EVENT_PRE_CAC_EXPIRED "DFS-PRE-CAC-EXPIRED " #define AP_CSA_FINISHED "AP-CSA-FINISHED "