您的位置:首页 > 其它

跟一下wpa_supplicant(2) wifi enable

2013-03-25 20:36 911 查看
原文地址:http://blog.chinaunix.net/uid-20514606-id-3259410.html

在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 部分基本就这样了,结束
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: