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 等函數。
評論