android wifi之WifiMonitor

轉自:http://www.cnblogs.com/dongtaochen2039/archive/2012/04/10/2439051.html

android wifi之WifiMonitor

通過在網上的學習已經瞭解了wifi的大致流程,現在學習了wifi的核心類之一WifiMomitor,監控wpa_supplicant的消息並實時作出處理。

首先看該類官方的解釋:Listens for events from the wpa_supplicant server, and passes them on to the {@link StateMachine} for handling. Runs in its own thread.專門負責接收來自wpa_supplicant的事件,並將這些消息進行分類再交予StateMachine處理。在WifiStateMachine裏面的內部類DriverLoadedState中啓動wpa_supplicant之後調用了WifiMonitor的startMonitor()方法。該方法開啓了一個新的線程MonitorThread,接受來自wpa_supplicant的事件。該線程源碼如下:

複製代碼
class MonitorThread extends Thread {
        public MonitorThread() {
            super("WifiMonitor");
        }

        public void run() {

            if (connectToSupplicant()) {
                // Send a message indicating that it is now possible to send commands
                // to the supplicant
                mStateMachine.sendMessage(SUP_CONNECTION_EVENT);
            } else {
                mStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
                return;
            }

            //noinspection InfiniteLoopStatement
            for (;;) {
                String eventStr = WifiNative.waitForEvent();

                // Skip logging the common but mostly uninteresting scan-results event
                if (false && eventStr.indexOf(SCAN_RESULTS_STR) == -1) {
                    Log.d(TAG, "Event [" + eventStr + "]");
                }
                if (!eventStr.startsWith(EVENT_PREFIX_STR)) {
                }
               .........
               .........
               .........
            }}}
複製代碼

String eventStr = WifiNative.waitForEvent();這就是接收來自wpa_supplicant的事件然後對該字符串進行分析處理。下面將分別省略號部分的代碼進行分析,他們都是一些if和else if的塊:

複製代碼
               if (!eventStr.startsWith(EVENT_PREFIX_STR)) { 
                    if (eventStr.startsWith(WPA_EVENT_PREFIX_STR) &&0 < eventStr.indexOf(PASSWORD_MAY_BE_INCORRECT_STR)) {
                        mStateMachine.sendMessage(AUTHENTICATION_FAILURE_EVENT);
                    } else if (eventStr.startsWith(WPS_OVERLAP_STR)) {
                        mStateMachine.sendMessage(WPS_OVERLAP_EVENT);
                    } else if (eventStr.startsWith(P2P_EVENT_PREFIX_STR)) {
                        handleP2pEvents(eventStr);
                    } else if (eventStr.startsWith(HOST_AP_EVENT_PREFIX_STR)) {
                        handleHostApEvents(eventStr);
                    }
                    continue;
                }
複製代碼

這種情況裏面的第一個if代表該ap密碼可能錯誤。2.在PBC模式下發現WPS重疊錯誤。3.P2P 事件 4.在handleHostApEvents(eventStr)函數裏面分別向wifiStateMachine發送AP-STA-CONNECTED和AP-STA-DISCONNECTED消息。

複製代碼
                String eventName = eventStr.substring(EVENT_PREFIX_LEN_STR);
                int nameEnd = eventName.indexOf(' ');
                if (nameEnd != -1)
                    eventName = eventName.substring(0, nameEnd);
                if (eventName.length() == 0) {
                    if (false) Log.i(TAG, "Received wpa_supplicant event with empty event name");
                    continue;
                }
複製代碼

eventName = eventStr.substring(EVENT_PREFIX_LEN_STR);eventStr去除“CTRL-EVENT-”前綴,後得到eventName字符串。經第一個if處理後eventName變爲從開始到空格間的所有字符。若處理後的eventName是空字符串則返回。重新取值。

複製代碼
                int event;
                if (eventName.equals(CONNECTED_STR)) 
                    event = CONNECTED;
                else if (eventName.equals(DISCONNECTED_STR))
                    event = DISCONNECTED;
                else if (eventName.equals(STATE_CHANGE_STR))
                    event = STATE_CHANGE;
                else if (eventName.equals(SCAN_RESULTS_STR))
                    event = SCAN_RESULTS;
                else if (eventName.equals(LINK_SPEED_STR))
                    event = LINK_SPEED;
                else if (eventName.equals(TERMINATING_STR))
                    event = TERMINATING;
                else if (eventName.equals(DRIVER_STATE_STR))
                    event = DRIVER_STATE;
                else if (eventName.equals(EAP_FAILURE_STR))
                    event = EAP_FAILURE;
                else
                    event = UNKNOWN; 
複製代碼

得到事件的內容,將其放進event,以便操作。(1)ap(access point)密碼驗證已成功完成,數據鏈接可以使用了。(2)鏈接失敗數據鏈接不可用。(3)state change指的是supplicant的狀態改變了,接下來會調用handleSupplicantChang方法返回現在supplicant的狀態,handleSupplicantChang方法的最後調用了notifySupplicantStateChange方法(4)新的ap掃描結果可用了。(5)wpa_supplicant退出了。(8)EAP認證失敗。

在該thread方法的最後調用了handleEvent方法處理了其餘的event包含DISCONNECTED和CONNECTED(他倆調用了handleNetWorkStateChange方法該方法得到了新的網絡狀態後調用了notifyNetWorktStateChange方法向wifiStateMachine發送了新狀態message)以及SCAN_RESULTS(ap掃描結果,向wifiStateMachine發送了message),unknown(不做任何處理)。兩個notify方法都是向wifiStateMachine發送message以告知supplicant或者network狀態改變了。在message中加上了新的網絡狀態。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章