* 在wifi setting 中 check enanble 開始繼續java
1. 收到MESSAGE_ENABLE_WIFI
setWifiEnabledBlocking(wifiService.java)
=> mWifiStateTracker.loadDriver
=> mWifiStateTracker.startSupplicant()
==> WifiNative.startSupplicant (WifiNative.java)
===> android_net_wifi_startSupplicant(android_net_wifi_Wifi.cpp JNI)
====> wifi_start_supplicant (wifi.c hardware wifi lib)
就是去啓動wpa_supplicant 命令行
=> mWifiStateTracker.startEventLoop(); (WifiStateTracker.java)
==> mWifiMonitor.startMonitoring();
Monitoring thread 中:
===>connectToSupplicant() 判斷是否連上,該函數還打開兩個wpa_cli的控制
1. ctrl_conn ,用於JNI 經過wpa_cli往下發命令
2. monitor_conn 在wifi_wait_for_event (call by JNI
android_net_wifi_waitForEvent)
接收event ,java 層就是經過call 該JNI 來得到wpa的event
一來一去都有了,java 和 wpa 通信創建成功
===>鏈接成功後,發消息 EVENT_SUPPLICANT_CONNECTION
mWifiStateTracker.notifySupplicantConnection();
接收處理 EVENT_SUPPLICANT_CONNECTION 部分見下面分支 4.
接下來進入循環接收event
String eventStr = WifiNative.waitForEvent();
/* 就是監聽上面connectToSupplicant 中的monitor_conn */
而後將event string 轉換成int,而後
handleEvent(event, eventData);
主要有下面event:
event =CONNECTED;
event = DISCONNECTED;
event = STATE_CHANGE;
event = SCAN_RESULTS;
event = LINK_SPEED;
event = TERMINATING;
event = DRIVER_STATE;
event = DRIVER_STATE
event = LINK_SPEED 等等android
=> setWifiEnabledState(eventualWifiState, uid);(wifiService.java)
eventualWifiState 爲 WIFI_STATE_ENABLED
==> mWifiStateTracker.setWifiState(WIFI_STATE_ENABLED);
boardcast WIFI_STATE_CHANGED_ACTION + WIFI_STATE_ENABLED
處理接收該wifi 狀態廣播的分支見 3.app
2. settings\wifi\WifiEnabler.java
=> class WifiEnabler
BroadcastReceiver mReceiver = new BroadcastReceiver()
if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
handleWifiStateChanged(intent.getIntExtra(
WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN));
這部分就是處理wifi enable check 界面的 disable,和 打上勾的處理dom
3.packages\apps\Settings\src\com\android\settings\wifi\WifiSettings.java
接收處理前面1.最後提到的
boardcast WIFI_STATE_CHANGED_ACTION + WIFI_STATE_ENABLED
直接看代碼:
=> handleEvent(Intent intent) {
String action = intent.getAction();
if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
==> updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
WifiManager.WIFI_STATE_UNKNOWN));
由 WIFI_STATE_ENABLED 走到下面
===> mScanner.resume(); ( sendEmptyMessage(0);)
====> handleMessage
=====> mWifiManager.startScanActive() (wifiManager.java)
======> mService.startScan(true);
MESSAGE_START_SCAN
經過下面函數發出:
Message.obtain(mWifiHandler, MESSAGE_START_SCAN,
forceActive ? 1 : 0, 0).sendToTarget();
===> updateAccessPoints(); 讀conf network 配置,並設置到 java層的AP類socket
接收處理MESSAGE_START_SCAN的在 wifiService.java
handleMessage(MESSAGE_START_SCAN)
=> mWifiStateTracker.scan(forceActive); 而後到下面的分支7.!!!
ESSAGE_START_SCAN 另一條路是
wifiService.java: updateWifiState
-> MESSAGE_UPDATE_STATE
-> doUpdateWifiState
-> sendStartMessage(MESSAGE_START_SCAN)
具體不展開了函數
4. 前面分支2.中 EVENT_SUPPLICANT_CONNECTION
消息被WifiStateTracker處理
=> handleMessage(EVENT_SUPPLICANT_CONNECTION)
==> checkUseStaticIp 檢測是不是static ip 鏈接oop
==> 發Intend :
Intent(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
change 的內容爲 EXTRA_SUPPLICANT_CONNECTED
==> dhcpThread.start(); 啓動dhcp thread 並block 住,等待AP連上,在繼續運行
==> 判斷 complete 並 獲得接入點的BSSID(MAC addr) 經過 GetBSSID()
AP custom name 經過 GetSSID()
==> initializeMulticastFiltering (wifiService.java)
===> startPacketFiltering ->JNI 可看到debug message :
D/wpa_supplicant( 1468): nl80211_priv_driver_cmd RXFILTER-ADD 0 len = 4096
D/wpa_supplicant( 1468): nl80211_priv_driver_cmd RXFILTER-ADD 1 len = 4096
D/wpa_supplicant( 1468): nl80211_priv_driver_cmd RXFILTER-ADD 3 len = 4096
D/wpa_supplicant( 1468): nl80211_priv_driver_cmd RXFILTER-START len = 4096
==> setBluetoothScanMode
===> setBluetoothCoexistenceModeCommand
==> setNumAllowedChannels
/* Set the number of radio frequency channels that are allowed
to be used in the current regulatory domain */
若是你有什麼想法,就去動動Settings.Secure.WIFI_NUM_ALLOWED_CHANNELS參數ui
5. WPA_SUPPLICANT 部分開始蠢蠢欲動了:
能夠看到這樣的debug message:
RTM_NEWLINK: operstate=0 ifi_flags=0x1043 ([UP][RUNNING])
=>wpa_driver_nl80211_event_rtm_newlink 被event 驅動,看代碼:
/* 若是上次 disable 本次enable 發這個event! */
if (drv->if_disabled && (ifi->ifi_flags & IFF_UP)) {
==> wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED, NULL);
==> wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
==> wpa_supplicant_req_scan(wpa_s, 0, 0);
if_disabled 不知足因此沒走到這裏,因此發起scan 不在這裏開始的.小插曲命令行
6. 同時能夠看到這樣的消息 :Event 5 received on interface wlan0
在下面函數打出
=> wpa_driver_nl80211_event_link ==>
==> wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
event =EVENT_INTERFACE_ADDED
===> wpa_supplicant_event_interface_status
if (!wpa_s->interface_removed)
break; 什麼也沒作
(new link 部分處理沒有啓動scan,仍是由java部分啓動的,就是前面3.分支中的)debug
mWifiStateTracker.scan
7. 前面3.分支最後 開始mWifiStateTracker.scan(forceActive)
到WifiStateTracker.java,找到全名以下:
=> public synchronized boolean scan(boolean forceActive)
==> WifiNative.scanCommand
===> doSetScanMode(true);
從debug message (Unsupported command: SCAN-ACTIVE) 看來
主動掃描不支持???
===> doBooleanCommand("SCAN", "OK");
====> doCommand
=====> wifi_command(wifi.c)
執行到(wpa_supplicant中的ctrl_iface.c)代碼以下:
else if (os_strcmp(buf, "SCAN") == 0)
======> wpa_supplicant_req_scan(wpa_s, 0, 0);
立刻調度一個 scan =>
eloop_register_timeout(sec, usec,
wpa_supplicant_scan, wpa_s, NULL);
接下來到分支8.就在下面
8.
下面是eloop 部分,由於前面分支7.中eloop timeout 爲0,
立刻執行下面部分:
=> wpa_supplicant_scan:
==> wpa_supplicant_set_state(wpa_s, WPA_SCANNING);
從 debugmsage: State: INACTIVE -> SCANNING能夠看出從inactive 進入scanning
該函數會調用wpas_notify_state_changed,往下又調用了wpas_notify_state_changed
而後再到 wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_STATE_CHANGE
最後到 wpa_msg_cb,一函數指針,指向那個函數呢,請望下看:
wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);
該函數 msg debug call back func 經過前面monitor_conn,發給java的 WifiMonior
若是有時看到WifiMonitor的消息:
Event [CTRL-EVENT-STATE-CHANGE id=-1 state=2 BSSID=00:00:00:00:00:00]
就是這麼一層一層而後發出來的
==> wpa_dbg(wpa_s, MSG_DEBUG, "Starting AP scan for wildcard SSID");
==> wpa_supplicant_extra_ies
===> wps_build_probe_req_ie
關聯參數到 request probe ie (構建一個主動探測IE 的幀)
上面說的Unsupported command: SCAN-ACTIVE,和這裏描述矛盾嗎?
===> params->extra_ies = wpabuf_head(wps_ie);
===> params->extra_ies_len = wpabuf_len(wps_ie);
==> params.freqs = wpa_s->next_scan_freqs; 設置scan channel 到 params
==> wpa_supplicant_build_filter_ssids 設置過濾的ap到params
==> wpa_supplicant_trigger_scan(params)終於到了真正的帶參數掃描了!
===> wpa_drv_scan(wpa_s, params); 具體到nl80211 driver的
wpa_driver_nl80211_scan,終於潛到wpa_supplicant 的最底了
====> 在wpa_driver_nl80211_scan 最後有以下調用:
=====> eloop_register_timeout(timeout, 0,
wpa_driver_nl80211_scan_timeout,drv, drv->ctx);
接下來幹什麼,網撒出去了,該等着收網的時候了
10秒後timeout ,應該不會等到timeout 時間到,wifi compat driver
就會發event 來通知 scan result,eloop call back下面函數
=> wpa_driver_nl80211_scan_timeout:
==> wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
其中代碼:
case EVENT_SCAN_RESULTS:
===> wpa_supplicant_event_scan_results(wpa_s, data);
====> _wpa_supplicant_event_scan_results
這時你該能看到以下wpa_supplicant message:
看不到的話,要不是設備壞了的話,那就是進入無人區了
Received scan results (9 BSSes)
BSS: Start scan result update 1
BSS: Add new id 0 BSSID 00:1f:33:b9:5d:e0 SSID 'RD-test'
BSS: Add new id 1 BSSID 04:21:b0:e0:20:20 SSID 'xxxxx1'
BSS: Add new id 2 BSSID 00:22:b0:e0:20:20 SSID 'xxxxx2'
BSS: Add new id 3 BSSID 00:22:b0:e0:20:e8 SSID 'xxxx3'
BSS: Add new id 4 BSSID 00:22:b0:e0:20:1d SSID 'xxxx4'
BSS: Add new id 5 BSSID 04:21:b0:e0:20:1d SSID 'G-B-U-5'
BSS: Add new id 6 BSSID 0e:4c:39:78:01:94 SSID 'ChinaNet-WGEc'
BSS: Add new id 7 BSSID 5c:63:bf:a6:e4:50 SSID 'xxxxx'
BSS: Add new id 8 BSSID 04:27:b0:e0:20:20 SSID 'xxxxx'
New scan results available
另外還有下面這條分支也會接收掃描結果,多是driver 主動發上來的
貌似以下:
這個 event 由eloops 中 註冊的:
eloop_register_read_sock(nl_socket_get_fd(drv->nl_handle_event),
wpa_driver_nl80211_event_receive, drv, drv->nl_handle_event);
=> wpa_driver_nl80211_event_receive
經過process_event callback 來繼續處理 NL80211_CMD_NEW_SCAN_RESULTS 以下:
這時會: eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout,
取消前面的10s scan timeout eloop
==> send_scan_event
===> wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, &event);
===> wpa_supplicant_event_scan_results
====> _wpa_supplicant_event_scan_results
若是driver 沒有橫插1槓,前面也會走到下面:
=====> wpa_supplicant_get_scan_results 得到ap info
======> wpa_bss_update_scan_res
=======> wpa_bss_add
=====> wpa_msg_ctrl(wpa_s, MSG_INFO,
WPA_EVENT_SCAN_RESULTS);
=====> wpas_notify_scan_results(wpa_s);
======> wpas_wps_notify_scan_results
=======> wpas_wps_notify_scan_results
到這裏wpa_supplicant_event(EVENT_SCAN_RESULTS) 處理結束
下面這段messsage是由上面 wpa_bss_add
=> wpas_notify_bss_added
==> wpa_msg_ctrl(wpa_s, MSG_INFO,
WPA_EVENT_BSS_ADDED "%u " MACSTR,
引起monitor 接收 scan result 前的消息
D/wpa_supplicant( 1468): Event 5 received on interface wlan0
V/WifiMonitor( 1172): Event [CTRL-EVENT-BSS-ADDED 0 00:1f:33:b9:5d:e0]
V/WifiMonitor( 1172): Event [CTRL-EVENT-BSS-ADDED 1 04:21:b0:e0:20:20]
V/WifiMonitor( 1172): Event [CTRL-EVENT-BSS-ADDED 2 00:22:b0:e0:20:20]
V/WifiMonitor( 1172): Event [CTRL-EVENT-BSS-ADDED 3 00:22:b0:e0:20:e8]
V/WifiMonitor( 1172): Event [CTRL-EVENT-BSS-ADDED 4 00:22:b0:e0:20:1d]
V/WifiMonitor( 1172): Event [CTRL-EVENT-BSS-ADDED 5 04:21:b0:e0:20:1d]
V/WifiMonitor( 1172): Event [CTRL-EVENT-BSS-ADDED 6 0e:4c:39:78:01:94]
V/WifiMonitor( 1172): Event [CTRL-EVENT-BSS-ADDED 7 5c:63:bf:a6:e4:50]
V/WifiMonitor( 1172): Event [CTRL-EVENT-BSS-ADDED 8 04:27:b0:e0:20:20]
接下來還有收到這樣1條msg:
V/WifiMonitor( 1172): Event [WPS-AP-AVAILABLE ]
再跟下:
=> wpa_supplicant_event_scan_results
==> _wpa_supplicant_event_scan_results =>
wpa_dbg(wpa_s, MSG_DEBUG, "New scan results available");
wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS);
立刻結束,最後再回到java部分,上面發的WPA_EVENT_SCAN_RESULTS 被monitor接收:
=> handleEvent(int event, String remainder)(WifiMonitor.java)
case SCAN_RESULTS
==>mWifiStateTracker.notifyScanResultsAvailable();
===> setScanResultHandling(SUPPL_SCAN_HANDLING_NORMAL);
====> wifiStateTracker.setScanResultHandling
===> sendEmptyMessage(EVENT_SCAN_RESULTS_AVAILABLE);
接下來WifiStateTracker中的handleMessage會處理該消息
wpa_supplicant_get_scan_results中有對scan result排序, 通常按RSSI 強度來排, 若是有什麼想法,能夠動下 另外還有network group priority ,後面會提到 enable 部分基本就這樣了,結束