[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