Chinaunix首页 | 论坛 | 博客
  • 博客访问: 403854
  • 博文数量: 53
  • 博客积分: 1910
  • 博客等级: 中尉
  • 技术积分: 1130
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-10 14:56
文章分类

全部博文(53)

文章存档

2013年(1)

2012年(17)

2011年(33)

2010年(2)

分类: 嵌入式

2012-06-30 18:11:39

* 在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 部分基本就这样了,结束
 
阅读(8011) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~