WIFI模塊
申屠家振 修改 1.2011年1月19日 2.2011年1月27日 對android平臺(tái)的WIFI模塊進(jìn)行已經(jīng)有段時(shí)間了,,現(xiàn)在做一總結(jié),以便以后查閱與修正,。 心得之作,,如有異議,請斧正,。
WIFI是一種無線連接技術(shù),,可用于PC,PDA,手機(jī)等終端,。WIFI的目的是改善基于IEEE802.11標(biāo)準(zhǔn)的無線網(wǎng)絡(luò)產(chǎn)品之間的互通性,,也就是說WIFI是基于802.11標(biāo)準(zhǔn)的,但WIFI不等同無線網(wǎng)絡(luò),。
簡單介紹一下,,WIFI模塊的基本功能:
除了在WIFI設(shè)置界面可以開關(guān)WIFI,還有其他的入口可以開關(guān),,要查看這些開關(guān)狀態(tài)是否一致,。還有就是飛行模式對WIFI開關(guān)的影響,由于WIFI開和關(guān)都有一個(gè)時(shí)間過程,,而飛行模式的開關(guān)瞬間完成,,所以有時(shí)會(huì)出現(xiàn)沖突。
新可用網(wǎng)絡(luò)的定義是自WIFI模塊開啟后,,從未發(fā)現(xiàn)過的,,為加密的網(wǎng)絡(luò)。只有滿足了新可用網(wǎng)絡(luò)的定義,,才會(huì)有提醒,。
連接斷開各種不同加密類型的網(wǎng)絡(luò)(具體類型下文有詳解)
需要路由器關(guān)閉SIID廣播??墒謩?dòng)輸入SIID,,網(wǎng)絡(luò)加密類型,密碼,。對于OPAL手機(jī)來說,,路由器隱藏了SSID,手動(dòng)添加的網(wǎng)絡(luò)是無法連接的,。
手動(dòng)點(diǎn)擊搜索按鈕可以搜索網(wǎng)絡(luò),,也可以等待WIFI模塊自動(dòng)搜索網(wǎng)絡(luò)。
由于WIFI模塊是用電大戶,,所有為了省電,,android的WIFI加了一個(gè)休眠策略,可以設(shè)置永遠(yuǎn)不斷開,,充電時(shí)不斷開和鎖屏?xí)r斷開,。要測試休眠設(shè)置是否有效,,可以在路由器上PING手機(jī)的IP,,PING通就是連接狀態(tài)。OPAL手機(jī)的休眠策略屬于完全失效,,現(xiàn)在的情況是無論選哪個(gè)都會(huì)一直保持連接,,鎖屏后15分鐘再休眠。
Android系統(tǒng)里對IP設(shè)置的輸入限制很有問題,我一直認(rèn)為這是弱智的限制,。正常IP的范圍在0-255之間,,android對IP輸入的限制是整數(shù)0到整數(shù)255之間,也就是說0000.000200.001.001這樣一個(gè)IP都能合法輸入,。
【初始化】 2 ConnectivityService的構(gòu)造函數(shù)會(huì)創(chuàng)建WifiService 3 WifiStateTracker會(huì)創(chuàng)建WifiMonitor接收來自底層的事件,WifiService和WifiMonitor是整個(gè)模塊的核心,。WifiService負(fù)責(zé)啟動(dòng)關(guān)閉wpa_supplicant、啟動(dòng)關(guān)閉WifiMonitor監(jiān)視線程和把命令下發(fā)給wpa_supplicant,而WifiMonitor則負(fù)責(zé)從wpa_supplicant接收事件通知,。 【連接AP】 1 WirelessSettings在初始化的時(shí)候配置了由WifiEnabler來處理Wifi按鈕 2當(dāng)用戶按下Wifi按鈕后, Android會(huì)調(diào)用WifiEnabler的onPreferenceChange,再由WifiEnabler調(diào)用WifiManager的setWifiEnabled接口函數(shù),通過AIDL,實(shí)際調(diào)用的是WifiService的setWifiEnabled函數(shù),WifiService接著向自身發(fā)送一條MESSAGE_ENABLE_WIFI消息,在處理該消息的代碼中做真正的使能工作:首先裝載WIFI內(nèi)核模塊(該模塊的位置硬編碼為"/system/lib/modules/wlan.ko" ),然 后 啟 動(dòng)wpa_supplicant (配 置 文 件 硬 編 碼 為"/data/misc/wifi/wpa_supplicant.conf")再通過WifiStateTracker來啟動(dòng)WifiMonitor中的監(jiān)視線程 3當(dāng)使能成功后,會(huì)廣播發(fā)送WIFI_STATE_CHANGED_ACTION這個(gè)Intent通知外界WIFI已 經(jīng) 成 功 使 能 了 ,。WifiEnabler創(chuàng) 建 的 時(shí) 候 就 會(huì) 向Android注 冊 接 收WIFI_STATE_CHANGED_ACTION,因此它會(huì)收到該Intent,從而開始掃描 【查找AP】 1掃描的入口函數(shù)是WifiService的startScan,它其實(shí)也就是往wpa_supplicant發(fā)送SCAN命令。 2當(dāng)wpa_supplicant處理完SCAN命令后,它會(huì)向控制通道發(fā)送事件通知掃描完成,從而wifi_wait_for_event函數(shù)會(huì)接收到該事件,由此WifiMonitor中的MonitorThread會(huì)被執(zhí)行來出來這個(gè)事件,。 3 WifiStateTracker則接著廣播發(fā)送SCAN_RESULTS_AVAILABLE_ACTION這個(gè)Intent,。 4 WifiLayer注冊了接收SCAN_RESULTS_AVAILABLE_ACTION這個(gè)Intent,所以它的相關(guān)處理函數(shù)handleScanResultsAvailable會(huì)被調(diào)用,在該函數(shù)中,先會(huì)去拿到SCAN的結(jié)果(最終是往wpa_supplicant發(fā)送SCAN_RESULT命令并讀取返回值來實(shí)現(xiàn)的),List<ScanResult> list = mWifiManager.getScanResults();對每一個(gè)掃描返回的AP,WifiLayer會(huì)調(diào)用WifiSettings的onAccessPointSetChanged函數(shù),從而最終把該AP加到GUI顯示列表中。 【配置AP參數(shù)】 當(dāng)用戶在WifiSettings界面上選擇了一個(gè)AP后,會(huì)顯示配置AP參數(shù)的一個(gè)對話框,。 showAccessPointDialog(state, AccessPointDialog.MODE_INFO); 【連接】 當(dāng)用戶在AcessPointDialog中選擇好加密方式和輸入密鑰之后,再點(diǎn)擊連接按鈕,Android就會(huì)去連接這個(gè)AP,。 1 WifiLayer會(huì)先檢測這個(gè)AP是不是之前被配置過,這個(gè)是通過向wpa_supplicant發(fā)送LIST_NETWORK命令并且比較返回值來實(shí)現(xiàn)的, //Need WifiConfiguration for the AP WifiConfiguration config = findConfiguredNetwork(state); 如果wpa_supplicant沒有這個(gè)AP的配置信息,則會(huì)向wpa_supplicant發(fā)送ADD_NETWORK命令來添加該AP 2 ADD_NETWORK命 令 會(huì) 返 回 一 個(gè)ID,WifiLayer再 用 這 個(gè) 返 回 的ID作 為參數(shù)向wpa_supplicant發(fā)送ENABLE_NETWORK命令,從而讓wpa_supplicant去連接該AP。 【配置IP地址】 1當(dāng)wpa_supplicant成功連接上AP之后,它會(huì)向控制通道發(fā)送事件通知連接上AP了,從而wifi_wait_for_event函數(shù)會(huì)接收到該事件,由此WifiMonitor中的MonitorThread會(huì)被執(zhí)行來出來這個(gè)事件 2 WifiMonitor再調(diào)用WifiStateTracker的notifyStateChange,WifiStateTracker則接著會(huì)往自身發(fā)送EVENT_DHCP_START消息來啟動(dòng)DHCP去獲取IP地址 3然后再廣播發(fā)送NETWORK_STATE_CHANGED_ACTION這個(gè)Intent 4 WifiLayer注冊了接收NETWORK_STATE_CHANGED_ACTION這個(gè)Intent,所以它的相關(guān)處理函數(shù)handleNetworkStateChanged會(huì)被調(diào)用,當(dāng)DHCP拿到IP地址之后,會(huì)再發(fā)送EVENT_DHCP_SUCCEEDED消息 5 WifiLayer處 理EVENT_DHCP_SUCCEEDED消 息,會(huì) 再 次 廣 播 發(fā) 送 至此為止,整個(gè)連接過程完成 2. wpa_supplicant Android平臺(tái)使用的WiFi控制框架是基于大名鼎鼎的wpa_supplicant,,它是一個(gè)安全中間件,,為各種無線網(wǎng)卡提供統(tǒng)一的安全機(jī)制,如下圖所示: 對應(yīng)上述結(jié)構(gòu),,基于Android的手機(jī)中的WiFi控制分為三大組件: 在手機(jī)內(nèi)存的/etc/wpa_supplicant.conf中我們可以直接看到WIFI支持的網(wǎng)絡(luò)類型,,每種類型都有例子,,比如: #Both WPA-PSK and WPA-EAP is accepted. Only CCMP is accepted as pairwise and # group cipher. #network={ # ssid="example" # bssid=00:11:22:33:44:55 # proto=WPA RSN # key_mgmt=WPA-PSK WPA-EAP # pairwise=CCMP # group=CCMP # psk=06b4be19da289f475aa46a33cb793029d4ab3db7a23ee92382eb0106c72ac7bb #} 不同類型的網(wǎng)絡(luò),不同的參數(shù)等等,,應(yīng)有盡有,。
我們在上面已經(jīng)知道WIFI的啟動(dòng)過程,,在功能運(yùn)行中也會(huì)輸出相應(yīng)的日志信息,下面就來詳細(xì)了解一下,。(請注意,,WIFI開啟后會(huì)更改電池狀態(tài)等其他狀態(tài)。關(guān)閉WIFI時(shí),,android的策略是卸載驅(qū)動(dòng)來省電,。如有缺失就是問題。不過下文刪去了與WIFI無關(guān)的LOG?。?/font> 1.開啟WIFI&自動(dòng)搜索 E/WifiHW ( 1201): ==JOHN DEBUG==: [WIFI] Load Driver 加載驅(qū)動(dòng) D/SettingsWifiEnabler( 1321): Received wifi state changed from Disabled to Enabling 接收到廣播:WIFI正在開啟 D/WifiService( 1201): ACTION_BATTERY_CHANGED pluggedType: 2 電池狀態(tài)改變 E/WifiHW(1201):==JOHNDEBUG==:moduleaddress:4b938008 filename:/system/lib/modules/dhd.ko args:firmware_path=/system/wlan/broadcom/rtecdc.bin nvram_path=/system/wlan/broadcom/nvram.txt WIFI硬件:加載內(nèi)核模塊 I/wpa_supplicant( 2490): CTRL-EVENT-STATE-CHANGE id=-1 state=2 wpa_supplicant發(fā)出事件通知 V/WifiMonitor( 1201): Event [CTRL-EVENT-STATE-CHANGE id=-1 state=2] WifiMonitor從wpa_supplicant接收事件通知 I/wpa_supplicant( 2490): CTRL-EVENT-SCAN-RESULTS Ready wpa_supplicant發(fā)出事件通知:準(zhǔn)備好開始搜索網(wǎng)絡(luò)了 E/wpa_supplicant( 2490): wpa_driver_priv_driver_cmd SCAN-ACTIVE len = 4096 wpa_supplicant發(fā)出事件通知:驅(qū)動(dòng)命令行.主動(dòng)搜索.LEN E/wpa_supplicant( 2490): wpa_driver_priv_driver_cmd SCAN-ACTIVE len = 0, 11 wpa_supplicant發(fā)出事件通知:驅(qū)動(dòng)命令行.主動(dòng)搜索.LEN E/wpa_supplicant( 2490): wpa_driver_priv_driver_cmd SCAN-PASSIVE len = 4096 wpa_supplicant發(fā)出事件通知:驅(qū)動(dòng)命令行.被動(dòng)搜索.LEN E/wpa_supplicant( 2490): wpa_driver_priv_driver_cmd SCAN-PASSIVE len = 0, 12 wpa_supplicant發(fā)出事件通知:驅(qū)動(dòng)命令行.被動(dòng)搜索.LEN=0.12 D/SettingsWifiEnabler( 1321): Received wifi state changed from Enabling to Enabled 接收到廣播:WIFI已經(jīng)開啟 E/wpa_supplicant( 2490): wpa_driver_priv_driver_cmd RSSI len = 4096 wpa_supplicant發(fā)出事件通知: E/wpa_supplicant( 2490): wpa_driver_priv_driver_cmd RSSI len = 4, 4 wpa_supplicant發(fā)出事件通知: E/wpa_supplicant( 2490): wpa_driver_priv_driver_cmd LINKSPEED len = 4096 wpa_supplicant發(fā)出事件通知: E/wpa_supplicant( 2490): wpa_driver_priv_driver_cmd LinkSpeed 54 len = 12, 12 wpa_supplicant發(fā)出事件通知: E/wpa_supplicant( 2490): wpa_driver_priv_driver_cmd MACADDR len = 4096 wpa_supplicant發(fā)出事件通知:驅(qū)動(dòng)命令行.MAC地址.LEN E/wpa_supplicant( 2490): wpa_driver_priv_driver_cmd Macaddr = 44:A4:2D:27:25:BE wpa_supplicant發(fā)出事件通知:驅(qū)動(dòng)命令行.MAC地址 E/wpa_supplicant( 2490): len = 28, 28 wpa_supplicant發(fā)出事件通知: V/WifiStateTracker( 1201): Connection to supplicant established, state=SCANNING WIFI狀態(tài)跟蹤:連接請求確認(rèn),,狀態(tài)=搜索 D/NetworkStateTracker( 1201): setDetailed state, ld =IDLE and new state=SCANNING 網(wǎng)絡(luò)狀態(tài)跟蹤:更新顯示為搜索狀態(tài) V/WifiStateTracker( 1201): Changing supplicant state: SCANNING ==> INACTIVE WIFI狀態(tài)跟蹤:更改請求狀態(tài):搜索中->不活動(dòng) 2.點(diǎn)擊連接&獲取狀態(tài) E/WifiHW ( 1201): ==JOHN DEBUG==: [WIFI] Load Driver WIFI硬件:加載驅(qū)動(dòng) D/SettingsWifiEnabler( 1321): Received wifi state changed from Disabled to Enabling 收到廣播,WIFI狀態(tài)正在開啟 E/WifiHW(1201):==JOHNDEBUG==:moduleaddress:4b938008 filename:/system/lib/modules/dhd.ko args:firmware_path=/system/wlan/broadcom/rtecdc.bin nvram_path=/system/wlan/broadcom/nvram.txt WIFI硬件:加載內(nèi)核模塊 E/WifiHW ( 1201): ==JOHN DEBUG==: return of insmod : ret = 0, Unknown error: 0 WIFI硬件:返回裝載模塊報(bào)告:返回指令0,,未知錯(cuò)誤0 …… I/wpa_supplicant( 2490): Trying to associate with 1c:bd:b9:f6:a7:9f (SSID='LosAngeles' freq=2412 MHz) wpa_supplicant發(fā)出事件通知:嘗試連接,,(SSID='LosAngeles'頻段=2412 MHz) V/WifiMonitor( 1201):Event[Trying to associate with 1c:bd:b9:f6:a7:9f (SSID='LosAngeles' freq=2412 MHz)] WifiMonitor接收wpa_supplicant的事件 V/WifiMonitor( 1201): Event [CTRL-EVENT-STATE-CHANGE id=-1 state=3] WifiMonitor接收事件 V/WifiStateTracker( 1201): Changing supplicant state: SCANNING ==> ASSOCIATING WIFI狀態(tài)跟蹤:更改請求狀態(tài):搜索中->匹配中 D/NetworkStateTracker( 1201): setDetailed state, ld =SCANNING and new state=CONNECTING 網(wǎng)絡(luò)狀態(tài)跟蹤:更新顯示為正在連接狀態(tài) D/ConnectivityService( 1201): ConnectivityChange for WIFI: CONNECTING/CONNECTING 連接管理服務(wù):改變WIFI連接狀態(tài):正在連接/正在連接 V/WifiStateTracker( 1201): Changing supplicant state: ASSOCIATING ==> ASSOCIATED WIFI狀態(tài)跟蹤:更改請求狀態(tài):匹配中->已匹配 D/NetworkStateTracker( 1201): setDetailed state, ld =CONNECTING and new state=CONNECTING 網(wǎng)絡(luò)狀態(tài)跟蹤:更新顯示為正在連接狀態(tài) I/wpa_supplicant( 2490): Associated with 1c:bd:b9:f6:a7:9f wpa_supplicant發(fā)出事件通知:已和1c:bd:b9:f6:a7:9f匹配 V/WifiMonitor( 1201): Event [Associated with 1c:bd:b9:f6:a7:9f] WifiMonitor接收wpa_supplicant的事件 V/WifiStateTracker( 1201): Changing supplicant state: ASSOCIATED ==> FOUR_WAY_HANDSHAKE WIFI狀態(tài)跟蹤:更改請求狀態(tài):已匹配->TCP中斷連接 D/NetworkStateTracker( 1201): setDetailed state, ld =CONNECTING and new state=AUTHENTICATING 網(wǎng)絡(luò)狀態(tài)跟蹤:更新顯示為鑒定中 D/ConnectivityService( 1201): Dropping ConnectivityChange for WIFI: CONNECTING/AUTHENTICATING 連接管理服務(wù):拋出WIFI連接狀態(tài)改變:已連接/鑒定中 V/WifiStateTracker( 1201): Changing supplicant state: FOUR_WAY_HANDSHAKE ==> GROUP_HANDSHAKE WIFI狀態(tài)跟蹤:更改請求狀態(tài):TCP中斷連接->確認(rèn)標(biāo)志位 D/NetworkStateTracker( 1201): setDetailed state, ld =AUTHENTICATING and new state=AUTHENTICATING 網(wǎng)絡(luò)狀態(tài)跟蹤:更新顯示為鑒定中 I/wpa_supplicant( 2490): WPA: Key negotiation completed with 1c:bd:b9:f6:a7:9f [PTK=CCMP GTK=TKIP] wpa_supplicant發(fā)出事件通知:WPA:與1c:bd:b9:f6:a7:9f確定標(biāo)志位 I/wpa_supplicant( 2490): CTRL-EVENT-STATE-CHANGE id=0 state=7 wpa_supplicant發(fā)出事件通知: I/wpa_supplicant( 2490): CTRL-EVENT-CONNECTED - Connection to 1c:bd:b9:f6:a7:9f completed (auth) [id=0 id_str=] wpa_supplicant發(fā)出事件通知:連接完成 V/WifiMonitor( 1201): Event [WPA: Key negotiation completed with 1c:bd:b9:f6:a7:9f [PTK=CCMP GTK=TKIP]] WifiMonitor接收wpa_supplicant事件 V/WifiMonitor( 1201): Event [CTRL-EVENT-STATE-CHANGE id=0 state=7] WifiMonitor接收wpa_supplicant事件 V/WifiMonitor( 1201): Event [CTRL-EVENT-CONNECTED - Connection to 1c:bd:b9:f6:a7:9f completed (auth) [id=0 id_str=]] WifiMonitor接收wpa_supplicant事件 V/WifiStateTracker( 1201): Changing supplicant state: GROUP_HANDSHAKE ==> COMPLETED WIFI狀態(tài)跟蹤:更改請求狀態(tài):確認(rèn)標(biāo)志位->完成 V/WifiStateTracker( 1201): New network state is CONNECTED WIFI狀態(tài)跟蹤:新網(wǎng)絡(luò)狀態(tài)為已連接 D/NetworkStateTracker( 1201): setDetailed state, ld =AUTHENTICATING and new state=OBTAINING_IPADDR 網(wǎng)絡(luò)狀態(tài)跟蹤:更新顯示為獲取IP地址 D/ConnectivityService( 1201): Dropping ConnectivityChange for WIFI: CONNECTING/OBTAINING_IPADDR 連接管理服務(wù):拋出WIFI |
|