libiwinfo: implement hwmodelist()
authorJo-Philipp Wich <jow@openwrt.org>
Tue, 19 Oct 2010 20:58:48 +0000 (20:58 +0000)
committerJo-Philipp Wich <jow@openwrt.org>
Tue, 19 Oct 2010 20:58:48 +0000 (20:58 +0000)
12 files changed:
contrib/package/iwinfo/Makefile
contrib/package/iwinfo/src/iwinfo.h
contrib/package/iwinfo/src/iwinfo.lua
contrib/package/iwinfo/src/iwinfo_lualib.c
contrib/package/iwinfo/src/iwinfo_madwifi.c
contrib/package/iwinfo/src/iwinfo_madwifi.h
contrib/package/iwinfo/src/iwinfo_nl80211.c
contrib/package/iwinfo/src/iwinfo_nl80211.h
contrib/package/iwinfo/src/iwinfo_wext.c
contrib/package/iwinfo/src/iwinfo_wext.h
contrib/package/iwinfo/src/iwinfo_wl.c
contrib/package/iwinfo/src/iwinfo_wl.h

index e7e16f6..ddfcbeb 100644 (file)
@@ -7,7 +7,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libiwinfo
-PKG_RELEASE:=6
+PKG_RELEASE:=7
 
 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
 
index 6d05289..a9889bd 100644 (file)
 
 #define IWINFO_BUFSIZE 24 * 1024
 
+#define IWINFO_80211_A       (1 << 0)
+#define IWINFO_80211_B       (1 << 1)
+#define IWINFO_80211_G       (1 << 2)
+#define IWINFO_80211_N       (1 << 3)
+
 #define IWINFO_CIPHER_NONE   (1 << 0)
 #define IWINFO_CIPHER_WEP40  (1 << 1)
 #define IWINFO_CIPHER_TKIP   (1 << 2)
index 76b9e4a..1de43fa 100755 (executable)
@@ -26,14 +26,31 @@ function print_info(api, dev)
        local iw = iwinfo[api]
        local enc = iw.encryption(dev)
 
-       printf("%-9s Type: %s  ESSID: \"%s\"",
-               dev, api, s(iw.ssid(dev)))
+       local function hwmode()
+               local m = iw.hwmodelist(dev)
+               if m then
+                       local s = "802.11"
+                       if m.a then s = s.."a" end
+                       if m.b then s = s.."b" end
+                       if m.g then s = s.."g" end
+                       if m.n then s = s.."n" end
+                       return s
+               else
+                       return "?"
+               end
+       end
+
+       printf("%-9s ESSID: \"%s\"",
+               dev, s(iw.ssid(dev)))
 
        printf("          Access Point: %s",
                s(iw.bssid(dev)))
 
+       printf("          Type: %s  HW Mode(s): %s",
+               api, hwmode())
+
        printf("          Mode: %s  Channel: %d (%.3f GHz)",
-               iw.mode(dev), n(iw.channel(dev)), n(iw.frequency(dev)) / 1000)
+               s(iw.mode(dev)), n(iw.channel(dev)), n(iw.frequency(dev)) / 1000)
 
        printf("          Tx-Power: %s dBm  Link Quality: %s/%s",
                s(iw.txpower(dev)), s(iw.quality(dev)), s(iw.quality_max(dev)))
index 95600c8..c87e559 100644 (file)
@@ -697,6 +697,34 @@ static int iwinfo_L_encryption(lua_State *L, int (*func)(const char *, char *))
        return 0;
 }
 
+/* Wrapper for hwmode list */
+static int iwinfo_L_hwmodelist(lua_State *L, int (*func)(const char*, int *))
+{
+       const char *ifname = luaL_checkstring(L, 1);
+       int hwmodes = 0;
+
+       if( !(*func)(ifname, &hwmodes) )
+       {
+               lua_newtable(L);
+
+               lua_pushboolean(L, hwmodes & IWINFO_80211_A);
+               lua_setfield(L, -2, "a");
+
+               lua_pushboolean(L, hwmodes & IWINFO_80211_B);
+               lua_setfield(L, -2, "b");
+
+               lua_pushboolean(L, hwmodes & IWINFO_80211_G);
+               lua_setfield(L, -2, "g");
+
+               lua_pushboolean(L, hwmodes & IWINFO_80211_N);
+               lua_setfield(L, -2, "n");
+
+               return 1;
+       }
+
+       return 0;
+}
+
 /* Wrapper for country list */
 static char * iwinfo_L_country_lookup(char *buf, int len, int iso3166)
 {
@@ -774,6 +802,7 @@ LUA_WRAP_LIST(wl,txpwrlist)
 LUA_WRAP_LIST(wl,scanlist)
 LUA_WRAP_LIST(wl,freqlist)
 LUA_WRAP_LIST(wl,countrylist)
+LUA_WRAP_LIST(wl,hwmodelist)
 LUA_WRAP_LIST(wl,encryption)
 #endif
 
@@ -797,6 +826,7 @@ LUA_WRAP_LIST(madwifi,txpwrlist)
 LUA_WRAP_LIST(madwifi,scanlist)
 LUA_WRAP_LIST(madwifi,freqlist)
 LUA_WRAP_LIST(madwifi,countrylist)
+LUA_WRAP_LIST(madwifi,hwmodelist)
 LUA_WRAP_LIST(madwifi,encryption)
 #endif
 
@@ -820,6 +850,7 @@ LUA_WRAP_LIST(nl80211,txpwrlist)
 LUA_WRAP_LIST(nl80211,scanlist)
 LUA_WRAP_LIST(nl80211,freqlist)
 LUA_WRAP_LIST(nl80211,countrylist)
+LUA_WRAP_LIST(nl80211,hwmodelist)
 LUA_WRAP_LIST(nl80211,encryption)
 #endif
 
@@ -842,6 +873,7 @@ LUA_WRAP_LIST(wext,txpwrlist)
 LUA_WRAP_LIST(wext,scanlist)
 LUA_WRAP_LIST(wext,freqlist)
 LUA_WRAP_LIST(wext,countrylist)
+LUA_WRAP_LIST(wext,hwmodelist)
 LUA_WRAP_LIST(wext,encryption)
 
 #ifdef USE_WL
@@ -864,6 +896,7 @@ static const luaL_reg R_wl[] = {
        LUA_REG(wl,scanlist),
        LUA_REG(wl,freqlist),
        LUA_REG(wl,countrylist),
+       LUA_REG(wl,hwmodelist),
        LUA_REG(wl,encryption),
        LUA_REG(wl,mbssid_support),
        { NULL, NULL }
@@ -890,6 +923,7 @@ static const luaL_reg R_madwifi[] = {
        LUA_REG(madwifi,scanlist),
        LUA_REG(madwifi,freqlist),
        LUA_REG(madwifi,countrylist),
+       LUA_REG(madwifi,hwmodelist),
        LUA_REG(madwifi,encryption),
        LUA_REG(madwifi,mbssid_support),
        { NULL, NULL }
@@ -916,6 +950,7 @@ static const luaL_reg R_nl80211[] = {
        LUA_REG(nl80211,scanlist),
        LUA_REG(nl80211,freqlist),
        LUA_REG(nl80211,countrylist),
+       LUA_REG(nl80211,hwmodelist),
        LUA_REG(nl80211,encryption),
        LUA_REG(nl80211,mbssid_support),
        { NULL, NULL }
@@ -941,6 +976,7 @@ static const luaL_reg R_wext[] = {
        LUA_REG(wext,scanlist),
        LUA_REG(wext,freqlist),
        LUA_REG(wext,countrylist),
+       LUA_REG(wext,hwmodelist),
        LUA_REG(wext,encryption),
        LUA_REG(wext,mbssid_support),
        { NULL, NULL }
index 5289f42..aad4b42 100644 (file)
@@ -886,6 +886,33 @@ int madwifi_get_countrylist(const char *ifname, char *buf, int *len)
        return 0;
 }
 
+int madwifi_get_hwmodelist(const char *ifname, int *buf)
+{
+       char chans[IWINFO_BUFSIZE] = { 0 };
+       struct iwinfo_freqlist_entry *e = NULL;
+       int len = 0;
+
+       if( !madwifi_get_freqlist(ifname, &chans, &len) )
+       {
+               for( e = (struct iwinfo_freqlist_entry *)chans; e->channel; e++ )
+               {
+                       if( e->channel <= 14 )
+                       {
+                               *buf |= IWINFO_80211_B;
+                               *buf |= IWINFO_80211_G;
+                       }
+                       else
+                       {
+                               *buf |= IWINFO_80211_A;
+                       }
+               }
+
+               return 0;
+       }
+
+       return -1;
+}
+
 int madwifi_get_mbssid_support(const char *ifname, int *buf)
 {
        /* We assume that multi bssid is always possible */
index 7e0129c..b16c36f 100644 (file)
@@ -43,6 +43,7 @@ int madwifi_get_txpwrlist(const char *ifname, char *buf, int *len);
 int madwifi_get_scanlist(const char *ifname, char *buf, int *len);
 int madwifi_get_freqlist(const char *ifname, char *buf, int *len);
 int madwifi_get_countrylist(const char *ifname, char *buf, int *len);
+int madwifi_get_hwmodelist(const char *ifname, int *buf);
 int madwifi_get_mbssid_support(const char *ifname, int *buf);
 void madwifi_close(void);
 
index 6b98023..33013fc 100644 (file)
@@ -1302,7 +1302,6 @@ int nl80211_get_scanlist(const char *ifname, char *buf, int *len)
 
 int nl80211_get_freqlist(const char *ifname, char *buf, int *len)
 {
-       char *phy;
        int count = 0, bands_remain, freqs_remain;
        struct nl80211_msg_conveyor *req, *res;
        struct nlattr *bands[NL80211_BAND_ATTR_MAX + 1];
@@ -1310,15 +1309,6 @@ int nl80211_get_freqlist(const char *ifname, char *buf, int *len)
        struct nlattr *band, *freq;
        struct iwinfo_freqlist_entry *e = (struct iwinfo_freqlist_entry *)buf;
 
-       static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
-               [NL80211_FREQUENCY_ATTR_FREQ]         = { .type = NLA_U32  },
-               [NL80211_FREQUENCY_ATTR_DISABLED]     = { .type = NLA_FLAG },
-               [NL80211_FREQUENCY_ATTR_PASSIVE_SCAN] = { .type = NLA_FLAG },
-               [NL80211_FREQUENCY_ATTR_NO_IBSS]      = { .type = NLA_FLAG },
-               [NL80211_FREQUENCY_ATTR_RADAR]        = { .type = NLA_FLAG },
-               [NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32  },
-       };
-
        req = nl80211_msg(ifname, NL80211_CMD_GET_WIPHY, 0);
        if( req )
        {
@@ -1335,9 +1325,10 @@ int nl80211_get_freqlist(const char *ifname, char *buf, int *len)
                                        bands[NL80211_BAND_ATTR_FREQS], freqs_remain)
                                {
                                        nla_parse(freqs, NL80211_FREQUENCY_ATTR_MAX,
-                                               nla_data(freq), nla_len(freq), freq_policy);
+                                               nla_data(freq), nla_len(freq), NULL);
 
-                                       if( freqs[NL80211_FREQUENCY_ATTR_DISABLED] )
+                                       if( !freqs[NL80211_FREQUENCY_ATTR_FREQ] ||
+                                           freqs[NL80211_FREQUENCY_ATTR_DISABLED] )
                                                continue;
 
                                        e->mhz = nla_get_u32(freqs[NL80211_FREQUENCY_ATTR_FREQ]);
@@ -1408,6 +1399,62 @@ int nl80211_get_countrylist(const char *ifname, char *buf, int *len)
        return 0;
 }
 
+int nl80211_get_hwmodelist(const char *ifname, int *buf)
+{
+       int bands_remain, freqs_remain;
+       struct nl80211_msg_conveyor *req, *res;
+       struct nlattr *bands[NL80211_BAND_ATTR_MAX + 1];
+       struct nlattr *freqs[NL80211_FREQUENCY_ATTR_MAX + 1];
+       struct nlattr *band, *freq;
+       uint16_t caps = 0;
+
+       req = nl80211_msg(ifname, NL80211_CMD_GET_WIPHY, 0);
+       if( req )
+       {
+               res = nl80211_send(req);
+               if( res )
+               {
+                       nla_for_each_nested(band,
+                               res->attr[NL80211_ATTR_WIPHY_BANDS], bands_remain)
+                       {
+                               nla_parse(bands, NL80211_BAND_ATTR_MAX, nla_data(band),
+                                         nla_len(band), NULL);
+
+                               if( bands[NL80211_BAND_ATTR_HT_CAPA] )
+                                       caps = nla_get_u16(bands[NL80211_BAND_ATTR_HT_CAPA]);
+
+                               /* Treat HT20/HT40 as 11n */
+                               if( caps & (1 << 1) )
+                                       *buf |= IWINFO_80211_N;
+
+                               nla_for_each_nested(freq,
+                                       bands[NL80211_BAND_ATTR_FREQS], freqs_remain)
+                               {
+                                       nla_parse(freqs, NL80211_FREQUENCY_ATTR_MAX,
+                                               nla_data(freq), nla_len(freq), NULL);
+
+                                       if( !freqs[NL80211_FREQUENCY_ATTR_FREQ] )
+                                               continue;
+
+                                       if( nla_get_u32(freqs[NL80211_FREQUENCY_ATTR_FREQ]) < 2485 )
+                                       {
+                                               *buf |= IWINFO_80211_B;
+                                               *buf |= IWINFO_80211_G;
+                                       }
+                                       else
+                                       {
+                                               *buf |= IWINFO_80211_A;
+                                       }
+                               }
+                       }
+                       nl80211_free(res);
+               }
+               nl80211_free(req);
+       }
+
+       return *buf ? 0 : -1;
+}
+
 int nl80211_get_mbssid_support(const char *ifname, int *buf)
 {
        /* We assume that multi bssid is always possible */
index 6c03ca1..569da00 100644 (file)
@@ -79,6 +79,7 @@ int nl80211_get_txpwrlist(const char *ifname, char *buf, int *len);
 int nl80211_get_scanlist(const char *ifname, char *buf, int *len);
 int nl80211_get_freqlist(const char *ifname, char *buf, int *len);
 int nl80211_get_countrylist(const char *ifname, char *buf, int *len);
+int nl80211_get_hwmodelist(const char *ifname, int *buf);
 int nl80211_get_mbssid_support(const char *ifname, int *buf);
 void nl80211_close(void);
 
index 298fd93..5eecd0d 100644 (file)
@@ -471,6 +471,33 @@ int wext_get_countrylist(const char *ifname, char *buf, int *len)
        return -1;
 }
 
+int wext_get_hwmodelist(const char *ifname, int *buf)
+{
+       char chans[IWINFO_BUFSIZE] = { 0 };
+       struct iwinfo_freqlist_entry *e = NULL;
+       int len = 0;
+
+       if( !wext_get_freqlist(ifname, chans, &len) )
+       {
+               for( e = (struct iwinfo_freqlist_entry *)chans; e->channel; e++ )
+               {
+                       if( e->channel <= 14 )
+                       {
+                               *buf |= IWINFO_80211_B;
+                               *buf |= IWINFO_80211_G;
+                       }
+                       else
+                       {
+                               *buf |= IWINFO_80211_A;
+                       }
+               }
+
+               return 0;
+       }
+
+       return -1;
+}
+
 int wext_get_encryption(const char *ifname, char *buf)
 {
        /* No reliable crypto info in wext */
index d58fa1c..03a5199 100644 (file)
@@ -47,6 +47,7 @@ int wext_get_txpwrlist(const char *ifname, char *buf, int *len);
 int wext_get_scanlist(const char *ifname, char *buf, int *len);
 int wext_get_freqlist(const char *ifname, char *buf, int *len);
 int wext_get_countrylist(const char *ifname, char *buf, int *len);
+int wext_get_hwmodelist(const char *ifname, int *buf);
 int wext_get_mbssid_support(const char *ifname, int *buf);
 void wext_scan_close(void);
 void wext_close(void);
index cb778fe..a08dcd2 100644 (file)
@@ -544,6 +544,11 @@ int wl_get_countrylist(const char *ifname, char *buf, int *len)
        return -1;
 }
 
+int wl_get_hwmodelist(const char *ifname, int *buf)
+{
+       return wext_get_hwmodelist(ifname, buf);
+}
+
 int wl_get_mbssid_support(const char *ifname, int *buf)
 {
        wlc_rev_info_t revinfo;
index b734cb6..97a8741 100644 (file)
@@ -44,6 +44,7 @@ int wl_get_txpwrlist(const char *ifname, char *buf, int *len);
 int wl_get_scanlist(const char *ifname, char *buf, int *len);
 int wl_get_freqlist(const char *ifname, char *buf, int *len);
 int wl_get_countrylist(const char *ifname, char *buf, int *len);
+int wl_get_hwmodelist(const char *ifname, int *buf);
 int wl_get_mbssid_support(const char *ifname, int *buf);
 void wl_close(void);