Control the Android WiFi TxPower
I am doing some experiments using Android devices and need to manually set the TxPower of the WiFi.
A brief investigation in the Android API didn't give me any satisfied methods. Thus I am considering using iwconfig or tools alike. The following are what I did.
Compile iwconfig with PIE support
First problem I come upon is that Android (after 4.1) enforces any dynamically linked programs to support PIE (Position Independent Executables). You can find many precompiled version of iwconfig online, but I think most of them are not PIE supported. In short, if it's not PIE supported, Android will give you the following error.
Error: only position independent executables (PIE) are supported
You can check whether a program is compiled with PIE support using readelf. If it gives you DYN, you are good to go. Otherwise with EXEC, you need to recompile.
$ readelf -l iwconfig | grep -i "file type" Elf file type is DYN (Shared object file)
To compile it with PIE support, you need:
- Android NDK of your target version.
- Android SDK of your target version.
- A rooted Android device (with Android 4.1 or higher).
Then you can either: download the source from this page and compile using the NDK tools, or use the handy scripts by @nvamelichev. I suggest the latter one.
After you cloned his repo,
- Modify the config.sh script to incorporate your NDK and SDK version and path.
- In the Android.mk script, remove/add tools per your need. For me, I only kept iwconfig.
- Add -fPIC to CFLAGS and -pie to LDFLAGS.
- Run build.sh and your compiled program will be in the libs folder.
- Push the program to your device at /system/xbin/ and chmod to 755.
Control your WiFi
The rest is easy, you can do most old school stuffs with iwconfig. For example, you can control the TxPower by
$ adb root $ adb shell $ iwconfig wlan0 txpower 30mW
The following is a test script, it sets the txpower from 10mW to 100mW, with a step size of 10mW.
#!/bin/bash
let power=10
for i in `seq 0 9`; do
let p=$power+$i*10
echo "$p mW"
adb shell iwconfig wlan0 txpower "$p"mW
adb shell iwconfig wlan0 |grep Tx-Power
sleep 3
done
echo "reset to 30 mW"
adb shell iwconfig wlan0 txpower 30mW
adb shell iwconfig wlan0 |grep Tx-Power
And the following is its output on my Nexus 5.
10 mW
Bit Rate=72 Mb/s Tx-Power=10 dBm
20 mW
Bit Rate=72 Mb/s Tx-Power=14 dBm
30 mW
Bit Rate=72 Mb/s Tx-Power=15 dBm
40 mW
Bit Rate=72 Mb/s Tx-Power=17 dBm
50 mW
Bit Rate=72 Mb/s Tx-Power=17 dBm
60 mW
Bit Rate=72 Mb/s Tx-Power=18 dBm
70 mW
Bit Rate=72 Mb/s Tx-Power=19 dBm
80 mW
Bit Rate=72 Mb/s Tx-Power=20 dBm
90 mW
Bit Rate=72 Mb/s Tx-Power=20 dBm
100 mW
Bit Rate=72 Mb/s Tx-Power=20 dBm
reset to 30 mW
Bit Rate=72 Mb/s Tx-Power=15 dBm
You can also use the app WiFi TX Power which has some preset power levels. Notice that it also requires iwconfig.
TL;DR, you can use this precompiled iwconfig to control your android wifi.
By Lynxiayel
yulinling.net
15 Dec 2015 15 Dec 2015

