From bbbacbf2f8c27ac163853600971d1a1a28dddee3 Mon Sep 17 00:00:00 2001 From: Janusz Dziedzic Date: Wed, 5 Mar 2014 09:23:42 +0100 Subject: [PATCH] DFS: Print CAC info in ctrl_iface STATUS command Print CAC time and CAC left time in control interface STATUS command. Signed-off-by: Janusz Dziedzic --- src/ap/ap_drv_ops.c | 4 +++- src/ap/ctrl_iface_ap.c | 22 ++++++++++++++++++++++ src/ap/dfs.c | 31 +++++++++++++++++++++++++++++-- src/ap/hostapd.h | 3 +++ src/drivers/driver.h | 3 +++ src/drivers/driver_nl80211.c | 6 ++++++ 6 files changed, 66 insertions(+), 3 deletions(-) diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c index 9abcd7c97..6d3ae5a79 100644 --- a/src/ap/ap_drv_ops.c +++ b/src/ap/ap_drv_ops.c @@ -774,8 +774,10 @@ int hostapd_start_dfs_cac(struct hostapd_iface *iface, int mode, int freq, } res = hapd->driver->start_dfs_cac(hapd->drv_priv, &data); - if (!res) + if (!res) { iface->cac_started = 1; + os_get_reltime(&iface->dfs_cac_start); + } return res; } diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c index e1020a67e..976093342 100644 --- a/src/ap/ctrl_iface_ap.c +++ b/src/ap/ctrl_iface_ap.c @@ -423,6 +423,28 @@ int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf, return len; len += ret; + if (!iface->cac_started || !iface->dfs_cac_ms) { + ret = os_snprintf(buf + len, buflen - len, + "cac_time_seconds=%d\n" + "cac_time_left_seconds=N/A\n", + iface->dfs_cac_ms / 1000); + } else { + /* CAC started and CAC time set - calculate remaining time */ + struct os_reltime now; + unsigned int left_time; + + os_reltime_age(&iface->dfs_cac_start, &now); + left_time = iface->dfs_cac_ms / 1000 - now.sec; + ret = os_snprintf(buf + len, buflen - len, + "cac_time_seconds=%u\n" + "cac_time_left_seconds=%u\n", + iface->dfs_cac_ms / 1000, + left_time); + } + if (ret < 0 || (size_t) ret >= buflen - len) + return len; + len += ret; + ret = os_snprintf(buf + len, buflen - len, "channel=%u\n" "secondary_channel=%d\n" diff --git a/src/ap/dfs.c b/src/ap/dfs.c index 0f262ceb2..3fb18810c 100644 --- a/src/ap/dfs.c +++ b/src/ap/dfs.c @@ -573,6 +573,28 @@ static int dfs_are_channels_overlapped(struct hostapd_iface *iface, int freq, } +static unsigned int dfs_get_cac_time(struct hostapd_iface *iface, + int start_chan_idx, int n_chans) +{ + struct hostapd_channel_data *channel; + struct hostapd_hw_modes *mode; + int i; + unsigned int cac_time_ms = 0; + + mode = iface->current_mode; + + for (i = 0; i < n_chans; i++) { + channel = &mode->channels[start_chan_idx + i]; + if (!(channel->flag & HOSTAPD_CHAN_RADAR)) + continue; + if (channel->dfs_cac_ms > cac_time_ms) + cac_time_ms = channel->dfs_cac_ms; + } + + return cac_time_ms; +} + + /* * Main DFS handler * 1 - continue channel/ap setup @@ -596,6 +618,10 @@ int hostapd_handle_dfs(struct hostapd_iface *iface) /* Get number of used channels, depend on width */ n_chans = dfs_get_used_n_chans(iface); + /* 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, @@ -640,12 +666,13 @@ int hostapd_handle_dfs(struct hostapd_iface *iface) 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", + "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->conf->vht_oper_centr_freq_seg1_idx, + iface->dfs_cac_ms / 1000); res = hostapd_start_dfs_cac(iface, iface->conf->hw_mode, iface->freq, diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index 9a705a45f..090544d5a 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -348,6 +348,9 @@ struct hostapd_iface { unsigned int cs_c_off_proberesp; int csa_in_progress; + unsigned int dfs_cac_ms; + struct os_reltime dfs_cac_start; + #ifdef CONFIG_ACS unsigned int acs_num_completed_scans; #endif /* CONFIG_ACS */ diff --git a/src/drivers/driver.h b/src/drivers/driver.h index fa9c426ba..02ade1259 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -93,6 +93,9 @@ struct hostapd_channel_data { */ long double interference_factor; #endif /* CONFIG_ACS */ + + /* DFS CAC time in milliseconds */ + unsigned int dfs_cac_ms; }; #define HOSTAPD_MODE_FLAG_HT_INFO_KNOWN BIT(0) diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index d270d6b3c..27b4c48e3 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -6200,6 +6200,7 @@ static void phy_info_freq(struct hostapd_hw_modes *mode, u8 channel; chan->freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]); chan->flag = 0; + chan->dfs_cac_ms = 0; if (ieee80211_freq_to_chan(chan->freq, &channel) != NUM_HOSTAPD_MODES) chan->chan = channel; @@ -6226,6 +6227,11 @@ static void phy_info_freq(struct hostapd_hw_modes *mode, break; } } + + if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_CAC_TIME]) { + chan->dfs_cac_ms = nla_get_u32( + tb_freq[NL80211_FREQUENCY_ATTR_DFS_CAC_TIME]); + } }