前言
小弟从事android wifi framework部分开发已经有一年的时间了,虽然感觉什么都没有学习到,但是回想起刚接手android wifi时候的那份无知,其实肚子里面还是有点东西的,本着共同进步的想法,特此贴出来与各位分享。
在写wifi移植这个系列的文章的时候,小弟有一些事情需要说明,那就是我上面不会apk,下面不会supplicant和driver,这个是大公司的通病,基本每个工程师只熟悉很小一个模块,而我也不例外,一般apk的问题有同事负责处理,supplicant和driver的问题因为跟硬件和spec比较接近,这一块一般是由厂家在负责处理,目前比较大一点的wifi厂家有:realtek,ralink,atheros(ralink被mediatek收购了,atheros被qualcomm收购了)。
准备工作
在porting wifi之前你有一些东西需要准备,具体清单如下:
(1):android source(没有这个你怎么移植wifi网卡到自己的平台上?)
(2):kernel source(这个是android所依赖的kernel,主要用途是后续用来build driver使用)
(3):driver source(这个是需要加载driver的source,realtek和ralink一般能拿到源码,atheros是美国公司,版权看的比较重,基本拿不到driver的source)
(4):tool chain(build driver所使用的交叉编译链,必须要有)
有了上述4样你才可以开始着手后续的porting,本文主要讲解porting的flow,具体上述东西怎么使用以后再统一介绍。
正文
首先讲解一下porting wifi的大致流程,具体如下:
(1):load wifi driver(网卡启用的先决条件)
(2):起supplicant(这里面带参数很重要)
(3):给supplicant下指定的命令(这个是wifi framework与driver之间的通讯方式)
(1)load wifi driver
首先需要讲解一下,在android4.0之后,wifi的工作方式基本都采用的是比较标准的nl80211方式,以前的wext方式现在使用的已经很少了,关于nl80211和wext的区别,小弟由于接触的少,所以简单的说两句(有错误的请各位大大指正啊,万谢!)
wext:supplicant通过wext直接给wifi driver下命令,即不通过kernel,所以一般以wext工作的driver是不需要load cfg80211.ko的,这个cfg80211.ko就是kernel里面的wireless部分,主要对接supplicant和driver的。
nl80211:supplicant的命令以nl80211的方式下给kernel,经过kernel再发送给driver,这样子做的好处是supplicant和driver之间的通讯方式更加标准话,是以后的主流方式,我后面讲的driver都是以这种方式工作的。
既然是nl80211,那么首先需要build kernel,得到cfg80211.ko,然后用build过的kernel来build driver,得到具体的driver ko,这里面为了区分具体型号的ko,我把名字假设为8192cu.ko,这个是realtek的一款网卡8192cu,市面上比较常见的单频双天线网卡。
拿到两个ko之后load driver的准备工作就做完了,现在把两个ko copy到平台的/system/lib/modules/路径下,这个是android ko的存放路径,记得修改权限为644,不然可能会有权限问题,然后可以用命令把driver load到系统了,具体如下:
(1)#insmod cfg80211.ko
(2)#insmod 8192cu.ko ifname=wlan0 if2name=p2p0
第一步是加载kernel部分的module,这个是nl80211的前提,另一步是加载对应driver的module,这个是网卡使能的前提,之所在insmod 819cu.ko的时候要带后面的两个参数,主要原因是因为标准android所使用的interface是wlan0和p2p0,如果不带上的话可能带起来的interface不是这两个。
如果没有异常的话,load driver部分就完毕了,检验load driver是否正确,可以在/sys/class/net/路径下看有没有wlan0和p2p0两个interface,也可以用netcfg命令来查看是否多了wlan0和p2p0两个interface,如果有的话就说明load driver正确,如果没有的话可以看下网卡是否有插上,如果有插上的话可能就是driver有问题来,没有把卡带起来,这个问题一般要找厂家debug了,小弟接触的少,就帮不上什么忙了。
(2)起supplicant
标准的android系统framework是无法直接与driver进行通讯的,必须通过wpa_supplicant这个deamon来中转才行,这个主要是为了统一不同厂家和不同型号的wifi driver的接口,所以load 完driver之后要做的就是起supplicant,也有少许厂家在debug driver阶段可以不用起supplicant,例如ralink就可以使用iwpriv这个工具直接给driver下命令来作网络操作,由于小弟对driver不熟悉,所以也不在此扩展开来,另外这个不是android的标准流程,仅仅用作driver的debug。
起supplicant比较常见的方式如下:
#wpa_supplicant -Dnl80211 -iwlan0 -c/data/misc/wifi/wpa_supplicant.conf -N -Dnl80211 -ip2p0 -c/data/misc/wifi/p2p_supplicant.conf &
这个命名有点繁琐,我下面给大家详细的解释一下:
(1)wpa_supplicant:这个是android里面supplicant bin档的官方命名,这个可以自己去修改,路径在平台的/system/bin/下,属于环境变量,所以在启动的时候不用带上绝对路径。
(2)-Dnl80211:这个说明supplicant与driver的通讯方式采用的是nl80211,这个根据厂家提供的driver来具体设定,也可以是wext方式,以driver为准。
(3)-iwlan0和-ip2p0:说明会带起两个interface来作supplicant与driver之间的通讯interface,这个可以用netcfg看到这两个interface的状态是UP状态的,也可以用ifconfig来看到新增加的两个使能interface wlan0和p2p0
(4)-c/data/misc/wifi/wpa_supplicant.conf和-c/data/misc/wifi/p2p_supplicant.conf:这两个是android标准的supplicant配置文件,路径如上所述,如果p2p_supplicant.conf不存在的话,可以把wpa_supplicant.conf copy一份出来用作p2p_supplicant.conf,android的原生flow就是这么做的。
(5)-N:说明是在wlan0的基础上再加上一个interface,也就是new的意思 ,以前android4.0的时候只能起一个interface,所以也就没有这个参数了。
(6)&:后台运行符(linux基础,你懂的)
如果一切ok,就可以用ps命令在后台看到wpa_supplicant在后台跑了,这个时候需要验证一下supplicant是否运行正常,主要方法是看/data/system/wpa_supplicant/路径下是否有wlan0和p2p0两个socket,这个是wifi framework和supplicant之间的通讯socket,这里面的这个路径是在supplicant的config文件里面配置的,如果有的话就说明是ok的,如果没有的话就说明有问题,这个问题具体怎么定位后续再说。
(3)给supplicant下指定的命令
从android4.0之后,wifi就增加了wifi direct功能,这个也就是我们通常说的wifi p2p,具体功能跟蓝牙类似,但是能提供更大的带宽,所以使无线传屏功能成为了可能,可以丢掉HDMI无线传输1080p的视频,这个是以后要说的widi和miracast功能,目前android端主要使用的是miracast,例如三星的All Share Cast和小米的WLAN Display,nexus4的无线显示等等都是基于miracast功能,pc端则是WIDI的天下,这个主要是因为WIDI是intel开发出来的技术,在pc上intel的地位你懂的。
废话说多了,现在来看怎么通过supplicant来实现wifi sta连线和p2p连线,这里要说的是sta连线就是我们平时连接路由器的功能,p2p连线就是wifi direct功能,下面分别简单实现sta和p2p连线:
1:sta连线
如果一切ok,而且cheny这个路由器能够联通外网,那么此时你就可以ping通外网,平台与路由器之间的连线就建立起来了。
2:p2p连线
#wpa_cli -ip2p0
>p2p_find (搜索附近的p2p设备)
>p2p_connect 5e:0a:5b:1c:fd:a5 pbc (根据反馈回来的scan list选择想要连线的p2p设备,第一个参数是将要连线p2p设备的mac,另外一个是连线的方式pbc)
>status (查询supplicant的状态)
>quit (退出wpa_cli命令行)
如果一切ok,那么你就可以用ping来ping通另一个p2p设备来哈,不用通过路由器的中转,目前已经有一些厂家针对这个p2p协议有开发一些高速传输软件,例如android上比较有名的快牙,广告介绍的神乎其神,其实底层的实现就是这么简单。
总结
如果上述功能都ok,那么就说明driver和supplicant在该平台是ok的,这个是driver的移植第一步,一般这个是由wifi厂家来确保的,我们学习这个flow的主要作用是检验我们拿到的driver和supplicant是否ok,不然冒然开始做移植,后续出问题来难以定位到具体是什么原因,具体android部分的修改,我们下次再介绍,写的不好请大家指正,小弟也是刚学习android的菜鸟,谢谢!
来源:oschina
链接:https://my.oschina.net/u/4323338/blog/4209235