[OpenWrt-Devel] [PATCH] [iwinfo] Allow non-negative RSSI reading

Dmitry Ivanov dmitrijs.ivanovs at ubnt.com
Fri May 8 04:48:53 EDT 2015


WLAN RSSI reading can be non-negative, i.e. 0 dBm and more.
For example, this occurs with QCA9561 when transmitter is very close.
Driver, Linux kernel and iw tool do allow this.

This patch allows non-negative RSSI in iwinfo too.

Signed-off-by: Dmitry Ivanov <dima at ubnt.com>
---
 include/iwinfo.h   |  4 +++-
 iwinfo_cli.c       | 10 +++++-----
 iwinfo_madwifi.c   |  1 +
 iwinfo_nl80211.c   | 52 +++++++++++++++++++++++++---------------------------
 iwinfo_wext_scan.c |  1 +
 iwinfo_wl.c        | 12 ++++++++++++
 6 files changed, 47 insertions(+), 33 deletions(-)

diff --git a/include/iwinfo.h b/include/iwinfo.h
index 57a88e2..c1628b8 100644
--- a/include/iwinfo.h
+++ b/include/iwinfo.h
@@ -76,6 +76,7 @@ struct iwinfo_rate_entry {
 struct iwinfo_assoclist_entry {
 	uint8_t	mac[6];
 	int8_t signal;
+	uint8_t signal_known;
 	int8_t noise;
 	uint32_t inactive;
 	uint32_t rx_packets;
@@ -109,7 +110,8 @@ struct iwinfo_scanlist_entry {
 	uint8_t ssid[IWINFO_ESSID_MAX_SIZE+1];
 	enum iwinfo_opmode mode;
 	uint8_t channel;
-	uint8_t signal;
+	int8_t  signal;
+	uint8_t signal_known;
 	uint8_t quality;
 	uint8_t quality_max;
 	struct iwinfo_crypto_entry crypto;
diff --git a/iwinfo_cli.c b/iwinfo_cli.c
index d9a59e2..d89eb04 100644
--- a/iwinfo_cli.c
+++ b/iwinfo_cli.c
@@ -104,11 +104,11 @@ static char * format_quality_max(int qmax)
 	return buf;
 }
 
-static char * format_signal(int sig)
+static char * format_signal(int sig, unsigned int sig_known)
 {
 	static char buf[10];
 
-	if (!sig)
+	if (!sig_known)
 		snprintf(buf, sizeof(buf), "unknown");
 	else
 		snprintf(buf, sizeof(buf), "%d dBm", sig);
@@ -461,7 +461,7 @@ static char * print_signal(const struct iwinfo_ops *iw, const char *ifname)
 	if (iw->signal(ifname, &sig))
 		sig = 0;
 
-	return format_signal(sig);
+	return format_signal(sig, 1);
 }
 
 static char * print_noise(const struct iwinfo_ops *iw, const char *ifname)
@@ -592,7 +592,7 @@ static void print_scanlist(const struct iwinfo_ops *iw, const char *ifname)
 			IWINFO_OPMODE_NAMES[e->mode],
 			format_channel(e->channel));
 		printf("          Signal: %s  Quality: %s/%s\n",
-			format_signal(e->signal - 0x100),
+			format_signal(e->signal, e->signal_known),
 			format_quality(e->quality),
 			format_quality_max(e->quality_max));
 		printf("          Encryption: %s\n\n",
@@ -682,7 +682,7 @@ static void print_assoclist(const struct iwinfo_ops *iw, const char *ifname)
 
 		printf("%s  %s / %s (SNR %d)  %d ms ago\n",
 			format_bssid(e->mac),
-			format_signal(e->signal),
+			format_signal(e->signal, e->signal_known),
 			format_noise(e->noise),
 			(e->signal - e->noise),
 			e->inactive);
diff --git a/iwinfo_madwifi.c b/iwinfo_madwifi.c
index bb7fc63..da21bfe 100644
--- a/iwinfo_madwifi.c
+++ b/iwinfo_madwifi.c
@@ -763,6 +763,7 @@ static int madwifi_get_assoclist(const char *ifname, char *buf, int *len)
 			memset(&entry, 0, sizeof(entry));
 
 			entry.signal = (si->isi_rssi - 95);
+			entry.signal_known - 1;
 			entry.noise  = noise;
 			memcpy(entry.mac, &si->isi_macaddr, 6);
 
diff --git a/iwinfo_nl80211.c b/iwinfo_nl80211.c
index 2562492..daed8ef 100644
--- a/iwinfo_nl80211.c
+++ b/iwinfo_nl80211.c
@@ -1606,7 +1606,10 @@ static int nl80211_get_assoclist_cb(struct nl_msg *msg, void *arg)
 	                      attr[NL80211_ATTR_STA_INFO], stats_policy))
 	{
 		if (sinfo[NL80211_STA_INFO_SIGNAL])
+		{
 			e->signal = nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
+			e->signal_known = 1;
+		}
 
 		if (sinfo[NL80211_STA_INFO_INACTIVE_TIME])
 			e->inactive = nla_get_u32(sinfo[NL80211_STA_INFO_INACTIVE_TIME]);
@@ -1889,7 +1892,7 @@ static void nl80211_get_scanlist_ie(struct nlattr **bss,
 
 static int nl80211_get_scanlist_cb(struct nl_msg *msg, void *arg)
 {
-	int8_t rssi;
+	int8_t rssi, rssi_limited;
 	uint16_t caps;
 
 	struct nl80211_scanlist *sl = arg;
@@ -1945,17 +1948,17 @@ static int nl80211_get_scanlist_cb(struct nl_msg *msg, void *arg)
 
 	if (bss[NL80211_BSS_SIGNAL_MBM])
 	{
-		sl->e->signal =
-			(uint8_t)((int32_t)nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]) / 100);
+		rssi = ((int32_t)nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM])) / 100;
+		rssi_limited = rssi;
 
-		rssi = sl->e->signal - 0x100;
+		if (rssi_limited < -110)
+			rssi_limited = -110;
+		else if (rssi_limited > -40)
+			rssi_limited = -40;
 
-		if (rssi < -110)
-			rssi = -110;
-		else if (rssi > -40)
-			rssi = -40;
-
-		sl->e->quality = (rssi + 110);
+		sl->e->signal = rssi;
+		sl->e->signal_known = 1;
+		sl->e->quality = rssi_limited + 110;
 		sl->e->quality_max = 70;
 	}
 
@@ -2057,7 +2060,7 @@ static int wpasupp_ssid_decode(const char *in, char *out, int outlen)
 
 static int nl80211_get_scanlist(const char *ifname, char *buf, int *len)
 {
-	int freq, rssi, qmax, count, mode;
+	int freq, rssi, rssi_limited, qmax, count, mode;
 	char *res;
 	char ssid[129] = { 0 };
 	char bssid[18] = { 0 };
@@ -2132,24 +2135,19 @@ static int nl80211_get_scanlist(const char *ifname, char *buf, int *len)
 
 				/* Signal */
 				e->signal = rssi;
+				e->signal_known = 1;
 
 				/* Quality */
-				if (rssi < 0)
-				{
-					/* The cfg80211 wext compat layer assumes a signal range
-					 * of -110 dBm to -40 dBm, the quality value is derived
-					 * by adding 110 to the signal level */
-					if (rssi < -110)
-						rssi = -110;
-					else if (rssi > -40)
-						rssi = -40;
-
-					e->quality = (rssi + 110);
-				}
-				else
-				{
-					e->quality = rssi;
-				}
+				rssi_limited = rssi;
+				/* The cfg80211 wext compat layer assumes a signal range
+					* of -110 dBm to -40 dBm, the quality value is derived
+					* by adding 110 to the signal level */
+				if (rssi_limited < -110)
+					rssi_limited = -110;
+				else if (rssi_limited > -40)
+					rssi_limited = -40;
+
+				e->quality = (rssi_limited + 110);
 
 				/* Max. Quality */
 				e->quality_max = qmax;
diff --git a/iwinfo_wext_scan.c b/iwinfo_wext_scan.c
index a066721..4014f82 100644
--- a/iwinfo_wext_scan.c
+++ b/iwinfo_wext_scan.c
@@ -304,6 +304,7 @@ static inline void wext_fill_entry(struct stream_descr *stream, struct iw_event
 
 		case IWEVQUAL:
 			e->signal = event->u.qual.level;
+			e->signal_known = 1;
 			e->quality = event->u.qual.qual;
 			e->quality_max = iw_range->max_qual.qual;
 			break;
diff --git a/iwinfo_wl.c b/iwinfo_wl.c
index 7cbda96..2928378 100644
--- a/iwinfo_wl.c
+++ b/iwinfo_wl.c
@@ -450,9 +450,15 @@ static int wl_get_assoclist(const char *ifname, char *buf, int *len)
 			memcpy(rssi.mac, &macs->ea[i], 6);
 
 			if (!wl_ioctl(ifname, WLC_GET_RSSI, &rssi, sizeof(struct wl_sta_rssi)))
+			{
 				entry.signal = (rssi.rssi - 0x100);
+				entry.signal_known = 1;
+			}
 			else
+			{
 				entry.signal = 0;
+				entry.signal_known = 0;
+			}
 
 			entry.noise = noise;
 			memcpy(entry.mac, &macs->ea[i], 6);
@@ -481,9 +487,15 @@ static int wl_get_assoclist(const char *ifname, char *buf, int *len)
 				rssi.mac[5] = strtol(&macstr[15], NULL, 16);
 
 				if (!wl_ioctl(ifname, WLC_GET_RSSI, &rssi, sizeof(struct wl_sta_rssi)))
+				{
 					entry.signal = (rssi.rssi - 0x100);
+					entry.signal_known = 1;
+				}
 				else
+				{
 					entry.signal = 0;
+					entry.signal_known = 0;
+				}
 
 				entry.noise = noise;
 				memcpy(entry.mac, rssi.mac, 6);
-- 
2.1.4
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list