ANDROID移植WIFI設(shè)計原理(源碼分析)
《ANDROID移植WIFI設(shè)計原理(源碼分析)》由會員分享,可在線閱讀,更多相關(guān)《ANDROID移植WIFI設(shè)計原理(源碼分析)(7頁珍藏版)》請在裝配圖網(wǎng)上搜索。
1、Android移植: wifi設(shè)計原理(源碼分析) 博客分類: Android AndroidEXT 初始化 在 SystemServer 啟動的時候,會生成一個 ConnectivityService 的實例, 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ù)會創(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 會創(chuàng)建 WifiMonitor 接收來自底層的事件,WifiService 和 WifiMonitor 是整 個模塊的核心。WifiService 負責啟動關(guān)閉 wpa_supplicant、啟動關(guān)閉 WifiMonitor 監(jiān)視線程 和把命令下發(fā)給 wpa_supplicant,而 WifiMonitor 則負責從 wpa_supplicant 接收事件通知。 連接 AP 1. 使能 W
4、IFI WirelessSettings 在初始化的時候配置了由 WifiEnabler 來處理 Wifi 按鈕, private void initToggles() { mWifiEnabler = new WifiEnabler( this, (WifiManager) getSystemService(WIFI_SERVICE), (CheckBoxPreference) findPreference(KEY_TOGGLE_WIFI)); 當用戶按下 Wifi 按鈕后, Android 會調(diào)用 WifiEnabl
5、er 的 onPreferenceChange, 再由 WifiEnabler 調(diào)用 WifiManager 的 setWifiEnabled 接口函數(shù),通過 AIDL,實際調(diào)用的是 WifiService 的 setWifiEnabled 函數(shù),WifiService 接著向自身發(fā)送一條 MESSAGE_ENABLE_WIFI 消息,在 處理該消息的代碼中做真正的使能工作:首先裝載 WIFI 內(nèi)核模塊(該模塊的位置硬編碼為 "/system/lib/modules/wlan.ko" ), 然 后 啟 動 wpa_supplicant ( 配 置 文 件 硬 編 碼 為 "/dat
6、a/misc/wifi/wpa_supplicant.conf") 再通過 WifiStateTracker 來啟動 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; } 當使能成功后,會廣播
9、發(fā)送 WIFI_STATE_CHANGED_ACTION 這個 Intent 通知外界 WIFI 已 經(jīng) 成 功 使 能 了 。 WifiEnabler 創(chuàng) 建 的 時 候 就 會 向 Android 注 冊 接 收 WIFI_STATE_CHANGED_ACTION,因此它會收到該 Intent,從而開始掃描。 private void handleWifiStateChanged(int wifiState) { if (wifiState == WIFI_STATE_ENABLED) { loadConfiguredAccessPoints();
10、 attemptScan(); } 2. 查找 AP 掃描的入口函數(shù)是 WifiService 的 startScan,它其實也就是往 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; } 當 wpa_supplicant 處理完 SCAN 命令后,它會向控制通道發(fā)送事件通知掃描完成,從而 wifi_wait_for_event 函數(shù)會接收到該事件,由此 WifiMonitor 中的 MonitorThread 會被執(zhí)行來 出來這個事件,
12、 void handleEvent(int event, String remainder) { case SCAN_RESULTS: mWifiStateTracker.notifyScanResultsAvailable(); break; WifiStateTracker 則接著廣播發(fā)送 SCAN_RESULTS_AVAILABLE_ACTION 這個 Intent case EVENT_SCAN_RESULTS_AVAILABLE: mContext.sendBroadcast(new I
13、ntent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
WifiLayer 注冊了接收 SCAN_RESULTS_AVAILABLE_ACTION 這個 Intent,所以它的相關(guān)
處理函數(shù) handleScanResultsAvailable 會被調(diào)用,在該函數(shù)中,先會去拿到 SCAN 的結(jié)果(最
終是往 wpa_supplicant 發(fā)送 SCAN_RESULT 命令并讀取返回值來實現(xiàn)的) ,
List
14、一個掃描返回的 AP,WifiLayer 會調(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ù) 當用戶在 WifiSettings 界面上選擇了一個 AP 后,會顯示配置 AP 參數(shù)的一個對話框, public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preferenc
16、e preference) { if (preference instanceof AccessPointPreference) { AccessPointState state = ((AccessPointPreference) preference).getAccessPointState(); showAccessPointDialog(state, AccessPointDialog.MODE_INFO); } } 4. 連接 當用戶在 AcessPointDialog 中選擇好加密方式和輸入密鑰之后,再點擊
17、連接按鈕,Android 就會去連接這個 AP。 private void handleConnect() { String password = getEnteredPassword(); if (!TextUtils.isEmpty(password)) { mState.setPassword(password); } mWifiLayer.connectToNetwork(mState); } WifiLayer 會先檢測這個 AP 是不是之前被配置過,這個是通過向 wpa_supplicant 發(fā)送 LIST_NET
18、WORK 命令并且比較返回值來實現(xiàn)的, // Need WifiConfiguration for the AP WifiConfiguration config = findConfiguredNetwork(state); 如果 wpa_supplicant 沒有這個 AP 的配置信息, 則會向 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 命 令 會 返 回 一 個 ID , WifiLayer 再 用 這 個 返 回 的 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 地址 當 wpa_supplicant 成功連接上 AP 之后,它會向控制通道發(fā)送事件通知連接上 AP 了,從而
21、 wifi_wait_for_event 函數(shù)會接收到該事件,由此 WifiMonitor 中的 MonitorThread 會被執(zhí)行來 出來這個事件, void handleEvent(int event, String remainder) { case CONNECTED: handleNetworkStateChange(NetworkInfo.DetailedState.CONNECTED, remainder); break; WifiMonitor 再調(diào)用 WifiStateTracker 的 notify
22、StateChange,WifiStateTracker 則接著會往自身 發(fā)送 EVENT_DHCP_START 消息來啟動 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 這個 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 注冊了接收 NETWORK_STATE_CHANGED_ACTION 這個 Intent,所以
25、它的相關(guān) 處理函數(shù) handleNetworkStateChanged 會被調(diào)用, 當 DHCP 拿到 IP 地址之后,會再發(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 消 息 , 會 再 次 廣 播 發(fā) 送 NETWORK_STATE_CHANGED_ACTION 這個 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; 至此為止,整個連接過程完成。 問題: 目前的實現(xiàn)不支持 Ad-hoc 方式。
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 市教育局冬季運動會安全工作預(yù)案
- 2024年秋季《思想道德與法治》大作業(yè)及答案3套試卷
- 2024年教師年度考核表個人工作總結(jié)(可編輯)
- 2024年xx村兩委涉案資金退還保證書
- 2024年憲法宣傳周活動總結(jié)+在機關(guān)“弘揚憲法精神推動發(fā)改工作高質(zhì)量發(fā)展”專題宣講報告會上的講話
- 2024年XX村合作社年報總結(jié)
- 2024-2025年秋季第一學(xué)期初中歷史上冊教研組工作總結(jié)
- 2024年小學(xué)高級教師年終工作總結(jié)匯報
- 2024-2025年秋季第一學(xué)期初中物理上冊教研組工作總結(jié)
- 2024年xx鎮(zhèn)交通年度總結(jié)
- 2024-2025年秋季第一學(xué)期小學(xué)語文教師工作總結(jié)
- 2024年XX村陳規(guī)陋習(xí)整治報告
- 2025年學(xué)校元旦迎新盛典活動策劃方案
- 2024年學(xué)校周邊安全隱患自查報告
- 2024年XX鎮(zhèn)農(nóng)村規(guī)劃管控述職報告