译文:
我们想要让picoPC支持许多USB和miniPC接口的WiFi, 这篇指导文档提供详细的步骤来说明添加一个新的wifi驱动都要做哪些以及如何让wifi在特定的Android编译环境中正常工作.(虽然这个指导文档是为android2.1编写的, 但是也适合之前版本的android发布版和将来的版本)
内容:
0. 理解Android下WiFi如何工作
1. 在BoardConfig.mk中使能编译wpa_supplicant应用
2. (可选)使能wpa_supplicant应用的debug功能
3. 提供合适的wpa_supplicant.conf文件
4. 在init.rc里面创建正确的路径和权限
5. 确认在init.rc里面启动了wpa_supplicant和dhcpcd(可选)
6. 以模块的形式提供你的驱动或者在kernel里面或kernel支持的环境下编译, 同时修改相应的android代码
7. 提供一个fireware如果你的模块需要它
8. 用android定制的wpa_supplicant命令和SIOCSIWPRIV ioctl控制方法来让你的驱动工作
0. 理解Android下WiFi如何工作
Android使用了一个修改过的wpa_supplicant守护程序(external/wpa_supplicant目录下)来支持wifi, 我们可以通过在hardware/libhardware_legacy/wifi/wifi.c(WiFiHW)文件中创建的socket来控制它, Android UI上层APK使用了这个socket, 这个apk是frameworks/base/wifi/java/android/net/wifi/目录下生成的android.net.wifi, 它相应的JNI层的实现在frameworks/base/core/jni/android_net_wifi_Wifi.cpp文件中, 更高级别的网络管理在frameworks/base/core/java/android/net目录下实现.
1. 在BoardConfig.mk中使能编译wpa_supplicant应用
这个可以通过简单的添加BOARD_WPA_SUPPLICANT_DRIVER := WEXT到BoardConfig.mk文件中来实现. 这个变量将会导致"external/wpa_supplicant/Android.mk"中的WPA_BUILD_SUPPLICANT被设置为true, 然后编译driver_wext.c.
如果你有一个特别的wpa_supplicant驱动(例如madwifi或者我的android私有命令仿真器 -- 例如最新的paragraph), 你可以替换调AWEXT替换调WEXT, 或者使用你自己的驱动名称替换WEXT(比如MADWIFI, PRISM)
2. (可选)打开wpa_supplicant应用的debug功能
默认情况下 wpa_supplicant 程序的log级别是MSG_INFO, 有时这个并不够我们分析问题.
打开更多log的方法:
2.1 修改common.c并且设置wpa_debug_level = MSG_DEBUG
2.2 修改common.h并且把"#define wpa_printffrom if ((level) >= MSG_INFO)"修改成"if ((level) >= MSG_DEBUG)"
3. 提供合适的wpa_supplicant.conf文件
提供一个wpa_supplicant.conf非常重要,因为android的控制socket就在这个文件中指定(ctrl_interface=), 这个文件被编译文件AndroidBoard.mk拷贝到$(TARGET_OUT_ETC)/wifi目录下(通常是/system/etc/wifi/wpa_supplicant.conf). 这个位置将被添加到init.rc文件里面, 用来设置wpa_supplicant服务的配置选项.
这里有两个不通的方式来配置wpa_supplicant服务, 一个是在android的域名空间里面使用"私有"的socket, 由wpa_ctrl.c文件里面的socket_local_client_connect()函数创建, 另一个方法是使用标准的unix socket.
- 使用android特有的socket
ctrl_interface=wlan0
update_config=1
ctrl_interface=DIR=/data/system/wpa_supplicant GROUP=wifi
update_config=1
ap_scan=1
network={
key_mgmt=NONE
}
E/WifiHW ( ): Unable to open connection to supplicant on "/data/system/wpa_supplicant/wlan0": No such file or directory will appear.
mkdir /system/etc/wifi 0770 wifi wifi
chmod 0770 /system/etc/wifi
chmod 0660 /system/etc/wifi/wpa_supplicant.conf
chown wifi wifi /system/etc/wifi/wpa_supplicant.conf
#wpa_supplicant control socket for android wifi.c (android private socket)
mkdir /data/misc/wifi 0770 wifi wifi
mkdir /data/misc/wifi/sockets 0770 wifi wifi
chmod 0770 /data/misc/wifi
chmod 0660 /data/misc/wifi/wpa_supplicant.conf
chown wifi wifi /data/misc/wifi
chown wifi wifi /data/misc/wifi/wpa_supplicant.conf
# wpa_supplicant socket (unix socket mode)
mkdir /data/system/wpa_supplicant 0771 wifi wifi
chmod 0771 /data/system/wpa_supplicant
chown wifi wifi /data/system/wpa_supplicant
service wpa_supplicant /system/bin/wpa_supplicant -dd -Dwext -iwlan0 -c /system/etc/wifi/wpa_supplicant.conf
socket wpa_wlan0 dgram 660 wifi wifi
group system wifi inet
disabled
oneshot
service wpa_supplicant /system/bin/wpa_supplicant -dd -Dwext -iwlan0 -c /system/etc/wifi/wpa_supplicant.conf
group system wifi inet
disabled
oneshot
service dhcpcd /system/bin/dhcpcd wlan0
group system dhcp
disabled
oneshot
setprop wifi.interface "wlan0"
setprop wlan.driver.status "ok"
E/wpa_supplicant( ): wpa_driver_priv_driver_cmd failed wpa_driver_priv_driver_cmd RSSI len = 4096
E/wpa_supplicant( ): wpa_driver_priv_driver_cmd failed
D/wpa_supplicant( ): wpa_driver_priv_driver_cmd LINKSPEED len = 4096
E/wpa_supplicant( ): wpa_driver_priv_driver_cmd failed
I/wpa_supplicant( ): CTRL-EVENT-DRIVER-STATE HANGED