(wifi)wifi移植之命令行调试driver和supplicant

☆樱花仙子☆ 提交于 2021-02-01 08:52:56

前言    

    小弟从事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连线

#wpa_cli -iwlan0                                     (使用wpa_cli给supplicant下命令,这个是supplicant的client端)
>scan                                                        (让driver做扫描动作)
>scan_results                                         (让driver反馈扫描结果给supplicant)
>add_network                                         (添加一个网络,这里面会给一个号码,一般开机的第一次添加就是0)
>set_network 0 ssid "cheny"                (选择一个名叫cheny的路由器,这个是前面scan_result反馈回来的名字)
>set_network 0 psk "12345678"          (输入名叫cheny的路由器的密码12345678,加密方式是wpa-psk)
>enable_network 0                                 (使能cheny路由器,也就是建立连接)
>save                                                          (保存)
>status                                                        (查看supplicant的当前状态,一般结果是compeleted)
>quit                                                            (退出wpa_cli命令行)
#dhcpcd -iwlan0                                       (给wlan0这个interface分配ip)
#ifconfig wlan0                                          (查看wlan0的信息,一般会有ip,mac,gateway,netmask,dns等等信息)
    如果一切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的菜鸟,谢谢!
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!