[PATCH] driver: Function to directly poll signal quality

Paul Stewart pstew at chromium.org
Thu Mar 17 17:54:00 EDT 2011


This provides a means for the supplicant to directly request
signal quality metrics from the driver.  This is useful, for
example for background scan algorithms that might ask desire
this information out-of-band with CQM events.

Signed-off-by: Paul Stewart <pstew at google.com>
---
 src/drivers/driver.h         |   26 +++++++++++++++++++-------
 src/drivers/driver_ndis.c    |    1 +
 src/drivers/driver_nl80211.c |   27 ++++++++++++++++++++++-----
 wpa_supplicant/driver_i.h    |    8 ++++++++
 4 files changed, 50 insertions(+), 12 deletions(-)

diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 04b2a10..f2c3947 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -703,6 +703,17 @@ enum tdls_oper {
 };
 
 /**
+ * struct wpa_signal_change - Information about channel signal quality
+ */
+struct wpa_signal_info {
+	u32 frequency;
+	int above_threshold;
+	int current_signal;
+	int current_noise;
+	int current_txrate;
+};
+
+/**
  * struct wpa_driver_ops - Driver interface API definition
  *
  * This structure defines the API that each driver interface needs to implement
@@ -1893,6 +1904,13 @@ struct wpa_driver_ops {
 	int (*signal_monitor)(void *priv, int threshold, int hysteresis);
 
 	/**
+	 * signal_poll - Get current connection information
+	 * @priv: Private driver interface data
+	 * @conn_info: Connection info structure
+         */
+	int (*signal_poll)(void *priv, struct wpa_signal_info *signal_info);
+
+	/**
 	 * send_frame - Send IEEE 802.11 frame (testing use only)
 	 * @priv: Private driver interface data
 	 * @data: IEEE 802.11 frame with IEEE 802.11 header
@@ -3044,13 +3062,7 @@ union wpa_event_data {
 	/**
 	 * struct signal_change - Data for EVENT_SIGNAL_CHANGE events
 	 */
-	struct signal_change {
-		u32 frequency;
-		int above_threshold;
-		int current_signal;
-		int current_noise;
-		int current_txrate;
-	} signal_change;
+	struct wpa_signal_info signal_change;
 
 	/**
 	 * struct best_channel - Data for EVENT_BEST_CHANNEL events
diff --git a/src/drivers/driver_ndis.c b/src/drivers/driver_ndis.c
index 762931e..e2e2a7b 100644
--- a/src/drivers/driver_ndis.c
+++ b/src/drivers/driver_ndis.c
@@ -3303,6 +3303,7 @@ const struct wpa_driver_ops wpa_driver_ndis_ops = {
 	NULL /* suspend */,
 	NULL /* resume */,
 	NULL /* signal_monitor */,
+	NULL /* signal_poll */,
 	NULL /* send_frame */,
 	NULL /* shared_freq */,
 	NULL /* get_noa */,
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 07f56b9..a66e427 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -1080,7 +1080,7 @@ static int get_link_signal(struct nl_msg *msg, void *arg)
 		[NL80211_RATE_INFO_40_MHZ_WIDTH] = { .type = NLA_FLAG },
 		[NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG },
 	};
-	struct signal_change *sig_change = arg;
+	struct wpa_signal_info *sig_change = arg;
 
 	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
 		  genlmsg_attrlen(gnlh, 0), NULL);
@@ -1113,7 +1113,7 @@ static int get_link_signal(struct nl_msg *msg, void *arg)
 
 
 static int nl80211_get_link_signal(struct wpa_driver_nl80211_data *drv,
-				   struct signal_change *sig)
+				   struct wpa_signal_info *sig)
 {
 	struct nl_msg *msg;
 
@@ -1145,7 +1145,7 @@ static int get_link_noise(struct nl_msg *msg, void *arg)
 		[NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
 		[NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
 	};
-	struct signal_change *sig_change = arg;
+	struct wpa_signal_info *sig_change = arg;
 
 	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
 		  genlmsg_attrlen(gnlh, 0), NULL);
@@ -1181,7 +1181,7 @@ static int get_link_noise(struct nl_msg *msg, void *arg)
 
 
 static int nl80211_get_link_noise(struct wpa_driver_nl80211_data *drv,
-				  struct signal_change *sig_change)
+				  struct wpa_signal_info *sig_change)
 {
 	struct nl_msg *msg;
 
@@ -1215,7 +1215,7 @@ static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv,
 	struct nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
 	enum nl80211_cqm_rssi_threshold_event event;
 	union wpa_event_data ed;
-	struct signal_change sig;
+	struct wpa_signal_info sig;
 	int res;
 
 	if (tb[NL80211_ATTR_CQM] == NULL ||
@@ -6343,6 +6343,22 @@ nla_put_failure:
 }
 
 
+static int nl80211_signal_poll(void *priv,
+				struct wpa_signal_info *signal)
+{
+	struct i802_bss *bss = priv;
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+	int res;
+
+	os_memset(signal, 0, sizeof(*signal));
+	res = nl80211_get_link_signal(drv, signal);
+	if (res != 0)
+		return res;
+
+	return nl80211_get_link_noise(drv, signal);
+}
+
+
 static int nl80211_send_frame(void *priv, const u8 *data, size_t data_len,
 			      int encrypt)
 {
@@ -6493,6 +6509,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
 	.resume = wpa_driver_nl80211_resume,
 	.send_ft_action = nl80211_send_ft_action,
 	.signal_monitor = nl80211_signal_monitor,
+	.signal_poll = nl80211_signal_poll,
 	.send_frame = nl80211_send_frame,
 	.set_intra_bss = nl80211_set_intra_bss,
 	.set_param = nl80211_set_param,
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index 2f57af4..8c8d17c 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -504,6 +504,14 @@ static inline int wpa_drv_signal_monitor(struct wpa_supplicant *wpa_s,
 	return -1;
 }
 
+static inline int wpa_drv_signal_poll(struct wpa_supplicant *wpa_s,
+				      struct wpa_signal_info *signal)
+{
+	if (wpa_s->driver->signal_poll)
+		return wpa_s->driver->signal_poll(wpa_s->drv_priv, signal);
+	return -1;
+}
+
 static inline int wpa_drv_set_ap_wps_ie(struct wpa_supplicant *wpa_s,
 					const struct wpabuf *beacon,
 					const struct wpabuf *proberesp,
-- 
1.7.3.1



More information about the HostAP mailing list