Android WIFI 详解
注意:这里的每个事件的捕获(由wifimonitor完成),最终都会调用相应的mWifiStateTracker的消息通知函数上报消息;轮询和事件处理都是在Monitor线程类中实现的。
7)WifiNative
frameworks/base/wifi/java/android/net/wifi/WifiNative.java
里面定义了一个类WifiNative:其中声明了许多本地接口,可由native的标志看出,这是Java代码和本地库之间的联系接口;
8) android_net_wifi_Wifi.java
frameworks/base/core/jni/
里面定义了许多的JNI的本地代码实现,每个实现中都会调用wpa_supplicant适配层的接口,通过包含适配层的头文件wifi.h获取适配层定 义的接口;后面是一个JNINativeMethod数组,定义了每个本地接口和本地实现的对应关系;最后有一个注册函数 regester_XXX_XX(),用以把上面的方法类数组注册到系统中。
该类实现了本地接口的相关功能,并通过调用wpa的适配层的相关函数和wpa_supplicant通信,所以JNI是连接Java框架层和wpa适配层的桥梁.
9)wpa_supplicant适配层,wifi.c:目录libhardware/wifi/
里面定义很多字符串变量和适配层的接口实现,是对wpa_supplicant程序通信的接口封装,用来完成上层和wpa_supplicant的通信, 头文件在libhardware/include/hardware下,这里的函数用来向JNI的本地实现提供调用接口。
这里的函数,我把它们分为三类函数:
一 类是命令相关的(控制)函数,就是在JNI层android_XXX_Command()函数所调用的::Wifi_Command()函数,调用流 程:android_XXX_command()=>docommand()=>wifi_command()=> wifi_send_command()=>wpa_ctrl_require()。
二类是监听函数,即Wifi_wait_for_event()函数,调用流程:android_net_wifi_Waitforevent()=>wifi_wait_for_event()=>wpa_ctrl_recv()。
三类是剩下的函数。
10)wpa_supplicant与上层的接口,wpa_ctrl.c:external/wpa_supplicant
定义了三类套接字,并分别实现了和wpa_supplicant的通信,因此wpa_supplicant适配层和wpa_supplicant层是通过socket通讯的。
要 是从wifi.c中真的很难看出它和wpa_supplicant有什么关系,和它联系密切的是wpa_ctrl.h文件,这里面定义了一个类 wpa_ctrl,这个类中声明了两个Socket套接口,一个是本地一个是要连接的套接口,wpa_ctrl与wpa_supplicant的通信就需 要socket来帮忙了,而wpa_supplicant就是通过调用wpa_ctrl.h中定义的函数和wpa_supplicant进行通讯 的,wpa_ctrl类(其实是其中的两个socket)就是他们之间的桥梁。
11)wpa_supplicant和driver_wext驱动接口的联系:
driver.h:该文件定义了系列结构,首先是一个wpa_scan_result结构,这是一个扫描结果的通用格式,里面包含了扫描的所有信息(如 BSSID,SSID,信号质量,噪音水平,支持的最大波特率等等信息),每个驱动接口实现负责将从驱动中上传的扫描信息的格式转换到该通用的扫描信息格 式;然后是一些宏定义和枚举定义,最后也是最重要的是wpa_driver_ops结构,该结构是wpa driver的操作函数集合,里面有驱动接口的名称和很多的函数指针。
drviers.c:该文件很简单,首先是一些外部变量的引用声明,都是不同驱动操作接口的集合wpa_driver_XXX_ops变量;然后就是定义一个驱动操作接口集合的数组,根据宏定义添加对应的驱动操作接口集合的变量。
drvier_XXX.h:这是不同驱动接口头文件,主要声明了操作接口
drvier_XXX.c:实现操作接口,定义一个操作集合变量,并用上面定义的函数初始化其中的函数指针
注意:下面要搞清楚wpa_supplicant守护进程是如何操作,最后调用驱动接口集合中的函数的;要知道wpa_supplicant是为不同驱动 和操作系统具有更好移植性而被设计的,以便在wpa_supplicant层不用实现驱动的具体接口就可以添加新的驱动程序;在 wpa_supplicant结构中有一个wpa_drv_ops类型的drvier成员,在wpa_supplicant进程中,经常通过 Wpa_supplicant_XXX函数传递wpa_supplicant实例指针wpa_s参数给wpa_drv_XXX函数来调用它,在 wpa_drv_XX中会通过wpa_s->driver->XXX()的流程来调用通用驱动接口,简单才是生活的真相,可android始 终让我感到真相还是遥不可及。
12)WifiWatchdogService:
首 先声明了两个主要变量mWifiStateTracker,mWifiManager,需要这两个类对象来完成具体的控制工作,在 WifiWatchdogService的构造函数中,创建了这两个类,并通过regesterForWifiBroadcasts()注册了 BroadcastReceiver,BroadcastReceiver是用来获取网络变化的,然后启动了一个WatchdogTread线程,用来处 理从WifiStateTracker接收到的消息。
frameworks/base/services/java/com/android/server/WifiWatchdogService.java
WifiWatchdogService(Context context,WifiStateTracker wifiStateTracker) {
mContext = context;
mContentResolver = context.getContentResolver();
mWifiStateTracker =wifiStateTracker;
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
createThread();
// The content observer to listen needs a handler, which createThreadcreates
registerForSettingsChanges();
if (isWatchdogEnabled()) {
registerForWifiBroadcasts();
}
if (V) {
myLogV(WifiWatchdogService: Created);
}
}
WifiWatchdogHandler继承了handler类,成为一个消息处理类,定义handlemessage()函数,处理消息队列上的消息。
二,wpa_supplicant再解析
1)wpa_ctrl.h:
该文件中并没有定义structwpa_ctrl结构,因为在其他包含该文件的.c文件中不能直接使用该结构的成员,这里主要声明了几个用于使用 socket通信的函数接口,包 括:wpa_ctrl_open,wpa_ctrl_close,wpa_ctrl_attach,wpa_ctrl_detach,wpa_ctrl_cleanup,wpa_ctrl_recv,wpa_ctrl_request, wpa_ctrl_pending, wpa_ctrl_get_fd 等函数。
评论