WIFI扫描流程分析

来源:互联网 发布:dbc2000数据库 中文版 编辑:程序博客网 时间:2024/04/30 05:33

  一.启动wifi服务

1.在 SystemServer 启动的时候,会生成一个 ConnectivityService 的实例

路径为:/frameworks/base/services/java/com/android/server/SystemServer.java

try {

             Slog.i(TAG, "Connectivity Service");

             connectivity = ConnectivityService.getInstance(context);

             ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);

            } catch (Throwable e) {

                Slog.e(TAG, "Failure starting Connectivity Service", e);

            }

2.ConnectivityService 类中private ConnectivityService(Context context) 构造函数创建

    WifiService和WifiStateTracker对象

/frameworks/base/services/java/com/android/server/ConnectivityService.java

for (int netType : mPriorityList) {

            switch (mNetAttributes[netType].mRadio) {

            case ConnectivityManager.TYPE_WIFI:

                if (DBG) Slog.v(TAG, "Starting Wifi Service.");

                WifiStateTracker wst = new WifiStateTracker(context, mHandler);

                WifiService wifiService = new WifiService(context, wst);

                ServiceManager.addService(Context.WIFI_SERVICE, wifiService);

                wifiService.startWifi();

                mNetTrackers[ConnectivityManager.TYPE_WIFI] = wst;

                wst.startMonitoring();

                break;

}

}

3.创建WifiStateTracker和WifiService对象用来启动wifi管理服务WifiStateTracker 会创建   

    WifiMonitor 用来接收来自底层的事件,WifiService 和 WifiMonitor 是整个模块的核心

4.WifiService 负责启动关闭 wpa_supplicant、启动关闭 WifiMonitor 监视线程和把命令下发 

               给 wpa_supplicant

     5. WifiMonitor

               开始运行线程,会请求连接wpa_supplicant,通过调用WifiStateTracker函数connectToSupplicant然后通过wifi.c的wifi_connect_to_supplicant,接着向wpa_ctrl的wpa_ctrl_open。然后通过CreateFile函数向wpa_supplicant读取数据。连接成功后会发送EVENT_SUPPLICANT_CONNECTION消息启动获取DHCP地址线程阻塞调用(当连接上AP的时候,该线程会被执行起来获取IP地址),并记录自己的MAC地址(因为MAC地址不会改变

所以请求一次即可) 接着开启一个死循环处理wpa_supplicant发送的事件。

 

 

 

当用户点击Wi-Fi按钮 的时候WifiEnabler中的onPreferenceChange函数会被调用,再由该函数调用WifiManagersetWifiEnabled函数,它先引用AIDL经由IWifiManager通过Binder机制调用WifiServicesetWifiEnabled设置Wifi开启状态。同时WifiService会发送MESSAGE_ENABLE_WIFI消息,由WifiService 

setWifiEnabledBlocking函数响应该消息,负责Wifi可用的需要工作。首先他会加载驱动

loadDriver(),然后开启wpa_supplicant(
"/data/misc/wifi/wpa_supplicant.conf")
再注册广播消息,而后通过 WifiStateTracker 来启动 WifiMonitor 中的监视线程。以上工作使能成功后,会调用setWifiEnabledState最后广播WIFI_STATE_CHANGED_ACTION 这个Intent,至此Wifi能动开启。

接下来是扫描AP

WifiSettingsWifiEnabler Android
WIFI_STATE_CHANGED_ACTION,
因此他们都会收到WIFI_STATE_CHANGED_ACTION 这个IntentWifiEnabler负责使得图标加亮,WifiSettings负责使得开启扫描AP。经由

WifiService startScan,再通过JNIandroid_net_wifi_scanCommand函数向wpa_supplicant发送扫描命令. wpa_supplicant 处理完 SCAN 命令后,它会向控制通道发送事件通知扫描完成,从而wifi_wait_for_event 函数会接收到该事件,由此 WifiMonitor 中的 MonitorThread 会被执行来处理接扫描结果事件。此线程通过WifiStateTracker 广播 SCAN_RESULTS_AVAILABLE_ACTION这个Intent。而WifiSettings注册了接收此Intent,最终由其相应函数updateAccessPointsAP列表,以GUI的形式列出来。