* 在wifi setting 中 check enanble 开始继续
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 等等
=> setWifiEnabledState(eventualWifiState, uid);(wifiService.java)
eventualWifiState 为 WIFI_STATE_ENABLED
==> mWifiStateTracker.setWifiState(WIFI_STATE_ENABLED);
boardcast WIFI_STATE_CHANGED_ACTION + WIFI_STATE_ENABLED
处理接收该wifi 状态广播的分支见 3.
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,和 打上勾的处理
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类
接收处理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 连接
==> 发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参数
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.分支中的)
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 部分基本就这样了,结束