本文部分內(nèi)容修正自《Androd系統(tǒng)原理及開發(fā)要點詳解》,部分內(nèi)容為原創(chuàng)!
前言:
最近項目中要實現(xiàn)幾個與WiFi相關(guān)的機能:WPS,WiFI proxy,Airplane Mode相關(guān)的小機能等。我借著這次機會,對Android的WiFi框架進行了一下學(xué)習(xí),對其有一個初步的了解。所以特地整理了出來,以備與各位探討,并歡迎指教。
一、WiFi基本框架
Android的WiFi系統(tǒng)自上而下包括如下一些內(nèi)容:
WiFi部分在Android系統(tǒng)中作為網(wǎng)絡(luò)部分使用的方法和通常的網(wǎng)絡(luò)相同。唯一特殊的部分是在Settings程序中的WiFi相關(guān)設(shè)置內(nèi)容,它們調(diào)用了WiFi提供了WiFi架構(gòu)提供的Java層接口。
add tip:
JAVA應(yīng)用層 Setting、WifiSwitcher等應(yīng)用
上下的通訊為Binder機制
JAVA框架層
Wifi manager
Wifi service
上下通訊為JNI
C/C++ 框架層
Wifi的JNI
WPA適配層
Wpa_supplicant程序
內(nèi)核空間 Wifi的內(nèi)核驅(qū)動程序
二、WiFi本地實現(xiàn)
Android的WiFi本地部分實現(xiàn)主要包括wpa_spplicant以及wpa_supplicant適配層。
WPA是WiFi Protected Access的縮寫,中文含義為“WiFi網(wǎng)絡(luò)安全存取”。WPA是一種基于標(biāo)準(zhǔn)的可互操作的WLAN安全性增強解決方案,可大大增強現(xiàn)有以及未來無線局域網(wǎng)絡(luò)的數(shù)據(jù)保護和訪問控制水平。
1、 wpa_supplicant
wpa_supplicant是一個開源項目,已經(jīng)被移植到Linux,Windows以及很多嵌入式系統(tǒng)上。它是WPA的應(yīng)用層認(rèn)證客戶端,負(fù)責(zé)完成認(rèn)證相關(guān)的登錄、加密等工作。wpa_supplicant的源代碼目錄為:
./external/wpa_supplicant/
./external/wpa_supplicant_6/
這個工程中的內(nèi)容編譯后主要結(jié)果是生成動態(tài)庫libwpa_client.so和可執(zhí)行程序wpa_supplicant。
wpa_supplicant是一個獨立運行的守護進程,其核心是一個消息循環(huán),在消息循環(huán)中處理WPA狀態(tài)機、控制命令、驅(qū)動事件、配置信息等。wpa_supplicant有很多控制接口,也提供命令行和通行界面的控制模式:而Android與wpa_supplicant的通信通過Socket完成。
關(guān)于wpa_supplicant更多的信息,請參考: http://w1.fi/wpa_supplicant/
libwpa_client.so是一個給客戶單鏈接和調(diào)用的庫,用于和wpa_supplicant守護進程進行通信。
2、 wpa_supplicant適配層
wpa_supplicant適配層是通用的wpa_supplicant的封裝,在Android中作為WiFi部分的硬件抽象層來使用。wpa_supplicant適配層主要用于與wpa_supplicant守護進程的通信,以提供給Android框架使用,它實現(xiàn)了加載、控制和消息監(jiān)控等功能。
wpa_supplicant適配層的源代碼路徑是:
./hardware/libhardware_legacy/include/hardware_legacy/wifi.h
./hardware/libhardware_legacy/wifi/
wpa_supplicant適配層是libhardware_legacy.so的一部分,它需要包含wpa_supplicant的頭文件wpa_ctrl.h,動態(tài)鏈接庫libwpa_client.so。通過wifi.h文件為上一層提供程序調(diào)用接口(實際上就是WiFi的JNI部分)。
wpa_supplicant適配層的構(gòu)成非常的簡單,除了一些加載和連接的接口,它最重要的部分是以下兩個接口:
int wifi_command(const char *command, char *reply, size_t *reply_len);
int wifi_wait_for_event(char *buf, size_t len);
wifi_command()提供講明亮發(fā)送到WiFi系統(tǒng)下層的功能,wifi_wait_for_event()負(fù)責(zé)事件進入的通道,這個函數(shù)將被阻塞,直到收到一個WiFi事件,并以字符串的形式返回。
在wifi.c的實現(xiàn)中:
1)、wifi_command()是wifi_send_command()的封裝, wifi_send_command()通過wpa_ctrl_request()直接命令轉(zhuǎn)發(fā)給wpa_supplicant進程,并返回結(jié)果。
2)、wifi_wait_for_event()僅僅調(diào)用wpa_ctrl_recv()來接受上一次wpa_supplicant上報的事件,如果沒有事件則阻塞于此,上層會通過循環(huán)由此來讀取每一個上報的事件。
本層還提供一些一些與DHCP(動態(tài)主機分配協(xié)議)相關(guān)的操作。
三、WiFi的JNI層
Android中的WiFi系統(tǒng)的JNI部分實現(xiàn)的源碼文件為:
./frameworks/base/core/jni/android_net_wifi_Wifi.cpp
這里實現(xiàn)的本地函數(shù),都是通過調(diào)用wpa_supplicant適配層的接口來實現(xiàn)的(包含適配層的頭文件wifi.h)。
JNI層的接口注冊到Java層的源代碼文件為:
./frameworks/base/wifi/java/android/net/wifi/WifiNative.java
WifiNative將為WifiService、WifiStateTracker、WifiMonitor等幾個WiFi框架內(nèi)部組件提供底層操作支持。
四、WiFi的Java FrameWork層
WiFi系統(tǒng)的Java部分代碼實現(xiàn)的目錄為:
./frameworks/base/wifi/java/android/net/wifi/ // WiFi服務(wù)層的內(nèi)容
./ frameworks/base/services/java/com/android/server/ // WiFi部分的接口
WiFi系統(tǒng)Java層的核心是根據(jù)IWifiManger接口所創(chuàng)建的Binder服務(wù)器端和客戶端,服務(wù)器端是WifiService,客戶端是WifiManger。
IWifiManger.aidl編譯后生成了IWifiManger.java,并生成IWifiManger.Stub(服務(wù)器端抽象類)和IWifiManger.Stub.Proxy(客戶端代理實現(xiàn)類)。WifiService通過繼承IWifiManger.Stub實現(xiàn),而客戶端通過getService()函數(shù)獲取IWifiManger.Stub.Proxy(即Service的代理類),將其作為參數(shù)傳遞給WifiManger,供其與WifiService通信時使用。
1. WiFiManger是WiFi部分與外界的接口,用戶通過它來訪問WiFi的核心功能。WifiWatchdogService這一系統(tǒng)組件也是用WifiManger來執(zhí)行一些具體操作。
2. WifiService是服務(wù)器端的實現(xiàn),作為WiFi部分的核心,處理實際的驅(qū)動加載、掃描、鏈接、斷開等命令,已經(jīng)底層上報的事件。對于主動的命令控制,WiFi是一個簡單的封裝,針對來自客戶端的控制命令,調(diào)用相應(yīng)的WifiNative底層實現(xiàn)。
一般接收到客戶端的命令后,將其轉(zhuǎn)換成對應(yīng)的自身消息塞入消息隊列中,以便客戶端的調(diào)用可以及時返回,然后在WifiHandler的handleMessage()中處理對應(yīng)的消息。而底層上報的事件,WifiService則通過啟動WifiStateTracker來負(fù)責(zé)處理。
1) WifiStateTracker除了負(fù)責(zé)WiFi的電源管理模式等功能外,其核心是WifiMonitor所實現(xiàn)的事件輪詢機制,以及消息處理函數(shù)handleMessage()。
2) WifiMonitor通過開啟一個MonitorThread來實現(xiàn)事件的輪詢,輪詢的關(guān)鍵函數(shù)是前面提到的 阻塞式函數(shù)WifiNative.waitForEvent()。獲取事件后,WifiMonitor通過一系列的Handler通知給WifiStateTracker。這里WifiMonitor的通知機制是將底層事件轉(zhuǎn)換成WifiStateTracker所能識別的消息,塞入WifiStateTracker的消息循環(huán)中,最終在handleMessage()中由WifiStateTracker完成對應(yīng)的處理。
注:WifiStateTracker同樣是WiFi部分與外界的接口,它不像WifiManger那樣直接被實例化來操作,而是通過Intent機制來發(fā)消息通知給客戶端注冊的BroadcastReceiver,以完成和客戶端的接口。
3. WifiWatchdogService是ConnectivityService所啟動的服務(wù),但它并不是通過Binder來實現(xiàn)的服務(wù)。它的作用是監(jiān)控同一個網(wǎng)絡(luò)內(nèi)的接入點(Access Point),如果當(dāng)前接入點的DNS無法ping通,就自動切換到下一個接入點。WifiWatchdogService通過WifiManger和WifiStateTracker輔助完成具體的控制動作。WifiWatchdogService初始化時,通過registerForWifiBroadcasts注冊獲取網(wǎng)絡(luò)變化的BroadcastReceiver,也就是捕獲WifiStateTracker所發(fā)出的通知消息,并開啟一個WifiWatchdogThread線程來處理獲取的消息。通過更改Setting.Secure.WIFI_WARCHDOG_ON的配置,可以開啟和關(guān)閉WifiWatchdogService。
五、Setting中的WiFi設(shè)置
Android的Settings應(yīng)用程序?qū)IFI的使用,是典型的WiFi應(yīng)用方式,也是用戶可見的Android WiFi管理程序。這部分源代碼的目錄為:
. /packages/apps/Settings/src/com/android/settings/wifi/
Setting里的WiFi部分是用戶可見的設(shè)置界面,提供WiFi開關(guān)、掃描AP、鏈接/斷開的基本功能。另外i,通過實現(xiàn)WifiLayer.Callback接口提供了一組回調(diào)函數(shù),用以相應(yīng)用戶關(guān)心的WiFi狀態(tài)的變化。
WifiEnabler和WifiLayer都是WifiSettings的組成部分,同樣通過WifiManger來完成實際的功能,也同樣注冊一個BroadcastReceiver來響應(yīng)WifiStateTracker所發(fā)出的通知消息。WifiEnabler其實是一個比較簡單的類,提供開啟和關(guān)閉WiFi的功能,設(shè)置里面的外層WiFi開關(guān)菜單,就是直接通過它來做到的;而WifiLayer則提供更復(fù)雜的一些WiFi功能,如AP選擇等以供用戶自定義。