USB WIFI 移植笔记

前言:

这篇文章是从一个外国人写的wifi移植教程那里翻译过来的,原文链接暂时没找到,以后找到了再补上去。

在参考了原文的教程下,我也成功的将中龙通usb rt5370 wifi 模组移植到了android 平台上面。大笑大笑大笑

PS:原文拥有很长很长的评论和探讨,太精彩了!佩服佩服!

好了,下面是自己的译文:

 

0 理解android wifi如何工作(了解下面代码的功能)

hardware/libhardware_legacy/wifi/wifi.c
frameworks/base/wifi/java/android/net/wifi
frameworks/base/core/jni/android_net_wifi_Wifi.cpp
frameworks/base/core/java/android/net

 

1 BoardConfig.mk里面使能wap_supplicant编译选项

在BoardConfig.mk文件里加入:
BOARD_WPA_SUPPLICANT_DRIVER := WEXT
这将会使得在external/wpa_supplicant/Android.mk 里设置WPA_BUILD_SUPPLICANT 为true,
从而打开编译driver_wext.c的编译选项。
如果你有定制的wap_supplicant驱动,你可以用AWEXT或者你的驱动的名字替代WEXT(MADWIFI,PRISM etc)。

 

2 使能wap_supplicant debug(可选的)

 2.1 修改common.c ,设置wpa_debug_level = MSG_DEBUG(设置为MSG_INFO的话会输出少量信息)

 2.2 修改commmon.h文件 , 在 #define wpa_printf(level, ...) 里面,
 修改 if ((level) >= MSG_INFO) 为 if ((level) >= MSG_DEBUG)

 

3 为你的设备提供正确的wpa_supplicant.conf

提供 wpa_supplicant.conf是非常重要的,因为这个文件里指定了android 的控制socket 的路径(ctr_interface=),
这个文件会被你的AndroidBoard.mk拷贝至$(TARGET_OUT_ETC)/wifi,通常路径为:/system/etc/wifi/wpa_supplicant.conf 。
这个路径会被init.rc的wpa_supplicant服务所使用。
这里存在两种方式来配置wpa_supplicant服务,一种就是在android 命名空间里使用私有的socket,这个私有的socket
由wpa_ctrl.c里的socket_local_client_connect()函数生成。另一种就是使用标准的unix socket。

wpa_supplicant.conf 配置的最低要求:

 --Adroid 私有的 socket
ctrl_interface=wlan0
update_config=1

 -- Unix standard socket
ctrl_interface=DIR=/data/system/wpa_supplicant GROUP=wifi
update_config=1

根据的你的驱动你可能会加入:
ap_scan=1
假如你有AP关联问题,那么改为ap_scan=0,让你的驱动代替wpa_supplicant去关联。
假如你希望让你的wpa_suppilca发t连接到non-WPA或者开放的无线网络,那么加入:

network={
key_mgmt=NONE
}


4 在init.rc里面创建正确的权限和路径


不正确的权限将会导致wpa_supplicant不能创建或者打开控制socket 和libhardware_legacy/wifi/wifi.c 无法连接.
自从谷歌修改wpa_supplicant,让wifi 用户/组 来运行以来,这个目录架构和文件的拥有者应该属于wifi 用户/组
(see os_program_init() function in wpa_supplicant/os_unix.c ).

其他的一些错误如:
E/WifiHW  (  ): Unable to open connection to supplicant on "/data/system/wpa_supplicant/wlan0": No such file or directory will appear.

wpa_supplicant.conf也应该属于wifi 用户/组,因为wpa_supplicant会试图修改这个它。假如你的系统拥有/system,
并且文件系统是只读的,那么请使用/data/misc/wifi/wpa_supplicant.conf 这个位置,还有要使用新的位置来修改
init.rc里面的wpa_supplicant service。
确保这个路径在 init.rc里面是正确的:

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里面使用的是标准的unix socket,请假如:
# 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
Do not add these if you use Android private socket because it will make wpa_supplicant non-functional, becausehardware/libhardware_legacy/wifi/wifi.c check for existence of the/data/system/wpa_supplicant folder and will pass a wrong interface name to wpa_ctrl_open()function.

如果你使用的是私有的socket,那么不要加入上面这一段,否则会使得wpa_supplicant无效,因为hardware/libhardware_legacy/wifi/wifi.c会检查
/data/system/wpa_supplicant 目录的存在性,会不错误的接口名字传递给wpa_ctrl_open()函数。


5 确保你的wpa_supplicant 和 dhcpcd (optional)在init.rc里启动

- Android private socket:
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

- Unix standard socket:
service wpa_supplicant /system/bin/wpa_supplicant -dd -Dwext -iwlan0 -c /system/etc/wifi/wpa_supplicant.conf
group system wifi inet
disabled
oneshot

假如你的wifi驱动采用其他名字而不是wlan0 来创建一个wifi接口,那么将上面文字中wlan0修改为你的接口名。

在init.rc里面也要启动dhcpcd:

service dhcpcd /system/bin/dhcpcd wlan0
group system dhcp
disabled
oneshot

 

6提供你的驱动模块或者编译进你的内核的驱动,

还有支持你的驱动的内核。

首先确保CONFIG_PACKET 和CONFIG_NET_RADIO(wirele extentions) 在你的内核里面是使能的。
驱动编译的两种方式:一是编译为模块。二是直接编译进内核,(假如你希望依靠内核自己检测驱动的话,比如usb wifi )
但编译进内核的话就要修改代码。

 -- 编译为模块:
   在你的 BoardConfig.mk 里面定义:
   1. WIFI_DRIVER_MODULE_PATH := 模块加载的路径
       你还需要在路径里指定模块名,通常的是这样的:/system/lib/modules/wlan.ko
   2.  WIFI_DRIVER_MODULE_NAME:= 在驱动里面常见的网络接口名字,例如wlan0。
   3. WIFI_DRIVER_MODULE_ARG:= 一些在你加载驱动时想要传过去的声明,例如:nohwcrypt
当你要编译android系统是,确保你的内核模块已经复制进正确的目录里面。

 -- 编译进内核:
 -首先需要修改init.rc,以使hardware/libhardware_legacy/wifi/wifi.c 知道驱动里面已经加载了的网络接口名字,
 以及设置wpa_supplicant运行的状态:

setprop wifi.interface "wlan0"
setprop wlan.driver.status "ok"

不要像我前面提到的那样设置init.svc.wpa_supplicant "running",因为这会阻碍wpa_supplicant从init进程里启动。

 -第二,修改文件hardware/libhardware_legacy/wifi/wifi.c ,使得函数insmod()和rmmod() return 0 (简单的加入 return 0 ;因为要编译进内核啦,所以函数的第一行已经不需要了。)在check_driver_loaded()function里面检查/proc/modules之前也返回。

你可能会遇见wifi HW无法连接到wpa_supplicant socket的问题,即使拥有了正确的权限。可以尝试在GUI里面关闭/打开wifi来解决问题。

 

7 提供你的驱动所需的固件(如果需要的话)

如果你的驱动需要固件,那么将它拷贝至/etc/firmware 。 固件名字由驱动来定义,可能包含着一个目录例如:RTL8192SU/rtl8192sfw.bin,完整的路径应该是可用的。

 

8 确保你的驱动和android定制的wpa_supplicant 命令行

以及SIOCSIWPRIV ioctl 一起工作。

 

android 使用SIOCSIWPRIV ioctl 发送命令来修改驱动的行为和接受像信号强度,AP的mac地址,链接速度这些信息。除了谷歌 msm内核里分支里面的bcm4329驱动程序,这些ioctl通常不会在任何已知的无线驱动里实现。

那些没有实现ioctl的会出现像下面一样的错误信息:
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
After 4, WEXT_NUMBER_SEQUENTIAL_ERRORS errors, android will abort using the device.

 


 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值