跟一下wpa_supplicant(2) wifi enable
(2012-06-30 18:11)
* 在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 部分基本就这样了,结束 |
|
来自: arm_embed > 《Framework》