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

主要功能:

  1. 开启->扫描->连接->断开->关闭
  2. 显示扫描结果->添加/删除保存AP->AP详细信息显示
  3. 间歇扫描->选取连接过的AP->自动重连

次要功能:

  1. 降低功耗:修改扫描间隔,自动断开->自动连接
  2. 多卡切换->在wifi自动重连(仅在EAP-SIM方式下)
  3. 复杂的UI显示

(2)P2P

主要功能:

  1. 开启->扫描->连接->断开->关闭
  2. 显示永久组

次要功能:

UI相关

(3)SoftAp

主要功能:

  1. 开启->扫描->连接->断开->关闭
  2. 显示连接设备数量
  3. 禁止某AP连接

次要功能:

  1. 自动关闭
  2. UI相关

二、wifistatemachine

谷歌在新发布的android-O平台上对framework进行了大量的更改,从wifi部分来看,主要体现在两个部分:

  1. 分离部分代码,加强对framework的管制.这有利于降低android系统的碎片化,保证系统性能.
  2. 将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的连接方式:

传统方式:

  1. add_network
  2. set_network
  3. enable_network
  4. select_network

现在的方式(目前的连接方式和之前的方式的差别)

  1. add_network
  2. select_network

Framework与wpa_supplicant直接的通信方式也有所变化.如下所示:

在之前的android版本中,framework和wpa_supplicant之间是通过socket进行通信而不是现在的binder通信方式.

个人认为这样修改有如下好处:

  1. 从framework和wpa_supplicant的交互来看,双方信息交互频率用binder就可以满足,并且binder更加节省资源.
  2. 增加了代码的易读性,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权威指南

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值