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 1377ffe..312a3da 100644 (file)
@@ -308,6 +308,21 @@ static int iwinfo_L_type(lua_State *L)
        return 1;
 }
 
        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
  */
 /*
  * 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 },
 /* Common */
 static const luaL_reg R_common[] = {
        { "type", iwinfo_L_type },
+       { "__gc", iwinfo_L__gc  },
        { NULL, NULL }
 };
 
        { NULL, NULL }
 };
 
index daecf5d..9c3bb26 100644 (file)
@@ -292,6 +292,12 @@ int madwifi_probe(const char *ifname)
        return ( !!madwifi_isvap(ifname, NULL) || madwifi_iswifi(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);
 int madwifi_get_mode(const char *ifname, char *buf)
 {
        return wext_get_mode(ifname, buf);
index 1f22918..7e0129c 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);
 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
 
 #endif
index 7d2a96a..a693d53 100644 (file)
@@ -77,17 +77,7 @@ static int nl80211_init(void)
 
 
 err:
 
 
 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;
 }
 
        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;
 
 {
        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;
 
        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);
 
                ifidx = if_nametoindex(&ifname[4]);
        else
                ifidx = if_nametoindex(ifname);
 
-       if( ifidx < 0 )
+       if( (ifidx < 0) && (phyidx < 0) )
                return NULL;
 
        req = nlmsg_alloc();
                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);
 
        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);
 
 
        nlmsg_get(req);
 
@@ -395,6 +391,21 @@ int nl80211_probe(const char *ifname)
        return !!nl80211_ifname2phy(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);
 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)
 {
 
 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)
 }
 
 int nl80211_get_country(const char *ifname, char *buf)
index 0cf7419..97a2904 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);
 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
 
 #endif
index 7bd1574..e9e79e3 100644 (file)
@@ -113,6 +113,14 @@ int wext_probe(const char *ifname)
        return 0;
 }
 
        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;
 int wext_get_mode(const char *ifname, char *buf)
 {
        struct iwreq wrq;
index 917ea12..d58fa1c 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);
 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
 
 #endif
index f812618..d5b486b 100644 (file)
@@ -653,3 +653,9 @@ int wext_get_scanlist(const char *ifname, char *buf, int *len)
 
        return -1;
 }
 
        return -1;
 }
+
+void wext_scan_close(void)
+{
+       if( ioctl_socket > -1 )
+               close(ioctl_socket);
+}
index 81df81f..cb778fe 100644 (file)
@@ -75,6 +75,12 @@ int wl_probe(const char *ifname)
        return 0;
 }
 
        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;
 int wl_get_mode(const char *ifname, char *buf)
 {
        int ret = -1;
index 0a991a3..b734cb6 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);
 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
 
 #endif