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;
230879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenagaimport android.net.wifi.p2p.WifiP2pService;
240879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenagaimport android.net.wifi.p2p.WifiP2pService.P2pStatus;
25618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriffimport android.net.wifi.p2p.WifiP2pProvDiscEvent;
2621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport android.net.wifi.p2p.nsd.WifiP2pServiceResponse;
2755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.net.wifi.StateChangeResult;
2855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.Message;
2955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.util.Log;
3055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
3155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
3255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport com.android.internal.util.Protocol;
3355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport com.android.internal.util.StateMachine;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport java.util.List;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.regex.Pattern;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.regex.Matcher;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Listens for events from the wpa_supplicant server, and passes them on
4155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * to the {@link StateMachine} for handling. Runs in its own thread.
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class WifiMonitor {
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String TAG = "WifiMonitor";
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Events we receive from the supplicant daemon */
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int CONNECTED    = 1;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DISCONNECTED = 2;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int STATE_CHANGE = 3;
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int SCAN_RESULTS = 4;
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int LINK_SPEED   = 5;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int TERMINATING  = 6;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DRIVER_STATE = 7;
58b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff    private static final int EAP_FAILURE  = 8;
59b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff    private static final int UNKNOWN      = 9;
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** All events coming from the supplicant start with this prefix */
6255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String EVENT_PREFIX_STR = "CTRL-EVENT-";
6355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int EVENT_PREFIX_LEN_STR = EVENT_PREFIX_STR.length();
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** All WPA events coming from the supplicant start with this prefix */
6655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String WPA_EVENT_PREFIX_STR = "WPA:";
6755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String PASSWORD_MAY_BE_INCORRECT_STR =
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project       "pre-shared key may be incorrect";
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
70fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff    /* WPS events */
71d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    private static final String WPS_SUCCESS_STR = "WPS-SUCCESS";
7286a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff
7386a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff    /* Format: WPS-FAIL msg=%d [config_error=%d] [reason=%d (%s)] */
74d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    private static final String WPS_FAIL_STR    = "WPS-FAIL";
7586a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff    private static final String WPS_FAIL_PATTERN =
7686a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff            "WPS-FAIL msg=\\d+(?: config_error=(\\d+))?(?: reason=(\\d+))?";
7786a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff
7886a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff    /* config error code values for config_error=%d */
7986a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff    private static final int CONFIG_MULTIPLE_PBC_DETECTED = 12;
8086a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff    private static final int CONFIG_AUTH_FAILURE = 18;
8186a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff
8286a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff    /* reason code values for reason=%d */
8386a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff    private static final int REASON_TKIP_ONLY_PROHIBITED = 1;
8486a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff    private static final int REASON_WEP_PROHIBITED = 2;
8586a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff
8655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String WPS_OVERLAP_STR = "WPS-OVERLAP-DETECTED";
87d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    private static final String WPS_TIMEOUT_STR = "WPS-TIMEOUT";
88fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Names of events from wpa_supplicant (minus the prefix). In the
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * format descriptions, * &quot;<code>x</code>&quot;
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * designates a dynamic value that needs to be parsed out from the event
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * string
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CTRL-EVENT-CONNECTED - Connection to xx:xx:xx:xx:xx:xx completed
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </pre>
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <code>xx:xx:xx:xx:xx:xx</code> is the BSSID of the associated access point
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String CONNECTED_STR =    "CONNECTED";
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CTRL-EVENT-DISCONNECTED - Disconnect event - remove keys
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </pre>
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String DISCONNECTED_STR = "DISCONNECTED";
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CTRL-EVENT-STATE-CHANGE x
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </pre>
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <code>x</code> is the numerical value of the new state.
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String STATE_CHANGE_STR =  "STATE-CHANGE";
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CTRL-EVENT-SCAN-RESULTS ready
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </pre>
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String SCAN_RESULTS_STR =  "SCAN-RESULTS";
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CTRL-EVENT-LINK-SPEED x Mb/s
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </pre>
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@code x} is the link speed in Mb/sec.
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String LINK_SPEED_STR = "LINK-SPEED";
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CTRL-EVENT-TERMINATING - signal x
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </pre>
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <code>x</code> is the signal that caused termination.
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String TERMINATING_STR =  "TERMINATING";
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CTRL-EVENT-DRIVER-STATE state
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </pre>
1401523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff     * <code>state</code> can be HANGED
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
14255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String DRIVER_STATE_STR = "DRIVER-STATE";
143b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff    /**
144b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff     * <pre>
145b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff     * CTRL-EVENT-EAP-FAILURE EAP authentication failed
146b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff     * </pre>
147b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff     */
14855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String EAP_FAILURE_STR = "EAP-FAILURE";
149b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff
150b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff    /**
151b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff     * This indicates an authentication failure on EAP FAILURE event
152b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff     */
15355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String EAP_AUTH_FAILURE_STR = "EAP authentication failed";
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Regex pattern for extracting an Ethernet-style MAC address from a string.
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Matches a strings like the following:<pre>
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CTRL-EVENT-CONNECTED - Connection to 00:1e:58:ec:d5:6d completed (reauth) [id=1 id_str=]</pre>
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static Pattern mConnectedEventPattern =
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Pattern.compile("((?:[0-9a-f]{2}:){5}[0-9a-f]{2}) .* \\[id=([0-9]+) ");
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /** P2P events */
16455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_EVENT_PREFIX_STR = "P2P";
16555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
16655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo 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
16755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       name='p2p-TEST1' config_methods=0x188 dev_capab=0x27 group_capab=0x0 */
16855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_DEVICE_FOUND_STR = "P2P-DEVICE-FOUND";
16955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
17055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-DEVICE-LOST p2p_dev_addr=42:fc:89:e1:e2:27 */
17155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_DEVICE_LOST_STR = "P2P-DEVICE-LOST";
17255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
173c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff    /* P2P-FIND-STOPPED */
174c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff    private static final String P2P_FIND_STOPPED_STR = "P2P-FIND-STOPPED";
175c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff
17655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-GO-NEG-REQUEST 42:fc:89:a8:96:09 dev_passwd_id=4 */
17755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_GO_NEG_REQUEST_STR = "P2P-GO-NEG-REQUEST";
17855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
17955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_GO_NEG_SUCCESS_STR = "P2P-GO-NEG-SUCCESS";
18055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1819f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff    /* P2P-GO-NEG-FAILURE status=x */
18255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_GO_NEG_FAILURE_STR = "P2P-GO-NEG-FAILURE";
18355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
18455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_GROUP_FORMATION_SUCCESS_STR =
18555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            "P2P-GROUP-FORMATION-SUCCESS";
18655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
18755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_GROUP_FORMATION_FAILURE_STR =
18855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            "P2P-GROUP-FORMATION-FAILURE";
18955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
19055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-GROUP-STARTED p2p-wlan0-0 [client|GO] ssid="DIRECT-W8" freq=2437
19155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       [psk=2182b2e50e53f260d04f3c7b25ef33c965a3291b9b36b455a82d77fd82ca15bc|passphrase="fKG4jMe3"]
1920879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga       go_dev_addr=fa:7b:7a:42:02:13 [PERSISTENT] */
19355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_GROUP_STARTED_STR = "P2P-GROUP-STARTED";
19455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
19555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-GROUP-REMOVED p2p-wlan0-0 [client|GO] reason=REQUESTED */
19655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_GROUP_REMOVED_STR = "P2P-GROUP-REMOVED";
19755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
19855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-INVITATION-RECEIVED sa=fa:7b:7a:42:02:13 go_dev_addr=f8:7b:7a:42:02:13
19955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        bssid=fa:7b:7a:42:82:13 unknown-network */
20055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_INVITATION_RECEIVED_STR = "P2P-INVITATION-RECEIVED";
20155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
20255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-INVITATION-RESULT status=1 */
20355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_INVITATION_RESULT_STR = "P2P-INVITATION-RESULT";
20455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
20555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-PROV-DISC-PBC-REQ 42:fc:89:e1:e2:27 p2p_dev_addr=42:fc:89:e1:e2:27
20655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       pri_dev_type=1-0050F204-1 name='p2p-TEST2' config_methods=0x188 dev_capab=0x27
20755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       group_capab=0x0 */
20855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_PROV_DISC_PBC_REQ_STR = "P2P-PROV-DISC-PBC-REQ";
209618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
210618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    /* P2P-PROV-DISC-PBC-RESP 02:12:47:f2:5a:36 */
211618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    private static final String P2P_PROV_DISC_PBC_RSP_STR = "P2P-PROV-DISC-PBC-RESP";
212618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
21355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-PROV-DISC-ENTER-PIN 42:fc:89:e1:e2:27 p2p_dev_addr=42:fc:89:e1:e2:27
21455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       pri_dev_type=1-0050F204-1 name='p2p-TEST2' config_methods=0x188 dev_capab=0x27
21555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       group_capab=0x0 */
21655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_PROV_DISC_ENTER_PIN_STR = "P2P-PROV-DISC-ENTER-PIN";
21755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-PROV-DISC-SHOW-PIN 42:fc:89:e1:e2:27 44490607 p2p_dev_addr=42:fc:89:e1:e2:27
21855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       pri_dev_type=1-0050F204-1 name='p2p-TEST2' config_methods=0x188 dev_capab=0x27
21955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       group_capab=0x0 */
22055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_PROV_DISC_SHOW_PIN_STR = "P2P-PROV-DISC-SHOW-PIN";
221c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff    /* P2P-PROV-DISC-FAILURE p2p_dev_addr=42:fc:89:e1:e2:27 */
222c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff    private static final String P2P_PROV_DISC_FAILURE_STR = "P2P-PROV-DISC-FAILURE";
22355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
22421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /*
22521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Protocol format is as follows.<br>
22621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * See the Table.62 in the WiFi Direct specification for the detail.
22721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * ______________________________________________________________
22821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * |           Length(2byte)     | Type(1byte) | TransId(1byte)}|
22921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * ______________________________________________________________
23021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * | status(1byte)  |            vendor specific(variable)      |
23121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
23221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * P2P-SERV-DISC-RESP 42:fc:89:e1:e2:27 1 0300000101
23321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * length=3, service type=0(ALL Service), transaction id=1,
23421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * status=1(service protocol type not available)<br>
23521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
23621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * P2P-SERV-DISC-RESP 42:fc:89:e1:e2:27 1 0300020201
23721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * length=3, service type=2(UPnP), transaction id=2,
23821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * status=1(service protocol type not available)
23921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
24021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * P2P-SERV-DISC-RESP 42:fc:89:e1:e2:27 1 990002030010757569643a3131323
24121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * 2646534652d383537342d353961622d393332322d3333333435363738393034343a3
24221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * a75726e3a736368656d61732d75706e702d6f72673a736572766963653a436f6e746
24321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * 56e744469726563746f72793a322c757569643a36383539646564652d383537342d3
24421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * 53961622d393333322d3132333435363738393031323a3a75706e703a726f6f74646
24521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * 576696365
24621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * length=153,type=2(UPnP),transaction id=3,status=0
24721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
24821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * UPnP Protocol format is as follows.
24921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * ______________________________________________________
25021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * |  Version (1)  |          USN (Variable)            |
25121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
25221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * version=0x10(UPnP1.0) data=usn:uuid:1122de4e-8574-59ab-9322-33345678
25321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * 9044::urn:schemas-upnp-org:service:ContentDirectory:2,usn:uuid:6859d
25421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * ede-8574-59ab-9332-123456789012::upnp:rootdevice
25521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
25621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * P2P-SERV-DISC-RESP 58:17:0c:bc:dd:ca 21 1900010200045f6970
25721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * 70c00c000c01094d795072696e746572c027
25821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * length=25, type=1(Bonjour),transaction id=2,status=0
25921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
26021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Bonjour Protocol format is as follows.
26121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * __________________________________________________________
26221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * |DNS Name(Variable)|DNS Type(1)|Version(1)|RDATA(Variable)|
26321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
26421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * DNS Name=_ipp._tcp.local.,DNS type=12(PTR), Version=1,
26521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * RDATA=MyPrinter._ipp._tcp.local.
26621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
26721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
26821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private static final String P2P_SERV_DISC_RESP_STR = "P2P-SERV-DISC-RESP";
26921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
27055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String HOST_AP_EVENT_PREFIX_STR = "AP";
271bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff    /* AP-STA-CONNECTED 42:fc:89:a8:96:09 dev_addr=02:90:4c:a0:92:54 */
27255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String AP_STA_CONNECTED_STR = "AP-STA-CONNECTED";
27355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* AP-STA-DISCONNECTED 42:fc:89:a8:96:09 */
27455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String AP_STA_DISCONNECTED_STR = "AP-STA-DISCONNECTED";
27555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
27655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private final StateMachine mStateMachine;
277fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    private final WifiNative mWifiNative;
27855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
27955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Supplicant events reported to a state machine */
28055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int BASE = Protocol.BASE_WIFI_MONITOR;
28155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
28255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Connection to supplicant established */
28355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int SUP_CONNECTION_EVENT                 = BASE + 1;
28455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Connection to supplicant lost */
28555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int SUP_DISCONNECTION_EVENT              = BASE + 2;
28655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync   /* Network connection completed */
28755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int NETWORK_CONNECTION_EVENT             = BASE + 3;
28855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Network disconnection completed */
28955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int NETWORK_DISCONNECTION_EVENT          = BASE + 4;
29055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Scan results are available */
29155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int SCAN_RESULTS_EVENT                   = BASE + 5;
29255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Supplicate state changed */
29355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int SUPPLICANT_STATE_CHANGE_EVENT        = BASE + 6;
29455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Password failure and EAP authentication failure */
29555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int AUTHENTICATION_FAILURE_EVENT         = BASE + 7;
296d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    /* WPS success detected */
297d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    public static final int WPS_SUCCESS_EVENT                    = BASE + 8;
298d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    /* WPS failure detected */
299d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    public static final int WPS_FAIL_EVENT                       = BASE + 9;
300d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     /* WPS overlap detected */
301d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    public static final int WPS_OVERLAP_EVENT                    = BASE + 10;
302d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     /* WPS timeout detected */
303d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    public static final int WPS_TIMEOUT_EVENT                    = BASE + 11;
30455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Driver was hung */
305d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    public static final int DRIVER_HUNG_EVENT                    = BASE + 12;
30655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
30755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P events */
30855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_DEVICE_FOUND_EVENT               = BASE + 21;
30955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_DEVICE_LOST_EVENT                = BASE + 22;
31055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_GO_NEGOTIATION_REQUEST_EVENT     = BASE + 23;
31155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_GO_NEGOTIATION_SUCCESS_EVENT     = BASE + 25;
31255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_GO_NEGOTIATION_FAILURE_EVENT     = BASE + 26;
31355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_GROUP_FORMATION_SUCCESS_EVENT    = BASE + 27;
31455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_GROUP_FORMATION_FAILURE_EVENT    = BASE + 28;
31555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_GROUP_STARTED_EVENT              = BASE + 29;
31655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_GROUP_REMOVED_EVENT              = BASE + 30;
31755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_INVITATION_RECEIVED_EVENT        = BASE + 31;
31855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_INVITATION_RESULT_EVENT          = BASE + 32;
31955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_PROV_DISC_PBC_REQ_EVENT          = BASE + 33;
320618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    public static final int P2P_PROV_DISC_PBC_RSP_EVENT          = BASE + 34;
321618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    public static final int P2P_PROV_DISC_ENTER_PIN_EVENT        = BASE + 35;
322618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    public static final int P2P_PROV_DISC_SHOW_PIN_EVENT         = BASE + 36;
323c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff    public static final int P2P_FIND_STOPPED_EVENT               = BASE + 37;
32421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    public static final int P2P_SERV_DISC_RESP_EVENT             = BASE + 38;
325c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff    public static final int P2P_PROV_DISC_FAILURE_EVENT          = BASE + 39;
32655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
32755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* hostap events */
32855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int AP_STA_DISCONNECTED_EVENT            = BASE + 41;
32955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int AP_STA_CONNECTED_EVENT               = BASE + 42;
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33105d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff    /**
33205d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff     * This indicates the supplicant connection for the monitor is closed
33305d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff     */
33455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String MONITOR_SOCKET_CLOSED_STR = "connection closed";
33505d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff
33605d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff    /**
33705d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff     * This indicates a read error on the monitor socket conenction
33805d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff     */
33955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String WPA_RECV_ERROR_STR = "recv error";
34005d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff
34105d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff    /**
34205d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff     * Tracks consecutive receive errors
34305d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff     */
34405d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff    private int mRecvErrors = 0;
34505d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff
34605d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff    /**
34705d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff     * Max errors before we close supplicant connection
34805d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff     */
34905d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff    private static final int MAX_RECV_ERRORS    = 10;
35005d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff
351fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public WifiMonitor(StateMachine wifiStateMachine, WifiNative wifiNative) {
35255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mStateMachine = wifiStateMachine;
353fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative = wifiNative;
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void startMonitoring() {
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        new MonitorThread().start();
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    class MonitorThread extends Thread {
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public MonitorThread() {
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super("WifiMonitor");
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
364a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void run() {
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (connectToSupplicant()) {
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Send a message indicating that it is now possible to send commands
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // to the supplicant
37055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(SUP_CONNECTION_EVENT);
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
37255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //noinspection InfiniteLoopStatement
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (;;) {
378fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                String eventStr = mWifiNative.waitForEvent();
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Skip logging the common but mostly uninteresting scan-results event
38155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                if (false && eventStr.indexOf(SCAN_RESULTS_STR) == -1) {
38255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    Log.d(TAG, "Event [" + eventStr + "]");
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
38455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                if (!eventStr.startsWith(EVENT_PREFIX_STR)) {
38555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (eventStr.startsWith(WPA_EVENT_PREFIX_STR) &&
38655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                            0 < eventStr.indexOf(PASSWORD_MAY_BE_INCORRECT_STR)) {
38755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        mStateMachine.sendMessage(AUTHENTICATION_FAILURE_EVENT);
388d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    } else if (eventStr.startsWith(WPS_SUCCESS_STR)) {
389d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        mStateMachine.sendMessage(WPS_SUCCESS_EVENT);
390d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    } else if (eventStr.startsWith(WPS_FAIL_STR)) {
39186a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                        handleWpsFailEvent(eventStr);
39255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    } else if (eventStr.startsWith(WPS_OVERLAP_STR)) {
39355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        mStateMachine.sendMessage(WPS_OVERLAP_EVENT);
394d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                    } else if (eventStr.startsWith(WPS_TIMEOUT_STR)) {
395d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff                        mStateMachine.sendMessage(WPS_TIMEOUT_EVENT);
39655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    } else if (eventStr.startsWith(P2P_EVENT_PREFIX_STR)) {
39755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        handleP2pEvents(eventStr);
39855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    } else if (eventStr.startsWith(HOST_AP_EVENT_PREFIX_STR)) {
39955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        handleHostApEvents(eventStr);
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
40455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                String eventName = eventStr.substring(EVENT_PREFIX_LEN_STR);
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int nameEnd = eventName.indexOf(' ');
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (nameEnd != -1)
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    eventName = eventName.substring(0, nameEnd);
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (eventName.length() == 0) {
40943a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato                    if (false) Log.i(TAG, "Received wpa_supplicant event with empty event name");
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                /*
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 * Map event name into event enum
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                 */
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int event;
41655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                if (eventName.equals(CONNECTED_STR))
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    event = CONNECTED;
41855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                else if (eventName.equals(DISCONNECTED_STR))
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    event = DISCONNECTED;
42055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                else if (eventName.equals(STATE_CHANGE_STR))
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    event = STATE_CHANGE;
42255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                else if (eventName.equals(SCAN_RESULTS_STR))
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    event = SCAN_RESULTS;
42455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                else if (eventName.equals(LINK_SPEED_STR))
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    event = LINK_SPEED;
42655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                else if (eventName.equals(TERMINATING_STR))
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    event = TERMINATING;
42855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                else if (eventName.equals(DRIVER_STATE_STR))
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    event = DRIVER_STATE;
43055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                else if (eventName.equals(EAP_FAILURE_STR))
431b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff                    event = EAP_FAILURE;
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                else
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    event = UNKNOWN;
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String eventData = eventStr;
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (event == DRIVER_STATE || event == LINK_SPEED)
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    eventData = eventData.split(" ")[1];
438b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff                else if (event == STATE_CHANGE || event == EAP_FAILURE) {
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int ind = eventStr.indexOf(" ");
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (ind != -1) {
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        eventData = eventStr.substring(ind + 1);
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int ind = eventStr.indexOf(" - ");
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (ind != -1) {
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        eventData = eventStr.substring(ind + 3);
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (event == STATE_CHANGE) {
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    handleSupplicantStateChange(eventData);
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (event == DRIVER_STATE) {
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    handleDriverEvent(eventData);
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (event == TERMINATING) {
45505d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                    /**
45605d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                     * Close the supplicant connection if we see
45705d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                     * too many recv errors
45805d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                     */
45955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (eventData.startsWith(WPA_RECV_ERROR_STR)) {
46005d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                        if (++mRecvErrors > MAX_RECV_ERRORS) {
46143a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato                            if (false) {
46205d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                                Log.d(TAG, "too many recv errors, closing connection");
46305d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                            }
46405d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                        } else {
46505d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                            continue;
46605d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                        }
46705d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                    }
46805d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff
46905d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                    // notify and exit
47055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
472b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff                } else if (event == EAP_FAILURE) {
47355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    if (eventData.startsWith(EAP_AUTH_FAILURE_STR)) {
47455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        mStateMachine.sendMessage(AUTHENTICATION_FAILURE_EVENT);
475b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff                    }
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    handleEvent(event, eventData);
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
47905d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                mRecvErrors = 0;
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private boolean connectToSupplicant() {
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int connectTries = 0;
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            while (true) {
487fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                if (mWifiNative.connectToSupplicant()) {
488a8fbe1fb74d3bd40b73c90c85ac25e5176475ca5Irfan Sheriff                    return true;
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
490c949b9c3ffe5ed9e2112a15224a86c55651fedfdIrfan Sheriff                if (connectTries++ < 5) {
491c949b9c3ffe5ed9e2112a15224a86c55651fedfdIrfan Sheriff                    nap(1);
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private void handleDriverEvent(String state) {
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (state == null) {
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5031523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff            if (state.equals("HANGED")) {
50455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(DRIVER_HUNG_EVENT);
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Handle all supplicant events except STATE-CHANGE
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param event the event type
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param remainder the rest of the string following the
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * event name and &quot;&#8195;&#8212;&#8195;&quot;
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void handleEvent(int event, String remainder) {
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (event) {
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case DISCONNECTED:
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    handleNetworkStateChange(NetworkInfo.DetailedState.DISCONNECTED, remainder);
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case CONNECTED:
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    handleNetworkStateChange(NetworkInfo.DetailedState.CONNECTED, remainder);
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case SCAN_RESULTS:
52555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mStateMachine.sendMessage(SCAN_RESULTS_EVENT);
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case UNKNOWN:
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
53386a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        private void handleWpsFailEvent(String dataString) {
53486a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff            final Pattern p = Pattern.compile(WPS_FAIL_PATTERN);
53586a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff            Matcher match = p.matcher(dataString);
53686a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff            if (match.find()) {
53786a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                String cfgErr = match.group(1);
53886a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                String reason = match.group(2);
53986a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff
54086a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                if (reason != null) {
54186a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    switch(Integer.parseInt(reason)) {
54286a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                        case REASON_TKIP_ONLY_PROHIBITED:
54386a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                            mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT,
54486a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                                    WifiManager.WPS_TKIP_ONLY_PROHIBITED, 0));
54586a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                            return;
54686a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                        case REASON_WEP_PROHIBITED:
54786a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                            mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT,
54886a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                                    WifiManager.WPS_WEP_PROHIBITED, 0));
54986a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                            return;
55086a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    }
55186a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                }
55286a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                if (cfgErr != null) {
55386a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    switch(Integer.parseInt(cfgErr)) {
55486a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                        case CONFIG_AUTH_FAILURE:
55586a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                            mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT,
55686a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                                    WifiManager.WPS_AUTH_FAILURE, 0));
55786a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                            return;
55886a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                        case CONFIG_MULTIPLE_PBC_DETECTED:
55986a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                            mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT,
56086a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                                    WifiManager.WPS_OVERLAP_ERROR, 0));
56186a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                            return;
56286a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    }
56386a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                }
56486a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff            }
56586a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff            //For all other errors, return a generic internal error
56686a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff            mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT,
56786a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    WifiManager.ERROR, 0));
56886a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        }
56986a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff
5709f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff        /* <event> status=<err> and the special case of <event> reason=FREQ_CONFLICT */
5719f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff        private P2pStatus p2pError(String dataString) {
5729f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            P2pStatus err = P2pStatus.UNKNOWN;
5739f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            String[] tokens = dataString.split(" ");
5749f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            if (tokens.length < 2) return err;
5759f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            String[] nameValue = tokens[1].split("=");
5769f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            if (nameValue.length != 2) return err;
5779f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff
5789f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            /* Handle the special case of reason=FREQ+CONFLICT */
5799f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            if (nameValue[1].equals("FREQ_CONFLICT")) {
5809f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                return P2pStatus.NO_COMMON_CHANNEL;
5819f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            }
5829f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            try {
5839f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                err = P2pStatus.valueOf(Integer.parseInt(nameValue[1]));
5849f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            } catch (NumberFormatException e) {
5859f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                e.printStackTrace();
5869f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            }
5879f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            return err;
5889f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff        }
5899f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
59155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync         * Handle p2p events
59255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync         */
59355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private void handleP2pEvents(String dataString) {
59455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            if (dataString.startsWith(P2P_DEVICE_FOUND_STR)) {
59555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_DEVICE_FOUND_EVENT, new WifiP2pDevice(dataString));
59655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_DEVICE_LOST_STR)) {
59755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_DEVICE_LOST_EVENT, new WifiP2pDevice(dataString));
598c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff            } else if (dataString.startsWith(P2P_FIND_STOPPED_STR)) {
599c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff                mStateMachine.sendMessage(P2P_FIND_STOPPED_EVENT);
60055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_GO_NEG_REQUEST_STR)) {
60155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_GO_NEGOTIATION_REQUEST_EVENT,
60255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        new WifiP2pConfig(dataString));
60355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_GO_NEG_SUCCESS_STR)) {
60455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_GO_NEGOTIATION_SUCCESS_EVENT);
60555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_GO_NEG_FAILURE_STR)) {
6069f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                mStateMachine.sendMessage(P2P_GO_NEGOTIATION_FAILURE_EVENT, p2pError(dataString));
60755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_GROUP_FORMATION_SUCCESS_STR)) {
60855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_GROUP_FORMATION_SUCCESS_EVENT);
60955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_GROUP_FORMATION_FAILURE_STR)) {
6109f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                mStateMachine.sendMessage(P2P_GROUP_FORMATION_FAILURE_EVENT, p2pError(dataString));
61155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_GROUP_STARTED_STR)) {
61255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_GROUP_STARTED_EVENT, new WifiP2pGroup(dataString));
61355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_GROUP_REMOVED_STR)) {
61455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_GROUP_REMOVED_EVENT, new WifiP2pGroup(dataString));
61555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_INVITATION_RECEIVED_STR)) {
61655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_INVITATION_RECEIVED_EVENT,
61755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        new WifiP2pGroup(dataString));
61855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_INVITATION_RESULT_STR)) {
6199f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                mStateMachine.sendMessage(P2P_INVITATION_RESULT_EVENT, p2pError(dataString));
62055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_PROV_DISC_PBC_REQ_STR)) {
62155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_PROV_DISC_PBC_REQ_EVENT,
622618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        new WifiP2pProvDiscEvent(dataString));
623618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            } else if (dataString.startsWith(P2P_PROV_DISC_PBC_RSP_STR)) {
624618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                mStateMachine.sendMessage(P2P_PROV_DISC_PBC_RSP_EVENT,
625618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        new WifiP2pProvDiscEvent(dataString));
62655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_PROV_DISC_ENTER_PIN_STR)) {
62755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_PROV_DISC_ENTER_PIN_EVENT,
628618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        new WifiP2pProvDiscEvent(dataString));
629618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            } else if (dataString.startsWith(P2P_PROV_DISC_SHOW_PIN_STR)) {
630618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                mStateMachine.sendMessage(P2P_PROV_DISC_SHOW_PIN_EVENT,
631618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        new WifiP2pProvDiscEvent(dataString));
632c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff            } else if (dataString.startsWith(P2P_PROV_DISC_FAILURE_STR)) {
633c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                mStateMachine.sendMessage(P2P_PROV_DISC_FAILURE_EVENT);
63421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            } else if (dataString.startsWith(P2P_SERV_DISC_RESP_STR)) {
63521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                List<WifiP2pServiceResponse> list = WifiP2pServiceResponse.newInstance(dataString);
63621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                if (list != null) {
63721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    mStateMachine.sendMessage(P2P_SERV_DISC_RESP_EVENT, list);
63821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                } else {
63921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    Log.e(TAG, "Null service resp " + dataString);
64021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                }
64155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
64255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
64355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
64455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        /**
64555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync         * Handle hostap events
64655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync         */
64755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private void handleHostApEvents(String dataString) {
64855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            String[] tokens = dataString.split(" ");
64961472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga            /* AP-STA-CONNECTED 42:fc:89:a8:96:09 p2p_dev_addr=02:90:4c:a0:92:54 */
65055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            if (tokens[0].equals(AP_STA_CONNECTED_STR)) {
65161472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                mStateMachine.sendMessage(AP_STA_CONNECTED_EVENT, new WifiP2pDevice(dataString));
65261472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga            /* AP-STA-DISCONNECTED 42:fc:89:a8:96:09 p2p_dev_addr=02:90:4c:a0:92:54 */
65355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (tokens[0].equals(AP_STA_DISCONNECTED_STR)) {
65461472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                mStateMachine.sendMessage(AP_STA_DISCONNECTED_EVENT, new WifiP2pDevice(dataString));
65555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
65655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
65755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
65855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        /**
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Handle the supplicant STATE-CHANGE event
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param dataString New supplicant state string in the format:
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * id=network-id state=new-state
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private void handleSupplicantStateChange(String dataString) {
664b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff            WifiSsid wifiSsid = null;
66560c8c1570be28eba4cfb9969f5bbee8cbd66f37eIrfan Sheriff            int index = dataString.lastIndexOf("SSID=");
666b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff            if (index != -1) {
667b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff                wifiSsid = WifiSsid.createFromAsciiEncoded(
668b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff                        dataString.substring(index + 5));
669b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff            }
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String[] dataTokens = dataString.split(" ");
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6720049a1bf3f8bae3a10cfeff38aefce215bf1298bIrfan Sheriff            String BSSID = null;
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int networkId = -1;
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int newState  = -1;
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (String token : dataTokens) {
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String[] nameValue = token.split("=");
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (nameValue.length != 2) {
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6810049a1bf3f8bae3a10cfeff38aefce215bf1298bIrfan Sheriff                if (nameValue[0].equals("BSSID")) {
6820049a1bf3f8bae3a10cfeff38aefce215bf1298bIrfan Sheriff                    BSSID = nameValue[1];
6830049a1bf3f8bae3a10cfeff38aefce215bf1298bIrfan Sheriff                    continue;
6840049a1bf3f8bae3a10cfeff38aefce215bf1298bIrfan Sheriff                }
6850049a1bf3f8bae3a10cfeff38aefce215bf1298bIrfan Sheriff
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int value;
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    value = Integer.parseInt(nameValue[1]);
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (NumberFormatException e) {
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (nameValue[0].equals("id")) {
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    networkId = value;
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (nameValue[0].equals("state")) {
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    newState = value;
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (newState == -1) return;
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            SupplicantState newSupplicantState = SupplicantState.INVALID;
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (SupplicantState state : SupplicantState.values()) {
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (state.ordinal() == newState) {
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    newSupplicantState = state;
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (newSupplicantState == SupplicantState.INVALID) {
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.w(TAG, "Invalid supplicant state: " + newState);
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
712b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff            notifySupplicantStateChange(networkId, wifiSsid, BSSID, newSupplicantState);
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void handleNetworkStateChange(NetworkInfo.DetailedState newState, String data) {
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String BSSID = null;
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int networkId = -1;
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newState == NetworkInfo.DetailedState.CONNECTED) {
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Matcher match = mConnectedEventPattern.matcher(data);
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!match.find()) {
72243a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato                if (false) Log.d(TAG, "Could not find BSSID in CONNECTED event string");
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                BSSID = match.group(1);
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    networkId = Integer.parseInt(match.group(2));
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (NumberFormatException e) {
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    networkId = -1;
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
73255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        notifyNetworkStateChange(newState, BSSID, networkId);
73355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
73455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
73555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /**
73655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * Send the state machine a notification that the state of Wifi connectivity
73755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * has changed.
73855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * @param networkId the configured network on which the state change occurred
73955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * @param newState the new network state
74055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * @param BSSID when the new state is {@link DetailedState#CONNECTED
74155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * NetworkInfo.DetailedState.CONNECTED},
74255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * this is the MAC address of the access point. Otherwise, it
74355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * is {@code null}.
74455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     */
74555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    void notifyNetworkStateChange(NetworkInfo.DetailedState newState, String BSSID, int netId) {
74655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (newState == NetworkInfo.DetailedState.CONNECTED) {
74755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            Message m = mStateMachine.obtainMessage(NETWORK_CONNECTION_EVENT,
74855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    netId, 0, BSSID);
74955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            mStateMachine.sendMessage(m);
75055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        } else {
75155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            Message m = mStateMachine.obtainMessage(NETWORK_DISCONNECTION_EVENT,
75255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    netId, 0, BSSID);
75355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            mStateMachine.sendMessage(m);
75455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
75555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
75655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
75755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /**
75855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * Send the state machine a notification that the state of the supplicant
75955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * has changed.
76055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * @param networkId the configured network on which the state change occurred
761b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff     * @param wifiSsid network name
7627bdcb1eed755a6a326d807474d2c1476b82220b9Irfan Sheriff     * @param BSSID network address
76355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * @param newState the new {@code SupplicantState}
76455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     */
765b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff    void notifySupplicantStateChange(int networkId, WifiSsid wifiSsid, String BSSID,
766b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff            SupplicantState newState) {
76755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        mStateMachine.sendMessage(mStateMachine.obtainMessage(SUPPLICANT_STATE_CHANGE_EVENT,
768b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff                new StateChangeResult(networkId, wifiSsid, BSSID, newState)));
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sleep for a period of time.
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param secs the number of seconds to sleep
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static void nap(int secs) {
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Thread.sleep(secs * 1000);
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (InterruptedException ignore) {
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
782