iwinfo: add support for querying available HT modes
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
This commit is contained in:
parent
9842d2507f
commit
7b39bee1c6
8 changed files with 186 additions and 12 deletions
|
@ -66,6 +66,21 @@ enum iwinfo_opmode {
|
|||
extern const char *IWINFO_OPMODE_NAMES[];
|
||||
|
||||
|
||||
enum iwinfo_htmode {
|
||||
IWINFO_HTMODE_HT20 = (1 << 0),
|
||||
IWINFO_HTMODE_HT40 = (1 << 1),
|
||||
IWINFO_HTMODE_VHT20 = (1 << 2),
|
||||
IWINFO_HTMODE_VHT40 = (1 << 3),
|
||||
IWINFO_HTMODE_VHT80 = (1 << 4),
|
||||
IWINFO_HTMODE_VHT80_80 = (1 << 5),
|
||||
IWINFO_HTMODE_VHT160 = (1 << 6),
|
||||
|
||||
IWINFO_HTMODE_COUNT = 7
|
||||
};
|
||||
|
||||
extern const char *IWINFO_HTMODE_NAMES[IWINFO_HTMODE_COUNT];
|
||||
|
||||
|
||||
struct iwinfo_rate_entry {
|
||||
uint32_t rate;
|
||||
int8_t mcs;
|
||||
|
@ -165,6 +180,7 @@ struct iwinfo_ops {
|
|||
int (*quality_max)(const char *, int *);
|
||||
int (*mbssid_support)(const char *, int *);
|
||||
int (*hwmodelist)(const char *, int *);
|
||||
int (*htmodelist)(const char *, int *);
|
||||
int (*ssid)(const char *, char *);
|
||||
int (*bssid)(const char *, char *);
|
||||
int (*country)(const char *, char *);
|
||||
|
|
22
iwinfo_cli.c
22
iwinfo_cli.c
|
@ -744,6 +744,23 @@ static void print_countrylist(const struct iwinfo_ops *iw, const char *ifname)
|
|||
}
|
||||
}
|
||||
|
||||
static void print_htmodelist(const struct iwinfo_ops *iw, const char *ifname)
|
||||
{
|
||||
int i, htmodes = 0;
|
||||
|
||||
if (iw->htmodelist(ifname, &htmodes))
|
||||
{
|
||||
printf("No HT mode information available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(IWINFO_HTMODE_NAMES); i++)
|
||||
if (htmodes & (1 << i))
|
||||
printf("%s ", IWINFO_HTMODE_NAMES[i]);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void lookup_phy(const struct iwinfo_ops *iw, const char *section)
|
||||
{
|
||||
char buf[IWINFO_BUFSIZE];
|
||||
|
@ -781,6 +798,7 @@ int main(int argc, char **argv)
|
|||
" iwinfo <device> freqlist\n"
|
||||
" iwinfo <device> assoclist\n"
|
||||
" iwinfo <device> countrylist\n"
|
||||
" iwinfo <device> htmodelist\n"
|
||||
" iwinfo <backend> phyname <section>\n"
|
||||
);
|
||||
|
||||
|
@ -873,6 +891,10 @@ int main(int argc, char **argv)
|
|||
print_countrylist(iw, argv[1]);
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
print_htmodelist(iw, argv[1]);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Unknown command: %s\n", argv[i]);
|
||||
rv = 1;
|
||||
|
|
10
iwinfo_lib.c
10
iwinfo_lib.c
|
@ -57,6 +57,16 @@ const char *IWINFO_OPMODE_NAMES[] = {
|
|||
"P2P Go",
|
||||
};
|
||||
|
||||
const char *IWINFO_HTMODE_NAMES[] = {
|
||||
"HT20",
|
||||
"HT40",
|
||||
"VHT20",
|
||||
"VHT40",
|
||||
"VHT80",
|
||||
"VHT80+80",
|
||||
"VHT160",
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* ISO3166 country labels
|
||||
|
|
31
iwinfo_lua.c
31
iwinfo_lua.c
|
@ -509,6 +509,29 @@ static int iwinfo_L_hwmodelist(lua_State *L, int (*func)(const char *, int *))
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Wrapper for htmode list */
|
||||
static int iwinfo_L_htmodelist(lua_State *L, int (*func)(const char *, int *))
|
||||
{
|
||||
const char *ifname = luaL_checkstring(L, 1);
|
||||
int i, htmodes = 0;
|
||||
|
||||
if (!(*func)(ifname, &htmodes))
|
||||
{
|
||||
lua_newtable(L);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(IWINFO_HTMODE_NAMES); i++)
|
||||
{
|
||||
lua_pushboolean(L, htmodes & (1 << i));
|
||||
lua_setfield(L, -2, IWINFO_HTMODE_NAMES[i]);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Wrapper for mbssid_support */
|
||||
static int iwinfo_L_mbssid_support(lua_State *L, int (*func)(const char *, int *))
|
||||
{
|
||||
|
@ -636,6 +659,7 @@ LUA_WRAP_STRUCT_OP(wl,scanlist)
|
|||
LUA_WRAP_STRUCT_OP(wl,freqlist)
|
||||
LUA_WRAP_STRUCT_OP(wl,countrylist)
|
||||
LUA_WRAP_STRUCT_OP(wl,hwmodelist)
|
||||
LUA_WRAP_STRUCT_OP(wl,htmodelist)
|
||||
LUA_WRAP_STRUCT_OP(wl,encryption)
|
||||
LUA_WRAP_STRUCT_OP(wl,mbssid_support)
|
||||
LUA_WRAP_STRUCT_OP(wl,hardware_id)
|
||||
|
@ -665,6 +689,7 @@ LUA_WRAP_STRUCT_OP(madwifi,scanlist)
|
|||
LUA_WRAP_STRUCT_OP(madwifi,freqlist)
|
||||
LUA_WRAP_STRUCT_OP(madwifi,countrylist)
|
||||
LUA_WRAP_STRUCT_OP(madwifi,hwmodelist)
|
||||
LUA_WRAP_STRUCT_OP(madwifi,htmodelist)
|
||||
LUA_WRAP_STRUCT_OP(madwifi,encryption)
|
||||
LUA_WRAP_STRUCT_OP(madwifi,mbssid_support)
|
||||
LUA_WRAP_STRUCT_OP(madwifi,hardware_id)
|
||||
|
@ -694,6 +719,7 @@ LUA_WRAP_STRUCT_OP(nl80211,scanlist)
|
|||
LUA_WRAP_STRUCT_OP(nl80211,freqlist)
|
||||
LUA_WRAP_STRUCT_OP(nl80211,countrylist)
|
||||
LUA_WRAP_STRUCT_OP(nl80211,hwmodelist)
|
||||
LUA_WRAP_STRUCT_OP(nl80211,htmodelist)
|
||||
LUA_WRAP_STRUCT_OP(nl80211,encryption)
|
||||
LUA_WRAP_STRUCT_OP(nl80211,mbssid_support)
|
||||
LUA_WRAP_STRUCT_OP(nl80211,hardware_id)
|
||||
|
@ -722,6 +748,7 @@ LUA_WRAP_STRUCT_OP(wext,scanlist)
|
|||
LUA_WRAP_STRUCT_OP(wext,freqlist)
|
||||
LUA_WRAP_STRUCT_OP(wext,countrylist)
|
||||
LUA_WRAP_STRUCT_OP(wext,hwmodelist)
|
||||
LUA_WRAP_STRUCT_OP(wext,htmodelist)
|
||||
LUA_WRAP_STRUCT_OP(wext,encryption)
|
||||
LUA_WRAP_STRUCT_OP(wext,mbssid_support)
|
||||
LUA_WRAP_STRUCT_OP(wext,hardware_id)
|
||||
|
@ -749,6 +776,7 @@ static const luaL_reg R_wl[] = {
|
|||
LUA_REG(wl,freqlist),
|
||||
LUA_REG(wl,countrylist),
|
||||
LUA_REG(wl,hwmodelist),
|
||||
LUA_REG(wl,htmodelist),
|
||||
LUA_REG(wl,encryption),
|
||||
LUA_REG(wl,mbssid_support),
|
||||
LUA_REG(wl,hardware_id),
|
||||
|
@ -781,6 +809,7 @@ static const luaL_reg R_madwifi[] = {
|
|||
LUA_REG(madwifi,freqlist),
|
||||
LUA_REG(madwifi,countrylist),
|
||||
LUA_REG(madwifi,hwmodelist),
|
||||
LUA_REG(madwifi,htmodelist),
|
||||
LUA_REG(madwifi,encryption),
|
||||
LUA_REG(madwifi,mbssid_support),
|
||||
LUA_REG(madwifi,hardware_id),
|
||||
|
@ -813,6 +842,7 @@ static const luaL_reg R_nl80211[] = {
|
|||
LUA_REG(nl80211,freqlist),
|
||||
LUA_REG(nl80211,countrylist),
|
||||
LUA_REG(nl80211,hwmodelist),
|
||||
LUA_REG(nl80211,htmodelist),
|
||||
LUA_REG(nl80211,encryption),
|
||||
LUA_REG(nl80211,mbssid_support),
|
||||
LUA_REG(nl80211,hardware_id),
|
||||
|
@ -844,6 +874,7 @@ static const luaL_reg R_wext[] = {
|
|||
LUA_REG(wext,freqlist),
|
||||
LUA_REG(wext,countrylist),
|
||||
LUA_REG(wext,hwmodelist),
|
||||
LUA_REG(wext,htmodelist),
|
||||
LUA_REG(wext,encryption),
|
||||
LUA_REG(wext,mbssid_support),
|
||||
LUA_REG(wext,hardware_id),
|
||||
|
|
|
@ -1024,6 +1024,12 @@ static int madwifi_get_hwmodelist(const char *ifname, int *buf)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int madwifi_get_htmodelist(const char *ifname, int *buf)
|
||||
{
|
||||
/* OpenWrt's madwifi did never support any HT rates */
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int madwifi_get_mbssid_support(const char *ifname, int *buf)
|
||||
{
|
||||
/* Test whether we can create another interface */
|
||||
|
@ -1116,6 +1122,7 @@ const struct iwinfo_ops madwifi_ops = {
|
|||
.quality_max = madwifi_get_quality_max,
|
||||
.mbssid_support = madwifi_get_mbssid_support,
|
||||
.hwmodelist = madwifi_get_hwmodelist,
|
||||
.htmodelist = madwifi_get_htmodelist,
|
||||
.mode = madwifi_get_mode,
|
||||
.ssid = madwifi_get_ssid,
|
||||
.bssid = madwifi_get_bssid,
|
||||
|
|
|
@ -2355,9 +2355,17 @@ static int nl80211_get_countrylist(const char *ifname, char *buf, int *len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int nl80211_get_hwmodelist_cb(struct nl_msg *msg, void *arg)
|
||||
|
||||
struct nl80211_modes
|
||||
{
|
||||
int *modes = arg;
|
||||
bool ok;
|
||||
uint32_t hw;
|
||||
uint32_t ht;
|
||||
};
|
||||
|
||||
static int nl80211_get_modelist_cb(struct nl_msg *msg, void *arg)
|
||||
{
|
||||
struct nl80211_modes *m = arg;
|
||||
int bands_remain, freqs_remain;
|
||||
uint16_t caps = 0;
|
||||
uint32_t vht_caps = 0;
|
||||
|
@ -2366,8 +2374,6 @@ static int nl80211_get_hwmodelist_cb(struct nl_msg *msg, void *arg)
|
|||
struct nlattr *freqs[NL80211_FREQUENCY_ATTR_MAX + 1];
|
||||
struct nlattr *band, *freq;
|
||||
|
||||
*modes = 0;
|
||||
|
||||
if (attr[NL80211_ATTR_WIPHY_BANDS])
|
||||
{
|
||||
nla_for_each_nested(band, attr[NL80211_ATTR_WIPHY_BANDS], bands_remain)
|
||||
|
@ -2380,7 +2386,13 @@ static int nl80211_get_hwmodelist_cb(struct nl_msg *msg, void *arg)
|
|||
|
||||
/* Treat any nonzero capability as 11n */
|
||||
if (caps > 0)
|
||||
*modes |= IWINFO_80211_N;
|
||||
{
|
||||
m->hw |= IWINFO_80211_N;
|
||||
m->ht |= IWINFO_HTMODE_HT20;
|
||||
|
||||
if (caps & (1 << 1))
|
||||
m->ht |= IWINFO_HTMODE_HT40;
|
||||
}
|
||||
|
||||
nla_for_each_nested(freq, bands[NL80211_BAND_ATTR_FREQS],
|
||||
freqs_remain)
|
||||
|
@ -2393,8 +2405,8 @@ static int nl80211_get_hwmodelist_cb(struct nl_msg *msg, void *arg)
|
|||
|
||||
if (nla_get_u32(freqs[NL80211_FREQUENCY_ATTR_FREQ]) < 2485)
|
||||
{
|
||||
*modes |= IWINFO_80211_B;
|
||||
*modes |= IWINFO_80211_G;
|
||||
m->hw |= IWINFO_80211_B;
|
||||
m->hw |= IWINFO_80211_G;
|
||||
}
|
||||
else if (bands[NL80211_BAND_ATTR_VHT_CAPA])
|
||||
{
|
||||
|
@ -2402,14 +2414,29 @@ static int nl80211_get_hwmodelist_cb(struct nl_msg *msg, void *arg)
|
|||
|
||||
/* Treat any nonzero capability as 11ac */
|
||||
if (vht_caps > 0)
|
||||
*modes |= IWINFO_80211_AC;
|
||||
{
|
||||
m->hw |= IWINFO_80211_AC;
|
||||
m->ht |= IWINFO_HTMODE_VHT20 | IWINFO_HTMODE_VHT40 | IWINFO_HTMODE_VHT80;
|
||||
|
||||
switch ((vht_caps >> 2) & 3)
|
||||
{
|
||||
case 2:
|
||||
m->ht |= IWINFO_HTMODE_VHT80_80;
|
||||
/* fall through */
|
||||
|
||||
case 1:
|
||||
m->ht |= IWINFO_HTMODE_VHT160;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!(*modes & IWINFO_80211_AC))
|
||||
else if (!(m->hw & IWINFO_80211_AC))
|
||||
{
|
||||
*modes |= IWINFO_80211_A;
|
||||
m->hw |= IWINFO_80211_A;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m->ok = 1;
|
||||
}
|
||||
|
||||
return NL_SKIP;
|
||||
|
@ -2418,17 +2445,46 @@ static int nl80211_get_hwmodelist_cb(struct nl_msg *msg, void *arg)
|
|||
static int nl80211_get_hwmodelist(const char *ifname, int *buf)
|
||||
{
|
||||
struct nl80211_msg_conveyor *req;
|
||||
struct nl80211_modes m = { };
|
||||
|
||||
req = nl80211_msg(ifname, NL80211_CMD_GET_WIPHY, 0);
|
||||
if (req)
|
||||
{
|
||||
nl80211_send(req, nl80211_get_hwmodelist_cb, buf);
|
||||
nl80211_send(req, nl80211_get_modelist_cb, &m);
|
||||
nl80211_free(req);
|
||||
}
|
||||
|
||||
return *buf ? 0 : -1;
|
||||
if (m.ok)
|
||||
{
|
||||
*buf = m.hw;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int nl80211_get_htmodelist(const char *ifname, int *buf)
|
||||
{
|
||||
struct nl80211_msg_conveyor *req;
|
||||
struct nl80211_modes m = { };
|
||||
|
||||
req = nl80211_msg(ifname, NL80211_CMD_GET_WIPHY, 0);
|
||||
if (req)
|
||||
{
|
||||
nl80211_send(req, nl80211_get_modelist_cb, &m);
|
||||
nl80211_free(req);
|
||||
}
|
||||
|
||||
if (m.ok)
|
||||
{
|
||||
*buf = m.ht;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int nl80211_get_ifcomb_cb(struct nl_msg *msg, void *arg)
|
||||
{
|
||||
struct nlattr **attr = nl80211_parse(msg);
|
||||
|
@ -2601,6 +2657,7 @@ const struct iwinfo_ops nl80211_ops = {
|
|||
.quality_max = nl80211_get_quality_max,
|
||||
.mbssid_support = nl80211_get_mbssid_support,
|
||||
.hwmodelist = nl80211_get_hwmodelist,
|
||||
.htmodelist = nl80211_get_htmodelist,
|
||||
.mode = nl80211_get_mode,
|
||||
.ssid = nl80211_get_ssid,
|
||||
.bssid = nl80211_get_bssid,
|
||||
|
|
|
@ -440,6 +440,12 @@ static int wext_get_hwmodelist(const char *ifname, int *buf)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int wext_get_htmodelist(const char *ifname, int *buf)
|
||||
{
|
||||
/* Stub */
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int wext_get_encryption(const char *ifname, char *buf)
|
||||
{
|
||||
/* No reliable crypto info in wext */
|
||||
|
@ -541,6 +547,7 @@ const struct iwinfo_ops wext_ops = {
|
|||
.quality_max = wext_get_quality_max,
|
||||
.mbssid_support = wext_get_mbssid_support,
|
||||
.hwmodelist = wext_get_hwmodelist,
|
||||
.htmodelist = wext_get_htmodelist,
|
||||
.mode = wext_get_mode,
|
||||
.ssid = wext_get_ssid,
|
||||
.bssid = wext_get_bssid,
|
||||
|
|
24
iwinfo_wl.c
24
iwinfo_wl.c
|
@ -630,6 +630,29 @@ static int wl_get_hwmodelist(const char *ifname, int *buf)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int wl_get_htmodelist(const char *ifname, int *buf)
|
||||
{
|
||||
int modes;
|
||||
|
||||
if (!wl_get_hwmodelist(ifname, &modes))
|
||||
{
|
||||
*buf = 0;
|
||||
|
||||
/* FIXME: determine real capabilities */
|
||||
|
||||
if (modes & IWINFO_80211_N)
|
||||
*buf |= IWINFO_HTMODE_HT20 | IWINFO_HTMODE_HT40;
|
||||
|
||||
if (modes & IWINFO_80211_AC)
|
||||
*buf |= IWINFO_HTMODE_VHT20 | IWINFO_HTMODE_VHT40 |
|
||||
IWINFO_HTMODE_VHT80;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int wl_get_mbssid_support(const char *ifname, int *buf)
|
||||
{
|
||||
wlc_rev_info_t revinfo;
|
||||
|
@ -715,6 +738,7 @@ const struct iwinfo_ops wl_ops = {
|
|||
.quality_max = wl_get_quality_max,
|
||||
.mbssid_support = wl_get_mbssid_support,
|
||||
.hwmodelist = wl_get_hwmodelist,
|
||||
.htmodelist = wl_get_htmodelist,
|
||||
.mode = wl_get_mode,
|
||||
.ssid = wl_get_ssid,
|
||||
.bssid = wl_get_bssid,
|
||||
|
|
Loading…
Reference in a new issue