[PATCH] roaming: get current RSSI
Holger Schurig
hs4233
Tue Sep 15 04:17:17 PDT 2009
Allows wpa_supplicant to fetch the RSSI from the WEXT and
NL80211 driver. This can be used in roaming code.
Signed-off-by: Holger Schurig <hs4233 at mail.mn-solutions.de>
---
Index: hostap/src/drivers/driver.h
===================================================================
--- hostap.orig/src/drivers/driver.h 2009-09-15 11:57:33.000000000 +0200
+++ hostap/src/drivers/driver.h 2009-09-15 11:58:22.000000000 +0200
@@ -539,6 +539,14 @@ struct wpa_driver_ops {
int (*get_bssid)(void *priv, u8 *bssid);
/**
+ * get_rssi - Get the current RSSI
+ * @priv: private interface data
+ *
+ * Return -1 on failure
+ */
+ int (*get_rssi)(void *priv);
+
+ /**
* get_ssid - Get the current SSID
* @priv: private driver interface data
* @ssid: buffer for SSID (at least 32 bytes)
Index: hostap/src/drivers/driver_wext.h
===================================================================
--- hostap.orig/src/drivers/driver_wext.h 2009-09-15 11:57:33.000000000 +0200
+++ hostap/src/drivers/driver_wext.h 2009-09-15 11:58:22.000000000 +0200
@@ -62,6 +62,7 @@ struct wpa_scan_results * wpa_driver_wex
void wpa_driver_wext_scan_timeout(void *eloop_ctx, void *timeout_ctx);
+int wpa_driver_wext_get_rssi(void *priv);
int wpa_driver_wext_alternative_ifindex(struct wpa_driver_wext_data *drv,
const char *ifname);
Index: hostap/src/drivers/driver_wext.c
===================================================================
--- hostap.orig/src/drivers/driver_wext.c 2009-09-15 11:57:33.000000000 +0200
+++ hostap/src/drivers/driver_wext.c 2009-09-15 11:59:34.000000000 +0200
@@ -147,6 +147,39 @@ int wpa_driver_wext_get_bssid(void *priv
/**
+ * wpa_driver_wext_get_rssi - Get RSSI, SIOCGIWSTATS
+ * @priv: Pointer to private wext data from wpa_driver_wext_init()
+ * Returns: 0 on success, -1 on failure
+ */
+int wpa_driver_wext_get_rssi(void *priv)
+{
+ struct wpa_driver_wext_data *drv = priv;
+ struct iwreq iwr;
+ struct iw_statistics iws;
+ int sig = 0;
+
+ os_memset(&iwr, 0, sizeof(iwr));
+ iwr.u.data.pointer = (char*)&iws;
+ iwr.u.data.length = sizeof(iws);
+ iwr.u.data.flags = 1;
+ os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+
+ if (ioctl(drv->ioctl_sock, SIOCGIWSTATS, &iwr) < 0) {
+ perror("ioctl[SIOCGIWSTATS");
+ return -1;
+ }
+
+ sig = iws.qual.level;
+ if (sig == 0)
+ return -1;
+ if (iws.qual.updated & IW_QUAL_DBM)
+ sig -= 0x100;
+
+ return sig;
+}
+
+
+/**
* wpa_driver_wext_set_bssid - Set BSSID, SIOCSIWAP
* @priv: Pointer to private wext data from wpa_driver_wext_init()
* @bssid: BSSID
@@ -2387,6 +2420,7 @@ const struct wpa_driver_ops wpa_driver_w
.name = "wext",
.desc = "Linux wireless extensions (generic)",
.get_bssid = wpa_driver_wext_get_bssid,
+ .get_rssi = wpa_driver_wext_get_rssi,
.get_ssid = wpa_driver_wext_get_ssid,
.set_wpa = wpa_driver_wext_set_wpa,
.set_key = wpa_driver_wext_set_key,
Index: hostap/wpa_supplicant/driver_i.h
===================================================================
--- hostap.orig/wpa_supplicant/driver_i.h 2009-09-15 11:57:33.000000000 +0200
+++ hostap/wpa_supplicant/driver_i.h 2009-09-15 11:58:22.000000000 +0200
@@ -153,6 +153,14 @@ static inline int wpa_drv_get_ssid(struc
return -1;
}
+static inline int wpa_drv_get_rssi(struct wpa_supplicant *wpa_s)
+{
+ if (wpa_s->driver->get_rssi) {
+ return wpa_s->driver->get_rssi(wpa_s->drv_priv);
+ }
+ return -1;
+}
+
static inline int wpa_drv_set_key(struct wpa_supplicant *wpa_s, wpa_alg alg,
const u8 *addr, int key_idx, int set_tx,
const u8 *seq, size_t seq_len,
Index: hostap/src/drivers/driver_nl80211.c
===================================================================
--- hostap.orig/src/drivers/driver_nl80211.c 2009-09-15 11:57:33.000000000 +0200
+++ hostap/src/drivers/driver_nl80211.c 2009-09-15 12:04:23.000000000 +0200
@@ -3995,6 +3995,7 @@ static int i802_flush(void *priv)
nla_put_failure:
return -ENOBUFS;
}
+#endif
static int get_sta_handler(struct nl_msg *msg, void *arg)
@@ -4009,6 +4010,7 @@ static int get_sta_handler(struct nl_msg
[NL80211_STA_INFO_TX_BYTES] = { .type = NLA_U32 },
[NL80211_STA_INFO_RX_PACKETS] = { .type = NLA_U32 },
[NL80211_STA_INFO_TX_PACKETS] = { .type = NLA_U32 },
+ [NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 },
};
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
@@ -4044,10 +4046,49 @@ static int get_sta_handler(struct nl_msg
if (stats[NL80211_STA_INFO_TX_PACKETS])
data->tx_packets =
nla_get_u32(stats[NL80211_STA_INFO_TX_PACKETS]);
+ if (stats[NL80211_STA_INFO_SIGNAL])
+ data->last_rssi =
+ (int8_t)nla_get_u8(stats[NL80211_STA_INFO_SIGNAL]);
return NL_SKIP;
}
+
+/**
+ * wpa_driver_nl80211_get_rssi - Fetch the signal
+ * @priv: Pointer to private wext data from wpa_driver_nl80211_init()
+ * Returns: Signal result on success, -1 on failure
+ */
+int wpa_driver_nl80211_get_rssi(void *priv)
+{
+ struct wpa_driver_nl80211_data *drv = priv;
+ struct nl_msg *msg;
+ struct hostap_sta_driver_data data;
+ int ret;
+
+ data.last_rssi = -1;
+ msg = nlmsg_alloc();
+ if (!msg)
+ return -ENOMEM;
+
+ genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
+ 0, NL80211_CMD_GET_STATION, 0);
+
+ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid);
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(drv->ifname));
+
+ ret = send_and_recv_msgs(drv, msg, get_sta_handler, &data);
+ //wpa_printf(MSG_DEBUG, "%s %d, RSSI %d", __func__, ret, data.last_rssi);
+ if (ret || data.last_rssi <= 0)
+ return -1;
+ else
+ return data.last_rssi;
+ nla_put_failure:
+ return -1;
+}
+
+
+#ifdef HOSTAPD
static int i802_read_sta_data(void *priv, struct hostap_sta_driver_data *data,
const u8 *addr)
{
@@ -4451,6 +4492,7 @@ const struct wpa_driver_ops wpa_driver_n
#ifndef HOSTAPD
.get_bssid = wpa_driver_nl80211_get_bssid,
.get_ssid = wpa_driver_nl80211_get_ssid,
+ .get_rssi = wpa_driver_nl80211_get_rssi,
.set_key = wpa_driver_nl80211_set_key,
#endif /* HOSTAPD */
.scan2 = wpa_driver_nl80211_scan,
--
http://www.holgerschurig.de
More information about the Hostap
mailing list