[PATCH 1/4] driver: Function to directly poll signal quality
Paul Stewart
pstew
Thu Mar 17 14:54:00 PDT 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 40f1d0e..1b0c498 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -705,6 +705,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
@@ -1895,6 +1906,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
@@ -3051,13 +3069,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 f9f8566..aa44274 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -1082,7 +1082,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);
@@ -1115,7 +1115,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;
@@ -1147,7 +1147,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);
@@ -1183,7 +1183,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;
@@ -1217,7 +1217,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 ||
@@ -6371,6 +6371,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)
{
@@ -6521,6 +6537,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