Android WiFi框架学习-打开WiFi

Android WiFi框架学习--打开WiFi

  一、Wi-Fi各层文件路径

  1、WifiSettings部分(Java应用层)

  packages/apps/Settings/src/com/android/settings/wifi/

  WifiSettings.java & WifiEnabler.java

  2、Java Framework部分
frameworks/base/services/java/com/android/server/WifiService.java
frameworks/base/wifi/java/android/net/wifi/

  WifiManager.java & WifiMonitor.java & WifiStateMachine.java &WifiNative.java

  3、Wifi的JNI部分

  frameworks/base/core/jni/android_net_wifi_Wifi.cpp

  4、 Wifi的HAL(硬件抽象层)代码

  hardware/libhardware_legary/wifi/wifi.c

  5、 wpa_supplicant的源码部分 

  vendor/******/common/external/p2p_supplicant_8/

  vendor/******/common/external/wpa_supplicant_8/

  注:第1、2点只是针对“开启wifi”这一过程列出的部分主要文件。

  二、相关文件介绍

  1、WifiSettings & WifiEnabler

  都属于应用程序层,是对相关操作结果的一个视觉呈现。主要负责界面初始化、接收底层事件消息进行界面更新、发出相应命令等。

  2、WifiManager & WifiService & WifiStateMachine & WifiMonitor & WifiNative

  WifiManager:是Wi-Fi部分对外的接口,通过它来访问Wi-Fi的核心功能。

  WifiService:是Wi-Fi部分的核心,负责Wi-Fi整个流程的控制。

  WifiStateMachine:继承了StateMachine(一个层次结构的状态机,可以处理一些消息,并维护一个层次结构的状态)。它开始处于初始状态(InitialState),可以在不同的状态之间进行转换,需要通过延后deferMessage()+状态切换transitionTo()才能处理同一个message。在WifiStateMachine中,下发了加载驱动和启动supplicant命令,启动了WifiMonitor。Wifi状态机层次结构图如下:

  

  WifiMonitor:开启一个MonitorThread来实现事件的轮询,而轮询的关键函数是WifiNative.waitForEvent()。WifiMonitor将接收到的底层事件转换成WifiStateMachine所能识别的消息,然后将消息发送给WifiStateMachine。

  WifiNative:封装了一系列本地调用的接口函数,通过JNI调用C++代码。

  3、android_net_wifi_Wifi.cpp

  这里实现的本地函数,除了register_android_net_wifi_WifiManager(JNIEnv* env)是调用AndroidRuntime里的函数,用来注册本地方法,其他都是通过调用wpa_supplicant适配层的接口来实现的。

  4、wifi.c

  作为Wi-Fi部分的硬件抽象层来使用,主要用于与wpa_supplicant守护进程的通信,它实现了驱动加载、命令、消息监控等功能。它包含了wpa_supplicant的头文件wpa_ctrl.h,。

  它有两个非常重要的接口函数:

  1)        int wifi_command(const char *ifname, const char *command, char *reply, size_t *reply_len)是对wifi_send_command()的封装,wifi_send_command()通过wpa_ctrl_request()直接把命令转发给wpa_supplicant进程,并返回结果。

  2)        int wifi_wait_for_event(const char *ifname, char *buf, size_t buflen)是对wifi_wait_on_socket()的封装,wifi_wait_on_socket()调用wpa_ctrl_recv()来接收上一次wpa_supplicant上报的消息。如果没有消息则阻塞于此。上层会通过循环来读取每一个上报的消息。

  5、wpa_ctrl.c & ctrl_iface_unix.c & ctrl_iface.c & l2_packet_linux.c

  wpa_ctrl.c:它是一个单独的以C语言文件形式的小程序库,wpa_supplicant实现了一系列的控制接口,而它提供辅助函数使得上行控制接口便于使用。外部程序可以链接到这个文件,然后就可以使用wpa_ctrl.h中声明的库函数与wpa_supplicant相互作用。其主要工作是通过unix domain socket建立一个control interface的client结点,与wpa_supplicant的server结点通信。

  ctrl_iface.unix.c:实现wpa_supplicant的unix domain socket通信机制中的server结点,完成对client结点的响应。其中最主要的两个函数为:

  1)        static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx, void *sock_ctx):接收并解析client发送的request命令,然后根据不同的命令调用底层不同的处理函数,将获得的response回馈给client结点。

  2)        static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv, int level, const char *buf, size_t len):向注册的monitor interface主动发送event事件。

  ctrl_iface.c:主要实现了各种request命令的底层处理函数。

  Note:上行接口--wpa_supplicant提供两种由外部模块获取信息的方式:一种是外部模块通过发送request命令然后获取response的问答模式;另一种是wpa_supplicant主动向外部发送event事件,由外部模块监听接收。外部模块通过调用wpa_ctrl_open()两次,建立两个control interface接口,一个为ctrl interface,用于发送命令,获取消息;另一个为monitor interface,用于监听接收来自wpa_supplicant的event。此举可以降低通信的耦合性,避免response和event的相互干扰。

  6、drivers.c & driver.h & driver_wext.c & driver_wext.h

  drivers.c:驱动接口列表,drivers.c文件中必须注册一个wpa_driver_ops结构体指针,driver.h中的部分or全部函数在结构体wpa_driver_ops中注册。wpa_supplicant工作独立于硬件部分,wpa_supplicant将调用这些接口里的函数来控制驱动/无线局域网卡。通过回调函数wpa_supplicant_event()来获取驱动响应的消息。

  driver.h:定义了一系列驱动接口供wpa_supplicant和hostapd使用。文件共分为数据结构、宏定义、枚举、函数四个部分,数据结构用于各种驱动程序操作;函数部分定义了用于驱动事件报告的函数wpa_supplicant_event()和一些方便的辅助函数。

  driver_wext.c & driver_wext.h:实现了wext形式的wpa_driver_ops,并创建了PF_INET socket接口和PF_NETLINK socket接口,然后通过这两个接口完成与kernel的信息交互。

  l2_packet_linux.c:主要用于实现PF_PACKET socket接口,通过该接口,wpa_supplicant可以直接将802.1X packet发送到L2层,而不经过TCP/IP协议栈。

  Note:下行接口--wpa_suplicant提供的下行接口主要用于和kernel(driver)进行通信,下发命令和获取信息。主要包括3种接口:

  1)         PF_INET socket接口:主要用于向kernel发送ioctl命令,控制并获取相应信息。

  2)         PF_NETLINK socket接口:主要用于接收kernel发送上来的event事件。

  3)         PF_PACKET socket接口:主要用于向driver传递802.1X报文。

  注:对于第五、六点,更多信息请见

  三、流程介绍

  从点击打开wifi到wifi开启成功至扫描AP,其流程如下图:

  

  流程框图:

  

  与wpa_supplicant交互:

  

你可能感兴趣的:(android)