一、概述
Wi-Fi是一个无线网路通信技术的品牌,是一种将个人电脑,手持设备(PAD,手机等)等中断设备以无线方式互相连接的技术,经常有人将WI-FI等同于无线网际网络,这是一个误区,Wi-Fi实际上是一种商业认证,同时也是一种无线联网的技术。
目前项目中WI-FI和BT代码基本上由BROADCOM公司提供,其中包括Wi-Fi功能包含Wi-Fi的正常网络连接,Wi-FiDirect,Wi-Fisoftap。BT功能包括BT设备的搜索、被搜索、配对、文件传输和接收等功能,这些功能的测试都是确定代码的移植是否成功的依据。
二、代码结构
1、整个Wi-Fi模块的运行流程如下图:
如果想看详细的Wi-Fi模块分析,可以到网上找“android中wifi原理详解”一文进行详细阅读。
2、BROADCOM每次更新Wi-Fi驱动的时候会提供两个包例如wfd_sdk_20110914.tgz和5.90.125.69.2.tgz这两个包。
2.1、wfd_sdk_20110914.tgz包括需要向项目中添加的Code、需要更新的驱动库文件、编译驱动模块的脚本和代码、控制wpa_supplicant代码,驱动升级的大体方法README,这个README很重要,在升级wifi驱动之前建议要读一下。
2.2、5.90.125.69.2.tgz包含需要升级的firmware和编译生成firmware的脚本和代码。
3、简单分析BROADCOM提供代码
wfd_sdk_20110914
|--android-2.3.4_r1.mod /*AP部分升级后代码*/
|--android-2.3.4_r1.orig /*AP部分升级前的原始版本代码*/
|--compat-wireless /*生成驱动模块的脚本和代码*/
|--hostap /*控制wap_supplicant部分的代码*/
|--libnl /*库文件*/
|--P2P_API_README
|--README
|--README-P2P
`--wpa_supplicant.conf /*wpa_suplicant的配置文件*/
5.90.125.69.2
|--apps
|--BCMLogo.gif
|--firmware
|--host
|--HowTo.txt
|--open-src /*生成firmware的代码和脚本*/
`--README.txt
4、升级的方法
wifi代码升级主要有四个方面
4.1、AP代码部分升级
1、这部分升级主要是将BROADCOM最新修改的代码加入到我们的项目中,是把BROAD-COM的orig版本和mod版本相互比较,然后把生成的patch再加入到我们的项目中,这样才能做到升级的目的,切忌不要直接用mod版本与自己的项目比较后,直接添加patch,这样不但工作效率低,而且不利于下次的升级。
生成的wifi.patch就是我们要升级的代码,如下图
然后进入到项目目录,把需要升级的代码用patch命令进行添加
用patch-p1 命令,将patch添加到代码中,带添加过程中一直按回车键就可,如下图:
patch命令运行完毕之后,在项目的根目录下与行repo status,如下图:
其中后缀是rej格式的文件,是自动升级没有成功的,需要作业者进入目录下,查看rej格式的文件和项目的文件,查找没有升级成功的原因,然后再手动田间
orig格式的文件,是没有升级之前的源文件,如果发生编译错误也可以作为参照进行修改。
在wfd_sdk_20110915中的libnl文件夹,添加方法与AP部分类似,先比较,再修改。
4.2、wfd_sdk_20110914中hostap代码添加
hostap/
|--Android.mk
`--wpa_supplicant
在wfd_sdk_20110914的hostap中的wpa_supplicant是一个安全中间件,为各种无线网卡提供统一的安全机制,完成wpa_supplicantdaemon服务功能是“上传下达”。所有客户端通过它控制硬件网卡,通过发送字符串命令控制是否扫描AP,提取扫描结果和是否关联AP等操作,同时将驱动的执行状态发送给用户。(这里的AP相当于热点的意思)
Android.mk就非常有特点了只有一句话include$(callall-subdir-makefiles)遍历所有的文件的makefile,所以Android.mk需要和wpa_supplicant文件夹放在通一级目录下。
一般都是更新/home/changjiangh/cocktail/external/wpa_supplicant_6/wpa_sup-plicant_broadcom,方法还是打patch的方法,就不赘述了。
4.3、编译compat-wireless
编译compat-wireless生成的驱动模块,这一步就比较简单了,因为BROADCOM已经写好了脚本,只需要修改一下环境变量再执行一下脚本就可以了,简单说明一下环境变量的意思。
make
ARCH=arm
CROSS_COMPILE=/home/changjiang-h/work/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-
KLIB=/home/changjiang-h/work/out/target/product/msm7630_cocktail/obj/KERNEL_OBJKLIB_BUILD=/home/changjiang-h/work/out/target/product/msm7630_cocktail/obj/KERNEL_OBJ
前提是你需要吧代码,编译过,因为没编译过可
CROSS_COMPILE:交叉编译环境的路径
KLIB=内核源码根目录绝对地址
KLIB_BUILD=内核源码根目录绝对地址
4.4、编译open-src
编译open-src是在包5.90.125.69.2中的open-src文件,目的是生成最新的firmware。
在路径5.90.125.69.2/open-src/src/dhd/linux/下会有一个mk_wfd.sh的脚本,修改环境变量运行脚本就可以完成工作
makeLINUXVER=2.6
LINUXDIR=/home/changjiang-h/tail/out/target/product/msm7630_cocktail/obj/KERNEL_OBJ
ARCH=armCOMPAT_WIRELESS=/home/changjiang-h/wfd_sdk_20110914/compat-wirelessCROSS_COMPILE=/home/changjiang-h/tail/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-OEM_ANDROID=1
dhd-cdc-sdmmc-nexus-cfg80211-gpl-debug
COMPAT_WIRELESS:是文件compat-wireless的绝对路径
dhd-cdc-sdmmc-nexus-cfg80211-gpl-debug是目标生成的文件夹,生成的bcm4329.ko就在这个文件夹下
4.5、替换驱动模块和firmware模块
将compat-wireless和open-src生成的bcm4329.ko、cfg80211.ko、compat.ko与项目代码中的文件做替换,完成驱动模块和firmware模块的升级。
4.6、修改wpa_supplicant.conf
需要修改的选项可能在BROADCOM中提供,会修改./hardware/broadcom/wlan/bcm433-0/config/wpa_supplicant.conf,本次只是修改了device_name,所以只修改device_name即可
5.注意事项
1、在代码编译过程中可能会有错误,这些错误可能是在打patch过程中代码重复,删除即可。需要细心和耐心即可。
2、wpa_supplicant是否升级成功,进去adbshell,看/system/bin/目录下是否有wpa_suppli-cent和wpa_cli的可执行文件
3、看ko模块是否加载成功,可以在打开wifi后执行lsmod命令查看。
Part 1
问:打开wifi,连接wifi热点,提示连接成功,但headbar上不显示wifi图标,back退出wifi设置,再进入,提示wifi已断开。
答:首先现象复现,当现象复现时进入adb shell,然后输入ifconfig 查看是否有wlan0 端口,然后在adb shell 中ping 192.168.1.101(嵌入式设备的IP),如果能Ping通则说明底层wifi设备与AP是连接通的。所以把问题转向上层。上层在frameworks/base/services/java/com/android/server/ConnectivityService.java文件中查看private void handleDisconnect(NetworkInfo info)函数的实现,问题可能出现在这里。
Part 2
问:出现新热点,需要重启WIFI才可以扫描到。
问:20s内无法连接到WIFI热点。
问:已连接的热点关闭,不会自动连接下一个热点。
答:这些问题都是供应商芯片的firmware没有配置好,所以直接找FAE换掉。
Part 3
问:调试中如果遇到dhd_sdio_probe fail 。
问:发现sdio register timeout 。
答:因为我们用到的WIFI数据通道是SDIO接口,所以要在log信息中查看sdcard是否有加载。没加载的话就看看WIFI芯片的上电(如WIFI_REG_ON这个PIN脚)。
Part 4
问:如果在wifi的设置里面选中wifi选项出现ERRO(或错误)的提示。
答:首先在adb shell中lsmod查看.ko文件是否已经加载。如没加载cat /proc/kmsg查看是否是版本匹配的问题。如遇版本匹配则在kernel/scripts/setlocalversion中将echo “+”中去掉。如果顺利加载了驱动,则要看看MAC地址是否有,并且是否合理。
Part 5
问:发现在WIFI设置选项中有已经选上了wifi并且勾应打上了,过一会出现wifi的勾自动消失。
答:这种情况在adb shell中用ifconfig查看Wlan的接口用的是否是wlan0,有可能是eth0。如果是eth0则在hardware/libhardware_legacy/wifi/wifi.c中的#define WIFI_DRIVER_MODULE_ARG "firmware_path=/system/etc/firmware/wlan/sdio.bin nvram_path=/data/simcom/nvram.txt iface_name=wlan0" 中查看iface_name=wlan0是否已经加上。
Part 6
问:有的路由器不能扫描的到。
答:查看wlan的设置的channel是否在1-14这个频段,因为如果wlan设置成USA模式则channel的范围在1-11之间,channel 12,13,14就不会收索的到。所以要在nvram.txt中修改成ccode=ALL,并且在gqcom_cfg.ini中把APCntryCode=ALL。这样应该就可以扫描到所有的channel了。当然如果上层还是没有收索到的话,在Settings.java中也要做相应的修改。
常用的命令:wl channels_in_country
wl chanlist
wl channels
wl country