Commit a79f9b9a authored by Bruno Randolf's avatar Bruno Randolf

Get channel width from IE and show for each node

parent 9e5efc1c
......@@ -2,7 +2,6 @@ TODO:
-----
* extend network protocol for new chan and filters
* calculate available bandwidth for info bars (Usage%) based on channel width
* Detect 802.11n and 802.11ac and respective channel widths (40, 80 160)
Later:
......
......@@ -106,7 +106,7 @@ static int get_center_freq_vht(unsigned int freq, enum chan_width width) {
const char* channel_get_width_string(enum chan_width w) {
switch (w) {
case CHAN_WIDTH_UNSPEC: return "Unspecified";
case CHAN_WIDTH_UNSPEC: return "";
case CHAN_WIDTH_20: return "HT20";
case CHAN_WIDTH_40: return "HT40";
case CHAN_WIDTH_80: return "VHT80";
......@@ -118,7 +118,7 @@ const char* channel_get_width_string(enum chan_width w) {
const char* channel_get_width_string_short(enum chan_width w, bool ht40p) {
switch (w) {
case CHAN_WIDTH_UNSPEC: return "UNS";
case CHAN_WIDTH_UNSPEC: return "";
case CHAN_WIDTH_20: return "20";
case CHAN_WIDTH_40: return ht40p ? "40+" : "40-";
case CHAN_WIDTH_80: return "80";
......
......@@ -239,7 +239,8 @@ update_status_win(struct packet_info* p)
#define COL_RATE COL_SIG + 4
#define COL_SOURCE COL_RATE + 4
#define COL_MODE COL_SOURCE + 18
#define COL_ENC COL_MODE + 9
#define COL_WIDTH COL_MODE + 9
#define COL_ENC COL_WIDTH + 9
#define COL_ESSID COL_ENC + 6
#define COL_INFO COL_ESSID + 13
......@@ -274,6 +275,11 @@ print_node_list_line(int line, struct node_info* n)
mvwprintw(list_win, line, COL_RATE, "%3d", p->phy_rate/10);
mvwprintw(list_win, line, COL_SOURCE, "%-17s", mac_name_lookup(p->wlan_src, 0));
mvwprintw(list_win, line, COL_WIDTH, "%-2s %s",
get_80211std(n->wlan_chan_width, n->wlan_channel),
channel_get_width_string_short(n->wlan_chan_width, n->wlan_ht40plus));
wmove(list_win, line, COL_MODE-1);
if (n->wlan_mode & WLAN_MODE_AP) {
wprintw(list_win, " AP");
if (n->essid != NULL)
......@@ -345,6 +351,7 @@ update_node_list_win(void)
mvwprintw(list_win, 0, COL_RATE, "RAT");
mvwprintw(list_win, 0, COL_SOURCE, "TRANSMITTER");
mvwprintw(list_win, 0, COL_MODE, "MODE");
mvwprintw(list_win, 0, COL_WIDTH, "ST-BW");
mvwprintw(list_win, 0, COL_ENC, "ENCR");
mvwprintw(list_win, 0, COL_ESSID, "ESSID");
mvwprintw(list_win, 0, COL_INFO, "INFO");
......
......@@ -35,6 +35,7 @@
#include "ifctrl.h"
#include "main.h"
#include "wlan_util.h"
#include "ieee80211_util.h"
#ifndef NL80211_GENL_NAME
......@@ -402,19 +403,7 @@ static int nl80211_get_freqlist_cb(struct nl_msg *msg, void *arg)
if (bands[NL80211_BAND_ATTR_VHT_CAPA]) {
u_int32_t vht = nla_get_u32(bands[NL80211_BAND_ATTR_VHT_CAPA]);
switch (((vht & WLAN_IE_VHT_CAPAB_INFO_CHAN_WIDTH) >> 2)) {
case WLAN_IE_VHT_CAPAB_INFO_CHAN_WIDTH_80:
list->band[b].max_chan_width = CHAN_WIDTH_80;
break;
case WLAN_IE_VHT_CAPAB_INFO_CHAN_WIDTH_160:
list->band[b].max_chan_width = CHAN_WIDTH_160;
break;
case WLAN_IE_VHT_CAPAB_INFO_CHAN_WIDTH_BOTH:
list->band[b].max_chan_width = CHAN_WIDTH_8080;
break;
case 3:
printf("(reserved)\n");
}
list->band[b].max_chan_width = chan_width_from_vht_capab(vht);
}
nla_for_each_nested(freq, bands[NL80211_BAND_ATTR_FREQS], freqs_remain)
......
......@@ -119,6 +119,7 @@ struct packet_info {
unsigned int wlan_bintval; /* beacon interval */
unsigned int wlan_mode; /* AP, STA or IBSS */
unsigned char wlan_channel; /* channel from beacon, probe */
enum chan_width wlan_chan_width;
unsigned char wlan_qos_class; /* for QDATA frames */
unsigned int wlan_nav; /* frame NAV duration */
unsigned int wlan_seqno; /* sequence number */
......@@ -128,7 +129,7 @@ struct packet_info {
wlan_retry:1,
wlan_wpa:1,
wlan_rsn:1,
wlan_vht:1;
wlan_ht40plus:1;
/* batman-adv */
unsigned char bat_version;
......@@ -180,10 +181,13 @@ struct node_info {
unsigned int wlan_seqno;
struct essid_info* essid;
struct node_info* wlan_ap_node;
enum chan_width wlan_chan_width;
unsigned int wlan_wep:1, /* WEP active? */
wlan_wpa:1,
wlan_rsn:1;
wlan_rsn:1,
wlan_ht40plus:1;
/* batman */
unsigned char bat_gw:1;
......
......@@ -52,6 +52,8 @@ copy_nodeinfo(struct node_info* n, struct packet_info* p)
n->olsr_count++;
if (p->bat_gw)
n->bat_gw = 1;
if (p->wlan_ht40plus)
n->wlan_ht40plus = 1;
if (p->wlan_bssid[0] != 0xff &&
!(p->wlan_bssid[0] == 0 && p->wlan_bssid[1] == 0 &&
p->wlan_bssid[2] == 0 && p->wlan_bssid[3] == 0 &&
......@@ -117,6 +119,9 @@ copy_nodeinfo(struct node_info* n, struct packet_info* p)
n->wlan_retries_last = 0;
n->wlan_seqno = p->wlan_seqno;
}
if (p->wlan_chan_width > n->wlan_chan_width)
n->wlan_chan_width = p->wlan_chan_width;
}
......
......@@ -317,11 +317,35 @@ wlan_parse_information_elements(unsigned char *buf, int len, struct packet_info
p->wlan_rsn = 1;
break;
case WLAN_IE_ID_VHT_CAPAB:
case WLAN_IE_ID_HT_CAPAB:
DEBUG("HT %d %x\n", ie->len, ie->var[0]);
if (ie->var[0] & WLAN_IE_HT_CAPAB_INFO_CHAN_WIDTH_40)
p->wlan_chan_width = CHAN_WIDTH_40;
else
p->wlan_chan_width = CHAN_WIDTH_20;
break;
case WLAN_IE_ID_HT_OPER:
DEBUG("HT OPER %d %x\n", ie->len, ie->var[0]);
if (ie->len > 1) {
switch (ie->var[1] & WLAN_IE_HT_OPER_INFO_CHAN_OFFSET) {
case 0: p->wlan_chan_width = CHAN_WIDTH_20; break;
case 1: p->wlan_ht40plus = true; break;
case 3: p->wlan_ht40plus = false; break;
default: DEBUG("HT OPER wrong?"); break;
}
}
break;
case WLAN_IE_ID_VHT_OPER:
case WLAN_IE_ID_VHT_OMN:
DEBUG("VHT\n");
p->wlan_vht = 1;
DEBUG("VHT OPER %d %x\n", ie->len, ie->var[0]);
p->wlan_chan_width = CHAN_WIDTH_80; /* minimum, otherwise not AC */
break;
case WLAN_IE_ID_VHT_CAPAB:
DEBUG("VHT %d %x\n", ie->len, ie->var[0]);
p->wlan_chan_width = chan_width_from_vht_capab(ie->var[0]);
break;
case WLAN_IE_ID_VENDOR:
......
......@@ -176,6 +176,7 @@ struct information_element {
#define WLAN_IE_ID_DSSS_PARAM 3
#define WLAN_IE_ID_HT_CAPAB 45
#define WLAN_IE_ID_RSN 48
#define WLAN_IE_ID_HT_OPER 61
#define WLAN_IE_ID_VHT_CAPAB 191
#define WLAN_IE_ID_VHT_OPER 192
#define WLAN_IE_ID_VHT_OMN 199
......@@ -185,6 +186,8 @@ struct information_element {
// present in Beacon, Assoc Req/Resp, Reassoc Req/Resp, Probe Req/Resp, Mesh Peering Open/Close
#define WLAN_IE_HT_CAPAB_INFO_CHAN_WIDTH_40 0x0002
#define WLAN_IE_HT_OPER_INFO_CHAN_OFFSET 0x0003
/* VHT capability info */
#define WLAN_IE_VHT_CAPAB_INFO_CHAN_WIDTH 0x0000000c
#define WLAN_IE_VHT_CAPAB_INFO_CHAN_WIDTH_80 0 /* 80MHz only */
......
......@@ -195,3 +195,28 @@ mcs_index_to_rate(int mcs, int ht20, int lgi)
}
return 0;
}
enum chan_width chan_width_from_vht_capab(u_int32_t vht) {
switch (((vht & WLAN_IE_VHT_CAPAB_INFO_CHAN_WIDTH) >> 2)) {
case WLAN_IE_VHT_CAPAB_INFO_CHAN_WIDTH_80: return CHAN_WIDTH_80;
case WLAN_IE_VHT_CAPAB_INFO_CHAN_WIDTH_160: return CHAN_WIDTH_160;
case WLAN_IE_VHT_CAPAB_INFO_CHAN_WIDTH_BOTH: return CHAN_WIDTH_8080;
default: printf("(reserved)\n"); return CHAN_WIDTH_UNSPEC;
}
}
const char* get_80211std(enum chan_width width, int chan) {
switch (width) {
case CHAN_WIDTH_UNSPEC:
return chan > 14 ? "A" : "BG";
case CHAN_WIDTH_20:
case CHAN_WIDTH_40:
return "N";
case CHAN_WIDTH_80:
case CHAN_WIDTH_160:
case CHAN_WIDTH_8080:
return "AC";
default:
return "?";
}
}
......@@ -51,4 +51,9 @@ rate_index_to_rate(int idx);
int
mcs_index_to_rate(int mcs, int ht20, int lgi);
enum chan_width
chan_width_from_vht_capab(u_int32_t vht);
const char* get_80211std(enum chan_width width, int chan);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment