欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
android Wifi模塊分析(二)

二,Wifi模塊解析

1)框架分析 

       首先,用戶(hù)程序使用WifiManager類(lèi)來(lái)管理Wifi模塊,它能夠獲得Wifi模塊的狀態(tài),配置和控制Wifi模塊,而所有這些操作都要依賴(lài)Wifiservice類(lèi)來(lái)實(shí)現。

       WifiServiceWifiMonitor類(lèi)是Wifi框架的核心,如圖所示。下面先來(lái)看看WifiService是什么時(shí)候,怎么被創(chuàng )建和初始化的。

       systemServer啟動(dòng)之后,它會(huì )創(chuàng )建一個(gè)ConnectivityServer對象,這個(gè)對象的構造函數會(huì )創(chuàng )建一個(gè)WifiService的實(shí)例,代碼如下所示:

 

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

{

……

case ConnectivityManager.TYPE_WIFI:

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

                WifiStateTracker wst = new WifiStateTracker(context, mHandler);                             //創(chuàng )建WifiStateTracker實(shí)例

                WifiService wifiService = new WifiService(context, wst);//創(chuàng )建WifiService實(shí)例

                ServiceManager.addService(Context.WIFI_SERVICE, wifiService);           //向服務(wù)管理系統添加Wifi服務(wù)

                wifiService.startWifi();     //啟動(dòng)Wifi

                mNetTrackers[ConnectivityManager.TYPE_WIFI] = wst;

                wst.startMonitoring(); //啟動(dòng)WifiMonitor中的WifiThread線(xiàn)程

……

}

       WifiService的主要工作:WifiMonitorWpa_supplicant的啟動(dòng)和關(guān)閉,向Wpa_supplicant發(fā)送命令。

       WifiMonitor的主要工作:阻塞監聽(tīng)并接收來(lái)自Wpa_supplicant的消息,然后發(fā)送給WifiStateTracker。

       上面兩個(gè)線(xiàn)程通過(guò)AF_UNIX套接字和Wpa_supplicant通信,在通信過(guò)程中有兩種連接方式:控制連接和監聽(tīng)連接。它們創(chuàng )建代碼如下:

ctrl_conn = wpa_ctrl_open(ifname);

.. .. ..

 monitor_conn = wpa_ctrl_open(ifname);

 

2Wifi啟動(dòng)流程

       1)使能Wifi

       要想使用Wifi模塊,必須首先使能Wifi,當你第一次按下Wifi使能按鈕時(shí),WirelessSettings會(huì )實(shí)例化一個(gè)WifiEnabler對象,實(shí)例化代碼如下:

 

packages/apps/settings/src/com/android/settings/WirelessSettings.java

protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

……

              CheckBoxPreference wifi = (CheckBoxPreference) findPreference(KEY_TOGGLE_WIFI);

              mWifiEnabler = new WifiEnabler(this, wifi);

……

}

       WifiEnabler類(lèi)的定義大致如下,它實(shí)現了一個(gè)監聽(tīng)接口,當WifiEnabler對象被初始化后,它監聽(tīng)到你按鍵的動(dòng)作,會(huì )調用響應函數onPreferenceChange(),這個(gè)函數會(huì )調用WifiManagersetWifiEnabled()函數。

public class WifiEnabler implements Preference.OnPreferenceChangeListener {

……

public boolean onPreferenceChange(Preference preference, Object value) {

        boolean enable = (Boolean) value;

……

if (mWifiManager.setWifiEnabled(enable)) {

                mCheckBox.setEnabled(false);

……

}

……

}

       我們都知道Wifimanager只是個(gè)服務(wù)代理,所以它會(huì )調用WifiServicesetWifiEnabled()函數,而這個(gè)函數會(huì )調用sendEnableMessage()函數,了解android 消息處理機制的都知道,這個(gè)函數最終會(huì )給自己發(fā)送一個(gè)MESSAGE_ENABLE_WIFI的消息,被WifiService里面定義的handlermessage()函數處理,會(huì )調用setWifiEnabledBlocking()函數。下面是調用流程:

 

mWifiEnabler.onpreferencechange()=>mWifiManage.setWifienabled()=>mWifiService.setWifiEnabled()=>mWifiService.sendEnableMessage()=>mWifiService.handleMessage()=>mWifiService.setWifiEnabledBlocking().

 

setWifiEnabledBlocking()函數中主要做如下工作:加載Wifi驅動(dòng),啟動(dòng)wpa_supplicant,注冊廣播接收器,啟動(dòng)WifiThread監聽(tīng)線(xiàn)程。代碼如下:

……

if (enable) {

            if (!mWifiStateTracker.loadDriver()) {

                Slog.e(TAG, "Failed to load Wi-Fi driver.");

                setWifiEnabledState(WIFI_STATE_UNKNOWN, uid);

                return false;

            }

            if (!mWifiStateTracker.startSupplicant()) {

                mWifiStateTracker.unloadDriver();

                Slog.e(TAG, "Failed to start supplicant daemon.");

                setWifiEnabledState(WIFI_STATE_UNKNOWN, uid);

                return false;

            }

 

            registerForBroadcasts();

            mWifiStateTracker.startEventLoop();

……

       至此,Wifi使能結束,自動(dòng)進(jìn)入掃描階段。

 

(2) 掃描AP

       當驅動(dòng)加載成功后,如果配置文件的AP_SCAN = 1,掃描會(huì )自動(dòng)開(kāi)始,WifiMonitor將會(huì )從supplicant收到一個(gè)消息EVENT_DRIVER_STATE_CHANGED,調用handleDriverEvent(),然后調用mWifiStateTracker.notifyDriverStarted(),該函數向消息隊列添加EVENT_DRIVER_STATE_CHANGED,handlermessage()函數處理消息時(shí)調用scan()函數,并通過(guò)WifiNative將掃描命令發(fā)送到wpa_supplicant。

 

Frameworks/base/wifi/java/android/net/wifi/WifiMonitor.java

private void handleDriverEvent(String state) {

            if (state == null) {

                return;

            }

            if (state.equals("STOPPED")) {

                mWifiStateTracker.notifyDriverStopped();

            } else if (state.equals("STARTED")) {

                mWifiStateTracker.notifyDriverStarted();

            } else if (state.equals("HANGED")) {

                mWifiStateTracker.notifyDriverHung();

            }

        }

 

Frameworks/base/wifi/java/android/net/wifi/WifiStateTracker.java

case EVENT_DRIVER_STATE_CHANGED:

        

                switch (msg.arg1) {

                case DRIVER_STARTED:

                    

                    setNumAllowedChannels();

                    synchronized (this) {

                        if (mRunState == RUN_STATE_STARTING) {

                            mRunState = RUN_STATE_RUNNING;

                            if (!mIsScanOnly) {

                                reconnectCommand();

                            } else {

                                // In some situations, supplicant needs to be kickstarted to

                                // start the background scanning

                                scan(true);

                            }

                        }

                    }

                    break;             

 

上面是啟動(dòng)Wifi時(shí),自動(dòng)進(jìn)行的AP的掃描,用戶(hù)當然也可以手動(dòng)掃描AP,這部分實(shí)現在WifiService里面,WifiService通過(guò)startScan()接口函數發(fā)送掃描命令到supplicant。

 

Frameworks/base/wifi/java/android/net/wifi/WifiStateTracker.java

public boolean startScan(boolean forceActive) {

        enforceChangePermission();

 

        switch (mWifiStateTracker.getSupplicantState()) {

            case DISCONNECTED:

            case INACTIVE:

            case SCANNING:

            case DORMANT:

                break;

            default:

                mWifiStateTracker.setScanResultHandling(

                        WifiStateTracker.SUPPL_SCAN_HANDLING_LIST_ONLY);

                break;

        }

        return mWifiStateTracker.scan(forceActive);

    }

       然后下面的流程同上面的自動(dòng)掃描,我們來(lái)分析一下手動(dòng)掃描從哪里開(kāi)始的。我們應該知道手動(dòng)掃描是通過(guò)菜單鍵的掃描鍵來(lái)響應的,而響應該動(dòng)作的應該是WifiSettings類(lèi)中Scanner類(lèi)的handlerMessage()函數,它調用WifiManagerstartScanActive(),這才調用WifiServicestartScan()。

 

packages/apps/Settings/src/com/android/settings/wifi wifisettings.java

public boolean onCreateOptionsMenu(Menu menu) {

        menu.add(Menu.NONE, MENU_ID_SCAN, 0, R.string.wifi_menu_scan)

                .setIcon(R.drawable.ic_menu_scan_network);

        menu.add(Menu.NONE, MENU_ID_ADVANCED, 0, R.string.wifi_menu_advanced)

                .setIcon(android.R.drawable.ic_menu_manage);

        return super.onCreateOptionsMenu(menu);

    }

 

       當按下菜單鍵時(shí),WifiSettings就會(huì )調用這個(gè)函數繪制菜單。如果選擇掃描按鈕,WifiSettings會(huì )調用onOptionsItemSelected()。

 

packages/apps/Settings/src/com/android/settings/wifi wifisettings.java

public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {

            case MENU_ID_SCAN:

                if (mWifiManager.isWifiEnabled()) {

                    mScanner.resume();

                }

                return true;

            case MENU_ID_ADVANCED:

                startActivity(new Intent(this, AdvancedSettings.class));

                return true;

        }

        return super.onOptionsItemSelected(item);

}

 

private class Scanner extends Handler {

        private int mRetry = 0;

 

        void resume() {

            if (!hasMessages(0)) {

                sendEmptyMessage(0);

            }

        }

 

        void pause() {

            mRetry = 0;

            mAccessPoints.setProgress(false);

            removeMessages(0);

        }

 

        @Override

        public void handleMessage(Message message) {

            if (mWifiManager.startScanActive()) {

                mRetry = 0;

            } else if (++mRetry >= 3) {

                mRetry = 0;

                Toast.makeText(WifiSettings.this, R.string.wifi_fail_to_scan,

                        Toast.LENGTH_LONG).show();

                return;

            }

            mAccessPoints.setProgress(mRetry != 0);

            sendEmptyMessageDelayed(0, 6000);

        }

    }

      

這里的mWifiManager.startScanActive()就會(huì )調用WifiService里的startScan()函數,下面的流程和上面的一樣,這里不贅述。

supplicant完成了這個(gè)掃描命令后,它會(huì )發(fā)送一個(gè)消息給上層,提醒他們掃描已經(jīng)完成,WifiMonitor會(huì )接收到這消息,然后再發(fā)送給WifiStateTracker。

 

Frameworks/base/wifi/java/android/net/wifi/WifiMonitor.java

void handleEvent(int event, String remainder) {

            switch (event) {

                case DISCONNECTED:

                    handleNetworkStateChange(NetworkInfo.DetailedState.DISCONNECTED, remainder);

                    break;

 

                case CONNECTED:

                    handleNetworkStateChange(NetworkInfo.DetailedState.CONNECTED, remainder);

                    break;

 

                case SCAN_RESULTS:

                    mWifiStateTracker.notifyScanResultsAvailable();

                    break;

 

                case UNKNOWN:

                    break;

            }

        }

WifiStateTracker將會(huì )廣播SCAN_RESULTS_AVAILABLE_ACTION消息:

 

Frameworks/base/wifi/java/android/net/wifi/WifiStateTracker.java

public void handleMessage(Message msg) {

        Intent intent;

……

case EVENT_SCAN_RESULTS_AVAILABLE:

                if (ActivityManagerNative.isSystemReady()) {

                    mContext.sendBroadcast(new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));

                }

                sendScanResultsAvailable();

               

                setScanMode(false);

                break;

……

       由于WifiSettings類(lèi)注冊了intent,能夠處理SCAN_RESULTS_AVAILABLE_ACTION消息,它會(huì )調用handleEvent(),調用流程如下所示。

 

WifiSettings.handleEvent() => WifiSettings.updateAccessPoints() => mWifiManager.getScanResults() => mService.getScanResults() => mWifiStateTracker.scanResults() => WifiNative.scanResultsCommand()……

 

將獲取AP列表的命令發(fā)送到supplicant,然后supplicant通過(guò)Socket發(fā)送掃描結果,由上層接收并顯示。這和前面的消息獲取流程基本相同。

 

(3)配置,連接AP

當用戶(hù)選擇一個(gè)活躍的AP時(shí),WifiSettings響應打開(kāi)一個(gè)對話(huà)框來(lái)配置AP,比如加密方法和連接AP的驗證模式。配置好AP后,WifiService添加或更新網(wǎng)絡(luò )連接到特定的AP。

 

packages/apps/settings/src/com/android/settings/wifi/WifiSetttings.java

public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {

        if (preference instanceof AccessPoint) {

            mSelected = (AccessPoint) preference;

            showDialog(mSelected, false);

        } else if (preference == mAddNetwork) {

            mSelected = null;

            showDialog(null, true);

        } else if (preference == mNotifyOpenNetworks) {

            Secure.putInt(getContentResolver(),

                    Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,

                    mNotifyOpenNetworks.isChecked() ? 1 : 0);

        } else {

            return super.onPreferenceTreeClick(screen, preference);

        }

        return true;

    }

 

       配置好以后,當按下“Connect Press”時(shí),WifiSettings通過(guò)發(fā)送LIST_NETWORK命令到supplicant來(lái)檢查該網(wǎng)絡(luò )是否配置。如果沒(méi)有該網(wǎng)絡(luò )或沒(méi)有配置它,WifiService調用addorUpdateNetwork()函數來(lái)添加或更新網(wǎng)絡(luò ),然后發(fā)送命令給supplicant,連接到這個(gè)網(wǎng)絡(luò )。下面是從響應連接按鈕到WifiService發(fā)送連接命令的代碼:

 

packages/apps/settings/src/com/android/settings/wifi/WifiSetttings.java

public void onClick(DialogInterface dialogInterface, int button) {

        if (button == WifiDialog.BUTTON_FORGET && mSelected != null) {

            forget(mSelected.networkId);

        } else if (button == WifiDialog.BUTTON_SUBMIT && mDialog != null) {

            WifiConfiguration config = mDialog.getConfig();

 

            if (config == null) {

                if (mSelected != null && !requireKeyStore(mSelected.getConfig())) {

                    connect(mSelected.networkId);

                }

            } else if (config.networkId != -1) {

                if (mSelected != null) {

                    mWifiManager.updateNetwork(config);

                    saveNetworks();

                }

            } else {

                int networkId = mWifiManager.addNetwork(config);

                if (networkId != -1) {

                    mWifiManager.enableNetwork(networkId, false);

                    config.networkId = networkId;

                    if (mDialog.edit || requireKeyStore(config)) {

                        saveNetworks();

                    } else {

                        connect(networkId);

                    }

                }

            }

        }

    }

      

      

Frameworks\base\wifi\java\android\net\wifi\WifiManager.java

       public int updateNetwork(WifiConfiguration config) {

        if (config == null || config.networkId < 0) {

            return -1;

        }

        return addOrUpdateNetwork(config);

}

private int addOrUpdateNetwork(WifiConfiguration config) {

        try {

            return mService.addOrUpdateNetwork(config);

        } catch (RemoteException e) {

            return -1;

        }

    }

 

WifiService.addOrUpdateNetwork()通過(guò)調用mWifiStateTracker.setNetworkVariable()將連接命令發(fā)送到Wpa_supplicant。

 

4)獲取IP地址

當連接到supplicant后,WifiMonitor就會(huì )通知WifiStateTracker。

 

Frameworks/base/wifi/java/android/net/wifi/WifiMonitor.java

Public void Run(){

if (connectToSupplicant()) {

                // Send a message indicating that it is now possible to send commands

                // to the supplicant

                mWifiStateTracker.notifySupplicantConnection();

            } else {

                mWifiStateTracker.notifySupplicantLost();

                return;

            }

……

}

 

WifiStateTracker發(fā)送EVENT_SUPPLICANT_CONNECTION消息到消息隊列,這個(gè)消息有自己的handlermessage()函數處理,它會(huì )啟動(dòng)一個(gè)DHCP線(xiàn)程,而這個(gè)線(xiàn)程會(huì )一直等待一個(gè)消息事件,來(lái)啟動(dòng)DHCP協(xié)議分配IP地址。

 

frameworks/base/wifi/java/android/net/wifi/WifiStateTracker.java

void notifySupplicantConnection() {

        sendEmptyMessage(EVENT_SUPPLICANT_CONNECTION);

}

 

public void handleMessage(Message msg) {

        Intent intent;

 

        switch (msg.what) {

            case EVENT_SUPPLICANT_CONNECTION:

             ……

             HandlerThread dhcpThread = new HandlerThread("DHCP Handler Thread");

                dhcpThread.start();

                mDhcpTarget = new DhcpHandler(dhcpThread.getLooper(), this);

……

……

}

Wpa_supplicant連接到AP后,它會(huì )發(fā)送一個(gè)消息給上層來(lái)通知連接成功,WifiMonitor會(huì )接受到這個(gè)消息并上報給WifiStateTracker。

 

Frameworks/base/wifi/java/android/net/wifi/WifiMonitor.java

void handleEvent(int event, String remainder) {

            switch (event) {

                case DISCONNECTED:

                    handleNetworkStateChange(NetworkInfo.DetailedState.DISCONNECTED, remainder);

                    break;

 

                case CONNECTED:

                    handleNetworkStateChange(NetworkInfo.DetailedState.CONNECTED, remainder);

                    break;

                ……

}

 

private void handleNetworkStateChange(NetworkInfo.DetailedState newState, String data) {

        String BSSID = null;

        int networkId = -1;

        if (newState == NetworkInfo.DetailedState.CONNECTED) {

            Matcher match = mConnectedEventPattern.matcher(data);

            if (!match.find()) {

                if (Config.LOGD) Log.d(TAG, "Could not find BSSID in CONNECTED event string");

            } else {

                BSSID = match.group(1);

                try {

                    networkId = Integer.parseInt(match.group(2));

                } catch (NumberFormatException e) {

                    networkId = -1;

                }

            }

        }

        mWifiStateTracker.notifyStateChange(newState, BSSID, networkId);

}

      

void notifyStateChange(DetailedState newState, String BSSID, int networkId) {

        Message msg = Message.obtain(

            this, EVENT_NETWORK_STATE_CHANGED,

            new NetworkStateChangeResult(newState, BSSID, networkId));

        msg.sendToTarget();

    }

 

case EVENT_NETWORK_STATE_CHANGED:

……

configureInterface();

……

 

private void configureInterface() {

        checkPollTimer();

        mLastSignalLevel = -1;

        if (!mUseStaticIp) {          //使用DHCP線(xiàn)程動(dòng)態(tài)IP

            if (!mHaveIpAddress && !mObtainingIpAddress) {

                mObtainingIpAddress = true;

 

                                   //發(fā)送啟動(dòng)DHCP線(xiàn)程獲取IP

                mDhcpTarget.sendEmptyMessage(EVENT_DHCP_START);

            }

        } else {        //使用靜態(tài)IP,IP信息從mDhcpInfo中獲取

            int event;

            if (NetworkUtils.configureInterface(mInterfaceName, mDhcpInfo)) {

                mHaveIpAddress = true;

                event = EVENT_INTERFACE_CONFIGURATION_SUCCEEDED;

                if (LOCAL_LOGD) Log.v(TAG, "Static IP configuration succeeded");

            } else {

                mHaveIpAddress = false;

                event = EVENT_INTERFACE_CONFIGURATION_FAILED;

                if (LOCAL_LOGD) Log.v(TAG, "Static IP configuration failed");

            }

            sendEmptyMessage(event);           //發(fā)送IP獲得成功消息事件

        }

    }

              DhcpThread獲取EVENT_DHCP_START消息事件后,調用handleMessage()函數,啟動(dòng)DHCP獲取IP地址的服務(wù)。

 

public void handleMessage(Message msg) {

            int event;

switch (msg.what) {

                case EVENT_DHCP_START:

 

……

Log.d(TAG, "DhcpHandler: DHCP request started");

 

//啟動(dòng)一個(gè)DHCP client的精靈進(jìn)程,為mInterfaceName請求分配一個(gè)IP//

    if (NetworkUtils.runDhcp(mInterfaceName, mDhcpInfo)) {

     event = EVENT_INTERFACE_CONFIGURATION_SUCCEEDED;

         if (LOCAL_LOGD) Log.v(TAG, "DhcpHandler: DHCP request succeeded");

    } else {

           event = EVENT_INTERFACE_CONFIGURATION_FAILED;

           Log.i(TAG, "DhcpHandler: DHCP request failed: " +

                            NetworkUtils.getDhcpError());

        }

……

}

這里調用了一個(gè)NetworkUtils.runDhcp()函數,NetworkUtils類(lèi)是一個(gè)網(wǎng)絡(luò )服務(wù)的輔助類(lèi),它主要定義了一些本地接口,這些接口會(huì )通過(guò)他們的JNIandroid_net_NetUtils.cpp文件和DHCP client通信,并獲取IP地址。

至此,IP地址獲取完畢,Wifi啟動(dòng)流程結束。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
android中wifi原理及流程分析(很經(jīng)典)
wifi使用的相關(guān)流程
android 系統啟動(dòng)后的 wifi加載 過(guò)程
getSystemService原理
圖解框架
android WIFI模塊
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久