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
35c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapndeimport java.util.HashMap;
36c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapndeimport java.util.Iterator;
3721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriffimport java.util.List;
38c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapndeimport java.util.Map;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.regex.Pattern;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.regex.Matcher;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Listens for events from the wpa_supplicant server, and passes them on
4455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * to the {@link StateMachine} for handling. Runs in its own thread.
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class WifiMonitor {
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
50c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde    private static final boolean DBG = false;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String TAG = "WifiMonitor";
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Events we receive from the supplicant daemon */
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int CONNECTED    = 1;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DISCONNECTED = 2;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int STATE_CHANGE = 3;
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int SCAN_RESULTS = 4;
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int LINK_SPEED   = 5;
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int TERMINATING  = 6;
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DRIVER_STATE = 7;
62b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff    private static final int EAP_FAILURE  = 8;
63c1b631e757999232674e53e9a1bc21abed6b1862Deepthi Gowri    private static final int ASSOC_REJECT = 9;
64c1b631e757999232674e53e9a1bc21abed6b1862Deepthi Gowri    private static final int UNKNOWN      = 10;
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** All events coming from the supplicant start with this prefix */
6755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String EVENT_PREFIX_STR = "CTRL-EVENT-";
6855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int EVENT_PREFIX_LEN_STR = EVENT_PREFIX_STR.length();
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** All WPA events coming from the supplicant start with this prefix */
7155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String WPA_EVENT_PREFIX_STR = "WPA:";
7255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String PASSWORD_MAY_BE_INCORRECT_STR =
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project       "pre-shared key may be incorrect";
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
75fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff    /* WPS events */
76d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    private static final String WPS_SUCCESS_STR = "WPS-SUCCESS";
7786a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff
7886a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff    /* Format: WPS-FAIL msg=%d [config_error=%d] [reason=%d (%s)] */
79d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    private static final String WPS_FAIL_STR    = "WPS-FAIL";
8086a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff    private static final String WPS_FAIL_PATTERN =
8186a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff            "WPS-FAIL msg=\\d+(?: config_error=(\\d+))?(?: reason=(\\d+))?";
8286a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff
8386a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff    /* config error code values for config_error=%d */
8486a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff    private static final int CONFIG_MULTIPLE_PBC_DETECTED = 12;
8586a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff    private static final int CONFIG_AUTH_FAILURE = 18;
8686a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff
8786a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff    /* reason code values for reason=%d */
8886a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff    private static final int REASON_TKIP_ONLY_PROHIBITED = 1;
8986a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff    private static final int REASON_WEP_PROHIBITED = 2;
9086a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff
9155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String WPS_OVERLAP_STR = "WPS-OVERLAP-DETECTED";
92d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    private static final String WPS_TIMEOUT_STR = "WPS-TIMEOUT";
93fcb659b66756ac02bd1491ae1365b27e8509a890Irfan Sheriff
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Names of events from wpa_supplicant (minus the prefix). In the
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * format descriptions, * &quot;<code>x</code>&quot;
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * designates a dynamic value that needs to be parsed out from the event
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * string
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CTRL-EVENT-CONNECTED - Connection to xx:xx:xx:xx:xx:xx completed
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </pre>
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <code>xx:xx:xx:xx:xx:xx</code> is the BSSID of the associated access point
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String CONNECTED_STR =    "CONNECTED";
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CTRL-EVENT-DISCONNECTED - Disconnect event - remove keys
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </pre>
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String DISCONNECTED_STR = "DISCONNECTED";
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CTRL-EVENT-STATE-CHANGE x
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </pre>
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <code>x</code> is the numerical value of the new state.
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String STATE_CHANGE_STR =  "STATE-CHANGE";
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CTRL-EVENT-SCAN-RESULTS ready
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </pre>
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String SCAN_RESULTS_STR =  "SCAN-RESULTS";
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CTRL-EVENT-LINK-SPEED x Mb/s
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </pre>
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@code x} is the link speed in Mb/sec.
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String LINK_SPEED_STR = "LINK-SPEED";
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CTRL-EVENT-TERMINATING - signal x
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </pre>
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <code>x</code> is the signal that caused termination.
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
14055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String TERMINATING_STR =  "TERMINATING";
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CTRL-EVENT-DRIVER-STATE state
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </pre>
1451523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff     * <code>state</code> can be HANGED
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
14755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String DRIVER_STATE_STR = "DRIVER-STATE";
148b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff    /**
149b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff     * <pre>
150b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff     * CTRL-EVENT-EAP-FAILURE EAP authentication failed
151b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff     * </pre>
152b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff     */
15355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String EAP_FAILURE_STR = "EAP-FAILURE";
154b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff
155b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff    /**
156b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff     * This indicates an authentication failure on EAP FAILURE event
157b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff     */
15855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String EAP_AUTH_FAILURE_STR = "EAP authentication failed";
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
161c1b631e757999232674e53e9a1bc21abed6b1862Deepthi Gowri     * This indicates an assoc reject event
162c1b631e757999232674e53e9a1bc21abed6b1862Deepthi Gowri     */
163c1b631e757999232674e53e9a1bc21abed6b1862Deepthi Gowri    private static final String ASSOC_REJECT_STR = "ASSOC-REJECT";
164c1b631e757999232674e53e9a1bc21abed6b1862Deepthi Gowri
165c1b631e757999232674e53e9a1bc21abed6b1862Deepthi Gowri    /**
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Regex pattern for extracting an Ethernet-style MAC address from a string.
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Matches a strings like the following:<pre>
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CTRL-EVENT-CONNECTED - Connection to 00:1e:58:ec:d5:6d completed (reauth) [id=1 id_str=]</pre>
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static Pattern mConnectedEventPattern =
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Pattern.compile("((?:[0-9a-f]{2}:){5}[0-9a-f]{2}) .* \\[id=([0-9]+) ");
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /** P2P events */
17455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_EVENT_PREFIX_STR = "P2P";
17555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
17655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo 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
17755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       name='p2p-TEST1' config_methods=0x188 dev_capab=0x27 group_capab=0x0 */
17855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_DEVICE_FOUND_STR = "P2P-DEVICE-FOUND";
17955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
18055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-DEVICE-LOST p2p_dev_addr=42:fc:89:e1:e2:27 */
18155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_DEVICE_LOST_STR = "P2P-DEVICE-LOST";
18255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
183c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff    /* P2P-FIND-STOPPED */
184c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff    private static final String P2P_FIND_STOPPED_STR = "P2P-FIND-STOPPED";
185c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff
18655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-GO-NEG-REQUEST 42:fc:89:a8:96:09 dev_passwd_id=4 */
18755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_GO_NEG_REQUEST_STR = "P2P-GO-NEG-REQUEST";
18855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
18955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_GO_NEG_SUCCESS_STR = "P2P-GO-NEG-SUCCESS";
19055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1919f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff    /* P2P-GO-NEG-FAILURE status=x */
19255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_GO_NEG_FAILURE_STR = "P2P-GO-NEG-FAILURE";
19355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
19455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_GROUP_FORMATION_SUCCESS_STR =
19555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            "P2P-GROUP-FORMATION-SUCCESS";
19655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
19755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_GROUP_FORMATION_FAILURE_STR =
19855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            "P2P-GROUP-FORMATION-FAILURE";
19955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
20055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-GROUP-STARTED p2p-wlan0-0 [client|GO] ssid="DIRECT-W8" freq=2437
20155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       [psk=2182b2e50e53f260d04f3c7b25ef33c965a3291b9b36b455a82d77fd82ca15bc|passphrase="fKG4jMe3"]
2020879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga       go_dev_addr=fa:7b:7a:42:02:13 [PERSISTENT] */
20355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_GROUP_STARTED_STR = "P2P-GROUP-STARTED";
20455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
20555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-GROUP-REMOVED p2p-wlan0-0 [client|GO] reason=REQUESTED */
20655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_GROUP_REMOVED_STR = "P2P-GROUP-REMOVED";
20755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
20855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-INVITATION-RECEIVED sa=fa:7b:7a:42:02:13 go_dev_addr=f8:7b:7a:42:02:13
20955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        bssid=fa:7b:7a:42:82:13 unknown-network */
21055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_INVITATION_RECEIVED_STR = "P2P-INVITATION-RECEIVED";
21155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
21255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-INVITATION-RESULT status=1 */
21355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_INVITATION_RESULT_STR = "P2P-INVITATION-RESULT";
21455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
21555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-PROV-DISC-PBC-REQ 42:fc:89:e1:e2:27 p2p_dev_addr=42:fc:89:e1:e2:27
21655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       pri_dev_type=1-0050F204-1 name='p2p-TEST2' config_methods=0x188 dev_capab=0x27
21755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       group_capab=0x0 */
21855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_PROV_DISC_PBC_REQ_STR = "P2P-PROV-DISC-PBC-REQ";
219618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
220618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    /* P2P-PROV-DISC-PBC-RESP 02:12:47:f2:5a:36 */
221618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    private static final String P2P_PROV_DISC_PBC_RSP_STR = "P2P-PROV-DISC-PBC-RESP";
222618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff
22355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-PROV-DISC-ENTER-PIN 42:fc:89:e1:e2:27 p2p_dev_addr=42:fc:89:e1:e2:27
22455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       pri_dev_type=1-0050F204-1 name='p2p-TEST2' config_methods=0x188 dev_capab=0x27
22555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       group_capab=0x0 */
22655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_PROV_DISC_ENTER_PIN_STR = "P2P-PROV-DISC-ENTER-PIN";
22755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P-PROV-DISC-SHOW-PIN 42:fc:89:e1:e2:27 44490607 p2p_dev_addr=42:fc:89:e1:e2:27
22855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       pri_dev_type=1-0050F204-1 name='p2p-TEST2' config_methods=0x188 dev_capab=0x27
22955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync       group_capab=0x0 */
23055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String P2P_PROV_DISC_SHOW_PIN_STR = "P2P-PROV-DISC-SHOW-PIN";
231c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff    /* P2P-PROV-DISC-FAILURE p2p_dev_addr=42:fc:89:e1:e2:27 */
232c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff    private static final String P2P_PROV_DISC_FAILURE_STR = "P2P-PROV-DISC-FAILURE";
23355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
23421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    /*
23521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Protocol format is as follows.<br>
23621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * See the Table.62 in the WiFi Direct specification for the detail.
23721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * ______________________________________________________________
23821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * |           Length(2byte)     | Type(1byte) | TransId(1byte)}|
23921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * ______________________________________________________________
24021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * | status(1byte)  |            vendor specific(variable)      |
24121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
24221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * P2P-SERV-DISC-RESP 42:fc:89:e1:e2:27 1 0300000101
24321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * length=3, service type=0(ALL Service), transaction id=1,
24421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * status=1(service protocol type not available)<br>
24521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
24621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * P2P-SERV-DISC-RESP 42:fc:89:e1:e2:27 1 0300020201
24721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * length=3, service type=2(UPnP), transaction id=2,
24821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * status=1(service protocol type not available)
24921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
25021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * P2P-SERV-DISC-RESP 42:fc:89:e1:e2:27 1 990002030010757569643a3131323
25121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * 2646534652d383537342d353961622d393332322d3333333435363738393034343a3
25221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * a75726e3a736368656d61732d75706e702d6f72673a736572766963653a436f6e746
25321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * 56e744469726563746f72793a322c757569643a36383539646564652d383537342d3
25421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * 53961622d393333322d3132333435363738393031323a3a75706e703a726f6f74646
25521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * 576696365
25621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * length=153,type=2(UPnP),transaction id=3,status=0
25721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
25821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * UPnP Protocol format is as follows.
25921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * ______________________________________________________
26021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * |  Version (1)  |          USN (Variable)            |
26121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
26221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * version=0x10(UPnP1.0) data=usn:uuid:1122de4e-8574-59ab-9322-33345678
26321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * 9044::urn:schemas-upnp-org:service:ContentDirectory:2,usn:uuid:6859d
26421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * ede-8574-59ab-9332-123456789012::upnp:rootdevice
26521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
26621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * P2P-SERV-DISC-RESP 58:17:0c:bc:dd:ca 21 1900010200045f6970
26721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * 70c00c000c01094d795072696e746572c027
26821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * length=25, type=1(Bonjour),transaction id=2,status=0
26921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
27021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * Bonjour Protocol format is as follows.
27121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * __________________________________________________________
27221ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * |DNS Name(Variable)|DNS Type(1)|Version(1)|RDATA(Variable)|
27321ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
27421ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * DNS Name=_ipp._tcp.local.,DNS type=12(PTR), Version=1,
27521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     * RDATA=MyPrinter._ipp._tcp.local.
27621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     *
27721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff     */
27821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    private static final String P2P_SERV_DISC_RESP_STR = "P2P-SERV-DISC-RESP";
27921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff
28055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String HOST_AP_EVENT_PREFIX_STR = "AP";
281bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff    /* AP-STA-CONNECTED 42:fc:89:a8:96:09 dev_addr=02:90:4c:a0:92:54 */
28255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String AP_STA_CONNECTED_STR = "AP-STA-CONNECTED";
28355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* AP-STA-DISCONNECTED 42:fc:89:a8:96:09 */
28455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String AP_STA_DISCONNECTED_STR = "AP-STA-DISCONNECTED";
28555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
28655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Supplicant events reported to a state machine */
28755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int BASE = Protocol.BASE_WIFI_MONITOR;
28855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
28955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Connection to supplicant established */
29055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int SUP_CONNECTION_EVENT                 = BASE + 1;
29155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Connection to supplicant lost */
29255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int SUP_DISCONNECTION_EVENT              = BASE + 2;
29355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync   /* Network connection completed */
29455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int NETWORK_CONNECTION_EVENT             = BASE + 3;
29555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Network disconnection completed */
29655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int NETWORK_DISCONNECTION_EVENT          = BASE + 4;
29755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Scan results are available */
29855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int SCAN_RESULTS_EVENT                   = BASE + 5;
29955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Supplicate state changed */
30055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int SUPPLICANT_STATE_CHANGE_EVENT        = BASE + 6;
30155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Password failure and EAP authentication failure */
30255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int AUTHENTICATION_FAILURE_EVENT         = BASE + 7;
303d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    /* WPS success detected */
304d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    public static final int WPS_SUCCESS_EVENT                    = BASE + 8;
305d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    /* WPS failure detected */
306d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    public static final int WPS_FAIL_EVENT                       = BASE + 9;
307d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     /* WPS overlap detected */
308d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    public static final int WPS_OVERLAP_EVENT                    = BASE + 10;
309d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff     /* WPS timeout detected */
310d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    public static final int WPS_TIMEOUT_EVENT                    = BASE + 11;
31155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Driver was hung */
312d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff    public static final int DRIVER_HUNG_EVENT                    = BASE + 12;
31355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
31455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* P2P events */
31555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_DEVICE_FOUND_EVENT               = BASE + 21;
31655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_DEVICE_LOST_EVENT                = BASE + 22;
31755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_GO_NEGOTIATION_REQUEST_EVENT     = BASE + 23;
31855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_GO_NEGOTIATION_SUCCESS_EVENT     = BASE + 25;
31955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_GO_NEGOTIATION_FAILURE_EVENT     = BASE + 26;
32055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_GROUP_FORMATION_SUCCESS_EVENT    = BASE + 27;
32155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_GROUP_FORMATION_FAILURE_EVENT    = BASE + 28;
32255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_GROUP_STARTED_EVENT              = BASE + 29;
32355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_GROUP_REMOVED_EVENT              = BASE + 30;
32455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_INVITATION_RECEIVED_EVENT        = BASE + 31;
32555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_INVITATION_RESULT_EVENT          = BASE + 32;
32655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int P2P_PROV_DISC_PBC_REQ_EVENT          = BASE + 33;
327618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    public static final int P2P_PROV_DISC_PBC_RSP_EVENT          = BASE + 34;
328618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    public static final int P2P_PROV_DISC_ENTER_PIN_EVENT        = BASE + 35;
329618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff    public static final int P2P_PROV_DISC_SHOW_PIN_EVENT         = BASE + 36;
330c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff    public static final int P2P_FIND_STOPPED_EVENT               = BASE + 37;
33121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff    public static final int P2P_SERV_DISC_RESP_EVENT             = BASE + 38;
332c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff    public static final int P2P_PROV_DISC_FAILURE_EVENT          = BASE + 39;
33355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
33455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* hostap events */
33555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int AP_STA_DISCONNECTED_EVENT            = BASE + 41;
33655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final int AP_STA_CONNECTED_EVENT               = BASE + 42;
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
338c1b631e757999232674e53e9a1bc21abed6b1862Deepthi Gowri    /* Indicates assoc reject event */
339c1b631e757999232674e53e9a1bc21abed6b1862Deepthi Gowri    public static final int ASSOCIATION_REJECTION_EVENT          = BASE + 43;
34005d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff    /**
34105d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff     * This indicates the supplicant connection for the monitor is closed
34205d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff     */
34355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String MONITOR_SOCKET_CLOSED_STR = "connection closed";
34405d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff
34505d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff    /**
34605d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff     * This indicates a read error on the monitor socket conenction
34705d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff     */
34855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String WPA_RECV_ERROR_STR = "recv error";
34905d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff
35005d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff    /**
35105d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff     * Max errors before we close supplicant connection
35205d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff     */
35305d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff    private static final int MAX_RECV_ERRORS    = 10;
35405d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff
355c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde    private final String mInterfaceName;
356c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde    private final WifiNative mWifiNative;
357c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde    private final StateMachine mWifiStateMachine;
358c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde    private boolean mMonitoring;
359c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde
360fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff    public WifiMonitor(StateMachine wifiStateMachine, WifiNative wifiNative) {
361c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        if (DBG) Log.d(TAG, "Creating WifiMonitor");
362fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff        mWifiNative = wifiNative;
363c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        mInterfaceName = wifiNative.mInterfaceName;
364c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        mWifiStateMachine = wifiStateMachine;
365c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        mMonitoring = false;
366c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde
367c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        WifiMonitorSingleton.getMonitor().registerInterfaceMonitor(mInterfaceName, this);
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void startMonitoring() {
371c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        WifiMonitorSingleton.getMonitor().startMonitoring(mInterfaceName);
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
374c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde    public void stopMonitoring() {
375c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        WifiMonitorSingleton.getMonitor().stopMonitoring(mInterfaceName);
376c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde    }
377c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde
378c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde    public void stopSupplicant() {
379c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        WifiMonitorSingleton.getMonitor().stopSupplicant();
380c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde    }
381c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde
382c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde    public void killSupplicant(boolean p2pSupported) {
383c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        WifiMonitorSingleton.getMonitor().killSupplicant(p2pSupported);
384c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde    }
385c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde
386c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde    private static class WifiMonitorSingleton {
387c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        private static Object sSingletonLock = new Object();
388c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        private static WifiMonitorSingleton sWifiMonitorSingleton = null;
389c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        private HashMap<String, WifiMonitor> mIfaceMap = new HashMap<String, WifiMonitor>();
390c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        private boolean mConnected = false;
391c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        private WifiNative mWifiNative;
392c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde
393c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        private WifiMonitorSingleton() {
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
395a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff
396c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        static WifiMonitorSingleton getMonitor() {
397c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            if (DBG) Log.d(TAG, "WifiMonitorSingleton gotten");
398c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            synchronized (sSingletonLock) {
399c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                if (sWifiMonitorSingleton == null) {
400c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    if (DBG) Log.d(TAG, "WifiMonitorSingleton created");
401c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    sWifiMonitorSingleton = new WifiMonitorSingleton();
402c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                }
403c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            }
404c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            return sWifiMonitorSingleton;
405c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        }
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
407c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        public synchronized void startMonitoring(String iface) {
408c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            WifiMonitor m = mIfaceMap.get(iface);
409c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            if (m == null) {
410c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                Log.e(TAG, "startMonitor called with unknown iface=" + iface);
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
414c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            Log.d(TAG, "startMonitoring(" + iface + ") with mConnected = " + mConnected);
415c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde
416c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            if (mConnected) {
417c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                m.mMonitoring = true;
418c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                m.mWifiStateMachine.sendMessage(SUP_CONNECTION_EVENT);
419c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            } else {
420c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                if (DBG) Log.d(TAG, "connecting to supplicant");
421c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                int connectTries = 0;
422c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                while (true) {
423c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    if (mWifiNative.connectToSupplicant()) {
424c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        m.mMonitoring = true;
425c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        m.mWifiStateMachine.sendMessage(SUP_CONNECTION_EVENT);
426c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        new MonitorThread(mWifiNative, this).start();
427c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        mConnected = true;
428c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        break;
429c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    }
430c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    if (connectTries++ < 5) {
431c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        try {
432c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                            Thread.sleep(1000);
433c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        } catch (InterruptedException ignore) {
434c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        }
435c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    } else {
436c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        mIfaceMap.remove(iface);
437c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        m.mWifiStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
438e8fabf98fb5e5543050679b4f4bff677bbc4164bVinit Deshapnde                        Log.e(TAG, "startMonitoring(" + iface + ") failed!");
439c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        break;
440c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    }
441c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                }
442c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            }
443c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        }
444c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde
445c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        public synchronized void stopMonitoring(String iface) {
446c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            WifiMonitor m = mIfaceMap.get(iface);
447c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            if (DBG) Log.d(TAG, "stopMonitoring(" + iface + ") = " + m.mWifiStateMachine);
448c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            m.mMonitoring = false;
449c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            m.mWifiStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
450c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        }
451c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde
452c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        public synchronized void registerInterfaceMonitor(String iface, WifiMonitor m) {
453c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            if (DBG) Log.d(TAG, "registerInterface(" + iface + "+" + m.mWifiStateMachine + ")");
454c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            mIfaceMap.put(iface, m);
455c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            if (mWifiNative == null) {
456c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                mWifiNative = m.mWifiNative;
457c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            }
458c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        }
459c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde
460c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        public synchronized void unregisterInterfaceMonitor(String iface) {
461c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            // REVIEW: When should we call this? If this isn't called, then WifiMonitor
462c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            // objects will remain in the mIfaceMap; and won't ever get deleted
463c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde
464c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            WifiMonitor m = mIfaceMap.remove(iface);
465c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            if (DBG) Log.d(TAG, "unregisterInterface(" + iface + "+" + m.mWifiStateMachine + ")");
466c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        }
467c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde
468c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        public synchronized void stopSupplicant() {
469c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            mWifiNative.stopSupplicant();
470c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        }
471c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde
472c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        public synchronized void killSupplicant(boolean p2pSupported) {
473c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            mWifiNative.killSupplicant(p2pSupported);
474c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            mConnected = false;
475c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            Iterator<Map.Entry<String, WifiMonitor>> it = mIfaceMap.entrySet().iterator();
476c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            while (it.hasNext()) {
477c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                Map.Entry<String, WifiMonitor> e = it.next();
478c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                WifiMonitor m = e.getValue();
479c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                m.mMonitoring = false;
480c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            }
481c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        }
482c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde
483c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        private synchronized WifiMonitor getMonitor(String iface) {
484c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            return mIfaceMap.get(iface);
485c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        }
486c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde    }
487c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde
488c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde    private static class MonitorThread extends Thread {
489c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        private final WifiNative mWifiNative;
490c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        private final WifiMonitorSingleton mWifiMonitorSingleton;
491c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        private int mRecvErrors = 0;
492c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        private StateMachine mStateMachine = null;
493c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde
494c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        public MonitorThread(WifiNative wifiNative, WifiMonitorSingleton wifiMonitorSingleton) {
495c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            super("WifiMonitor");
496c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            mWifiNative = wifiNative;
497c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            mWifiMonitorSingleton = wifiMonitorSingleton;
498c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        }
499c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde
500c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        public void run() {
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //noinspection InfiniteLoopStatement
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (;;) {
503fc7f95abcda6fa35c175f9225358ea75c22952abIrfan Sheriff                String eventStr = mWifiNative.waitForEvent();
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Skip logging the common but mostly uninteresting scan-results event
506c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                if (DBG && eventStr.indexOf(SCAN_RESULTS_STR) == -1) {
50755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    Log.d(TAG, "Event [" + eventStr + "]");
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
509c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde
510bbabe1433361d83e4cabab80acdc839e437a8452Dmitry Shmidt                String iface = "p2p0";
511c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                WifiMonitor m = null;
512c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                mStateMachine = null;
513c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde
514c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                if (eventStr.startsWith("IFNAME=")) {
515c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    int space = eventStr.indexOf(' ');
516c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    if (space != -1) {
517bbabe1433361d83e4cabab80acdc839e437a8452Dmitry Shmidt                        iface = eventStr.substring(7,space);
518c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        m = mWifiMonitorSingleton.getMonitor(iface);
5194b2766a3d8eaf6f7f50c05108c15010a3f275bdeVinit Deshapnde                        if (m == null && iface.startsWith("p2p-")) {
5204b2766a3d8eaf6f7f50c05108c15010a3f275bdeVinit Deshapnde                            // p2p interfaces are created dynamically, but we have
5214b2766a3d8eaf6f7f50c05108c15010a3f275bdeVinit Deshapnde                            // only one P2p state machine monitoring all of them; look
5224b2766a3d8eaf6f7f50c05108c15010a3f275bdeVinit Deshapnde                            // for it explicitly, and send messages there ..
5234b2766a3d8eaf6f7f50c05108c15010a3f275bdeVinit Deshapnde                            m = mWifiMonitorSingleton.getMonitor("p2p0");
5244b2766a3d8eaf6f7f50c05108c15010a3f275bdeVinit Deshapnde                        }
525bbabe1433361d83e4cabab80acdc839e437a8452Dmitry Shmidt                        eventStr = eventStr.substring(space + 1);
526bbabe1433361d83e4cabab80acdc839e437a8452Dmitry Shmidt                    }
527bbabe1433361d83e4cabab80acdc839e437a8452Dmitry Shmidt                } else {
528bbabe1433361d83e4cabab80acdc839e437a8452Dmitry Shmidt                    // events without prefix belong to p2p0 monitor
529bbabe1433361d83e4cabab80acdc839e437a8452Dmitry Shmidt                    m = mWifiMonitorSingleton.getMonitor("p2p0");
530bbabe1433361d83e4cabab80acdc839e437a8452Dmitry Shmidt                }
531bbabe1433361d83e4cabab80acdc839e437a8452Dmitry Shmidt
532bbabe1433361d83e4cabab80acdc839e437a8452Dmitry Shmidt                if (m != null) {
533bbabe1433361d83e4cabab80acdc839e437a8452Dmitry Shmidt                    if (m.mMonitoring) {
534bbabe1433361d83e4cabab80acdc839e437a8452Dmitry Shmidt                        mStateMachine = m.mWifiStateMachine;
535bbabe1433361d83e4cabab80acdc839e437a8452Dmitry Shmidt                    } else {
536bbabe1433361d83e4cabab80acdc839e437a8452Dmitry Shmidt                        if (DBG) Log.d(TAG, "Dropping event because monitor (" + iface +
537bbabe1433361d83e4cabab80acdc839e437a8452Dmitry Shmidt                                            ") is stopped");
538bbabe1433361d83e4cabab80acdc839e437a8452Dmitry Shmidt                        continue;
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
542c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                if (mStateMachine != null) {
543c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    if (dispatchEvent(eventStr)) {
544c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        break;
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
547c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    if (DBG) Log.d(TAG, "Sending to all monitors because there's no interface id");
548c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    boolean done = false;
549c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    Iterator<Map.Entry<String, WifiMonitor>> it =
550c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                            mWifiMonitorSingleton.mIfaceMap.entrySet().iterator();
551c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    while (it.hasNext()) {
552c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        Map.Entry<String, WifiMonitor> e = it.next();
553c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        m = e.getValue();
554c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        mStateMachine = m.mWifiStateMachine;
555c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        if (dispatchEvent(eventStr)) {
556c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                            done = true;
55705d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                        }
55805d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff                    }
55905d72117f9b449914979b008c17edd6c5645565bIrfan Sheriff
560c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    if (done) {
561c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        // After this thread terminates, we'll no longer
562c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        // be connected to the supplicant
563c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        if (DBG) Log.d(TAG, "Disconnecting from the supplicant, no more events");
564c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        mWifiMonitorSingleton.mConnected = false;
565c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        break;
566b98d878f43748a64c68ffe05ce64c5b7c72fe922Irfan Sheriff                    }
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
571c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        /* @return true if the event was supplicant disconnection */
572c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        private boolean dispatchEvent(String eventStr) {
573c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde
574c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            if (!eventStr.startsWith(EVENT_PREFIX_STR)) {
575c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                if (eventStr.startsWith(WPA_EVENT_PREFIX_STR) &&
576c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        0 < eventStr.indexOf(PASSWORD_MAY_BE_INCORRECT_STR)) {
577c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    mStateMachine.sendMessage(AUTHENTICATION_FAILURE_EVENT);
578c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                } else if (eventStr.startsWith(WPS_SUCCESS_STR)) {
579c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    mStateMachine.sendMessage(WPS_SUCCESS_EVENT);
580c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                } else if (eventStr.startsWith(WPS_FAIL_STR)) {
581c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    handleWpsFailEvent(eventStr);
582c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                } else if (eventStr.startsWith(WPS_OVERLAP_STR)) {
583c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    mStateMachine.sendMessage(WPS_OVERLAP_EVENT);
584c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                } else if (eventStr.startsWith(WPS_TIMEOUT_STR)) {
585c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    mStateMachine.sendMessage(WPS_TIMEOUT_EVENT);
586c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                } else if (eventStr.startsWith(P2P_EVENT_PREFIX_STR)) {
587c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    handleP2pEvents(eventStr);
588c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                } else if (eventStr.startsWith(HOST_AP_EVENT_PREFIX_STR)) {
589c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    handleHostApEvents(eventStr);
590c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                }
591c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                else {
592c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    if (DBG) Log.w(TAG, "couldn't identify event type - " + eventStr);
593c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                }
594c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                return false;
595c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            }
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
597c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            String eventName = eventStr.substring(EVENT_PREFIX_LEN_STR);
598c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            int nameEnd = eventName.indexOf(' ');
599c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            if (nameEnd != -1)
600c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                eventName = eventName.substring(0, nameEnd);
601c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            if (eventName.length() == 0) {
602c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                if (DBG) Log.i(TAG, "Received wpa_supplicant event with empty event name");
603c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                return false;
604c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            }
605c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            /*
606c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde             * Map event name into event enum
607c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde             */
608c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            int event;
609c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            if (eventName.equals(CONNECTED_STR))
610c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                event = CONNECTED;
611c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            else if (eventName.equals(DISCONNECTED_STR))
612c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                event = DISCONNECTED;
613c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            else if (eventName.equals(STATE_CHANGE_STR))
614c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                event = STATE_CHANGE;
615c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            else if (eventName.equals(SCAN_RESULTS_STR))
616c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                event = SCAN_RESULTS;
617c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            else if (eventName.equals(LINK_SPEED_STR))
618c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                event = LINK_SPEED;
619c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            else if (eventName.equals(TERMINATING_STR))
620c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                event = TERMINATING;
621c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            else if (eventName.equals(DRIVER_STATE_STR))
622c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                event = DRIVER_STATE;
623c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            else if (eventName.equals(EAP_FAILURE_STR))
624c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                event = EAP_FAILURE;
625c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            else if (eventName.equals(ASSOC_REJECT_STR))
626c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                event = ASSOC_REJECT;
627c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            else
628c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                event = UNKNOWN;
629c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde
630c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            String eventData = eventStr;
631c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            if (event == DRIVER_STATE || event == LINK_SPEED)
632c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                eventData = eventData.split(" ")[1];
633c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            else if (event == STATE_CHANGE || event == EAP_FAILURE) {
634c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                int ind = eventStr.indexOf(" ");
635c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                if (ind != -1) {
636c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    eventData = eventStr.substring(ind + 1);
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
638c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            } else {
639c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                int ind = eventStr.indexOf(" - ");
640c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                if (ind != -1) {
641c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    eventData = eventStr.substring(ind + 3);
642c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                }
643c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            }
644c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde
645c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            if (event == STATE_CHANGE) {
646c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                handleSupplicantStateChange(eventData);
647c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            } else if (event == DRIVER_STATE) {
648c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                handleDriverEvent(eventData);
649c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            } else if (event == TERMINATING) {
650c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                /**
651c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                 * Close the supplicant connection if we see
652c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                 * too many recv errors
653c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                 */
654c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                if (eventData.startsWith(WPA_RECV_ERROR_STR)) {
655c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    if (++mRecvErrors > MAX_RECV_ERRORS) {
656c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        if (DBG) {
657c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                            Log.d(TAG, "too many recv errors, closing connection");
658c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        }
659c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    } else {
660c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        return false;
661c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    }
662c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                }
663c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde
664c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                // notify and exit
665c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                mStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
666c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                return true;
667c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            } else if (event == EAP_FAILURE) {
668c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                if (eventData.startsWith(EAP_AUTH_FAILURE_STR)) {
669c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    mStateMachine.sendMessage(AUTHENTICATION_FAILURE_EVENT);
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
671c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            } else if (event == ASSOC_REJECT) {
672c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                mStateMachine.sendMessage(ASSOCIATION_REJECTION_EVENT);
673c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            } else {
674c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                handleEvent(event, eventData);
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
676c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            mRecvErrors = 0;
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private void handleDriverEvent(String state) {
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (state == null) {
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6841523da22e91217e06a01610c202d5e52c2e9dfceIrfan Sheriff            if (state.equals("HANGED")) {
68555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(DRIVER_HUNG_EVENT);
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Handle all supplicant events except STATE-CHANGE
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param event the event type
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param remainder the rest of the string following the
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * event name and &quot;&#8195;&#8212;&#8195;&quot;
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void handleEvent(int event, String remainder) {
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (event) {
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case DISCONNECTED:
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    handleNetworkStateChange(NetworkInfo.DetailedState.DISCONNECTED, remainder);
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case CONNECTED:
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    handleNetworkStateChange(NetworkInfo.DetailedState.CONNECTED, remainder);
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case SCAN_RESULTS:
70655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                    mStateMachine.sendMessage(SCAN_RESULTS_EVENT);
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case UNKNOWN:
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
71486a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        private void handleWpsFailEvent(String dataString) {
71586a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff            final Pattern p = Pattern.compile(WPS_FAIL_PATTERN);
71686a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff            Matcher match = p.matcher(dataString);
71786a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff            if (match.find()) {
71886a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                String cfgErr = match.group(1);
71986a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                String reason = match.group(2);
72086a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff
72186a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                if (reason != null) {
72286a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    switch(Integer.parseInt(reason)) {
72386a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                        case REASON_TKIP_ONLY_PROHIBITED:
72486a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                            mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT,
72586a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                                    WifiManager.WPS_TKIP_ONLY_PROHIBITED, 0));
72686a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                            return;
72786a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                        case REASON_WEP_PROHIBITED:
72886a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                            mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT,
72986a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                                    WifiManager.WPS_WEP_PROHIBITED, 0));
73086a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                            return;
73186a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    }
73286a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                }
73386a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                if (cfgErr != null) {
73486a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    switch(Integer.parseInt(cfgErr)) {
73586a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                        case CONFIG_AUTH_FAILURE:
73686a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                            mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT,
73786a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                                    WifiManager.WPS_AUTH_FAILURE, 0));
73886a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                            return;
73986a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                        case CONFIG_MULTIPLE_PBC_DETECTED:
74086a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                            mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT,
74186a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                                    WifiManager.WPS_OVERLAP_ERROR, 0));
74286a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                            return;
74386a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    }
74486a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                }
74586a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff            }
74686a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff            //For all other errors, return a generic internal error
74786a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff            mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT,
74886a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff                    WifiManager.ERROR, 0));
74986a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff        }
75086a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff
7519f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff        /* <event> status=<err> and the special case of <event> reason=FREQ_CONFLICT */
7529f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff        private P2pStatus p2pError(String dataString) {
7539f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            P2pStatus err = P2pStatus.UNKNOWN;
7549f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            String[] tokens = dataString.split(" ");
7559f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            if (tokens.length < 2) return err;
7569f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            String[] nameValue = tokens[1].split("=");
7579f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            if (nameValue.length != 2) return err;
7589f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff
7599f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            /* Handle the special case of reason=FREQ+CONFLICT */
7609f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            if (nameValue[1].equals("FREQ_CONFLICT")) {
7619f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                return P2pStatus.NO_COMMON_CHANNEL;
7629f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            }
7639f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            try {
7649f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                err = P2pStatus.valueOf(Integer.parseInt(nameValue[1]));
7659f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            } catch (NumberFormatException e) {
7669f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                e.printStackTrace();
7679f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            }
7689f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff            return err;
7699f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff        }
7709f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
77255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync         * Handle p2p events
77355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync         */
77455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private void handleP2pEvents(String dataString) {
77555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            if (dataString.startsWith(P2P_DEVICE_FOUND_STR)) {
77655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_DEVICE_FOUND_EVENT, new WifiP2pDevice(dataString));
77755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_DEVICE_LOST_STR)) {
77855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_DEVICE_LOST_EVENT, new WifiP2pDevice(dataString));
779c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff            } else if (dataString.startsWith(P2P_FIND_STOPPED_STR)) {
780c111d1caa8d4cc5d2139b5abd4d2db1f78560effIrfan Sheriff                mStateMachine.sendMessage(P2P_FIND_STOPPED_EVENT);
78155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_GO_NEG_REQUEST_STR)) {
78255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_GO_NEGOTIATION_REQUEST_EVENT,
78355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        new WifiP2pConfig(dataString));
78455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_GO_NEG_SUCCESS_STR)) {
78555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_GO_NEGOTIATION_SUCCESS_EVENT);
78655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_GO_NEG_FAILURE_STR)) {
7879f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                mStateMachine.sendMessage(P2P_GO_NEGOTIATION_FAILURE_EVENT, p2pError(dataString));
78855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_GROUP_FORMATION_SUCCESS_STR)) {
78955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_GROUP_FORMATION_SUCCESS_EVENT);
79055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_GROUP_FORMATION_FAILURE_STR)) {
7919f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                mStateMachine.sendMessage(P2P_GROUP_FORMATION_FAILURE_EVENT, p2pError(dataString));
79255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_GROUP_STARTED_STR)) {
79355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_GROUP_STARTED_EVENT, new WifiP2pGroup(dataString));
79455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_GROUP_REMOVED_STR)) {
79555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_GROUP_REMOVED_EVENT, new WifiP2pGroup(dataString));
79655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_INVITATION_RECEIVED_STR)) {
79755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_INVITATION_RECEIVED_EVENT,
79855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                        new WifiP2pGroup(dataString));
79955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_INVITATION_RESULT_STR)) {
8009f452d0b5ccad77fb6acfd1b20d5f77c9f425d22Irfan Sheriff                mStateMachine.sendMessage(P2P_INVITATION_RESULT_EVENT, p2pError(dataString));
80155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_PROV_DISC_PBC_REQ_STR)) {
80255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_PROV_DISC_PBC_REQ_EVENT,
803618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        new WifiP2pProvDiscEvent(dataString));
804618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            } else if (dataString.startsWith(P2P_PROV_DISC_PBC_RSP_STR)) {
805618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                mStateMachine.sendMessage(P2P_PROV_DISC_PBC_RSP_EVENT,
806618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        new WifiP2pProvDiscEvent(dataString));
80755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (dataString.startsWith(P2P_PROV_DISC_ENTER_PIN_STR)) {
80855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                mStateMachine.sendMessage(P2P_PROV_DISC_ENTER_PIN_EVENT,
809618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        new WifiP2pProvDiscEvent(dataString));
810618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff            } else if (dataString.startsWith(P2P_PROV_DISC_SHOW_PIN_STR)) {
811618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                mStateMachine.sendMessage(P2P_PROV_DISC_SHOW_PIN_EVENT,
812618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                        new WifiP2pProvDiscEvent(dataString));
813c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff            } else if (dataString.startsWith(P2P_PROV_DISC_FAILURE_STR)) {
814c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff                mStateMachine.sendMessage(P2P_PROV_DISC_FAILURE_EVENT);
81521ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff            } else if (dataString.startsWith(P2P_SERV_DISC_RESP_STR)) {
81621ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                List<WifiP2pServiceResponse> list = WifiP2pServiceResponse.newInstance(dataString);
81721ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                if (list != null) {
81821ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    mStateMachine.sendMessage(P2P_SERV_DISC_RESP_EVENT, list);
81921ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                } else {
82021ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                    Log.e(TAG, "Null service resp " + dataString);
82121ba8153325e010224c6bc75a0acdc98b6ca82e8Irfan Sheriff                }
82255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
82355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
82455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
82555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        /**
82655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync         * Handle hostap events
82755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync         */
82855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        private void handleHostApEvents(String dataString) {
82955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            String[] tokens = dataString.split(" ");
83061472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga            /* AP-STA-CONNECTED 42:fc:89:a8:96:09 p2p_dev_addr=02:90:4c:a0:92:54 */
83155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            if (tokens[0].equals(AP_STA_CONNECTED_STR)) {
83261472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                mStateMachine.sendMessage(AP_STA_CONNECTED_EVENT, new WifiP2pDevice(dataString));
83361472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga            /* AP-STA-DISCONNECTED 42:fc:89:a8:96:09 p2p_dev_addr=02:90:4c:a0:92:54 */
83455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            } else if (tokens[0].equals(AP_STA_DISCONNECTED_STR)) {
83561472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                mStateMachine.sendMessage(AP_STA_DISCONNECTED_EVENT, new WifiP2pDevice(dataString));
83655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
83755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
83855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
83955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        /**
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Handle the supplicant STATE-CHANGE event
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param dataString New supplicant state string in the format:
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * id=network-id state=new-state
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private void handleSupplicantStateChange(String dataString) {
845b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff            WifiSsid wifiSsid = null;
84660c8c1570be28eba4cfb9969f5bbee8cbd66f37eIrfan Sheriff            int index = dataString.lastIndexOf("SSID=");
847b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff            if (index != -1) {
848b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff                wifiSsid = WifiSsid.createFromAsciiEncoded(
849b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff                        dataString.substring(index + 5));
850b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff            }
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String[] dataTokens = dataString.split(" ");
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8530049a1bf3f8bae3a10cfeff38aefce215bf1298bIrfan Sheriff            String BSSID = null;
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int networkId = -1;
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int newState  = -1;
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (String token : dataTokens) {
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String[] nameValue = token.split("=");
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (nameValue.length != 2) {
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8620049a1bf3f8bae3a10cfeff38aefce215bf1298bIrfan Sheriff                if (nameValue[0].equals("BSSID")) {
8630049a1bf3f8bae3a10cfeff38aefce215bf1298bIrfan Sheriff                    BSSID = nameValue[1];
8640049a1bf3f8bae3a10cfeff38aefce215bf1298bIrfan Sheriff                    continue;
8650049a1bf3f8bae3a10cfeff38aefce215bf1298bIrfan Sheriff                }
8660049a1bf3f8bae3a10cfeff38aefce215bf1298bIrfan Sheriff
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int value;
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    value = Integer.parseInt(nameValue[1]);
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (NumberFormatException e) {
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (nameValue[0].equals("id")) {
8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    networkId = value;
8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (nameValue[0].equals("state")) {
8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    newState = value;
8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (newState == -1) return;
8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            SupplicantState newSupplicantState = SupplicantState.INVALID;
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (SupplicantState state : SupplicantState.values()) {
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (state.ordinal() == newState) {
8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    newSupplicantState = state;
8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (newSupplicantState == SupplicantState.INVALID) {
8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.w(TAG, "Invalid supplicant state: " + newState);
8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
893b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff            notifySupplicantStateChange(networkId, wifiSsid, BSSID, newSupplicantState);
8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
896c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        private void handleNetworkStateChange(NetworkInfo.DetailedState newState, String data) {
897c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            String BSSID = null;
898c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            int networkId = -1;
899c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            if (newState == NetworkInfo.DetailedState.CONNECTED) {
900c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                Matcher match = mConnectedEventPattern.matcher(data);
901c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                if (!match.find()) {
902c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    if (DBG) Log.d(TAG, "Could not find BSSID in CONNECTED event string");
903c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                } else {
904c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    BSSID = match.group(1);
905c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    try {
906c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        networkId = Integer.parseInt(match.group(2));
907c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    } catch (NumberFormatException e) {
908c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        networkId = -1;
909c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    }
9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
911c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                notifyNetworkStateChange(newState, BSSID, networkId);
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
91455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
915c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        /**
916c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde         * Send the state machine a notification that the state of Wifi connectivity
917c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde         * has changed.
918c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde         * @param networkId the configured network on which the state change occurred
919c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde         * @param newState the new network state
920c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde         * @param BSSID when the new state is {@link DetailedState#CONNECTED
921c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde         * NetworkInfo.DetailedState.CONNECTED},
922c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde         * this is the MAC address of the access point. Otherwise, it
923c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde         * is {@code null}.
924c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde         */
925c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        void notifyNetworkStateChange(NetworkInfo.DetailedState newState, String BSSID, int netId) {
926c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            if (newState == NetworkInfo.DetailedState.CONNECTED) {
927c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                Message m = mStateMachine.obtainMessage(NETWORK_CONNECTION_EVENT,
928c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        netId, 0, BSSID);
929c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                mStateMachine.sendMessage(m);
930c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            } else {
931c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                Message m = mStateMachine.obtainMessage(NETWORK_DISCONNECTION_EVENT,
932c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                        netId, 0, BSSID);
933c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                mStateMachine.sendMessage(m);
934c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            }
93555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
93655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
937c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        /**
938c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde         * Send the state machine a notification that the state of the supplicant
939c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde         * has changed.
940c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde         * @param networkId the configured network on which the state change occurred
941c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde         * @param wifiSsid network name
942c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde         * @param BSSID network address
943c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde         * @param newState the new {@code SupplicantState}
944c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde         */
945c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde        void notifySupplicantStateChange(int networkId, WifiSsid wifiSsid, String BSSID,
946c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                SupplicantState newState) {
947c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde            mStateMachine.sendMessage(mStateMachine.obtainMessage(SUPPLICANT_STATE_CHANGE_EVENT,
948c249c2cc6b601ed1ff063f1748ba4399b9270209Vinit Deshapnde                    new StateChangeResult(networkId, wifiSsid, BSSID, newState)));
9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
952