ANDROID移植WIFI設(shè)計(jì)原理(源碼分析)
《ANDROID移植WIFI設(shè)計(jì)原理(源碼分析)》由會(huì)員分享,可在線閱讀,更多相關(guān)《ANDROID移植WIFI設(shè)計(jì)原理(源碼分析)(7頁珍藏版)》請(qǐng)?jiān)谘b配圖網(wǎng)上搜索。
1、Android移植: wifi設(shè)計(jì)原理(源碼分析) 博客分類: Android AndroidEXT 初始化 在 SystemServer 啟動(dòng)的時(shí)候,會(huì)生成一個(gè) ConnectivityService 的實(shí)例, try { Log.i(TAG, "Starting Connectivity Service."); ServiceManager.addService(Context.CONNECTIVITY_SERVICE, new ConnectivityService(context)); } catch (Throwa
2、ble e) { Log.e(TAG, "Failure starting Connectivity Service", e); } ConnectivityService 的構(gòu)造函數(shù)會(huì)創(chuàng)建 WifiService, if (DBG) Log.v(TAG, "Starting Wifi Service."); mWifiStateTracker = new WifiStateTracker(context, handler); WifiService wifiService = new WifiService(context, mWifi
3、StateTracker); ServiceManager.addService(Context.WIFI_SERVICE, wifiService); 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. 使能 W
4、IFI WirelessSettings 在初始化的時(shí)候配置了由 WifiEnabler 來處理 Wifi 按鈕, private void initToggles() { mWifiEnabler = new WifiEnabler( this, (WifiManager) getSystemService(WIFI_SERVICE), (CheckBoxPreference) findPreference(KEY_TOGGLE_WIFI)); 當(dāng)用戶按下 Wifi 按鈕后, Android 會(huì)調(diào)用 WifiEnabl
5、er 的 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 ( 配 置 文 件 硬 編 碼 為 "/dat
6、a/misc/wifi/wpa_supplicant.conf") 再通過 WifiStateTracker 來啟動(dòng) WifiMonitor 中的監(jiān)視 , 線程。 private boolean setWifiEnabledBlocking(boolean enable) { final int eventualWifiState = enable ? WIFI_STATE_ENABLED : WIFI_STATE_DISABLED; updateWifiState(enable ? WIFI_STATE_ENABLING : W
7、IFI_STATE_DISABLING); if (enable) { if (!WifiNative.loadDriver()) { Log.e(TAG, "Failed to load Wi-Fi driver."); updateWifiState(WIFI_STATE_UNKNOWN); return false; } if (!WifiNative.startSupplicant()) { WifiNative.unloadDriver(); Log.e
8、(TAG, "Failed to start supplicant daemon."); updateWifiState(WIFI_STATE_UNKNOWN); return false; } mWifiStateTracker.startEventLoop(); } // Success! persistWifiEnabled(enable); updateWifiState(eventualWifiState); return true; } 當(dāng)使能成功后,會(huì)廣播
9、發(fā)送 WIFI_STATE_CHANGED_ACTION 這個(gè) Intent 通知外界 WIFI 已 經(jīng) 成 功 使 能 了 。 WifiEnabler 創(chuàng) 建 的 時(shí) 候 就 會(huì) 向 Android 注 冊(cè) 接 收 WIFI_STATE_CHANGED_ACTION,因此它會(huì)收到該 Intent,從而開始掃描。 private void handleWifiStateChanged(int wifiState) { if (wifiState == WIFI_STATE_ENABLED) { loadConfiguredAccessPoints();
10、 attemptScan(); } 2. 查找 AP 掃描的入口函數(shù)是 WifiService 的 startScan,它其實(shí)也就是往 wpa_supplicant 發(fā)送 SCAN 命 令。 static jboolean android_net_wifi_scanCommand(JNIEnv* env, jobject clazz) { jboolean result; // Ignore any error from setting the scan mode. // The scan will still work. (void)
11、doBooleanCommand("DRIVER SCAN-ACTIVE", "OK"); result = doBooleanCommand("SCAN", "OK"); (void)doBooleanCommand("DRIVER SCAN-PASSIVE", "OK"); return result; } 當(dāng) wpa_supplicant 處理完 SCAN 命令后,它會(huì)向控制通道發(fā)送事件通知掃描完成,從而 wifi_wait_for_event 函數(shù)會(huì)接收到該事件,由此 WifiMonitor 中的 MonitorThread 會(huì)被執(zhí)行來 出來這個(gè)事件,
12、 void handleEvent(int event, String remainder) { case SCAN_RESULTS: mWifiStateTracker.notifyScanResultsAvailable(); break; WifiStateTracker 則接著廣播發(fā)送 SCAN_RESULTS_AVAILABLE_ACTION 這個(gè) Intent case EVENT_SCAN_RESULTS_AVAILABLE: mContext.sendBroadcast(new I
13、ntent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
WifiLayer 注冊(cè)了接收 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
14、一個(gè)掃描返回的 AP,WifiLayer 會(huì)調(diào)用 WifiSettings 的 onAccessPointSetChanged 函數(shù), 從而最終把該 AP 加到 GUI 顯示列表中。 public void onAccessPointSetChanged(AccessPointState ap, boolean added) { AccessPointPreference pref = mAps.get(ap); if (added) { if (pref == null) { pref = new AccessPointPrefere
15、nce(this, ap); mAps.put(ap, pref); } else { pref.setEnabled(true); } mApCategory.addPreference(pref); } } 3. 配置 AP 參數(shù) 當(dāng)用戶在 WifiSettings 界面上選擇了一個(gè) AP 后,會(huì)顯示配置 AP 參數(shù)的一個(gè)對(duì)話框, public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preferenc
16、e preference) { if (preference instanceof AccessPointPreference) { AccessPointState state = ((AccessPointPreference) preference).getAccessPointState(); showAccessPointDialog(state, AccessPointDialog.MODE_INFO); } } 4. 連接 當(dāng)用戶在 AcessPointDialog 中選擇好加密方式和輸入密鑰之后,再點(diǎn)擊
17、連接按鈕,Android 就會(huì)去連接這個(gè) AP。 private void handleConnect() { String password = getEnteredPassword(); if (!TextUtils.isEmpty(password)) { mState.setPassword(password); } mWifiLayer.connectToNetwork(mState); } WifiLayer 會(huì)先檢測(cè)這個(gè) AP 是不是之前被配置過,這個(gè)是通過向 wpa_supplicant 發(fā)送 LIST_NET
18、WORK 命令并且比較返回值來實(shí)現(xiàn)的, // Need WifiConfiguration for the AP WifiConfiguration config = findConfiguredNetwork(state); 如果 wpa_supplicant 沒有這個(gè) AP 的配置信息, 則會(huì)向 wpa_supplicant 發(fā)送 ADD_NETWORK 命令來添加該 AP, if (config == null) { // Connecting for the first time, need to create it
19、 config = addConfiguration(state, ADD_CONFIGURATION_ENABLE|ADD_CONFIGURATION_SAVE); } ADD_NETWORK 命 令 會(huì) 返 回 一 個(gè) ID , WifiLayer 再 用 這 個(gè) 返 回 的 ID 作 為 參 數(shù) 向 wpa_supplicant 發(fā)送 ENABLE_NETWORK 命令,從而讓 wpa_supplicant 去連接該 AP。 // Make sure that network is enabled, and disable oth
20、ers mReenableApsOnNetworkStateChange = true; if (!mWifiManager.enableNetwork(workId, true)) { Log.e(TAG, "Could not enable network ID " + workId); error(R.string.error_connecting); return false; } 5. 配置 IP 地址 當(dāng) wpa_supplicant 成功連接上 AP 之后,它會(huì)向控制通道發(fā)送事件通知連接上 AP 了,從而
21、 wifi_wait_for_event 函數(shù)會(huì)接收到該事件,由此 WifiMonitor 中的 MonitorThread 會(huì)被執(zhí)行來 出來這個(gè)事件, void handleEvent(int event, String remainder) { case CONNECTED: handleNetworkStateChange(NetworkInfo.DetailedState.CONNECTED, remainder); break; WifiMonitor 再調(diào)用 WifiStateTracker 的 notify
22、StateChange,WifiStateTracker 則接著會(huì)往自身 發(fā)送 EVENT_DHCP_START 消息來啟動(dòng) DHCP 去獲取 IP 地址, private void handleConnectedState() { setPollTimer(); mLastSignalLevel = -1; if (!mHaveIPAddress & !mObtainingIPAddress) { mObtainingIPAddress = true; mDhcpTarget.obtainMessage(EVENT_DHCP_S
23、TART).sendToTarget(); } } 然后再廣播發(fā)送 NETWORK_STATE_CHANGED_ACTION 這個(gè) Intent case EVENT_NETWORK_STATE_CHANGED: if (result.state != DetailedState.DISCONNECTED || !mDisconnectPending) { intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
24、 intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, mNetworkInfo); if (result.BSSID != null) intent.putExtra(WifiManager.EXTRA_BSSID, result.BSSID); mContext.sendStickyBroadcast(intent); } break; WifiLayer 注冊(cè)了接收 NETWORK_STATE_CHANGED_ACTION 這個(gè) Intent,所以
25、它的相關(guān) 處理函數(shù) handleNetworkStateChanged 會(huì)被調(diào)用, 當(dāng) DHCP 拿到 IP 地址之后,會(huì)再發(fā)送 EVENT_DHCP_SUCCEEDED 消息, private class DhcpHandler extends Handler { public void handleMessage(Message msg) { switch (msg.what) { case EVENT_DHCP_START: if (NetworkUtils.runDhcp(mInterfaceName, mDhcpInf
26、o)) { event = EVENT_DHCP_SUCCEEDED; } WifiLayer 處 理 EVENT_DHCP_SUCCEEDED 消 息 , 會(huì) 再 次 廣 播 發(fā) 送 NETWORK_STATE_CHANGED_ACTION 這個(gè) Intent,這次帶上完整的 IP 地址信息。 case EVENT_DHCP_SUCCEEDED: mWifiInfo.setIpAddress(mDhcpInfo.ipAddress); setDetailedState(Detaile
27、dState.CONNECTED); intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION); intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, mNetworkInfo); mContext.sendStickyBroadcast(intent); break; 至此為止,整個(gè)連接過程完成。 問題: 目前的實(shí)現(xiàn)不支持 Ad-hoc 方式。
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 市教育局冬季運(yùn)動(dòng)會(huì)安全工作預(yù)案
- 2024年秋季《思想道德與法治》大作業(yè)及答案3套試卷
- 2024年教師年度考核表個(gè)人工作總結(jié)(可編輯)
- 2024年xx村兩委涉案資金退還保證書
- 2024年憲法宣傳周活動(dòng)總結(jié)+在機(jī)關(guān)“弘揚(yáng)憲法精神推動(dòng)發(fā)改工作高質(zhì)量發(fā)展”專題宣講報(bào)告會(huì)上的講話
- 2024年XX村合作社年報(bào)總結(jié)
- 2024-2025年秋季第一學(xué)期初中歷史上冊(cè)教研組工作總結(jié)
- 2024年小學(xué)高級(jí)教師年終工作總結(jié)匯報(bào)
- 2024-2025年秋季第一學(xué)期初中物理上冊(cè)教研組工作總結(jié)
- 2024年xx鎮(zhèn)交通年度總結(jié)
- 2024-2025年秋季第一學(xué)期小學(xué)語文教師工作總結(jié)
- 2024年XX村陳規(guī)陋習(xí)整治報(bào)告
- 2025年學(xué)校元旦迎新盛典活動(dòng)策劃方案
- 2024年學(xué)校周邊安全隱患自查報(bào)告
- 2024年XX鎮(zhèn)農(nóng)村規(guī)劃管控述職報(bào)告