WifiMonitor.java revision d3975a917799b85cacaf382b65c5832813066b51
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.net.wifi;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.NetworkInfo;
2055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.p2p.WifiP2pConfig;
2155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.p2p.WifiP2pDevice;
2255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.p2p.WifiP2pGroup;
23618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriffimport android.net.wifi.p2p.WifiP2pProvDiscEvent;
2455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.StateChangeResult;
2555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.Message;
2655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.util.Log;
2755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
2855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
2955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport com.android.internal.util.Protocol;
3055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport com.android.internal.util.StateMachine;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.regex.Pattern;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.regex.Matcher;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Listens for events from the wpa_supplicant server, and passes them on
3755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * to the {@link StateMachine} for handling. Runs in its own thread.
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class WifiMonitor {
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String TAG = "WifiMonitor";
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Events we receive from the supplicant daemon */
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int CONNECTED    = 1;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DISCONNECTED = 2;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int STATE_CHANGE = 3;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int SCAN_RESULTS = 4;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int LINK_SPEED   = 5;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int TERMINATING  = 6;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DRIVER_STATE = 7;
54b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff    private static final int EAP_FAILURE  = 8;
55b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff    private static final int UNKNOWN      = 9;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** All events coming from the supplicant start with this prefix */
5855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String EVENT_PREFIX_STR = "CTRL-EVENT-";
5955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int EVENT_PREFIX_LEN_STR = EVENT_PREFIX_STR.length();
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** All WPA events coming from the supplicant start with this prefix */
6255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String WPA_EVENT_PREFIX_STR = "WPA:";
6355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String PASSWORD_MAY_BE_INCORRECT_STR =
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project       "pre-shared key may be incorrect";
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
66fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff    /* WPS events */
67d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    private static final String WPS_SUCCESS_STR = "WPS-SUCCESS";
68d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    private static final String WPS_FAIL_STR    = "WPS-FAIL";
6955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String WPS_OVERLAP_STR = "WPS-OVERLAP-DETECTED";
70d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    private static final String WPS_TIMEOUT_STR = "WPS-TIMEOUT";
71fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Names of events from wpa_supplicant (minus the prefix). In the
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * format descriptions, * &quot;<code>x</code>&quot;
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * designates a dynamic value that needs to be parsed out from the event
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * string
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CTRL-EVENT-CONNECTED - Connection to xx:xx:xx:xx:xx:xx completed
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </pre>
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <code>xx:xx:xx:xx:xx:xx</code> is the BSSID of the associated access point
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String CONNECTED_STR =    "CONNECTED";
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CTRL-EVENT-DISCONNECTED - Disconnect event - remove keys
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </pre>
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String DISCONNECTED_STR = "DISCONNECTED";
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CTRL-EVENT-STATE-CHANGE x
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </pre>
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <code>x</code> is the numerical value of the new state.
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String STATE_CHANGE_STR =  "STATE-CHANGE";
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CTRL-EVENT-SCAN-RESULTS ready
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </pre>
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String SCAN_RESULTS_STR =  "SCAN-RESULTS";
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CTRL-EVENT-LINK-SPEED x Mb/s
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </pre>
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@code x} is the link speed in Mb/sec.
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String LINK_SPEED_STR = "LINK-SPEED";
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CTRL-EVENT-TERMINATING - signal x
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </pre>
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <code>x</code> is the signal that caused termination.
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String TERMINATING_STR =  "TERMINATING";
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CTRL-EVENT-DRIVER-STATE state
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </pre>
1231523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff     * <code>state</code> can be HANGED
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String DRIVER_STATE_STR = "DRIVER-STATE";
126b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff    /**
127b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff     * <pre>
128b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff     * CTRL-EVENT-EAP-FAILURE EAP authentication failed
129b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff     * </pre>
130b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff     */
13155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String EAP_FAILURE_STR = "EAP-FAILURE";
132b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff
133b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff    /**
134b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff     * This indicates an authentication failure on EAP FAILURE event
135b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff     */
13655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String EAP_AUTH_FAILURE_STR = "EAP authentication failed";
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Regex pattern for extracting an Ethernet-style MAC address from a string.
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Matches a strings like the following:<pre>
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CTRL-EVENT-CONNECTED - Connection to 00:1e:58:ec:d5:6d completed (reauth) [id=1 id_str=]</pre>
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static Pattern mConnectedEventPattern =
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Pattern.compile("((?:[0-9a-f]{2}:){5}[0-9a-f]{2}) .* \\[id=([0-9]+) ");
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /** P2P events */
14755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_EVENT_PREFIX_STR = "P2P";
14855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
14955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-DEVICE-FOUND fa:7b:7a:42:02:13 p2p_dev_addr=fa:7b:7a:42:02:13 pri_dev_type=1-0050F204-1
15055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       name='p2p-TEST1' config_methods=0x188 dev_capab=0x27 group_capab=0x0 */
15155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_DEVICE_FOUND_STR = "P2P-DEVICE-FOUND";
15255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
15355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-DEVICE-LOST p2p_dev_addr=42:fc:89:e1:e2:27 */
15455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_DEVICE_LOST_STR = "P2P-DEVICE-LOST";
15555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
15655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-GO-NEG-REQUEST 42:fc:89:a8:96:09 dev_passwd_id=4 */
15755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_GO_NEG_REQUEST_STR = "P2P-GO-NEG-REQUEST";
15855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
15955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_GO_NEG_SUCCESS_STR = "P2P-GO-NEG-SUCCESS";
16055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
16155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_GO_NEG_FAILURE_STR = "P2P-GO-NEG-FAILURE";
16255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
16355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_GROUP_FORMATION_SUCCESS_STR =
16455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            "P2P-GROUP-FORMATION-SUCCESS";
16555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
16655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_GROUP_FORMATION_FAILURE_STR =
16755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            "P2P-GROUP-FORMATION-FAILURE";
16855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
16955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-GROUP-STARTED p2p-wlan0-0 [client|GO] ssid="DIRECT-W8" freq=2437
17055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       [psk=2182b2e50e53f260d04f3c7b25ef33c965a3291b9b36b455a82d77fd82ca15bc|passphrase="fKG4jMe3"]
17155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       go_dev_addr=fa:7b:7a:42:02:13 */
17255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_GROUP_STARTED_STR = "P2P-GROUP-STARTED";
17355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
17455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-GROUP-REMOVED p2p-wlan0-0 [client|GO] reason=REQUESTED */
17555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_GROUP_REMOVED_STR = "P2P-GROUP-REMOVED";
17655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
17755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-INVITATION-RECEIVED sa=fa:7b:7a:42:02:13 go_dev_addr=f8:7b:7a:42:02:13
17855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        bssid=fa:7b:7a:42:82:13 unknown-network */
17955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_INVITATION_RECEIVED_STR = "P2P-INVITATION-RECEIVED";
18055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
18155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-INVITATION-RESULT status=1 */
18255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_INVITATION_RESULT_STR = "P2P-INVITATION-RESULT";
18355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
18455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-PROV-DISC-PBC-REQ 42:fc:89:e1:e2:27 p2p_dev_addr=42:fc:89:e1:e2:27
18555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       pri_dev_type=1-0050F204-1 name='p2p-TEST2' config_methods=0x188 dev_capab=0x27
18655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       group_capab=0x0 */
18755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_PROV_DISC_PBC_REQ_STR = "P2P-PROV-DISC-PBC-REQ";
188618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
189618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    /* P2P-PROV-DISC-PBC-RESP 02:12:47:f2:5a:36 */
190618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    private static final String P2P_PROV_DISC_PBC_RSP_STR = "P2P-PROV-DISC-PBC-RESP";
191618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
19255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-PROV-DISC-ENTER-PIN 42:fc:89:e1:e2:27 p2p_dev_addr=42:fc:89:e1:e2:27
19355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       pri_dev_type=1-0050F204-1 name='p2p-TEST2' config_methods=0x188 dev_capab=0x27
19455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       group_capab=0x0 */
19555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_PROV_DISC_ENTER_PIN_STR = "P2P-PROV-DISC-ENTER-PIN";
19655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-PROV-DISC-SHOW-PIN 42:fc:89:e1:e2:27 44490607 p2p_dev_addr=42:fc:89:e1:e2:27
19755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       pri_dev_type=1-0050F204-1 name='p2p-TEST2' config_methods=0x188 dev_capab=0x27
19855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       group_capab=0x0 */
19955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_PROV_DISC_SHOW_PIN_STR = "P2P-PROV-DISC-SHOW-PIN";
20055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
20155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String HOST_AP_EVENT_PREFIX_STR = "AP";
202bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff    /* AP-STA-CONNECTED 42:fc:89:a8:96:09 dev_addr=02:90:4c:a0:92:54 */
20355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String AP_STA_CONNECTED_STR = "AP-STA-CONNECTED";
20455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* AP-STA-DISCONNECTED 42:fc:89:a8:96:09 */
20555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String AP_STA_DISCONNECTED_STR = "AP-STA-DISCONNECTED";
20655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
20755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private final StateMachine mStateMachine;
208fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private final WifiNative mWifiNative;
20955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
21055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Supplicant events reported to a state machine */
21155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int BASE = Protocol.BASE_WIFI_MONITOR;
21255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
21355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Connection to supplicant established */
21455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int SUP_CONNECTION_EVENT                 = BASE + 1;
21555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Connection to supplicant lost */
21655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int SUP_DISCONNECTION_EVENT              = BASE + 2;
21755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync   /* Network connection completed */
21855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int NETWORK_CONNECTION_EVENT             = BASE + 3;
21955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Network disconnection completed */
22055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int NETWORK_DISCONNECTION_EVENT          = BASE + 4;
22155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Scan results are available */
22255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int SCAN_RESULTS_EVENT                   = BASE + 5;
22355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Supplicate state changed */
22455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int SUPPLICANT_STATE_CHANGE_EVENT        = BASE + 6;
22555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Password failure and EAP authentication failure */
22655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int AUTHENTICATION_FAILURE_EVENT         = BASE + 7;
227d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    /* WPS success detected */
228d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    public static final int WPS_SUCCESS_EVENT                    = BASE + 8;
229d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    /* WPS failure detected */
230d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    public static final int WPS_FAIL_EVENT                       = BASE + 9;
231d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     /* WPS overlap detected */
232d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    public static final int WPS_OVERLAP_EVENT                    = BASE + 10;
233d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     /* WPS timeout detected */
234d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    public static final int WPS_TIMEOUT_EVENT                    = BASE + 11;
23555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Driver was hung */
236d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    public static final int DRIVER_HUNG_EVENT                    = BASE + 12;
23755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
23855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P events */
23955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_DEVICE_FOUND_EVENT               = BASE + 21;
24055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_DEVICE_LOST_EVENT                = BASE + 22;
24155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_GO_NEGOTIATION_REQUEST_EVENT     = BASE + 23;
24255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_GO_NEGOTIATION_SUCCESS_EVENT     = BASE + 25;
24355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_GO_NEGOTIATION_FAILURE_EVENT     = BASE + 26;
24455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_GROUP_FORMATION_SUCCESS_EVENT    = BASE + 27;
24555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_GROUP_FORMATION_FAILURE_EVENT    = BASE + 28;
24655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_GROUP_STARTED_EVENT              = BASE + 29;
24755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_GROUP_REMOVED_EVENT              = BASE + 30;
24855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_INVITATION_RECEIVED_EVENT        = BASE + 31;
24955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_INVITATION_RESULT_EVENT          = BASE + 32;
25055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_PROV_DISC_PBC_REQ_EVENT          = BASE + 33;
251618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    public static final int P2P_PROV_DISC_PBC_RSP_EVENT          = BASE + 34;
252618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    public static final int P2P_PROV_DISC_ENTER_PIN_EVENT        = BASE + 35;
253618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    public static final int P2P_PROV_DISC_SHOW_PIN_EVENT         = BASE + 36;
25455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
25555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* hostap events */
25655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int AP_STA_DISCONNECTED_EVENT            = BASE + 41;
25755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int AP_STA_CONNECTED_EVENT               = BASE + 42;
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25905d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff    /**
26005d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff     * This indicates the supplicant connection for the monitor is closed
26105d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff     */
26255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String MONITOR_SOCKET_CLOSED_STR = "connection closed";
26305d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff
26405d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff    /**
26505d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff     * This indicates a read error on the monitor socket conenction
26605d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff     */
26755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String WPA_RECV_ERROR_STR = "recv error";
26805d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff
26905d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff    /**
27005d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff     * Tracks consecutive receive errors
27105d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff     */
27205d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff    private int mRecvErrors = 0;
27305d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff
27405d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff    /**
27505d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff     * Max errors before we close supplicant connection
27605d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff     */
27705d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff    private static final int MAX_RECV_ERRORS    = 10;
27805d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff
279fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public WifiMonitor(StateMachine wifiStateMachine, WifiNative wifiNative) {
28055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mStateMachine = wifiStateMachine;
281fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative = wifiNative;
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void startMonitoring() {
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        new MonitorThread().start();
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    class MonitorThread extends Thread {
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public MonitorThread() {
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super("WifiMonitor");
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
292a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void run() {
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (connectToSupplicant()) {
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Send a message indicating that it is now possible to send commands
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // to the supplicant
29855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(SUP_CONNECTION_EVENT);
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
30055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //noinspection InfiniteLoopStatement
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (;;) {
306fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                String eventStr = mWifiNative.waitForEvent();
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Skip logging the common but mostly uninteresting scan-results event
30955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                if (false && eventStr.indexOf(SCAN_RESULTS_STR) == -1) {
31055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    Log.d(TAG, "Event [" + eventStr + "]");
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
31255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                if (!eventStr.startsWith(EVENT_PREFIX_STR)) {
31355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (eventStr.startsWith(WPA_EVENT_PREFIX_STR) &&
31455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            0 < eventStr.indexOf(PASSWORD_MAY_BE_INCORRECT_STR)) {
31555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        mStateMachine.sendMessage(AUTHENTICATION_FAILURE_EVENT);
316d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    } else if (eventStr.startsWith(WPS_SUCCESS_STR)) {
317d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        mStateMachine.sendMessage(WPS_SUCCESS_EVENT);
318d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    } else if (eventStr.startsWith(WPS_FAIL_STR)) {
319d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        mStateMachine.sendMessage(WPS_FAIL_EVENT);
32055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    } else if (eventStr.startsWith(WPS_OVERLAP_STR)) {
32155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        mStateMachine.sendMessage(WPS_OVERLAP_EVENT);
322d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    } else if (eventStr.startsWith(WPS_TIMEOUT_STR)) {
323d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        mStateMachine.sendMessage(WPS_TIMEOUT_EVENT);
32455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    } else if (eventStr.startsWith(P2P_EVENT_PREFIX_STR)) {
32555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        handleP2pEvents(eventStr);
32655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    } else if (eventStr.startsWith(HOST_AP_EVENT_PREFIX_STR)) {
32755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        handleHostApEvents(eventStr);
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                String eventName = eventStr.substring(EVENT_PREFIX_LEN_STR);
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int nameEnd = eventName.indexOf(' ');
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (nameEnd != -1)
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    eventName = eventName.substring(0, nameEnd);
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (eventName.length() == 0) {
33743a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato                    if (false) Log.i(TAG, "Received wpa_supplicant event with empty event name");
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                /*
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 * Map event name into event enum
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 */
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int event;
34455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                if (eventName.equals(CONNECTED_STR))
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    event = CONNECTED;
34655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                else if (eventName.equals(DISCONNECTED_STR))
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    event = DISCONNECTED;
34855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                else if (eventName.equals(STATE_CHANGE_STR))
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    event = STATE_CHANGE;
35055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                else if (eventName.equals(SCAN_RESULTS_STR))
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    event = SCAN_RESULTS;
35255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                else if (eventName.equals(LINK_SPEED_STR))
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    event = LINK_SPEED;
35455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                else if (eventName.equals(TERMINATING_STR))
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    event = TERMINATING;
35655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                else if (eventName.equals(DRIVER_STATE_STR))
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    event = DRIVER_STATE;
35855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                else if (eventName.equals(EAP_FAILURE_STR))
359b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff                    event = EAP_FAILURE;
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                else
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    event = UNKNOWN;
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String eventData = eventStr;
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (event == DRIVER_STATE || event == LINK_SPEED)
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    eventData = eventData.split(" ")[1];
366b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff                else if (event == STATE_CHANGE || event == EAP_FAILURE) {
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int ind = eventStr.indexOf(" ");
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (ind != -1) {
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        eventData = eventStr.substring(ind + 1);
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int ind = eventStr.indexOf(" - ");
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (ind != -1) {
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        eventData = eventStr.substring(ind + 3);
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (event == STATE_CHANGE) {
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    handleSupplicantStateChange(eventData);
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (event == DRIVER_STATE) {
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    handleDriverEvent(eventData);
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (event == TERMINATING) {
38305d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                    /**
38405d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                     * Close the supplicant connection if we see
38505d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                     * too many recv errors
38605d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                     */
38755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (eventData.startsWith(WPA_RECV_ERROR_STR)) {
38805d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                        if (++mRecvErrors > MAX_RECV_ERRORS) {
38943a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato                            if (false) {
39005d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                                Log.d(TAG, "too many recv errors, closing connection");
39105d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                            }
39205d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                        } else {
39305d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                            continue;
39405d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                        }
39505d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                    }
39605d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff
39705d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                    // notify and exit
39855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
400b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff                } else if (event == EAP_FAILURE) {
40155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (eventData.startsWith(EAP_AUTH_FAILURE_STR)) {
40255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        mStateMachine.sendMessage(AUTHENTICATION_FAILURE_EVENT);
403b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff                    }
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    handleEvent(event, eventData);
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
40705d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                mRecvErrors = 0;
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private boolean connectToSupplicant() {
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int connectTries = 0;
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            while (true) {
415fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                if (mWifiNative.connectToSupplicant()) {
416a8fbe1fb74d3bd40b73c90c85ac25e5176475ca5Irfan Sheriff                    return true;
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
418c949b9c3ffe5ed9e2112a15224a86c55651fedfdIrfan Sheriff                if (connectTries++ < 5) {
419c949b9c3ffe5ed9e2112a15224a86c55651fedfdIrfan Sheriff                    nap(1);
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private void handleDriverEvent(String state) {
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (state == null) {
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4311523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff            if (state.equals("HANGED")) {
43255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(DRIVER_HUNG_EVENT);
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Handle all supplicant events except STATE-CHANGE
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param event the event type
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param remainder the rest of the string following the
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * event name and &quot;&#8195;&#8212;&#8195;&quot;
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void handleEvent(int event, String remainder) {
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (event) {
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case DISCONNECTED:
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    handleNetworkStateChange(NetworkInfo.DetailedState.DISCONNECTED, remainder);
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case CONNECTED:
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    handleNetworkStateChange(NetworkInfo.DetailedState.CONNECTED, remainder);
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case SCAN_RESULTS:
45355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mStateMachine.sendMessage(SCAN_RESULTS_EVENT);
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case UNKNOWN:
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
46255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync         * Handle p2p events
46355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync         */
46455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private void handleP2pEvents(String dataString) {
46555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            if (dataString.startsWith(P2P_DEVICE_FOUND_STR)) {
46655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_DEVICE_FOUND_EVENT, new WifiP2pDevice(dataString));
46755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_DEVICE_LOST_STR)) {
46855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_DEVICE_LOST_EVENT, new WifiP2pDevice(dataString));
46955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_GO_NEG_REQUEST_STR)) {
47055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_GO_NEGOTIATION_REQUEST_EVENT,
47155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        new WifiP2pConfig(dataString));
47255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_GO_NEG_SUCCESS_STR)) {
47355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_GO_NEGOTIATION_SUCCESS_EVENT);
47455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_GO_NEG_FAILURE_STR)) {
47555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_GO_NEGOTIATION_FAILURE_EVENT);
47655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_GROUP_FORMATION_SUCCESS_STR)) {
47755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_GROUP_FORMATION_SUCCESS_EVENT);
47855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_GROUP_FORMATION_FAILURE_STR)) {
47955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_GROUP_FORMATION_FAILURE_EVENT);
48055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_GROUP_STARTED_STR)) {
48155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_GROUP_STARTED_EVENT, new WifiP2pGroup(dataString));
48255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_GROUP_REMOVED_STR)) {
48355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_GROUP_REMOVED_EVENT, new WifiP2pGroup(dataString));
48455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_INVITATION_RECEIVED_STR)) {
48555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_INVITATION_RECEIVED_EVENT,
48655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        new WifiP2pGroup(dataString));
48755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_INVITATION_RESULT_STR)) {
48855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                String[] tokens = dataString.split(" ");
48955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                if (tokens.length != 2) return;
49055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                String[] nameValue = tokens[1].split("=");
49155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                if (nameValue.length != 2) return;
49255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_INVITATION_RESULT_EVENT, nameValue[1]);
49355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_PROV_DISC_PBC_REQ_STR)) {
49455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_PROV_DISC_PBC_REQ_EVENT,
495618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        new WifiP2pProvDiscEvent(dataString));
496618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            } else if (dataString.startsWith(P2P_PROV_DISC_PBC_RSP_STR)) {
497618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                mStateMachine.sendMessage(P2P_PROV_DISC_PBC_RSP_EVENT,
498618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        new WifiP2pProvDiscEvent(dataString));
49955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_PROV_DISC_ENTER_PIN_STR)) {
50055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_PROV_DISC_ENTER_PIN_EVENT,
501618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        new WifiP2pProvDiscEvent(dataString));
502618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            } else if (dataString.startsWith(P2P_PROV_DISC_SHOW_PIN_STR)) {
503618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                mStateMachine.sendMessage(P2P_PROV_DISC_SHOW_PIN_EVENT,
504618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        new WifiP2pProvDiscEvent(dataString));
50555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
50655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
50755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
50855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        /**
50955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync         * Handle hostap events
51055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync         */
51155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private void handleHostApEvents(String dataString) {
51255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            String[] tokens = dataString.split(" ");
513bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff            /* AP-STA-CONNECTED 42:fc:89:a8:96:09 dev_addr=02:90:4c:a0:92:54 */
51455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            if (tokens[0].equals(AP_STA_CONNECTED_STR)) {
515bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                String[] nameValue = tokens[2].split("=");
516bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                if (nameValue.length != 2) return;
517bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                WifiP2pDevice device = new WifiP2pDevice();
518bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                device.interfaceAddress = tokens[1];
519bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                device.deviceAddress = nameValue[1];
520bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                mStateMachine.sendMessage(AP_STA_CONNECTED_EVENT, device);
521bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff            /* AP-STA-DISCONNECTED 42:fc:89:a8:96:09 */
52255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (tokens[0].equals(AP_STA_DISCONNECTED_STR)) {
523bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff                //TODO: fix this once wpa_supplicant reports this consistently
52455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(AP_STA_DISCONNECTED_EVENT, tokens[1]);
52555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
52655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
52755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
52855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        /**
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Handle the supplicant STATE-CHANGE event
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param dataString New supplicant state string in the format:
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * id=network-id state=new-state
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private void handleSupplicantStateChange(String dataString) {
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String[] dataTokens = dataString.split(" ");
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5360049a1bf3f8bae3a10cfeff38aefce215bf1298bIrfan Sheriff            String BSSID = null;
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int networkId = -1;
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int newState  = -1;
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (String token : dataTokens) {
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String[] nameValue = token.split("=");
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (nameValue.length != 2) {
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5450049a1bf3f8bae3a10cfeff38aefce215bf1298bIrfan Sheriff                if (nameValue[0].equals("BSSID")) {
5460049a1bf3f8bae3a10cfeff38aefce215bf1298bIrfan Sheriff                    BSSID = nameValue[1];
5470049a1bf3f8bae3a10cfeff38aefce215bf1298bIrfan Sheriff                    continue;
5480049a1bf3f8bae3a10cfeff38aefce215bf1298bIrfan Sheriff                }
5490049a1bf3f8bae3a10cfeff38aefce215bf1298bIrfan Sheriff
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int value;
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    value = Integer.parseInt(nameValue[1]);
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (NumberFormatException e) {
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Log.w(TAG, "STATE-CHANGE non-integer parameter: " + token);
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (nameValue[0].equals("id")) {
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    networkId = value;
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (nameValue[0].equals("state")) {
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    newState = value;
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (newState == -1) return;
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            SupplicantState newSupplicantState = SupplicantState.INVALID;
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (SupplicantState state : SupplicantState.values()) {
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (state.ordinal() == newState) {
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    newSupplicantState = state;
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (newSupplicantState == SupplicantState.INVALID) {
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.w(TAG, "Invalid supplicant state: " + newState);
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
57755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            notifySupplicantStateChange(networkId, BSSID, newSupplicantState);
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void handleNetworkStateChange(NetworkInfo.DetailedState newState, String data) {
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String BSSID = null;
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int networkId = -1;
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newState == NetworkInfo.DetailedState.CONNECTED) {
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Matcher match = mConnectedEventPattern.matcher(data);
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!match.find()) {
58743a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato                if (false) Log.d(TAG, "Could not find BSSID in CONNECTED event string");
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                BSSID = match.group(1);
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    networkId = Integer.parseInt(match.group(2));
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (NumberFormatException e) {
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    networkId = -1;
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
59755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        notifyNetworkStateChange(newState, BSSID, networkId);
59855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
59955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
60055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /**
60155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * Send the state machine a notification that the state of Wifi connectivity
60255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * has changed.
60355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * @param networkId the configured network on which the state change occurred
60455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * @param newState the new network state
60555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * @param BSSID when the new state is {@link DetailedState#CONNECTED
60655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * NetworkInfo.DetailedState.CONNECTED},
60755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * this is the MAC address of the access point. Otherwise, it
60855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * is {@code null}.
60955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     */
61055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    void notifyNetworkStateChange(NetworkInfo.DetailedState newState, String BSSID, int netId) {
61155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (newState == NetworkInfo.DetailedState.CONNECTED) {
61255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            Message m = mStateMachine.obtainMessage(NETWORK_CONNECTION_EVENT,
61355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    netId, 0, BSSID);
61455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            mStateMachine.sendMessage(m);
61555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        } else {
61655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            Message m = mStateMachine.obtainMessage(NETWORK_DISCONNECTION_EVENT,
61755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    netId, 0, BSSID);
61855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            mStateMachine.sendMessage(m);
61955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
62055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
62155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
62255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /**
62355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * Send the state machine a notification that the state of the supplicant
62455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * has changed.
62555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * @param networkId the configured network on which the state change occurred
62655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * @param newState the new {@code SupplicantState}
62755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     */
62855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    void notifySupplicantStateChange(int networkId, String BSSID, SupplicantState newState) {
62955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mStateMachine.sendMessage(mStateMachine.obtainMessage(SUPPLICANT_STATE_CHANGE_EVENT,
63055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                new StateChangeResult(networkId, BSSID, newState)));
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sleep for a period of time.
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param secs the number of seconds to sleep
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static void nap(int secs) {
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Thread.sleep(secs * 1000);
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (InterruptedException ignore) {
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
644