Browse Source

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 <janusz.dziedzic@tieto.com>
Janusz Dziedzic 11 years ago
parent
commit
bbbacbf2f8
6 changed files with 66 additions and 3 deletions
  1. 3 1
      src/ap/ap_drv_ops.c
  2. 22 0
      src/ap/ctrl_iface_ap.c
  3. 29 2
      src/ap/dfs.c
  4. 3 0
      src/ap/hostapd.h
  5. 3 0
      src/drivers/driver.h
  6. 6 0
      src/drivers/driver_nl80211.c

+ 3 - 1
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;
 }

+ 22 - 0
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"

+ 29 - 2
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,

+ 3 - 0
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 */

+ 3 - 0
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)

+ 6 - 0
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]);
+	}
 }