DFS: restart CAC in case of CAC is aborted

Message ID 800a151e-1e7d-2057-255b-5d56f3c32882@quantenna.com
State Superseded
Headers show
Series
  • DFS: restart CAC in case of CAC is aborted
Related show

Commit Message

Dmitrii Lebed Feb. 17, 2018, 8:53 a.m.
From: Dmitry Lebed <dlebed@quantenna.com>

If CAC is aborted, hostapd will continue wait for
CAC completion and will stuck in this state forever.
Adding CAC restart action on CAC aborted event,
considering "CAC aborted" state as recoverable.

Signed-off-by: Dmitrii Lebed <dlebed@quantenna.com>
---
  src/ap/dfs.c           | 69
+++++++++++++++++++++++++++++++-------------------
  src/ap/dfs.h           |  2 +-
  src/ap/drv_callbacks.c |  6 ++---
  3 files changed, 47 insertions(+), 30 deletions(-)

--
2.16.1



This email, including its contents and any attachment(s), may contain confidential information of Quantenna Communications, Inc. and is solely for the intended recipient(s). If you may have received this in error, please contact the sender and permanently delete this email, its contents and any attachment(s).

Patch

diff --git a/src/ap/dfs.c b/src/ap/dfs.c
index 5a0d7814b..f2d357262 100644
--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
@@ -636,6 +636,34 @@  static unsigned int dfs_get_cac_time(struct
hostapd_iface *iface,
        return cac_time_ms;
  }
  +static int dfs_start_cac(struct hostapd_iface *iface)
+{
+       int res;
+
+       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 res;
+}
   /*
   * Main DFS handler
@@ -719,31 +747,8 @@  int hostapd_handle_dfs(struct hostapd_iface *iface)
        /* 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;
+       return dfs_start_cac(iface);
  }
   @@ -768,10 +773,18 @@ 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 res = 0;
+
        wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_COMPLETED
                "success=%d freq=%d ht_enabled=%d chan_offset=%d chan_width=%d
cf1=%d cf2=%d",
                success, freq, ht_enabled, chan_offset, chan_width, cf1, cf2);
  +     if (iface->state != HAPD_IFACE_DFS || !iface->cac_started) {
+               wpa_printf(MSG_ERROR, "CAC complete received in wrong state=%d;
started=%d",
+                          iface->state, iface->cac_started);
+               return 1;
+       }
+
        if (success) {
                /* Complete iface/ap configuration */
                if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) {
@@ -800,9 +813,13 @@  int hostapd_dfs_complete_cac(struct hostapd_iface
*iface, int success, int freq,
                                iface->cac_started = 0;
                        }
                }
+       } else {
+               /* Restart CAC in case of CAC abort */
+               wpa_printf(MSG_DEBUG, "DFS restart CAC on %d MHz", iface->freq);
+               res = dfs_start_cac(iface);
        }
  -     return 0;
+       return res;
  }
   @@ -1074,7 +1091,7 @@ int hostapd_is_dfs_required(struct
hostapd_iface *iface)
  }
   -int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
+int hostapd_dfs_cac_started(struct hostapd_iface *iface, int freq,
                          int ht_enabled, int chan_offset, int chan_width,
                          int cf1, int cf2)
  {
diff --git a/src/ap/dfs.h b/src/ap/dfs.h
index f0fa6f688..2d1532815 100644
--- a/src/ap/dfs.h
+++ b/src/ap/dfs.h
@@ -25,7 +25,7 @@  int hostapd_dfs_nop_finished(struct hostapd_iface
*iface, int freq,
                             int ht_enabled,
                             int chan_offset, int chan_width, int cf1, int cf2);
  int hostapd_is_dfs_required(struct hostapd_iface *iface);
-int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
+int hostapd_dfs_cac_started(struct hostapd_iface *iface, int freq,
                          int ht_enabled, int chan_offset, int chan_width,
                          int cf1, int cf2);
  int hostapd_handle_dfs_offload(struct hostapd_iface *iface);
diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
index e4a458107..58e967704 100644
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -1398,9 +1398,9 @@  static void hostapd_event_dfs_cac_started(struct
hostapd_data *hapd,
                                          struct dfs_event *radar)
  {
        wpa_printf(MSG_DEBUG, "DFS offload CAC started on %d MHz", radar->freq);
-       hostapd_dfs_start_cac(hapd->iface, radar->freq, radar->ht_enabled,
-                             radar->chan_offset, radar->chan_width,
-                             radar->cf1, radar->cf2);
+       hostapd_dfs_cac_started(hapd->iface, radar->freq, radar->ht_enabled,
+                               radar->chan_offset, radar->chan_width,
+                               radar->cf1, radar->cf2);
  }
   #endif /* NEED_AP_MLME */