Android Wifi实现分析
其实现在已经到了android-9了。但是这篇文档写的是android-8而且android-9的变化不是非常大,所以也懒得修改。
一、模块功能分解
老架构,网上找的。8.0以后不一样了。
1. wifi.c没了,所有驱动相关的操作都通过treble架构移交厂商了
2.IPC方式变了,之前是socket与supplicant通信,现在是HIDL抽象的binder方式
3.扫描功能从supplicant中转移到android原生实现。
4.wpa_supplicant.conf去除,保存ap使用wificonfig.xml由android原生管理。(热点也是)
(1)STA
主要功能:
- 开启->扫描->连接->断开->关闭
- 显示扫描结果->添加/删除保存AP->AP详细信息显示
- 间歇扫描->选取连接过的AP->自动重连
次要功能:
- 降低功耗:修改扫描间隔,自动断开->自动连接
- 多卡切换->在wifi自动重连(仅在EAP-SIM方式下)
- 复杂的UI显示
(2)P2P
主要功能:
- 开启->扫描->连接->断开->关闭
- 显示永久组
次要功能:
UI相关
(3)SoftAp
主要功能:
- 开启->扫描->连接->断开->关闭
- 显示连接设备数量
- 禁止某AP连接
次要功能:
- 自动关闭
- UI相关
二、wifistatemachine
谷歌在新发布的android-O平台上对framework进行了大量的更改,从wifi部分来看,主要体现在两个部分:
- 分离部分代码,加强对framework的管制.这有利于降低android系统的碎片化,保证系统性能.
- 将framework从Java向C++迁移,提升系统整体运行效率.
(1)WifiStatemachine在android-O实现架构变化:
在android-O之前,framework上一共维护了20个状态.其中softAp相关的状态未列出.Android-O上删除了加载驱动相关的状态,将这部分实现迁移到C++部分.驱动加载成功后,会启动wpa_supplicant.图画的不好,凑合看吧
注:
红色部分为在android-O中删除的状态,下面会说这部分的处理在O中的变化,并且讨论变化的原因.
(2)Wifi enable
这部分的状态切换个刚开始没有看懂,因为ConnectModeState没有被显示的切换,调查发现状态机在切换过程中已经执行过ConnectModeState中的Enter和EXT,并且相应的在子状态DisconnectedState中无法处理的,会交给ConnectModeState(父状态)处理.
代码调用流程:
InitialState:
setOperationalMode->InitialState::ProcessMessage(CMD_START_SUPPLICANT)->setupForClientMode()->enableSupplicant()->startMonitoring()->transitionTo(mSupplicantStartingState)
加载驱动,启动wpa_supplicant,启动Monitor...
SupplicantStartingState:
setOperationalMode->InitialState::ProcessMessage(CMD_START_SUPPLICANT)->setupForClientMode()->enableSupplicant()->startMonitoring()->transitionTo(mSupplicantStartingState)
设置mac地址,初始化wps(Wi-Fi Protected Setup),发送wpa_supplicant状态变化广播...
SupplicantStartedState:
Enter()->setWifiState(WIFI_STATE_ENABLING)->transitionTo(mDisconnectedState)->setPowerSave();
设置相关参数,切换至DisconnectedState进行定期扫描...
DisconnectedState:
Enter()->processMessage(CMD_NO_NETWORKS_PERIODIC_SCAN)->startScan()->SupplicantStartedState::processMessage(CMD_START_SCAN)->checkOrDeferScanAllowed()->processMessage(CMD_START_SCAN)->handleScanRequest()->startScanNative()
进行定期扫描操作...
O的变化:
个人认为android-O的主要变化在于加载驱动这部分.按照逻辑,wifi启动先后顺序为:WifiService->load driver->start wpa_supplicant。所以认定driver的启动必然在wpa_supplicant启动之前完成.
setupForClientMode()->setupDriverForClientMode()->Server::createClientInterface()->SetupInterface()
(3)Wifi connect
根据上图,wifi在链接过程中先切换到ConnectModeState处理连接相关的消息,后直接切换至ObtainingIpState启动DHCP,后切换至同级状态ConnectedState.表示连接已经建立.
代码调用流程:
DisconnectedState:
connect->ConnectModeState::ProcessMessage(CONNECT_NETWORK)->addOrUpdateNetwork()->connectToUserSelectNetwork()->getConfiguredNetwork()->enableNetwork()->startConnectToNetwork()->ConnectModeState::ProcessMessage(CMD_START_CONNECT)->connectToNetwork()->ConnectModeState::ProcessMessage(NETWORK_CONNECTION_EVENT)->sendNetworkStateChangeBroadcast()->transitionTo(mObtainingIpState)
触发add_network,set_network,enable_network等一系列命令...
ObtainingIpState:
L2ConnectedState::Enter()->ObtainingIpState::Enter()->StoppedState::ProcessMessage(CMD_START)->StartedState::Enter()->transitionTo(mRunningState)->startIPv4()->processMessage(CMD_START_DHCP)->L2ConnectedState::ProcessMessage(CMD_IP_CONFIGURATION_SUCCESSFUL)->handleIPv4Success()->transitionTo(mConnectedState)
L2已经链接成功,接下来启动DHCP分配IP地址.成功后切换至ConnectedState
O的变化:
根据对android-O的代码研究,google改变了wifi的连接方式:
传统方式:
- add_network
- set_network
- enable_network
- select_network
现在的方式(目前的连接方式和之前的方式的差别):
- add_network
- select_network
Framework与wpa_supplicant直接的通信方式也有所变化.如下所示:
在之前的android版本中,framework和wpa_supplicant之间是通过socket进行通信而不是现在的binder通信方式.
个人认为这样修改有如下好处:
- 从framework和wpa_supplicant的交互来看,双方信息交互频率用binder就可以满足,并且binder更加节省资源.
- 增加了代码的易读性,binder的函数直接调用比以往的命令发送、字符串解析这种方式更加直观.
(4)Wifi disconnect
在ConnectedState下收到断开链接请求,交由父状态L2ConnectedState处理并切换至同级别状态DisconnectingState,在进入enter函数时发送延时消息,收到后切换至DisconnectedState.
代码调用流程:
L2ConnectedState:
disconnect->L2ConnectedState::ProcessMessage(CMD_DISCONNECT)
->disconnect()
->mSupplicantStaIfaceHal.disconnect()
->transitionTo(mDisconnectingState)
断开L2链接,切换至DisconnectingState.
DisconnectingState:
DisconnectingState::Enter()->ProcessMessage(CMD_DISCONNECTING_WATCHDOG_TIMER)->handleNetworkDisconnect()->stopRssiMonitoringOffload()->stopIpManager()->clearLinkProperties()->transitionTo(mDisconnectedState);
停止RSSI,停止IPMananger,回收底层资源并切换到DisconnectedState.
三、驱动架构
根据结构所示, firmware部分完成了硬件射频的工作.根据调查,驱动程序主要是负责传递消息,将上层发送的消息和数据封装为固件消息发送给固件并反馈结果.此部分参考了broadcom的实现。
(1)网络设备
Linux设备驱动分为:字符设备,块设备,网络设备. 在WLAN模块中,wifi自然属于网络设备之列.
下图为网络设备在Linux系统中的层次结构.
在让人耳熟能详的TCP/IP协议栈之下就是网络设备的地盘.这里首先说明一下net_device中几个重要的属性.
struct net_device{//用于存放网络设备的设备名称;char name[IFNAMSIZ]; --> wlan0//网络设备的接口索引值,独一无二的网络设备标识符;int ifindex; ---> ioctl的索引//网络设备接口的最大传输单元;unsigned mtu; --->1500//硬件接口头长度;unsigned short hard_header_len;//网络设备接口的MAC地址;unsigned char *dev_addr;}
(2)命令处理
在android-O的最新架构中,scan命令不再由wpa_supplicant发送给driver,而是直由上层的netlinkMananger发送,这样省略了通过wpa这个中间件.个人理解google这次修改的原因是因为scan命令是一个十分频繁并且要求实时反馈的命令,总是通过wpa_supplicant发送该信息在内存和时间上都没有好处.并且scan命令不同于assoc, disassoc, reassoc等需要封装完整的数据包给driver,所以scan命令也具备从wpa_supplicant中独立出来的条件.
(3)数据收发
作为网络设备, 最重要的功能就是保证数据收发的稳定和高速。所有网络设备的数据收发如下
下图简要说明了数据收发过程中的代码调用.
DHCP
DHCP为ipv4的NAT地址控制提供了有效的帮助,使得局域网内的ip地址可以精确的分配。
上图为DHCP的架构,其中还有ip地址租赁延长的消息没有体现出来。这里先不赘述。
总结
这里不介绍wpa_supplicant的内容,出于一下原因:
1. Wpa_supplicant代码体积大, 但是很少出现问题
2. Wpa_supplicant是开源项目,可以从网上得到资料
3. 深入理解android wifi模块这本书对wpa_supplicant进行了系统的讲解.
Wifi的内容很多,不仅设计了802.11协议还夹杂了各类rfc安全协议.所以这里仅仅介绍STA功能中简单的代码架构,具体的每一处代码还需要继续研究.此外,在驱动程序中可以看到,数据收发数据无差别的适应方式应该涵盖了STA,P2P,SoftAp.而前期的交互中,SoftAp部分代码基本与STA和P2P独立, 而STA和P2P之间有着相近的函数调用.
Android-O的变化可以看出google在接下来的版本中会继续将framework中java部分的实现向C++迁移,同时java8的特性也在这一版本中体现.不仅体现了google对android不遗余力的优化.
参考资料
http://weiguozhihui.blog.51cto.com/3060615/1584894
深入理解android WiFi、NFC、GPS卷
802.11权威指南
Android Wifi实现分析相关推荐
- Android WIFI框架分析(1)
趁做Android WIFI驱动移植,对Android WIFI框架做了深刻的分析,并做此文档共同学习. 对上层WIFI的应用,基本流程为:(1)WIFI初始化 (2)Wifi启动 (3) ...
- android wifi的进程,Android wifi简要分析
这里列了很多,但是大致可以分为四个主要的类ScanResult wifiConfiguration WifiInfo WifiManager (1)ScanResult,主要是通过wifi 硬件的扫描 ...
- android wifi模块分析
声明:本文纯属网上资料收集,版权归源作者所有,转载时请标明为转载文章 现在对android平台的wifi模块了解了一段时间,现在做一些简要总结,以便以后查阅和与修正,上正文. [Wifi模块学习流程] ...
- Android wifi探究二:Wifi framework层源码分析
上一篇博客初步认识了wpa_supplicant的作用和使用方法,并且尝试着梳理了wifi的大框架,不过,java层的框架我们忽略了,没有分析,也就是说上一篇博客简单的指出了wifi代码的大框架,那么 ...
- Android WiFi 经常掉线出现的几个原因分析!
Android WiFi 经常掉线出现的几个原因分析! 原因1 .从Log分析来看,这个是由于Dhcp request fail 导致最终disconnect . Log 分析如下: 16:53:3 ...
- Android WIFI调试助手源码分析
**WIFI调试助手源码(支持十六进制和ACSII发送与接收) 客户端(我自己修改的工程文件,支持十六制的接收与发送,主要是通信协议,代码简单,可轻松改造为上位机) ** 分为操作分析和代码分析. 1 ...
- Android -- Wifi启动流程分析
Android -- Wifi启动流程分析 Android网络各个模式中,Wifi应该是目前最常用的一种网络方式了:下面就简单介绍下Android中Wifi的启动流程. 当我在Setting菜单里点击 ...
- Android WiFi —softAP流程分析
Android WiFi - Ap功能实现与源码分析 0. 前言 wifiAp的ip WifiAp的config分析 2.1 默认的config 2.2 修改wifiAp的config配置流程 开启/ ...
- Android Wi-Fi子系统学习笔记
一.学习目的 了解Android Wi-Fi模组的移植及调试 二.基础知识 1.wifi的两个标志: (1)无线 (2)基于IEEE802.11协议 2.Android wifi模块的三个作用 (1 ...
最新文章
- linux部分基础命令总结,Linux 基础命令总结3
- Java性能优化推荐书!RocketMQ消息丢失场景及解决办法
- 请求https错误: unable to find valid certification
- R3获取kernel32地址
- 华为服务器操作系统密码,服务器操作系统密码忘记
- 室内空气流动原理图_新风系统的工作原理是什么 新风系统各部件的用途
- 了解下C#由转换二进制所引起的思考
- aspen变压吸附塔_空压机科普:吸附式干燥机的结构和原理
- Google的自动驾驶汽车无事故成功完成30万英里的驾驶路程
- linux java mail 时间,Javamail在Windows上工作,而不是在Linux上
- 一名网工对Linux运维的一次经历
- linux web目录安全设置,[LNMP]Linux的Web环境的安全配置
- 云计算的应用解决方案
- 蓝屏修复工具和蓝屏代码查询软件
- SQL注入语法类型和sql盲注
- 安卓移动端appium环境搭建流程
- oracle数据库书籍mobi,Oracle Database 12c PL/SQL开发指南(第7版) pdf epub mobi txt 下载...
- swiper禁用手动拖拽
- ffmpeg合并多个MP4视频
- (转)全球顶级对冲基金TOP50