libs/iwinfo: implement *_get_txpwrlist() to obtain valid tx power levels
authorJo-Philipp Wich <jow@openwrt.org>
Wed, 19 Aug 2009 04:03:00 +0000 (04:03 +0000)
committerJo-Philipp Wich <jow@openwrt.org>
Wed, 19 Aug 2009 04:03:00 +0000 (04:03 +0000)
libs/iwinfo/src/iwinfo.h
libs/iwinfo/src/iwinfo_lualib.c
libs/iwinfo/src/iwinfo_lualib.h
libs/iwinfo/src/iwinfo_madwifi.c
libs/iwinfo/src/iwinfo_madwifi.h
libs/iwinfo/src/iwinfo_wext.c
libs/iwinfo/src/iwinfo_wext.h
libs/iwinfo/src/iwinfo_wl.c
libs/iwinfo/src/iwinfo_wl.h

index af63183..be7c1ec 100644 (file)
@@ -29,5 +29,10 @@ struct iwinfo_assoclist_entry {
        int8_t noise;
 };
 
+struct iwinfo_txpwrlist_entry {
+       uint8_t dbm;
+       uint8_t mw;
+};
+
 #endif
 
index 3325463..6974280 100644 (file)
@@ -75,6 +75,39 @@ static int iwinfo_L_assoclist(lua_State *L, int (*func)(const char *, char *, in
        return 1;
 }
 
+/* Wrapper for tx power list */
+static int iwinfo_L_txpwrlist(lua_State *L, int (*func)(const char *, char *, int *))
+{
+       int i, x, len;
+       char rv[IWINFO_BUFSIZE];
+       const char *ifname = luaL_checkstring(L, 1);
+       struct iwinfo_txpwrlist_entry *e;
+
+       lua_newtable(L);
+       memset(rv, 0, sizeof(rv));
+
+       if( !(*func)(ifname, rv, &len) )
+       {
+               for( i = 0, x = 1; i < len; i += sizeof(struct iwinfo_txpwrlist_entry), x++ )
+               {
+                       e = (struct iwinfo_txpwrlist_entry *) &rv[i];
+
+                       lua_pushinteger(L, x);
+                       lua_newtable(L);
+
+                       lua_pushnumber(L, e->mw);
+                       lua_setfield(L, -2, "mw");
+                       
+                       lua_pushnumber(L, e->dbm);
+                       lua_setfield(L, -2, "dbm");
+
+                       lua_settable(L, -3);
+               }
+       }
+
+       return 1;
+}
+
 /* Broadcom */
 LUA_WRAP_INT(wl,channel)
 LUA_WRAP_INT(wl,frequency)
@@ -89,6 +122,7 @@ LUA_WRAP_STRING(wl,ssid)
 LUA_WRAP_STRING(wl,bssid)
 LUA_WRAP_STRING(wl,enctype)
 LUA_WRAP_ASSOCLIST(wl)
+LUA_WRAP_TXPWRLIST(wl)
 
 /* Madwifi */
 LUA_WRAP_INT(madwifi,channel)
@@ -104,6 +138,7 @@ LUA_WRAP_STRING(madwifi,ssid)
 LUA_WRAP_STRING(madwifi,bssid)
 LUA_WRAP_STRING(madwifi,enctype)
 LUA_WRAP_ASSOCLIST(madwifi)
+LUA_WRAP_TXPWRLIST(madwifi)
 
 /* Wext */
 LUA_WRAP_INT(wext,channel)
@@ -119,6 +154,7 @@ LUA_WRAP_STRING(wext,ssid)
 LUA_WRAP_STRING(wext,bssid)
 LUA_WRAP_STRING(wext,enctype)
 LUA_WRAP_ASSOCLIST(wext)
+LUA_WRAP_TXPWRLIST(wext)
 
 /* Broadcom table */
 static const luaL_reg R_wl[] = {
@@ -134,6 +170,7 @@ static const luaL_reg R_wl[] = {
        LUA_REG(wl,bssid),
        LUA_REG(wl,enctype),
        LUA_REG(wl,assoclist),
+       LUA_REG(wl,txpwrlist),
        LUA_REG(wl,mbssid_support),
        { NULL, NULL }
 };
@@ -152,6 +189,7 @@ static const luaL_reg R_madwifi[] = {
        LUA_REG(madwifi,bssid),
        LUA_REG(madwifi,enctype),
        LUA_REG(madwifi,assoclist),
+       LUA_REG(madwifi,txpwrlist),
        LUA_REG(madwifi,mbssid_support),
        { NULL, NULL }
 };
@@ -170,6 +208,7 @@ static const luaL_reg R_wext[] = {
        LUA_REG(wext,bssid),
        LUA_REG(wext,enctype),
        LUA_REG(wext,assoclist),
+       LUA_REG(wext,txpwrlist),
        LUA_REG(wext,mbssid_support),
        { NULL, NULL }
 };
index ca1a442..909080b 100644 (file)
                        type##_get_assoclist);                                          \
        }
 
+#define LUA_WRAP_TXPWRLIST(type)                                               \
+       static int iwinfo_L_##type##_txpwrlist(lua_State *L)\
+       {                                                                                                       \
+               return iwinfo_L_txpwrlist(L,                                    \
+                       type##_get_txpwrlist);                                          \
+       }
+
 #endif
 
index 17db10b..1165012 100644 (file)
@@ -398,6 +398,11 @@ int madwifi_get_assoclist(const char *ifname, char *buf, int *len)
        return -1;
 }
 
+int madwifi_get_txpwrlist(const char *ifname, char *buf, int *len)
+{
+       return wext_get_txpwrlist(ifname, buf, len);
+}
+
 int madwifi_get_mbssid_support(const char *ifname, int *buf)
 {
        /* We assume that multi bssid is always possible */
index 15fe72f..24573f3 100644 (file)
@@ -35,6 +35,7 @@ int madwifi_get_quality(const char *ifname, int *buf);
 int madwifi_get_quality_max(const char *ifname, int *buf);
 int madwifi_get_enctype(const char *ifname, char *buf);
 int madwifi_get_assoclist(const char *ifname, char *buf, int *len);
+int madwifi_get_txpwrlist(const char *ifname, char *buf, int *len);
 int madwifi_get_mbssid_support(const char *ifname, int *buf);
 
 #endif
index 859bb1f..24be10f 100644 (file)
@@ -22,6 +22,8 @@
 #include "iwinfo.h"
 #include "iwinfo_wext.h"
 
+#define LOG10_MAGIC    1.25892541179
+
 static int ioctl_socket = -1;
 
 static double wext_freq2float(const struct iw_freq *in)
@@ -50,6 +52,39 @@ static int wext_freq2mhz(const struct iw_freq *in)
        }
 }
 
+static int wext_dbm2mw(int in)
+{
+       double res = 1.0;
+       int ip = in / 10;
+       int fp = in % 10;
+       int k;
+
+       for(k = 0; k < ip; k++) res *= 10;
+       for(k = 0; k < fp; k++) res *= LOG10_MAGIC;
+
+       return (int)res;
+}
+
+static int wext_mw2dbm(int in)
+{
+       double fin = (double) in;
+       int res = 0;
+
+       while(fin > 10.0)
+       {
+               res += 10;
+               fin /= 10.0;
+       }
+
+       while(fin > 1.000001)
+       {
+               res += 1;
+               fin /= LOG10_MAGIC;
+       }
+
+       return res;
+}
+
 static int wext_ioctl(const char *ifname, int cmd, struct iwreq *wrq)
 {
        /* prepare socket */
@@ -297,6 +332,44 @@ int wext_get_assoclist(const char *ifname, char *buf, int *len)
        return -1;
 }
 
+int wext_get_txpwrlist(const char *ifname, char *buf, int *len)
+{
+       struct iwreq wrq;
+       struct iw_range range;
+       struct iwinfo_txpwrlist_entry entry;
+       int i;
+
+       wrq.u.data.pointer = (caddr_t) &range;
+       wrq.u.data.length  = sizeof(struct iw_range);
+       wrq.u.data.flags   = 0;
+
+       if( (wext_ioctl(ifname, SIOCGIWRANGE, &wrq) >= 0) &&
+           (range.num_txpower > 0) && (range.num_txpower <= IW_MAX_TXPOWER) &&
+           !(range.txpower_capa & IW_TXPOW_RELATIVE)
+       ) {
+               for( i = 0; i < range.num_txpower; i++ )
+               {
+                       if( range.txpower_capa & IW_TXPOW_MWATT )
+                       {
+                               entry.dbm = wext_mw2dbm(range.txpower[i]);
+                               entry.mw  = range.txpower[i];
+                       }
+                       else
+                       {
+                               entry.dbm = range.txpower[i];
+                               entry.mw  = wext_dbm2mw(range.txpower[i]);
+                       }
+
+                       memcpy(&buf[i*sizeof(entry)], &entry, sizeof(entry));
+               }
+
+               *len = i * sizeof(entry);
+               return 0;
+       }
+
+       return -1;      
+}
+
 int wext_get_mbssid_support(const char *ifname, int *buf)
 {
        /* No multi bssid support atm */
index 7ff6cfb..906b932 100644 (file)
@@ -35,6 +35,7 @@ int wext_get_quality(const char *ifname, int *buf);
 int wext_get_quality_max(const char *ifname, int *buf);
 int wext_get_enctype(const char *ifname, char *buf);
 int wext_get_assoclist(const char *ifname, char *buf, int *len);
+int wext_get_txpwrlist(const char *ifname, char *buf, int *len);
 int wext_get_mbssid_support(const char *ifname, int *buf);
 
 #endif
index 4247353..2c3126a 100644 (file)
@@ -366,6 +366,24 @@ int wl_get_assoclist(const char *ifname, char *buf, int *len)
        return -1;
 }
 
+int wl_get_txpwrlist(const char *ifname, char *buf, int *len)
+{
+       struct iwinfo_txpwrlist_entry entry;
+       uint8_t dbm[8] = { 0, 6, 8, 10, 12, 14, 16, 18 };
+       uint8_t mw[8]  = { 1, 3, 6, 10, 15, 25, 39, 63 };
+       int i;
+
+       for( i = 0; i < 8; i++ )
+       {
+               entry.dbm = dbm[i];
+               entry.mw  = mw[i];
+               memcpy(&buf[i*sizeof(entry)], &entry, sizeof(entry));
+       }
+
+       *len = 8 * sizeof(entry);
+       return 0;
+}
+
 int wl_get_mbssid_support(const char *ifname, int *buf)
 {
        wlc_rev_info_t revinfo;
index 8ae7917..1bee4f9 100644 (file)
@@ -35,6 +35,7 @@ int wl_get_quality(const char *ifname, int *buf);
 int wl_get_quality_max(const char *ifname, int *buf);
 int wl_get_enctype(const char *ifname, char *buf);
 int wl_get_assoclist(const char *ifname, char *buf, int *len);
+int wl_get_txpwrlist(const char *ifname, char *buf, int *len);
 int wl_get_mbssid_support(const char *ifname, int *buf);
 
 #endif