From: Jo-Philipp Wich Date: Wed, 19 Aug 2009 04:03:00 +0000 (+0000) Subject: libs/iwinfo: implement *_get_txpwrlist() to obtain valid tx power levels X-Git-Tag: 0.10.0~1172 X-Git-Url: https://git.archive.openwrt.org/?p=project%2Fluci.git;a=commitdiff_plain;h=91ceab5b19a7b8c8b748a27e7bd8cb2cd4a44132 libs/iwinfo: implement *_get_txpwrlist() to obtain valid tx power levels --- diff --git a/libs/iwinfo/src/iwinfo.h b/libs/iwinfo/src/iwinfo.h index af63183fb..be7c1ece0 100644 --- a/libs/iwinfo/src/iwinfo.h +++ b/libs/iwinfo/src/iwinfo.h @@ -29,5 +29,10 @@ struct iwinfo_assoclist_entry { int8_t noise; }; +struct iwinfo_txpwrlist_entry { + uint8_t dbm; + uint8_t mw; +}; + #endif diff --git a/libs/iwinfo/src/iwinfo_lualib.c b/libs/iwinfo/src/iwinfo_lualib.c index 33254637a..6974280b7 100644 --- a/libs/iwinfo/src/iwinfo_lualib.c +++ b/libs/iwinfo/src/iwinfo_lualib.c @@ -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 } }; diff --git a/libs/iwinfo/src/iwinfo_lualib.h b/libs/iwinfo/src/iwinfo_lualib.h index ca1a4421c..909080bb4 100644 --- a/libs/iwinfo/src/iwinfo_lualib.h +++ b/libs/iwinfo/src/iwinfo_lualib.h @@ -66,5 +66,12 @@ 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 diff --git a/libs/iwinfo/src/iwinfo_madwifi.c b/libs/iwinfo/src/iwinfo_madwifi.c index 17db10b3f..11650129c 100644 --- a/libs/iwinfo/src/iwinfo_madwifi.c +++ b/libs/iwinfo/src/iwinfo_madwifi.c @@ -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 */ diff --git a/libs/iwinfo/src/iwinfo_madwifi.h b/libs/iwinfo/src/iwinfo_madwifi.h index 15fe72f8a..24573f3b8 100644 --- a/libs/iwinfo/src/iwinfo_madwifi.h +++ b/libs/iwinfo/src/iwinfo_madwifi.h @@ -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 diff --git a/libs/iwinfo/src/iwinfo_wext.c b/libs/iwinfo/src/iwinfo_wext.c index 859bb1f1d..24be10fa9 100644 --- a/libs/iwinfo/src/iwinfo_wext.c +++ b/libs/iwinfo/src/iwinfo_wext.c @@ -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) ⦥ + 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 */ diff --git a/libs/iwinfo/src/iwinfo_wext.h b/libs/iwinfo/src/iwinfo_wext.h index 7ff6cfb7d..906b9324d 100644 --- a/libs/iwinfo/src/iwinfo_wext.h +++ b/libs/iwinfo/src/iwinfo_wext.h @@ -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 diff --git a/libs/iwinfo/src/iwinfo_wl.c b/libs/iwinfo/src/iwinfo_wl.c index 4247353f5..2c3126a83 100644 --- a/libs/iwinfo/src/iwinfo_wl.c +++ b/libs/iwinfo/src/iwinfo_wl.c @@ -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; diff --git a/libs/iwinfo/src/iwinfo_wl.h b/libs/iwinfo/src/iwinfo_wl.h index 8ae791758..1bee4f950 100644 --- a/libs/iwinfo/src/iwinfo_wl.h +++ b/libs/iwinfo/src/iwinfo_wl.h @@ -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