跟一下wpa_supplicant(2) wifi enable

* 在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 部分基本就這樣了,結束

相關文章
相關標籤/搜索