libiwinfo: support txpwrlist(), freqlist() and countrylist() for radioX pseudodevices...
authorJo-Philipp Wich <jow@openwrt.org>
Tue, 12 Oct 2010 04:56:36 +0000 (04:56 +0000)
committerJo-Philipp Wich <jow@openwrt.org>
Tue, 12 Oct 2010 04:56:36 +0000 (04:56 +0000)
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_wext_scan.c
contrib/package/iwinfo/src/iwinfo_wl.c
contrib/package/iwinfo/src/iwinfo_wl.h

index 1377ffeb249d3c49a07dbdd7f51cc72831952749..312a3dae7b05bd82c3404f5840dd6d227e41ac93 100644 (file)
@@ -308,6 +308,21 @@ static int iwinfo_L_type(lua_State *L)
        return 1;
 }
 
+/* Shutdown backends */
+static int iwinfo_L__gc(lua_State *L)
+{
+#ifdef USE_WL
+       wl_close();
+#endif
+#ifdef USE_MADWIFI
+       madwifi_close();
+#endif
+#ifdef USE_NL80211
+       nl80211_close();
+#endif
+       wext_close();
+}
+
 /*
  * Build a short textual description of the crypto info
  */
@@ -930,6 +945,7 @@ static const luaL_reg R_wext[] = {
 /* Common */
 static const luaL_reg R_common[] = {
        { "type", iwinfo_L_type },
+       { "__gc", iwinfo_L__gc  },
        { NULL, NULL }
 };
 
index daecf5df3d065c40cecdbf36bc54f1bcf7992fda..9c3bb2688ac213b6eb35c3cfb34a3beff153e1e2 100644 (file)
@@ -292,6 +292,12 @@ int madwifi_probe(const char *ifname)
        return ( !!madwifi_isvap(ifname, NULL) || madwifi_iswifi(ifname) );
 }
 
+void madwifi_close(void)
+{
+       if( ioctl_socket > -1 )
+               close(ioctl_socket);
+}
+
 int madwifi_get_mode(const char *ifname, char *buf)
 {
        return wext_get_mode(ifname, buf);
index 1f229183837f90b1a61839e23842fdd10c642f84..7e0129c9eec539c698609325dfcfa110e6f1bf42 100644 (file)
@@ -44,5 +44,6 @@ 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_mbssid_support(const char *ifname, int *buf);
+void madwifi_close(void);
 
 #endif
index 7d2a96a6c131376e73d4062ebe2cf2a0372ea5b1..a693d53db733fb1a71af2271ca1247ce8bafa553 100644 (file)
@@ -77,17 +77,7 @@ static int nl80211_init(void)
 
 
 err:
-       if( nls && nls->nl_sock )
-               nl_socket_free(nls->nl_sock);
-
-       if( nls && nls->nl_cache )
-               nl_cache_free(nls->nl_cache);
-
-       if( nls )
-               free(nls);
-
-       nls = NULL;
-
+       nl80211_close();
        return err;
 }
 
@@ -148,19 +138,21 @@ static struct nl80211_msg_conveyor * nl80211_msg(const char *ifname, int cmd, in
 {
        static struct nl80211_msg_conveyor cv;
 
-       int ifidx;
+       int ifidx = -1, phyidx = -1;
        struct nl_msg *req = NULL;
        struct nl_cb *cb = NULL;
 
        if( nl80211_init() < 0 )
                goto err;
 
-       if( !strncmp(ifname, "mon.", 4) )
+       if( !strncmp(ifname, "radio", 5) )
+               phyidx = atoi(&ifname[5]);
+       else if( !strncmp(ifname, "mon.", 4) )
                ifidx = if_nametoindex(&ifname[4]);
        else
                ifidx = if_nametoindex(ifname);
 
-       if( ifidx < 0 )
+       if( (ifidx < 0) && (phyidx < 0) )
                return NULL;
 
        req = nlmsg_alloc();
@@ -174,7 +166,11 @@ static struct nl80211_msg_conveyor * nl80211_msg(const char *ifname, int cmd, in
        genlmsg_put(req, 0, 0, genl_family_get_id(nls->nl80211), 0,
                flags, cmd, 0);
 
-       NLA_PUT_U32(req, NL80211_ATTR_IFINDEX, ifidx);
+       if( ifidx > -1 )
+               NLA_PUT_U32(req, NL80211_ATTR_IFINDEX, ifidx);
+
+       if( phyidx > -1 )
+               NLA_PUT_U32(req, NL80211_ATTR_WIPHY, phyidx);
 
        nlmsg_get(req);
 
@@ -395,6 +391,21 @@ int nl80211_probe(const char *ifname)
        return !!nl80211_ifname2phy(ifname);
 }
 
+void nl80211_close(void)
+{
+       if( nls )
+       {
+               if( nls->nl_sock )
+                       nl_socket_free(nls->nl_sock);
+
+               if( nls->nl_cache )
+                       nl_cache_free(nls->nl_cache);
+
+               free(nls);
+               nls = NULL;
+       }
+}
+
 int nl80211_get_mode(const char *ifname, char *buf)
 {
        return wext_get_mode(ifname, buf);
@@ -1171,7 +1182,63 @@ int nl80211_get_scanlist(const char *ifname, char *buf, int *len)
 
 int nl80211_get_freqlist(const char *ifname, char *buf, int *len)
 {
-       return wext_get_freqlist(ifname, buf, len);
+       char *phy;
+       int count = 0, 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;
+       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  },
+       };
+
+       if( !wext_get_freqlist(ifname, buf, len) )
+               return 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);
+
+                               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), freq_policy);
+
+                                       e->mhz = nla_get_u32(freqs[NL80211_FREQUENCY_ATTR_FREQ]);
+                                       e->channel = nl80211_freq2channel(e->mhz);
+
+                                       e++;
+                                       count++;
+                               }
+                       }
+                       nl80211_free(res);
+               }
+               nl80211_free(req);
+       }
+
+       if( count > 0 )
+       {
+               *len = count * sizeof(struct iwinfo_freqlist_entry);
+               return 0;
+       }
+
+       return -1;
 }
 
 int nl80211_get_country(const char *ifname, char *buf)
index 0cf74195d804ece9d349a4e62e8bef6e26b78467..97a290484f79e596f14cc777a1cfdf786b3257ea 100644 (file)
@@ -79,5 +79,6 @@ 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_mbssid_support(const char *ifname, int *buf);
+void nl80211_close(void);
 
 #endif
index 7bd1574c1889cd9e6ccb459855087d0d2abd7dcd..e9e79e3757e91231b93b966c59f332f5540f2184 100644 (file)
@@ -113,6 +113,14 @@ int wext_probe(const char *ifname)
        return 0;
 }
 
+void wext_close(void)
+{
+       wext_scan_close();
+
+       if( ioctl_socket > -1 )
+               close(ioctl_socket);
+}
+
 int wext_get_mode(const char *ifname, char *buf)
 {
        struct iwreq wrq;
index 917ea121f097a7a9a290da100adc11ab73312f3a..d58fa1c2f4122dfa2493cb583c88c184e59c47d9 100644 (file)
@@ -48,5 +48,7 @@ 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_mbssid_support(const char *ifname, int *buf);
+void wext_scan_close(void);
+void wext_close(void);
 
 #endif
index f8126183753d67131c2e2d3299ef44c46bf4b33a..d5b486b7e49a32bb18fe5134e20a58ebe7666060 100644 (file)
@@ -653,3 +653,9 @@ int wext_get_scanlist(const char *ifname, char *buf, int *len)
 
        return -1;
 }
+
+void wext_scan_close(void)
+{
+       if( ioctl_socket > -1 )
+               close(ioctl_socket);
+}
index 81df81faf4a5488456b45250096dd6caa0bf79e3..cb778fe3d01bfc3577421a74440c6a8a89d56ca3 100644 (file)
@@ -75,6 +75,12 @@ int wl_probe(const char *ifname)
        return 0;
 }
 
+void wl_close(void)
+{
+       if( ioctl_socket > -1 )
+               close(ioctl_socket);
+}
+
 int wl_get_mode(const char *ifname, char *buf)
 {
        int ret = -1;
index 0a991a35fe1f7a97aae167c99c4d30c9b2838783..b734cb6fb15be1e1a738ffa97a0f17fac5ec88ef 100644 (file)
@@ -45,5 +45,6 @@ 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_mbssid_support(const char *ifname, int *buf);
+void wl_close(void);
 
 #endif