前言

小弟从事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的菜鸟,谢谢!

(wifi)wifi移植之命令行调试driver和supplicant的更多相关文章

  1. linux命令行调试邮件服务器

    linux命令行调试邮件服务器 1. Linux客户端调试邮件过程 [root@mxtest ~]# telnet mail.xx.com 25 Trying 172.16.236.103... Co ...

  2. 方法:怎么用ionic命令行调试你的ionic app

    官网上有很详细的解说  http://blog.ionic.io/live-reload-all-things-ionic-cli/ 下面说说我自己的调试过程(android版): 首先用命令行进入你 ...

  3. perl-cgi命令行调试

    来源: http://www.cnblogs.com/itech/archive/2012/09/23/2698838.html 参考: http://docstore.mik.ua/orelly/l ...

  4. 使用GDB命令行调试器调试C/C++程序

    原文:http://xmodulo.com/gdb-command-line-debugger.html作者: Adrien Brochard 没有调试器的情况下编写程序时最糟糕的状况是什么?编译时跪 ...

  5. 记录tiny6410 jlink 命令行调试linux-2.6.38内核

    1\首先启动nandflash uboot->linux内核->文件系统,进入文件系统命令行 2\启动JLinkGDBServer -device ARM11 3\启动arm-none-e ...

  6. 使用GDB命令行调试器调试C/C++程序【转】

    转自:https://linux.cn/article-4302-1.html 编译自:http://xmodulo.com/gdb-command-line-debugger.html作者: Adr ...

  7. 【转载】PDB命令行调试Python代码

    转载自这里. (博主按:PDB调试python代码和用GDB调试c++代码很类似) 你有多少次陷入不得不更改别人代码的境地?如果你是一个开发团队的一员,那么你遇到上述境地的次数比你想要的还要多.然而, ...

  8. 记录ok6410 jlink 命令行调试uboot

    1\启动ok6410 进入uboot命令行 2\启动JLinkGDBServer -device ARM11 3\arm-none-eabi-gdb u-boot 初始化脚本 # Connect to ...

  9. Python开发环境Wing IDE如何进行命令行调试

    Wing IDE专业的调试探针提供了一种强大的方法来发现和解决复杂的错误.这很像Python Shell但允许用户直接参与进已经暂停的调试程序中: 通过键入在刚才发生异常的地方键入下列数值进行尝试: ...

随机推荐

  1. wlr快捷键

    ref:http://www.cnblogs.com/zhangyang/archive/2011/07/22/2113856.html   Windows Live Writer提供了许多方便的快捷 ...

  2. Python装饰器探究——装饰器参数

    Table of Contents 1. 探究装饰器参数 1.1. 编写传参的装饰器 1.2. 理解传参的装饰器 1.3. 传参和不传参的兼容 2. 参考资料 探究装饰器参数 编写传参的装饰器 通常我 ...

  3. P1182 数列分段Section II

    P1182 数列分段Section II 题目描述 对于给定的一个长度为N的正整数数列A[i],现要将其分成M(M≤N)段,并要求每段连续,且每段和的最大值最小. 关于最大值最小: 例如一数列4 2 ...

  4. P1336 最佳课题选择

    P1336 最佳课题选择 题目描述 Matrix67要在下个月交给老师n篇论文,论文的内容可以从m个课题中选择.由于课题数有限,Matrix67不得不重复选择一些课题.完成不同课题的论文所花的时间不同 ...

  5. Mac下安装Angular报错处理

    安装 Angular CLI 命令: sudo npm install -g @angular/cli 打印如下错误:(权限问题) gyp WARN EACCES user "root&qu ...

  6. laravel5.5开发composer扩展包

    目录 1. 下载laravel框架,并命名(framework) 2. 创建相关目录 3. 项目根目录下的composer.json文件中声明命名空间 4. 在包的根目录(packages/arche ...

  7. laravel5.5artisan命令

    目录 1. 简介 2. 编写命令 2.1 构建自己的命令 2.2 闭包命令 3. 定义输入期望 4.I/O 命令 5. 注册命令 6. 调用命令 1. 简介 Artisan 是 Laravel 自带的 ...

  8. js对数组去重的完整版

    数组去重是很常见的一个需求,而各种各样的姿势也很多,常见的如indexOf,或者hash,但是他们还是有缺陷,这里我查了一些资料做补充. 一般方式 //一般方法->使用indexOf Array ...

  9. day06_04 购物车讲解02

    1.0 补充知识 a,b = [2,3] print(a) print(b) #>>>2 #>>>3 a,b = (2,3) print(a) print(b) # ...

  10. oracle 隔离级别、事务怎么开始的以及如何查看数据库采用字符集

    把一下语句全部粘贴至控制台运行后可以查看oracle 隔离级别 declare trans_id ); begin trans_id := dbms_transaction.local_transac ...