diff mbox series

[IWINFO,RFC,1/2] iwinfo: export ht and vht operation in scan results

Message ID 20201115225321.31277-2-ansuelsmth@gmail.com
State Superseded
Headers show
Series [IWINFO,RFC,1/2] iwinfo: export ht and vht operation in scan results | expand

Commit Message

Ansuel Smith Nov. 15, 2020, 10:53 p.m. UTC
Export ht and vht operation data in scan results. These additional data
can be usefull to check wifi channel utilizzation by neraby stations.

Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
The final goal of this patch is to add a nice and easy graph to luci to
better check wifi channel utilizzation directly from the ui. This is
already possibile but the current implementation lacks of any clean
implementation to get channel width. With the new provided data, chan
width can be indirectly calculated and parsed by the ui.

If this gets accepted, I have some concerns about how to handle the
const char * struct used to print the data. (should I add them in the
iwinfo include?)

 include/iwinfo.h | 14 ++++++++++++++
 iwinfo_cli.c     | 40 +++++++++++++++++++++++++++++++++++++++-
 iwinfo_nl80211.c | 11 +++++++++++
 3 files changed, 64 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/include/iwinfo.h b/include/iwinfo.h
index 5e64294..66df429 100644
--- a/include/iwinfo.h
+++ b/include/iwinfo.h
@@ -170,6 +170,18 @@  struct iwinfo_crypto_entry {
 	uint8_t auth_algs;
 };
 
+struct iwinfo_scanlist_ht_chan_entry {
+	uint8_t primary_chan;
+	uint8_t secondary_chan_off;
+	uint8_t chan_width;
+};
+
+struct iwinfo_scanlist_vht_chan_entry {
+	uint8_t chan_width;
+	uint8_t center_chan_1;
+	uint8_t center_chan_2;
+};
+
 struct iwinfo_scanlist_entry {
 	uint8_t mac[6];
 	char ssid[IWINFO_ESSID_MAX_SIZE+1];
@@ -179,6 +191,8 @@  struct iwinfo_scanlist_entry {
 	uint8_t quality;
 	uint8_t quality_max;
 	struct iwinfo_crypto_entry crypto;
+	struct iwinfo_scanlist_ht_chan_entry ht_chan_info;
+	struct iwinfo_scanlist_vht_chan_entry vht_chan_info;
 };
 
 struct iwinfo_country_entry {
diff --git a/iwinfo_cli.c b/iwinfo_cli.c
index 0332bc2..0037b1f 100644
--- a/iwinfo_cli.c
+++ b/iwinfo_cli.c
@@ -585,6 +585,25 @@  static void print_scanlist(const struct iwinfo_ops *iw, const char *ifname)
 	char buf[IWINFO_BUFSIZE];
 	struct iwinfo_scanlist_entry *e;
 
+	const char *ht_secondary_offset[4] = {
+		"no secondary",
+		"above",
+		"[reserved!]",
+		"below",
+	};
+
+	const char *ht_chan_width[2] = {
+		"20 MHz",
+		"any",
+	};
+
+	const char *vht_chan_width[] = {
+		[0] = "20 or 40 MHz",
+		[1] = "80 MHz",
+		[3] = "80+80 MHz",
+		[2] = "160 MHz",
+	};
+
 	if (iw->scanlist(ifname, buf, &len))
 	{
 		printf("Scanning not possible\n\n");
@@ -612,8 +631,27 @@  static void print_scanlist(const struct iwinfo_ops *iw, const char *ifname)
 			format_signal(e->signal - 0x100),
 			format_quality(e->quality),
 			format_quality_max(e->quality_max));
-		printf("          Encryption: %s\n\n",
+		printf("          Encryption: %s\n",
 			format_encryption(&e->crypto));
+		printf("          HT Operation:\n");
+		printf("                    Primary Channel: %d\n",
+		       e->ht_chan_info.primary_chan);
+		printf("                    Secondary Channel Offset: %s\n",
+		       ht_secondary_offset[e->ht_chan_info.secondary_chan_off]);
+		printf("                    Channel Width: %s\n",
+		       ht_chan_width[e->ht_chan_info.chan_width]);
+
+		if (e->vht_chan_info.center_chan_1) {
+		  printf("          VHT Operation:\n");
+		  printf("                    Channel Width: %s\n",
+			 vht_chan_width[e->vht_chan_info.chan_width]);
+		  printf("                    Center Frequency 1: %d\n",
+			 e->vht_chan_info.center_chan_1);
+		  printf("                    Center Frequency 2: %d\n",
+			 e->vht_chan_info.center_chan_2);
+		}
+
+		printf("\n");
 	}
 }
 
diff --git a/iwinfo_nl80211.c b/iwinfo_nl80211.c
index 2b2a043..e86bf56 100644
--- a/iwinfo_nl80211.c
+++ b/iwinfo_nl80211.c
@@ -2306,6 +2308,16 @@  static void nl80211_get_scanlist_ie(struct nlattr **bss,
 				iwinfo_parse_rsn(&e->crypto, ie + 6, ie[1] - 4,
 				                 IWINFO_CIPHER_TKIP, IWINFO_KMGMT_PSK);
 			break;
+		case 61: /* HT oeration */
+			e->ht_chan_info.primary_chan = ie[2];
+			e->ht_chan_info.secondary_chan_off = ie[3] & 0x3;
+			e->ht_chan_info.chan_width = (ie[4] & 0x4)>>2;
+			break;
+		case 192: /* VHT operation */
+			e->vht_chan_info.chan_width = ie[2];
+			e->vht_chan_info.center_chan_1 = ie[3];
+			e->vht_chan_info.center_chan_2 = ie[4];
+			break;
 		}
 
 		ielen -= ie[1] + 2;