wukunting 2011-06-28
一、WIFI的基本架构
1、wifi用户空间的程序和库:
external/wpa_supplicant/
生成库libwpaclient.so和守护进程wpa_supplicant。
2、hardware/libhardware_legary/wifi/是wifi管理库。
3、JNI部分:
frameworks/base/core/jni/android_net_wifi_Wifi.cpp
4、JAVA部分:
frameworks/base/services/java/com/android/server/
frameworks/base/wifi/java/android/net/wifi/
5、WIFISettings应用程序位于:
packages/apps/Settings/src/com/android/settings/wifi/
二、WIFI在Android中如何工作
Android使用一个修改版wpa_supplicant作为daemon来控制WIFI,代码位于
external/wpa_supplicant。wpa_supplicant是通过socket与
hardware/libhardware_legacy/wifi/wifi.c通信。UI通过android.net.wifipackage
(frameworks/base/wifi/java/android/net/wifi/)发送命令给wifi.c。
相应的JNI实现位于frameworks/base/core/jni/android_net_wifi_Wifi.cpp。
更高一级的网络管理位于frameworks/base/core/java/android/net。
三、配置Android支持WIFI
在BoardConfig.mk中添加:
BOARD_HAVE_WIFI:=true
BOARD_WPA_SUPPLICANT_DRIVER:=WEXT
这将在external/wpa_supplicant/Android.mk设置WPA_BUILD_SUPPLICANT为true,
默认使用驱动driver_wext.c。
如果使用定制的wpa_supplicant驱动(例如madwifi),可以设置:
BOARD_WPA_SUPPLICANT_DRIVER:=MADWIFI
四、使能wpa_supplicant调试信息
默认wpa_supplicant设置为MSG_INFO,为了输出更多信息,可修改:
1、在common.c中设置wpa_debug_level=MSG_DEBUG;
2、在common.c中把#definewpa_printf宏中的
if((level)>=MSG_INFO)
改为
if((level)>=MSG_DEBUG)
五、配置wpa_supplicant.conf
wpa_supplicant是通过wpa_supplicant.conf中的ctrl_interface=来指定控制socket的,应该在
AndroidBoard.mk中配置好复制到$(TARGET_OUT_ETC)/wifi(也就是
/system/etc/wifi/wpa_supplicant.conf)
这个位置会在init.rc中再次检测的。
一般的wpa_supplicant.conf配置为:
ctrl_interface=DIR=/data/system/wpa_supplicantGROUP=wifi
update_config=1
fast_reauth=1
有时,驱动需要增加:
ap_scan=1
如果遇到AP连接问题,需要修改ap_scan=0来让驱动连接,代替wpa_supplicant。
如果要连接到non-WPAoropenwirelessnetworks,要增加:
network={
key_mgmt=NONE
}
六、配置路径和权限
Google修改的wpa_supplicant要运行在wifi用户和组下的。代码可见wpa_supplicant/os_unix.c
中的os_program_init()函数。
如果配置不对,会出现下面错误:
E/WifiHW():Unabletoopenconnectiontosupplicanton
"/data/system/wpa_supplicant/wlan0":Nosuchfileordirectorywillappear.
确认init.rc中有如下配置:
mkdir/system/etc/wifi0770wifiwifi
chmod0770/system/etc/wifi
chmod0660/system/etc/wifi/wpa_supplicant.conf
chownwifiwifi/system/etc/wifi/wpa_supplicant.conf
#wpa_supplicantsocket
mkdir/data/system/wpa_supplicant0771wifiwifi
chmod0771/data/system/wpa_supplicant
#wpa_supplicantcontrolsocketforandroidwifi.c
mkdir/data/misc/wifi0770wifiwifi
mkdir/data/misc/wifi/sockets0770wifiwifi
chmod0770/data/misc/wifi
chmod0660/data/misc/wifi/wpa_supplicant.conf
如果系统的/system目录为只读,那应该使用路径/data/misc/wifi/wpa_supplicant.conf。
七、运行wpa_supplicant和dhcpcd
在init.rc中确保有如下语句:
servicewpa_supplicant/system/bin/logwrapper/system/bin/wpa_supplicant-dd
-Dwext-iwlan0-c/data/misc/wifi/wpa_supplicant.conf
userroot
groupwifiinet
socketwpa_wlan0dgram660wifiwifi
oneshot
servicedhcpcd/system/bin/logwrapper/system/bin/dhcpcd-d-Bwlan0
disabled
oneshot
根据所用的WIFI驱动名字,修改wlan0为自己驱动的名字。
七、编译WIFI驱动为module或kernelbuiltin
1、编译为module
在BoardConfig.mk中添加:
WIFI_DRIVER_MODULE_PATH:="/system/lib/modules/ar6000.ko"
WIFI_DRIVER_MODULE_ARG:=""#forexamplenohwcrypt
WIFI_DRIVER_MODULE_NAME:="ar6000"#forexamplewlan0
WIFI_FIRMWARE_LOADER:=""
2、编译为kernelbuiltin
1)在hardware/libhardware_legacy/wifi/wifi.c要修改interface名字,
2)在init.rc中添加:
setpropwifi.interface"wlan0"
3)在hardware/libhardware_legacy/wifi/wifi.c中当insmod/rmmod时,
直接return0。
八、WIFI需要的firmware
Android不使用标准的hotplugbinary,WIFI需要的firmware要复制到/etc/firmware。
或者复制到WIFI驱动指定的位置,然后WIFI驱动会自动加载。
九、修改WIFI驱动适合Android
Google修改的wpa_supplicant要求SIOCSIWPRIVioctl发送命令到驱动,及接收信息,例如signal
strength,macaddressoftheAP,linkspeed等。所以要正确实现WIFI驱动,需要从
SIOCSIWPRIVioctl返回RSSI(signalstrength)和MACADDR信息。
如果没实现这个ioctl,会出现如下错误:
E/wpa_supplicant():wpa_driver_priv_driver_cmdfailed
wpa_driver_priv_driver_cmdRSSIlen=4096
E/wpa_supplicant():wpa_driver_priv_driver_cmdfailed
D/wpa_supplicant():wpa_driver_priv_driver_cmdLINKSPEEDlen=4096
E/wpa_supplicant():wpa_driver_priv_driver_cmdfailed
I/wpa_supplicant():CTRL-EVENT-DRIVER-STATEHANGED
十、设置dhcpcd.conf
一般/system/etc/dhcpcd/dhcpcd.conf的配置为:
interfacewlan0
optionsubnet_mask,routers,domain_name_servers
转载至:http://blog.chinaunix.net/space.php?uid=24605155&do=blog&cuid=2339509